diff --git a/.github/workflows/service-directory-snippets.yaml b/.github/workflows/service-directory-snippets.yaml new file mode 100644 index 0000000000..db4ac951e0 --- /dev/null +++ b/.github/workflows/service-directory-snippets.yaml @@ -0,0 +1,68 @@ +name: service-directory-snippets +on: + push: + branches: + - main + paths: + - 'service-directory/snippets/**' + pull_request: + paths: + - 'service-directory/snippets/**' + pull_request_target: + types: [labeled] + paths: + - 'service-directory/snippets/**' + schedule: + - cron: '0 0 * * 0' +jobs: + test: + if: ${{ github.event.action != 'labeled' || github.event.label.name == 'actions:force-run' }} + runs-on: ubuntu-latest + timeout-minutes: 60 + permissions: + contents: 'write' + pull-requests: 'write' + id-token: 'write' + steps: + - uses: actions/checkout@v3.1.0 + with: + ref: ${{github.event.pull_request.head.sha}} + - uses: 'google-github-actions/auth@v1.0.0' + with: + workload_identity_provider: 'projects/1046198160504/locations/global/workloadIdentityPools/github-actions-pool/providers/github-actions-provider' + service_account: 'kokoro-system-test@long-door-651.iam.gserviceaccount.com' + create_credentials_file: 'true' + access_token_lifetime: 600s + - uses: actions/setup-node@v3.5.1 + with: + node-version: 16 + - run: npm install + working-directory: service-directory/snippets + - run: npm test + working-directory: service-directory/snippets + env: + MOCHA_REPORTER_SUITENAME: service_directory_snippets + MOCHA_REPORTER_OUTPUT: service_directory_snippets_sponge_log.xml + MOCHA_REPORTER: xunit + - if: ${{ github.event.action == 'labeled' && github.event.label.name == 'actions:force-run' }} + uses: actions/github-script@v6 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + try { + await github.rest.issues.removeLabel({ + name: 'actions:force-run', + owner: 'GoogleCloudPlatform', + repo: 'nodejs-docs-samples', + issue_number: context.payload.pull_request.number + }); + } catch (e) { + if (!e.message.includes('Label does not exist')) { + throw e; + } + } + - if: ${{ github.event_name == 'schedule'}} + run: | + curl https://github.com/googleapis/repo-automation-bots/releases/download/flakybot-1.1.0/flakybot -o flakybot -s -L + chmod +x ./flakybot + ./flakybot --repo GoogleCloudPlatform/nodejs-docs-samples --commit_hash ${{github.sha}} --build_url https://github.com/${{github.repository}}/actions/runs/${{github.run_id}} diff --git a/.github/workflows/workflows.json b/.github/workflows/workflows.json index ea4290814e..0be8f5d7f2 100644 --- a/.github/workflows/workflows.json +++ b/.github/workflows/workflows.json @@ -57,6 +57,7 @@ "datacatalog/quickstart", "datastore/functions", "scheduler", + "service-directory/snippets", "talent", "video-intelligence", "contact-center-insights", diff --git a/service-directory/snippets/createEndpoint.js b/service-directory/snippets/createEndpoint.js new file mode 100644 index 0000000000..a6ade8e47d --- /dev/null +++ b/service-directory/snippets/createEndpoint.js @@ -0,0 +1,67 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +'use strict'; + +async function main( + projectId = 'my-project', + locationId = 'us-east1', + namespaceId = 'my-namespace', + serviceId = 'my-service', + endpointId = 'my-endpoint' +) { + // [START servicedirectory_create_endpoint] + // + // TODO(developer): Uncomment these variables before running the sample. + // + // const projectId = 'my-project'; + // const locationId = 'us-central1'; + // const namespaceId = 'my-namespace'; + // const serviceId = 'my-service'; + // const endpointId = 'my-endpoint'; + + // Imports the Google Cloud client library + const { + RegistrationServiceClient, + } = require('@google-cloud/service-directory'); + + // Creates a client + const registrationServiceClient = new RegistrationServiceClient(); + + // Build the service name + const serviceName = registrationServiceClient.servicePath( + projectId, + locationId, + namespaceId, + serviceId + ); + + async function createEndpoint() { + const [endpoint] = await registrationServiceClient.createEndpoint({ + parent: serviceName, + endpointId: endpointId, + endpoint: {address: '10.0.0.1', port: 8080}, + }); + + console.log(`Created endpoint: ${endpoint.name}`); + return endpoint; + } + + return createEndpoint(); + // [END servicedirectory_create_endpoint] +} + +const args = process.argv.slice(2); +main(...args).catch(console.error); diff --git a/service-directory/snippets/createNamespace.js b/service-directory/snippets/createNamespace.js new file mode 100644 index 0000000000..329b4eb141 --- /dev/null +++ b/service-directory/snippets/createNamespace.js @@ -0,0 +1,60 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +'use strict'; + +async function main( + projectId = 'my-project', + locationId = 'us-central1', + namespaceId = 'my-namespace' +) { + // [START servicedirectory_create_namespace] + // + // TODO(developer): Uncomment these variables before running the sample. + // + // const projectId = 'my-project'; + // const locationId = 'us-central1'; + // const namespaceId = 'my-namespace'; + + // Imports the Google Cloud client library + const { + RegistrationServiceClient, + } = require('@google-cloud/service-directory'); + + // Creates a client + const registrationServiceClient = new RegistrationServiceClient(); + + // Build the location name + const locationName = registrationServiceClient.locationPath( + projectId, + locationId + ); + + async function createNamespace() { + const [namespace] = await registrationServiceClient.createNamespace({ + parent: locationName, + namespaceId: namespaceId, + }); + + console.log(`Created namespace: ${namespace.name}`); + return namespace; + } + + return createNamespace(); + // [END servicedirectory_create_namespace] +} + +const args = process.argv.slice(2); +main(...args).catch(console.error); diff --git a/service-directory/snippets/createService.js b/service-directory/snippets/createService.js new file mode 100644 index 0000000000..56f060fefe --- /dev/null +++ b/service-directory/snippets/createService.js @@ -0,0 +1,63 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +'use strict'; + +async function main( + projectId = 'my-project', + locationId = 'us-east1', + namespaceId = 'my-namespace', + serviceId = 'my-service' +) { + // [START servicedirectory_create_service] + // + // TODO(developer): Uncomment these variables before running the sample. + // + // const projectId = 'my-project'; + // const locationId = 'us-central1'; + // const namespaceId = 'my-namespace'; + // const serviceId = 'my-service'; + + // Imports the Google Cloud client library + const { + RegistrationServiceClient, + } = require('@google-cloud/service-directory'); + + // Creates a client + const registrationServiceClient = new RegistrationServiceClient(); + + // Build the namespace name + const namespaceName = registrationServiceClient.namespacePath( + projectId, + locationId, + namespaceId + ); + + async function createService() { + const [service] = await registrationServiceClient.createService({ + parent: namespaceName, + serviceId: serviceId, + }); + + console.log(`Created service: ${service.name}`); + return service; + } + + return createService(); + // [END servicedirectory_create_service] +} + +const args = process.argv.slice(2); +main(...args).catch(console.error); diff --git a/service-directory/snippets/deleteEndpoint.js b/service-directory/snippets/deleteEndpoint.js new file mode 100644 index 0000000000..a5e0b42bed --- /dev/null +++ b/service-directory/snippets/deleteEndpoint.js @@ -0,0 +1,65 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +'use strict'; + +async function main( + projectId = 'my-project', + locationId = 'us-east1', + namespaceId = 'my-namespace', + serviceId = 'my-service', + endpointId = 'my-endpoint' +) { + // [START servicedirectory_delete_endpoint] + // + // TODO(developer): Uncomment these variables before running the sample. + // + // const projectId = 'my-project'; + // const locationId = 'us-central1'; + // const namespaceId = 'my-namespace'; + // const serviceId = 'my-service'; + // const endpointId = 'my-endpoint'; + + // Imports the Google Cloud client library + const { + RegistrationServiceClient, + } = require('@google-cloud/service-directory'); + + // Creates a client + const registrationServiceClient = new RegistrationServiceClient(); + + // Build the endpoint name + const endpointName = registrationServiceClient.endpointPath( + projectId, + locationId, + namespaceId, + serviceId, + endpointId + ); + + async function deleteEndpoint() { + await registrationServiceClient.deleteEndpoint({ + name: endpointName, + }); + + console.log(`Deleted endpoint: ${endpointName}`); + } + + deleteEndpoint(); + // [END servicedirectory_delete_endpoint] +} + +const args = process.argv.slice(2); +main(...args).catch(console.error); diff --git a/service-directory/snippets/deleteNamespace.js b/service-directory/snippets/deleteNamespace.js new file mode 100644 index 0000000000..040782fadd --- /dev/null +++ b/service-directory/snippets/deleteNamespace.js @@ -0,0 +1,59 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +'use strict'; + +async function main( + projectId = 'my-project', + locationId = 'us-east1', + namespaceId = 'my-namespace' +) { + // [START servicedirectory_delete_namespace] + // + // TODO(developer): Uncomment these variables before running the sample. + // + // const projectId = 'my-project'; + // const locationId = 'us-central1'; + // const namespaceId = 'my-namespace'; + + // Imports the Google Cloud client library + const { + RegistrationServiceClient, + } = require('@google-cloud/service-directory'); + + // Creates a client + const registrationServiceClient = new RegistrationServiceClient(); + + // Build the namespace name + const namespaceName = registrationServiceClient.namespacePath( + projectId, + locationId, + namespaceId + ); + + async function deleteNamespace() { + await registrationServiceClient.deleteNamespace({ + name: namespaceName, + }); + + console.log(`Deleted namespace: ${namespaceName}`); + } + + deleteNamespace(); + // [END servicedirectory_delete_namespace] +} + +const args = process.argv.slice(2); +main(...args).catch(console.error); diff --git a/service-directory/snippets/deleteService.js b/service-directory/snippets/deleteService.js new file mode 100644 index 0000000000..0e5766d502 --- /dev/null +++ b/service-directory/snippets/deleteService.js @@ -0,0 +1,62 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +'use strict'; + +async function main( + projectId = 'my-project', + locationId = 'us-east1', + namespaceId = 'my-namespace', + serviceId = 'my-service' +) { + // [START servicedirectory_delete_service] + // + // TODO(developer): Uncomment these variables before running the sample. + // + // const projectId = 'my-project'; + // const locationId = 'us-central1'; + // const namespaceId = 'my-namespace'; + // const serviceId = 'my-service'; + + // Imports the Google Cloud client library + const { + RegistrationServiceClient, + } = require('@google-cloud/service-directory'); + + // Creates a client + const registrationServiceClient = new RegistrationServiceClient(); + + // Build the service name + const serviceName = registrationServiceClient.servicePath( + projectId, + locationId, + namespaceId, + serviceId + ); + + async function deleteService() { + await registrationServiceClient.deleteService({ + name: serviceName, + }); + + console.log(`Deleted service: ${serviceName}`); + } + + deleteService(); + // [END servicedirectory_delete_service] +} + +const args = process.argv.slice(2); +main(...args).catch(console.error); diff --git a/service-directory/snippets/package.json b/service-directory/snippets/package.json new file mode 100644 index 0000000000..232dff7a5f --- /dev/null +++ b/service-directory/snippets/package.json @@ -0,0 +1,26 @@ +{ + "name": "nodejs-service-directory", + "private": true, + "license": "Apache-2.0", + "author": "Google LLC", + "engines": { + "node": ">=12.0.0" + }, + "files": [ + "*.js" + ], + "scripts": { + "test": "c8 mocha --timeout 600000 test/*.js" + }, + "dependencies": { + "@google-cloud/service-directory": "^4.0.4", + "eslint": "^7.0.0", + "json-schema": "^0.4.0", + "uuid": "^9.0.0" + }, + "devDependencies": { + "c8": "^7.0.0", + "chai": "^4.2.0", + "mocha": "^8.0.0" + } +} \ No newline at end of file diff --git a/service-directory/snippets/quickstart.js b/service-directory/snippets/quickstart.js new file mode 100644 index 0000000000..cbadcb9745 --- /dev/null +++ b/service-directory/snippets/quickstart.js @@ -0,0 +1,60 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +'use strict'; + +async function quickstart( + projectId = 'my-project', + locationId = 'us-central1' +) { + // [START servicedirectory_quickstart] + // + // TODO(developer): Uncomment these variables before running the sample. + // + // const projectId = 'my-project'; + // const locationId = 'us-central1'; + + // Imports the Google Cloud client library + const { + RegistrationServiceClient, + } = require('@google-cloud/service-directory'); + + // Creates a client + const registrationServiceClient = new RegistrationServiceClient(); + + // Build the location name + const locationName = registrationServiceClient.locationPath( + projectId, + locationId + ); + + async function listNamespaces() { + const [namespaces] = await registrationServiceClient.listNamespaces({ + parent: locationName, + }); + + console.log('Namespaces: '); + for (const n of namespaces) { + console.log(`${n.name}`); + } + return namespaces; + } + + return listNamespaces(); + // [END servicedirectory_quickstart] +} + +const args = process.argv.slice(2); +quickstart(...args).catch(console.error); diff --git a/service-directory/snippets/resolveService.js b/service-directory/snippets/resolveService.js new file mode 100644 index 0000000000..ba9a7ba754 --- /dev/null +++ b/service-directory/snippets/resolveService.js @@ -0,0 +1,67 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +'use strict'; + +async function main( + projectId = 'my-project', + locationId = 'us-east1', + namespaceId = 'my-namespace', + serviceId = 'my-service' +) { + // [START servicedirectory_resolve_service] + // + // TODO(developer): Uncomment these variables before running the sample. + // + // const projectId = 'my-project'; + // const locationId = 'us-central1'; + // const namespaceId = 'my-namespace'; + // const serviceId = 'my-service'; + + // Imports the Google Cloud client library + const {LookupServiceClient} = require('@google-cloud/service-directory'); + + // Creates a client + const lookupServiceClient = new LookupServiceClient(); + + // Build the service name + const serviceName = lookupServiceClient.servicePath( + projectId, + locationId, + namespaceId, + serviceId + ); + + async function resolveService() { + const [response] = await lookupServiceClient.resolveService({ + name: serviceName, + }); + + console.log(`Resolved service: ${response.service.name}`); + for (const e of response.service.endpoints) { + console.log(`\n${e.name}`); + console.log(`Address: ${e.address}`); + console.log(`Port: ${e.port}\n`); + } + return response.service; + } + + return resolveService(); + // [END servicedirectory_resolve_service] +} +module.exports.main = main; + +const args = process.argv.slice(2); +main(...args).catch(console.error); diff --git a/service-directory/snippets/test/quickstart.test.js b/service-directory/snippets/test/quickstart.test.js new file mode 100644 index 0000000000..bf5dc01877 --- /dev/null +++ b/service-directory/snippets/test/quickstart.test.js @@ -0,0 +1,38 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +'use strict'; + +const path = require('path'); +const {assert} = require('chai'); +const cp = require('child_process'); +const {describe, it} = require('mocha'); + +const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'}); + +const cwd = path.join(__dirname, '..'); + +const projectId = process.env.GCLOUD_PROJECT; +const locationId = 'us-central1'; + +describe('Service Directory Quickstart', () => { + it('should run quickstart.js', async () => { + const stdout = execSync(`node quickstart.js ${projectId} ${locationId}`, { + cwd, + }); + // build should have exited with success status. + assert(stdout); + }); +}); diff --git a/service-directory/snippets/test/samples.test.js b/service-directory/snippets/test/samples.test.js new file mode 100644 index 0000000000..80f71b56bf --- /dev/null +++ b/service-directory/snippets/test/samples.test.js @@ -0,0 +1,108 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +'use strict'; + +const {assert} = require('chai'); +const cp = require('child_process'); +const {describe, it, before} = require('mocha'); +const sd = require('@google-cloud/service-directory'); +const {v4} = require('uuid'); + +const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'}); + +const registrationServiceClient = new sd.RegistrationServiceClient(); +const projectId = process.env.GCLOUD_PROJECT; +const locationId = 'us-central1'; +const uniqueRunId = v4(); + +describe('Service Directory Samples', () => { + const namespaceId = `namespace-${uniqueRunId}`; + const namespaceName = registrationServiceClient.namespacePath( + projectId, + locationId, + namespaceId + ); + const serviceId = 'test-service'; + const serviceName = registrationServiceClient.servicePath( + projectId, + locationId, + namespaceId, + serviceId + ); + const endpointId = 'test-endpoint'; + const endpointName = registrationServiceClient.endpointPath( + projectId, + locationId, + namespaceId, + serviceId, + endpointId + ); + + before(async () => { + if (!projectId) { + throw new Error('missing GCLOUD_PROJECT!'); + } + }); + + it('should create a namespace', async () => { + const output = execSync( + `node createNamespace ${projectId} ${locationId} ${namespaceId}` + ); + assert.match(output, new RegExp(`Created namespace: ${namespaceName}`)); + }); + + it('should create a service', async () => { + const output = execSync( + `node createService ${projectId} ${locationId} ${namespaceId} ${serviceId}` + ); + assert.match(output, new RegExp(`Created service: ${serviceName}`)); + }); + + it('should create an endpoint', async () => { + const output = execSync( + `node createEndpoint ${projectId} ${locationId} ${namespaceId} ${serviceId} ${endpointId}` + ); + assert.match(output, new RegExp(`Created endpoint: ${endpointName}`)); + }); + + it('should resolve service', async () => { + const output = execSync( + `node resolveService ${projectId} ${locationId} ${namespaceId} ${serviceId}` + ); + assert.match(output, new RegExp(`Resolved service: ${serviceName}`)); + }); + + it('should delete an endpoint', async () => { + const output = execSync( + `node deleteEndpoint ${projectId} ${locationId} ${namespaceId} ${serviceId} ${endpointId}` + ); + assert.match(output, new RegExp(`Deleted endpoint: ${endpointName}`)); + }); + + it('should delete a service', async () => { + const output = execSync( + `node deleteService ${projectId} ${locationId} ${namespaceId} ${serviceId}` + ); + assert.match(output, new RegExp(`Deleted service: ${serviceName}`)); + }); + + it('should delete a namespace', async () => { + const output = execSync( + `node deleteNamespace ${projectId} ${locationId} ${namespaceId}` + ); + assert.match(output, new RegExp(`Deleted namespace: ${namespaceName}`)); + }); +});