Merge pull request #11 from spotify/rugvip/proxy

added protos,backend/hello,backend/envoy + compose setup
This commit is contained in:
Patrik Oldsberg
2020-02-03 15:00:59 +01:00
committed by GitHub
16 changed files with 2007 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
node_modules
+1
View File
@@ -0,0 +1 @@
node_modules/
+10
View File
@@ -0,0 +1,10 @@
FROM node:12
RUN mkdir /app
WORKDIR /app
COPY package.json yarn.lock ./
RUN yarn install
COPY . ./
CMD yarn run start
+21
View File
@@ -0,0 +1,21 @@
#!/bin/bash
# Path to this plugin, Note this must be an abolsute path on Windows (see #15)
PROTOC_GEN_TS_PATH="$(pwd)/node_modules/.bin/protoc-gen-ts"
# Path to the grpc_node_plugin
PROTOC_GEN_GRPC_PATH="$(pwd)/node_modules/.bin/grpc_tools_node_protoc_plugin"
# Directory to write generated code to (.js and .d.ts files)
OUT_DIR="$(pwd)/src/generated"
mkdir -p "$OUT_DIR"
protoc \
--plugin="protoc-gen-ts=${PROTOC_GEN_TS_PATH}" \
--plugin="protoc-gen-grpc=${PROTOC_GEN_GRPC_PATH}" \
--js_out="import_style=commonjs,binary:${OUT_DIR}" \
--ts_out="service=grpc-node:${OUT_DIR}" \
--proto_path="../../protos/" \
--grpc_out="${OUT_DIR}" \
hello.proto
+24
View File
@@ -0,0 +1,24 @@
{
"name": "hello",
"version": "1.0.0",
"main": "src/index.ts",
"license": "MIT",
"dependencies": {
"@grpc/proto-loader": "^0.5.3",
"grpc": "^1.24.2",
"grpc-tools": "^1.8.1",
"nodemon": "^2.0.2",
"ts-node": "^8.6.2",
"ts-protoc-gen": "^0.12.0",
"typescript": "^3.7.5"
},
"scripts": {
"start": "ts-node .",
"watch": "nodemon ."
},
"nodemonConfig": {
"watch": "./src",
"exec": "ts-node .",
"ext": "ts"
}
}
+20
View File
@@ -0,0 +1,20 @@
// GENERATED CODE -- DO NOT EDIT!
// package: spotify.backstage.hello.v1alpha1
// file: hello.proto
import * as hello_pb from "./hello_pb";
import * as grpc from "grpc";
interface IHelloService extends grpc.ServiceDefinition<grpc.UntypedServiceImplementation> {
hello: grpc.MethodDefinition<hello_pb.HelloRequest, hello_pb.HelloReply>;
}
export const HelloService: IHelloService;
export class HelloClient extends grpc.Client {
constructor(address: string, credentials: grpc.ChannelCredentials, options?: object);
hello(argument: hello_pb.HelloRequest, callback: grpc.requestCallback<hello_pb.HelloReply>): grpc.ClientUnaryCall;
hello(argument: hello_pb.HelloRequest, metadataOrOptions: grpc.Metadata | grpc.CallOptions | null, callback: grpc.requestCallback<hello_pb.HelloReply>): grpc.ClientUnaryCall;
hello(argument: hello_pb.HelloRequest, metadata: grpc.Metadata | null, options: grpc.CallOptions | null, callback: grpc.requestCallback<hello_pb.HelloReply>): grpc.ClientUnaryCall;
}
@@ -0,0 +1,44 @@
// GENERATED CODE -- DO NOT EDIT!
'use strict';
var grpc = require('grpc');
var hello_pb = require('./hello_pb.js');
function serialize_spotify_backstage_hello_v1alpha1_HelloReply(arg) {
if (!(arg instanceof hello_pb.HelloReply)) {
throw new Error('Expected argument of type spotify.backstage.hello.v1alpha1.HelloReply');
}
return Buffer.from(arg.serializeBinary());
}
function deserialize_spotify_backstage_hello_v1alpha1_HelloReply(buffer_arg) {
return hello_pb.HelloReply.deserializeBinary(new Uint8Array(buffer_arg));
}
function serialize_spotify_backstage_hello_v1alpha1_HelloRequest(arg) {
if (!(arg instanceof hello_pb.HelloRequest)) {
throw new Error('Expected argument of type spotify.backstage.hello.v1alpha1.HelloRequest');
}
return Buffer.from(arg.serializeBinary());
}
function deserialize_spotify_backstage_hello_v1alpha1_HelloRequest(buffer_arg) {
return hello_pb.HelloRequest.deserializeBinary(new Uint8Array(buffer_arg));
}
var HelloService = exports.HelloService = {
hello: {
path: '/spotify.backstage.hello.v1alpha1.Hello/Hello',
requestStream: false,
responseStream: false,
requestType: hello_pb.HelloRequest,
responseType: hello_pb.HelloReply,
requestSerialize: serialize_spotify_backstage_hello_v1alpha1_HelloRequest,
requestDeserialize: deserialize_spotify_backstage_hello_v1alpha1_HelloRequest,
responseSerialize: serialize_spotify_backstage_hello_v1alpha1_HelloReply,
responseDeserialize: deserialize_spotify_backstage_hello_v1alpha1_HelloReply,
},
};
exports.HelloClient = grpc.makeGenericClientConstructor(HelloService);
+45
View File
@@ -0,0 +1,45 @@
// package: spotify.backstage.hello.v1alpha1
// file: hello.proto
import * as jspb from "google-protobuf";
export class HelloRequest extends jspb.Message {
getName(): string;
setName(value: string): void;
serializeBinary(): Uint8Array;
toObject(includeInstance?: boolean): HelloRequest.AsObject;
static toObject(includeInstance: boolean, msg: HelloRequest): HelloRequest.AsObject;
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
static serializeBinaryToWriter(message: HelloRequest, writer: jspb.BinaryWriter): void;
static deserializeBinary(bytes: Uint8Array): HelloRequest;
static deserializeBinaryFromReader(message: HelloRequest, reader: jspb.BinaryReader): HelloRequest;
}
export namespace HelloRequest {
export type AsObject = {
name: string,
}
}
export class HelloReply extends jspb.Message {
getMessage(): string;
setMessage(value: string): void;
serializeBinary(): Uint8Array;
toObject(includeInstance?: boolean): HelloReply.AsObject;
static toObject(includeInstance: boolean, msg: HelloReply): HelloReply.AsObject;
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
static serializeBinaryToWriter(message: HelloReply, writer: jspb.BinaryWriter): void;
static deserializeBinary(bytes: Uint8Array): HelloReply;
static deserializeBinaryFromReader(message: HelloReply, reader: jspb.BinaryReader): HelloReply;
}
export namespace HelloReply {
export type AsObject = {
message: string,
}
}
+308
View File
@@ -0,0 +1,308 @@
/**
* @fileoverview
* @enhanceable
* @suppress {messageConventions} JS Compiler reports an error if a variable or
* field starts with 'MSG_' and isn't a translatable message.
* @public
*/
// GENERATED CODE -- DO NOT EDIT!
var jspb = require('google-protobuf');
var goog = jspb;
var global = Function('return this')();
goog.exportSymbol('proto.spotify.backstage.hello.v1alpha1.HelloReply', null, global);
goog.exportSymbol('proto.spotify.backstage.hello.v1alpha1.HelloRequest', null, global);
/**
* Generated by JsPbCodeGenerator.
* @param {Array=} opt_data Optional initial data array, typically from a
* server response, or constructed directly in Javascript. The array is used
* in place and becomes part of the constructed object. It is not cloned.
* If no data is provided, the constructed object will be empty, but still
* valid.
* @extends {jspb.Message}
* @constructor
*/
proto.spotify.backstage.hello.v1alpha1.HelloRequest = function(opt_data) {
jspb.Message.initialize(this, opt_data, 0, -1, null, null);
};
goog.inherits(proto.spotify.backstage.hello.v1alpha1.HelloRequest, jspb.Message);
if (goog.DEBUG && !COMPILED) {
/**
* @public
* @override
*/
proto.spotify.backstage.hello.v1alpha1.HelloRequest.displayName = 'proto.spotify.backstage.hello.v1alpha1.HelloRequest';
}
/**
* Generated by JsPbCodeGenerator.
* @param {Array=} opt_data Optional initial data array, typically from a
* server response, or constructed directly in Javascript. The array is used
* in place and becomes part of the constructed object. It is not cloned.
* If no data is provided, the constructed object will be empty, but still
* valid.
* @extends {jspb.Message}
* @constructor
*/
proto.spotify.backstage.hello.v1alpha1.HelloReply = function(opt_data) {
jspb.Message.initialize(this, opt_data, 0, -1, null, null);
};
goog.inherits(proto.spotify.backstage.hello.v1alpha1.HelloReply, jspb.Message);
if (goog.DEBUG && !COMPILED) {
/**
* @public
* @override
*/
proto.spotify.backstage.hello.v1alpha1.HelloReply.displayName = 'proto.spotify.backstage.hello.v1alpha1.HelloReply';
}
if (jspb.Message.GENERATE_TO_OBJECT) {
/**
* Creates an object representation of this proto suitable for use in Soy templates.
* Field names that are reserved in JavaScript and will be renamed to pb_name.
* To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
* For the list of reserved names please see:
* com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS.
* @param {boolean=} opt_includeInstance Whether to include the JSPB instance
* for transitional soy proto support: http://goto/soy-param-migration
* @return {!Object}
*/
proto.spotify.backstage.hello.v1alpha1.HelloRequest.prototype.toObject = function(opt_includeInstance) {
return proto.spotify.backstage.hello.v1alpha1.HelloRequest.toObject(opt_includeInstance, this);
};
/**
* Static version of the {@see toObject} method.
* @param {boolean|undefined} includeInstance Whether to include the JSPB
* instance for transitional soy proto support:
* http://goto/soy-param-migration
* @param {!proto.spotify.backstage.hello.v1alpha1.HelloRequest} msg The msg instance to transform.
* @return {!Object}
* @suppress {unusedLocalVariables} f is only used for nested messages
*/
proto.spotify.backstage.hello.v1alpha1.HelloRequest.toObject = function(includeInstance, msg) {
var f, obj = {
name: jspb.Message.getFieldWithDefault(msg, 1, "")
};
if (includeInstance) {
obj.$jspbMessageInstance = msg;
}
return obj;
};
}
/**
* Deserializes binary data (in protobuf wire format).
* @param {jspb.ByteSource} bytes The bytes to deserialize.
* @return {!proto.spotify.backstage.hello.v1alpha1.HelloRequest}
*/
proto.spotify.backstage.hello.v1alpha1.HelloRequest.deserializeBinary = function(bytes) {
var reader = new jspb.BinaryReader(bytes);
var msg = new proto.spotify.backstage.hello.v1alpha1.HelloRequest;
return proto.spotify.backstage.hello.v1alpha1.HelloRequest.deserializeBinaryFromReader(msg, reader);
};
/**
* Deserializes binary data (in protobuf wire format) from the
* given reader into the given message object.
* @param {!proto.spotify.backstage.hello.v1alpha1.HelloRequest} msg The message object to deserialize into.
* @param {!jspb.BinaryReader} reader The BinaryReader to use.
* @return {!proto.spotify.backstage.hello.v1alpha1.HelloRequest}
*/
proto.spotify.backstage.hello.v1alpha1.HelloRequest.deserializeBinaryFromReader = function(msg, reader) {
while (reader.nextField()) {
if (reader.isEndGroup()) {
break;
}
var field = reader.getFieldNumber();
switch (field) {
case 1:
var value = /** @type {string} */ (reader.readString());
msg.setName(value);
break;
default:
reader.skipField();
break;
}
}
return msg;
};
/**
* Serializes the message to binary data (in protobuf wire format).
* @return {!Uint8Array}
*/
proto.spotify.backstage.hello.v1alpha1.HelloRequest.prototype.serializeBinary = function() {
var writer = new jspb.BinaryWriter();
proto.spotify.backstage.hello.v1alpha1.HelloRequest.serializeBinaryToWriter(this, writer);
return writer.getResultBuffer();
};
/**
* Serializes the given message to binary data (in protobuf wire
* format), writing to the given BinaryWriter.
* @param {!proto.spotify.backstage.hello.v1alpha1.HelloRequest} message
* @param {!jspb.BinaryWriter} writer
* @suppress {unusedLocalVariables} f is only used for nested messages
*/
proto.spotify.backstage.hello.v1alpha1.HelloRequest.serializeBinaryToWriter = function(message, writer) {
var f = undefined;
f = message.getName();
if (f.length > 0) {
writer.writeString(
1,
f
);
}
};
/**
* optional string name = 1;
* @return {string}
*/
proto.spotify.backstage.hello.v1alpha1.HelloRequest.prototype.getName = function() {
return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
};
/** @param {string} value */
proto.spotify.backstage.hello.v1alpha1.HelloRequest.prototype.setName = function(value) {
jspb.Message.setProto3StringField(this, 1, value);
};
if (jspb.Message.GENERATE_TO_OBJECT) {
/**
* Creates an object representation of this proto suitable for use in Soy templates.
* Field names that are reserved in JavaScript and will be renamed to pb_name.
* To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
* For the list of reserved names please see:
* com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS.
* @param {boolean=} opt_includeInstance Whether to include the JSPB instance
* for transitional soy proto support: http://goto/soy-param-migration
* @return {!Object}
*/
proto.spotify.backstage.hello.v1alpha1.HelloReply.prototype.toObject = function(opt_includeInstance) {
return proto.spotify.backstage.hello.v1alpha1.HelloReply.toObject(opt_includeInstance, this);
};
/**
* Static version of the {@see toObject} method.
* @param {boolean|undefined} includeInstance Whether to include the JSPB
* instance for transitional soy proto support:
* http://goto/soy-param-migration
* @param {!proto.spotify.backstage.hello.v1alpha1.HelloReply} msg The msg instance to transform.
* @return {!Object}
* @suppress {unusedLocalVariables} f is only used for nested messages
*/
proto.spotify.backstage.hello.v1alpha1.HelloReply.toObject = function(includeInstance, msg) {
var f, obj = {
message: jspb.Message.getFieldWithDefault(msg, 1, "")
};
if (includeInstance) {
obj.$jspbMessageInstance = msg;
}
return obj;
};
}
/**
* Deserializes binary data (in protobuf wire format).
* @param {jspb.ByteSource} bytes The bytes to deserialize.
* @return {!proto.spotify.backstage.hello.v1alpha1.HelloReply}
*/
proto.spotify.backstage.hello.v1alpha1.HelloReply.deserializeBinary = function(bytes) {
var reader = new jspb.BinaryReader(bytes);
var msg = new proto.spotify.backstage.hello.v1alpha1.HelloReply;
return proto.spotify.backstage.hello.v1alpha1.HelloReply.deserializeBinaryFromReader(msg, reader);
};
/**
* Deserializes binary data (in protobuf wire format) from the
* given reader into the given message object.
* @param {!proto.spotify.backstage.hello.v1alpha1.HelloReply} msg The message object to deserialize into.
* @param {!jspb.BinaryReader} reader The BinaryReader to use.
* @return {!proto.spotify.backstage.hello.v1alpha1.HelloReply}
*/
proto.spotify.backstage.hello.v1alpha1.HelloReply.deserializeBinaryFromReader = function(msg, reader) {
while (reader.nextField()) {
if (reader.isEndGroup()) {
break;
}
var field = reader.getFieldNumber();
switch (field) {
case 1:
var value = /** @type {string} */ (reader.readString());
msg.setMessage(value);
break;
default:
reader.skipField();
break;
}
}
return msg;
};
/**
* Serializes the message to binary data (in protobuf wire format).
* @return {!Uint8Array}
*/
proto.spotify.backstage.hello.v1alpha1.HelloReply.prototype.serializeBinary = function() {
var writer = new jspb.BinaryWriter();
proto.spotify.backstage.hello.v1alpha1.HelloReply.serializeBinaryToWriter(this, writer);
return writer.getResultBuffer();
};
/**
* Serializes the given message to binary data (in protobuf wire
* format), writing to the given BinaryWriter.
* @param {!proto.spotify.backstage.hello.v1alpha1.HelloReply} message
* @param {!jspb.BinaryWriter} writer
* @suppress {unusedLocalVariables} f is only used for nested messages
*/
proto.spotify.backstage.hello.v1alpha1.HelloReply.serializeBinaryToWriter = function(message, writer) {
var f = undefined;
f = message.getMessage();
if (f.length > 0) {
writer.writeString(
1,
f
);
}
};
/**
* optional string message = 1;
* @return {string}
*/
proto.spotify.backstage.hello.v1alpha1.HelloReply.prototype.getMessage = function() {
return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
};
/** @param {string} value */
proto.spotify.backstage.hello.v1alpha1.HelloReply.prototype.setMessage = function(value) {
jspb.Message.setProto3StringField(this, 1, value);
};
goog.object.extend(exports, proto.spotify.backstage.hello.v1alpha1);
+24
View File
@@ -0,0 +1,24 @@
import grpc, { requestCallback, ServerUnaryCall } from 'grpc';
import { HelloService } from './generated/hello_grpc_pb';
import { HelloRequest, HelloReply } from './generated/hello_pb';
async function main() {
var server = new grpc.Server();
server.addService(HelloService, {
hello: (
call: ServerUnaryCall<HelloRequest>,
callback: requestCallback<HelloReply>
) => {
var reply = new HelloReply();
reply.setMessage(`Hello ${call.request.getName()}!`);
callback(null, reply);
}
});
server.bind('0.0.0.0:80', grpc.ServerCredentials.createInsecure());
server.start();
}
main().catch(error => {
console.error(error?.stack);
process.exit(1);
});
+14
View File
@@ -0,0 +1,14 @@
{
"compilerOptions": {
"target": "es2019",
"lib": ["es2019"],
"rootDir": "src",
"noEmit": true,
"module": "commonjs",
"moduleResolution": "node",
"strict": true,
"types": ["node"],
"esModuleInterop": true
},
"include": ["src/**/*.ts"]
}
File diff suppressed because it is too large Load Diff
+5
View File
@@ -0,0 +1,5 @@
FROM envoyproxy/envoy:latest
COPY ./envoy.yaml /etc/envoy/envoy.yaml
CMD /usr/local/bin/envoy -c /etc/envoy/envoy.yaml
+52
View File
@@ -0,0 +1,52 @@
admin:
access_log_path: /dev/stdout
address:
socket_address:
address: 0.0.0.0
port_value: 8001
static_resources:
listeners:
- name: listener_0
address:
socket_address:
address: 0.0.0.0
port_value: 80
filter_chains:
- filters:
- name: envoy.http_connection_manager
config:
codec_type: auto
stat_prefix: ingress_http
route_config:
name: local_route
virtual_hosts:
- name: local_service
domains: ['*']
routes:
- match: { prefix: '/' }
route:
cluster: hello_service
max_grpc_timeout: 0s
cors:
allow_origin_string_match:
- prefix: '*'
allow_methods: GET, PUT, DELETE, POST, OPTIONS
allow_headers: keep-alive,user-agent,cache-control,content-type,content-transfer-encoding,custom-header-1,x-accept-content-transfer-encoding,x-accept-response-streaming,x-user-agent,x-grpc-web,grpc-timeout
max_age: '1728000'
expose_headers: custom-header-1,grpc-status,grpc-message
http_filters:
- name: envoy.grpc_web
- name: envoy.cors
- name: envoy.router
clusters:
- name: hello_service
connect_timeout: 0.25s
type: logical_dns
http2_protocol_options: {}
lb_policy: round_robin
hosts:
- socket_address:
address: hello
port_value: 80
Regular → Executable
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/env docker-compose -f
version: "3.4"
services:
proxy:
container_name: boss-proxy
build:
context: backend/proxy
restart: unless-stopped
ports:
- "8080:80"
hello:
container_name: boss-hello
build:
context: backend/hello
restart: unless-stopped
+15
View File
@@ -0,0 +1,15 @@
syntax = "proto3";
package spotify.backstage.hello.v1alpha1;
service Hello {
rpc Hello(HelloRequest) returns (HelloReply);
}
message HelloRequest {
string name = 1;
}
message HelloReply {
string message = 1;
}