From 70e4d4aec3a793bd061783d5d6975a73c9e0c3dd Mon Sep 17 00:00:00 2001 From: Ace Nassri Date: Mon, 20 Aug 2018 16:42:37 -0700 Subject: [PATCH] Switch to standard health RPC --- pb/demo.proto | 2 -- pb/grpc/health/v1/health.proto | 43 ++++++++++++++++++++++++++++++++ src/currencyservice/genproto.sh | 2 +- src/currencyservice/package.json | 1 + src/currencyservice/server.js | 31 ++++++++++++++++++++--- src/paymentservice/genproto.sh | 4 +-- src/paymentservice/index.js | 2 +- src/paymentservice/server.js | 30 +++++++++++++++------- 8 files changed, 95 insertions(+), 20 deletions(-) create mode 100644 pb/grpc/health/v1/health.proto diff --git a/pb/demo.proto b/pb/demo.proto index 1547f3a..11b8c29 100644 --- a/pb/demo.proto +++ b/pb/demo.proto @@ -120,7 +120,6 @@ message Address { service CurrencyService { rpc GetSupportedCurrencies(Empty) returns (GetSupportedCurrenciesResponse) {} rpc Convert(CurrencyConversionRequest) returns (Money) {} - rpc Check(Empty) returns (Empty) {} } // Represents an amount of money with its currency type. @@ -157,7 +156,6 @@ message CurrencyConversionRequest { service PaymentService { rpc Charge(ChargeRequest) returns (ChargeResponse) {} - rpc Check(Empty) returns (Empty) {} } message CreditCardInfo { diff --git a/pb/grpc/health/v1/health.proto b/pb/grpc/health/v1/health.proto new file mode 100644 index 0000000..4b4677b --- /dev/null +++ b/pb/grpc/health/v1/health.proto @@ -0,0 +1,43 @@ +// Copyright 2015 The gRPC Authors +// +// 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 +// +// http://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. + +// The canonical version of this proto can be found at +// https://github.com/grpc/grpc-proto/blob/master/grpc/health/v1/health.proto + +syntax = "proto3"; + +package grpc.health.v1; + +option csharp_namespace = "Grpc.Health.V1"; +option go_package = "google.golang.org/grpc/health/grpc_health_v1"; +option java_multiple_files = true; +option java_outer_classname = "HealthProto"; +option java_package = "io.grpc.health.v1"; + +message HealthCheckRequest { + string service = 1; +} + +message HealthCheckResponse { + enum ServingStatus { + UNKNOWN = 0; + SERVING = 1; + NOT_SERVING = 2; + } + ServingStatus status = 1; +} + +service Health { + rpc Check(HealthCheckRequest) returns (HealthCheckResponse); +} diff --git a/src/currencyservice/genproto.sh b/src/currencyservice/genproto.sh index ba89804..362e7c8 100755 --- a/src/currencyservice/genproto.sh +++ b/src/currencyservice/genproto.sh @@ -17,4 +17,4 @@ #!/bin/bash -e # protos are loaded dynamically for node, simply copies over the proto. mkdir -p proto && \ -cp ../../pb/demo.proto proto \ No newline at end of file +cp -r ../../pb/ proto/ diff --git a/src/currencyservice/package.json b/src/currencyservice/package.json index 5b2f859..f923c96 100644 --- a/src/currencyservice/package.json +++ b/src/currencyservice/package.json @@ -8,6 +8,7 @@ "@google-cloud/debug-agent": "^2.6.0", "@google-cloud/profiler": "^0.1.14", "@google-cloud/trace-agent": "^2.11.0", + "@grpc/proto-loader": "^0.3.0", "async": "^1.5.2", "google-protobuf": "^3.0.0", "grpc": "^1.0.0", diff --git a/src/currencyservice/server.js b/src/currencyservice/server.js index 66da00c..69f7c3c 100644 --- a/src/currencyservice/server.js +++ b/src/currencyservice/server.js @@ -32,11 +32,33 @@ const path = require('path'); const grpc = require('grpc'); const request = require('request'); const xml2js = require('xml2js'); +const protoLoader = require('@grpc/proto-loader'); + +const MAIN_PROTO_PATH = path.join(__dirname, './proto/demo.proto'); +const HEALTH_PROTO_PATH = path.join(__dirname, './proto/grpc/health/v1/health.proto'); -const PROTO_PATH = path.join(__dirname, './proto/demo.proto'); const PORT = 7000; const DATA_URL = 'http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml'; -const shopProto = grpc.load(PROTO_PATH).hipstershop; + +const shopProto = _loadProto(MAIN_PROTO_PATH).hipstershop; +const healthProto = _loadProto(HEALTH_PROTO_PATH).grpc.health.v1; + +/** + * Helper function that loads a protobuf file. + */ +function _loadProto (path) { + const packageDefinition = protoLoader.loadSync( + path, + { + keepCase: true, + longs: String, + enums: String, + defaults: true, + oneofs: true + } + ); + return grpc.loadPackageDefinition(packageDefinition); +} /** * Helper function that gets currency data from an XML webpage @@ -134,7 +156,7 @@ function convert (call, callback) { * Endpoint for health checks */ function check (call, callback) { - callback(null); + callback(null, { status: 'SERVING' }); } /** @@ -144,7 +166,8 @@ function check (call, callback) { function main () { console.log(`Starting gRPC server on port ${PORT}...`); const server = new grpc.Server(); - server.addService(shopProto.CurrencyService.service, {getSupportedCurrencies, convert, check}); + server.addService(shopProto.CurrencyService.service, {getSupportedCurrencies, convert}); + server.addService(healthProto.Health.service, {check}); server.bind(`0.0.0.0:${PORT}`, grpc.ServerCredentials.createInsecure()); server.start(); } diff --git a/src/paymentservice/genproto.sh b/src/paymentservice/genproto.sh index 2529fd9..362e7c8 100755 --- a/src/paymentservice/genproto.sh +++ b/src/paymentservice/genproto.sh @@ -15,8 +15,6 @@ # limitations under the License. #!/bin/bash -e - # protos are loaded dynamically for node, simply copies over the proto. - mkdir -p proto && \ -cp ../../pb/demo.proto proto +cp -r ../../pb/ proto/ diff --git a/src/paymentservice/index.js b/src/paymentservice/index.js index 6f32be8..8e1ae74 100644 --- a/src/paymentservice/index.js +++ b/src/paymentservice/index.js @@ -33,7 +33,7 @@ require('@google-cloud/debug-agent').start({ const HipsterShopServer = require('./server'); const PORT = process.env['PORT']; -const PROTO_PATH = __dirname + '/proto/demo.proto'; +const PROTO_PATH = __dirname + '/proto/'; const server = new HipsterShopServer(PROTO_PATH, PORT); diff --git a/src/paymentservice/server.js b/src/paymentservice/server.js index d2f4a87..e2e4e45 100644 --- a/src/paymentservice/server.js +++ b/src/paymentservice/server.js @@ -12,17 +12,23 @@ // See the License for the specific language governing permissions and // limitations under the License. +const path = require('path'); const grpc = require('grpc'); const protoLoader = require('@grpc/proto-loader'); const charge = require('./charge'); class HipsterShopServer { - constructor(protoFile, port = HipsterShopServer.DEFAULT_PORT) { + constructor(protoRoot, port = HipsterShopServer.DEFAULT_PORT) { this.port = port; + this.packages = { + hipsterShop: this.loadProtoFile(path.join(protoRoot, 'demo.proto')), + health: this.loadProtoFile(path.join(protoRoot, 'grpc/health/v1/health.proto')) + }; + this.server = new grpc.Server(); - this.loadProto(protoFile); + this.loadAllProtos(protoRoot); } /** @@ -42,7 +48,7 @@ class HipsterShopServer { } static CheckHandler(call, callback) { - callback(null); + callback(null, { status: 'SERVING' }); } listen() { @@ -62,17 +68,23 @@ class HipsterShopServer { oneofs: true, } ); - const protoDescriptor = grpc.loadPackageDefinition(packageDefinition); - const hipsterShopPackage = protoDescriptor.hipstershop; - - this.addProtoService(hipsterShopPackage.PaymentService.service); + return grpc.loadPackageDefinition(packageDefinition); } - addProtoService(service) { + loadAllProtos(protoRoot) { + const hipsterShopPackage = this.packages.hipsterShop.hipstershop; + const healthPackage = this.packages.health.grpc.health.v1; + this.server.addService( - service, + hipsterShopPackage.PaymentService.service, { charge: HipsterShopServer.ChargeServiceHandler.bind(this), + } + ); + + this.server.addService( + healthPackage.Health.service, + { check: HipsterShopServer.CheckHandler.bind(this) } );