Merge branch 'master' into alund/shared

This commit is contained in:
Stefan Ålund
2020-02-04 10:37:07 +01:00
19 changed files with 1047 additions and 19 deletions
+1 -1
View File
@@ -4,7 +4,7 @@ on:
push:
paths:
- 'frontend/**'
- '.github/**'
- '.github/workflows/frontend.yml'
jobs:
build:
+29
View File
@@ -0,0 +1,29 @@
name: Inventory CI
on:
push:
paths:
- 'backend/inventory/**'
- '.github/workflows/inventory.yml'
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Set up Go
uses: actions/setup-go@v1
with:
go-version: 1.12
- name: checkout code
uses: actions/checkout@v1
- name: setup env
run: |
echo "::set-env name=GOPATH::$(go env GOPATH)"
echo "::add-path::$(go env GOPATH)/bin"
shell: bash
- name: build
run: go build -v ./...
working-directory: ./backend/inventory
- name: test
run: go test ./... -short
working-directory: ./backend/inventory
+2
View File
@@ -0,0 +1,2 @@
#!/bin/bash
protoc -I ../../ protos/inventory.proto --go_out=plugins=grpc:.
+11
View File
@@ -0,0 +1,11 @@
module github.com/spotify/backstage/inventory
go 1.12
require (
github.com/golang/protobuf v1.3.2
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3 // indirect
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135 // indirect
google.golang.org/grpc v1.27.0
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc // indirect
)
+46
View File
@@ -0,0 +1,46 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.27.0 h1:rRYRFMVgRv6E0D70Skyfsr28tDXIuuPZyWGMPdMcnXg=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+31
View File
@@ -0,0 +1,31 @@
package main
import (
"context"
"log"
"net"
pb "github.com/spotify/backstage/inventory/protos"
"google.golang.org/grpc"
)
const (
port = ":50051"
)
type inventoryServer struct {
}
func (s *inventoryServer) GetEntity(ctx context.Context, req *pb.GetEntityRequest) (*pb.GetEntityReply, error) {
return &pb.GetEntityReply{}, nil
}
func main() {
lis, err := net.Listen("tcp", port)
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
grpcServer := grpc.NewServer()
pb.RegisterInventoryServer(grpcServer, &inventoryServer{})
grpcServer.Serve(lis)
}
+324
View File
@@ -0,0 +1,324 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: protos/inventory.proto
package spotify_backstage_inventory_v1alpha1
import (
context "context"
fmt "fmt"
proto "github.com/golang/protobuf/proto"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
math "math"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
type GetEntityRequest struct {
Entity *Entity `protobuf:"bytes,1,opt,name=entity,proto3" json:"entity,omitempty"`
IncludeFacts []string `protobuf:"bytes,2,rep,name=include_facts,json=includeFacts,proto3" json:"include_facts,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *GetEntityRequest) Reset() { *m = GetEntityRequest{} }
func (m *GetEntityRequest) String() string { return proto.CompactTextString(m) }
func (*GetEntityRequest) ProtoMessage() {}
func (*GetEntityRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_1a8706afd37ce83a, []int{0}
}
func (m *GetEntityRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GetEntityRequest.Unmarshal(m, b)
}
func (m *GetEntityRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_GetEntityRequest.Marshal(b, m, deterministic)
}
func (m *GetEntityRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_GetEntityRequest.Merge(m, src)
}
func (m *GetEntityRequest) XXX_Size() int {
return xxx_messageInfo_GetEntityRequest.Size(m)
}
func (m *GetEntityRequest) XXX_DiscardUnknown() {
xxx_messageInfo_GetEntityRequest.DiscardUnknown(m)
}
var xxx_messageInfo_GetEntityRequest proto.InternalMessageInfo
func (m *GetEntityRequest) GetEntity() *Entity {
if m != nil {
return m.Entity
}
return nil
}
func (m *GetEntityRequest) GetIncludeFacts() []string {
if m != nil {
return m.IncludeFacts
}
return nil
}
type GetEntityReply struct {
Entity *Entity `protobuf:"bytes,1,opt,name=entity,proto3" json:"entity,omitempty"`
Facts []*Fact `protobuf:"bytes,2,rep,name=facts,proto3" json:"facts,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *GetEntityReply) Reset() { *m = GetEntityReply{} }
func (m *GetEntityReply) String() string { return proto.CompactTextString(m) }
func (*GetEntityReply) ProtoMessage() {}
func (*GetEntityReply) Descriptor() ([]byte, []int) {
return fileDescriptor_1a8706afd37ce83a, []int{1}
}
func (m *GetEntityReply) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GetEntityReply.Unmarshal(m, b)
}
func (m *GetEntityReply) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_GetEntityReply.Marshal(b, m, deterministic)
}
func (m *GetEntityReply) XXX_Merge(src proto.Message) {
xxx_messageInfo_GetEntityReply.Merge(m, src)
}
func (m *GetEntityReply) XXX_Size() int {
return xxx_messageInfo_GetEntityReply.Size(m)
}
func (m *GetEntityReply) XXX_DiscardUnknown() {
xxx_messageInfo_GetEntityReply.DiscardUnknown(m)
}
var xxx_messageInfo_GetEntityReply proto.InternalMessageInfo
func (m *GetEntityReply) GetEntity() *Entity {
if m != nil {
return m.Entity
}
return nil
}
func (m *GetEntityReply) GetFacts() []*Fact {
if m != nil {
return m.Facts
}
return nil
}
type Entity struct {
Kind string `protobuf:"bytes,1,opt,name=kind,proto3" json:"kind,omitempty"`
Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Entity) Reset() { *m = Entity{} }
func (m *Entity) String() string { return proto.CompactTextString(m) }
func (*Entity) ProtoMessage() {}
func (*Entity) Descriptor() ([]byte, []int) {
return fileDescriptor_1a8706afd37ce83a, []int{2}
}
func (m *Entity) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Entity.Unmarshal(m, b)
}
func (m *Entity) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Entity.Marshal(b, m, deterministic)
}
func (m *Entity) XXX_Merge(src proto.Message) {
xxx_messageInfo_Entity.Merge(m, src)
}
func (m *Entity) XXX_Size() int {
return xxx_messageInfo_Entity.Size(m)
}
func (m *Entity) XXX_DiscardUnknown() {
xxx_messageInfo_Entity.DiscardUnknown(m)
}
var xxx_messageInfo_Entity proto.InternalMessageInfo
func (m *Entity) GetKind() string {
if m != nil {
return m.Kind
}
return ""
}
func (m *Entity) GetId() string {
if m != nil {
return m.Id
}
return ""
}
type Fact struct {
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Fact) Reset() { *m = Fact{} }
func (m *Fact) String() string { return proto.CompactTextString(m) }
func (*Fact) ProtoMessage() {}
func (*Fact) Descriptor() ([]byte, []int) {
return fileDescriptor_1a8706afd37ce83a, []int{3}
}
func (m *Fact) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Fact.Unmarshal(m, b)
}
func (m *Fact) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Fact.Marshal(b, m, deterministic)
}
func (m *Fact) XXX_Merge(src proto.Message) {
xxx_messageInfo_Fact.Merge(m, src)
}
func (m *Fact) XXX_Size() int {
return xxx_messageInfo_Fact.Size(m)
}
func (m *Fact) XXX_DiscardUnknown() {
xxx_messageInfo_Fact.DiscardUnknown(m)
}
var xxx_messageInfo_Fact proto.InternalMessageInfo
func (m *Fact) GetName() string {
if m != nil {
return m.Name
}
return ""
}
func (m *Fact) GetValue() string {
if m != nil {
return m.Value
}
return ""
}
func init() {
proto.RegisterType((*GetEntityRequest)(nil), "spotify.backstage.inventory.v1alpha1.GetEntityRequest")
proto.RegisterType((*GetEntityReply)(nil), "spotify.backstage.inventory.v1alpha1.GetEntityReply")
proto.RegisterType((*Entity)(nil), "spotify.backstage.inventory.v1alpha1.Entity")
proto.RegisterType((*Fact)(nil), "spotify.backstage.inventory.v1alpha1.Fact")
}
func init() { proto.RegisterFile("protos/inventory.proto", fileDescriptor_1a8706afd37ce83a) }
var fileDescriptor_1a8706afd37ce83a = []byte{
// 273 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x2b, 0x28, 0xca, 0x2f,
0xc9, 0x2f, 0xd6, 0xcf, 0xcc, 0x2b, 0x4b, 0xcd, 0x2b, 0xc9, 0x2f, 0xaa, 0xd4, 0x03, 0x0b, 0x08,
0xa9, 0x14, 0x17, 0xe4, 0x97, 0x64, 0xa6, 0x55, 0xea, 0x25, 0x25, 0x26, 0x67, 0x17, 0x97, 0x24,
0xa6, 0xa7, 0xea, 0x21, 0x94, 0x94, 0x19, 0x26, 0xe6, 0x14, 0x64, 0x24, 0x1a, 0x2a, 0xd5, 0x72,
0x09, 0xb8, 0xa7, 0x96, 0xb8, 0xe6, 0x95, 0x64, 0x96, 0x54, 0x06, 0xa5, 0x16, 0x96, 0xa6, 0x16,
0x97, 0x08, 0xb9, 0x70, 0xb1, 0xa5, 0x82, 0x05, 0x24, 0x18, 0x15, 0x18, 0x35, 0xb8, 0x8d, 0x74,
0xf4, 0x88, 0x31, 0x4a, 0x0f, 0x6a, 0x08, 0x54, 0xaf, 0x90, 0x32, 0x17, 0x6f, 0x66, 0x5e, 0x72,
0x4e, 0x69, 0x4a, 0x6a, 0x7c, 0x5a, 0x62, 0x72, 0x49, 0xb1, 0x04, 0x93, 0x02, 0xb3, 0x06, 0x67,
0x10, 0x0f, 0x54, 0xd0, 0x0d, 0x24, 0xa6, 0x34, 0x83, 0x91, 0x8b, 0x0f, 0xc9, 0xfe, 0x82, 0x9c,
0x4a, 0x2a, 0xd9, 0xee, 0xc0, 0xc5, 0x8a, 0xb0, 0x95, 0xdb, 0x48, 0x8b, 0x38, 0x43, 0x40, 0x8e,
0x0a, 0x82, 0x68, 0x54, 0xd2, 0xe1, 0x62, 0x83, 0x98, 0x29, 0x24, 0xc4, 0xc5, 0x92, 0x9d, 0x99,
0x97, 0x02, 0x76, 0x0f, 0x67, 0x10, 0x98, 0x2d, 0xc4, 0xc7, 0xc5, 0x94, 0x99, 0x22, 0xc1, 0x04,
0x16, 0x61, 0xca, 0x4c, 0x51, 0x32, 0xe0, 0x62, 0x01, 0x69, 0x06, 0xa9, 0xcd, 0x4b, 0xcc, 0x4d,
0x85, 0xa9, 0x05, 0xb1, 0x85, 0x44, 0xb8, 0x58, 0xcb, 0x12, 0x73, 0x4a, 0x53, 0xa1, 0xca, 0x21,
0x1c, 0xa3, 0x36, 0x46, 0x2e, 0x4e, 0x4f, 0x98, 0x13, 0x84, 0x2a, 0xb9, 0x38, 0xe1, 0xe1, 0x20,
0x64, 0x46, 0x9c, 0x6b, 0xd1, 0x23, 0x4e, 0xca, 0x84, 0x64, 0x7d, 0x05, 0x39, 0x95, 0x49, 0x6c,
0xe0, 0xf4, 0x62, 0x0c, 0x08, 0x00, 0x00, 0xff, 0xff, 0xd1, 0x66, 0x0d, 0x53, 0x49, 0x02, 0x00,
0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConnInterface
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion6
// InventoryClient is the client API for Inventory service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type InventoryClient interface {
GetEntity(ctx context.Context, in *GetEntityRequest, opts ...grpc.CallOption) (*GetEntityReply, error)
}
type inventoryClient struct {
cc grpc.ClientConnInterface
}
func NewInventoryClient(cc grpc.ClientConnInterface) InventoryClient {
return &inventoryClient{cc}
}
func (c *inventoryClient) GetEntity(ctx context.Context, in *GetEntityRequest, opts ...grpc.CallOption) (*GetEntityReply, error) {
out := new(GetEntityReply)
err := c.cc.Invoke(ctx, "/spotify.backstage.inventory.v1alpha1.Inventory/GetEntity", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// InventoryServer is the server API for Inventory service.
type InventoryServer interface {
GetEntity(context.Context, *GetEntityRequest) (*GetEntityReply, error)
}
// UnimplementedInventoryServer can be embedded to have forward compatible implementations.
type UnimplementedInventoryServer struct {
}
func (*UnimplementedInventoryServer) GetEntity(ctx context.Context, req *GetEntityRequest) (*GetEntityReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetEntity not implemented")
}
func RegisterInventoryServer(s *grpc.Server, srv InventoryServer) {
s.RegisterService(&_Inventory_serviceDesc, srv)
}
func _Inventory_GetEntity_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetEntityRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(InventoryServer).GetEntity(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/spotify.backstage.inventory.v1alpha1.Inventory/GetEntity",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(InventoryServer).GetEntity(ctx, req.(*GetEntityRequest))
}
return interceptor(ctx, in, info, handler)
}
var _Inventory_serviceDesc = grpc.ServiceDesc{
ServiceName: "spotify.backstage.inventory.v1alpha1.Inventory",
HandlerType: (*InventoryServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "GetEntity",
Handler: _Inventory_GetEntity_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "protos/inventory.proto",
}
+2
View File
@@ -21,4 +21,6 @@ module.exports = {
version: 'detect',
},
},
// Adding this to .eslintignore just doesn't even, let me know if you can make it work ._.
ignorePatterns: ['**/*_pb.js', '**/*_pb.d.ts'],
};
+2
View File
@@ -23,4 +23,6 @@ module.exports = {
version: 'detect', // Tells eslint-plugin-react to automatically detect the version of React to use
},
},
// Adding this to .eslintignore just doesn't even, let me know if you can make it work ._.
ignorePatterns: ['**/*_pb.js', '**/*_pb.d.ts'],
};
+4 -4
View File
@@ -23,10 +23,10 @@
]
},
"scripts": {
"start": "cross-env SKIP_PREFLIGHT_CHECK=true react-scripts start",
"build": "cross-env SKIP_PREFLIGHT_CHECK=true react-scripts build",
"test": "cross-env SKIP_PREFLIGHT_CHECK=true react-scripts test",
"lint": "eslint ./src/**/*.{ts,tsx} --max-warnings=0 --format=codeframe"
"start": "cross-env EXTEND_ESLINT=true SKIP_PREFLIGHT_CHECK=true react-scripts start",
"build": "cross-env EXTEND_ESLINT=true SKIP_PREFLIGHT_CHECK=true react-scripts build",
"test": "cross-env EXTEND_ESLINT=true SKIP_PREFLIGHT_CHECK=true react-scripts test",
"lint": "cross-env EXTEND_ESLINT=true eslint ./src/**/*.{ts,tsx} --max-warnings=0 --format=codeframe"
},
"eslintConfig": {
"extends": "react-app"
+3 -2
View File
@@ -5,7 +5,8 @@ import App from './App';
describe('App', () => {
it('renders learn react link', () => {
const rendered = render(<App />);
rendered.getByText('This is Backstage with plugin hello-world');
rendered.getByText('Hello!');
rendered.getByText('This is Backstage!');
rendered.getByText('Backstage is an open platform for building developer portals');
rendered.getByText('…with plugin hello-world:');
});
});
@@ -5,6 +5,8 @@
"main:src": "src/index.ts",
"devDependencies": {
"@backstage/core": "0.0.0",
"@material-ui/core": "^4.9.1",
"@material-ui/icons": "^4.9.1",
"@spotify/web-scripts": "^6.0.0",
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.3.2",
@@ -13,14 +15,15 @@
"@types/node": "^12.0.0",
"@types/react": "^16.9.0",
"@types/react-dom": "^16.9.0",
"google-protobuf": "^3.11.2",
"grpc-web": "^1.0.7",
"react": "^16.12.0",
"react-dom": "^16.12.0",
"@material-ui/core": "^4.9.1",
"@material-ui/icons": "^4.9.1"
"react-dom": "^16.12.0"
},
"scripts": {
"lint": "web-scripts lint",
"test": "web-scripts test"
"test": "web-scripts test",
"proto": "../../../scripts/gen-proto.sh hello.proto"
},
"license": "Apache-2.0"
}
@@ -1,15 +1,43 @@
import React, { FC } from 'react';
import React, { FC, useState, useEffect } from 'react';
import Button from '@material-ui/core/Button';
import { HelloPromiseClient } from '../../proto/hello_grpc_web_pb';
import { HelloRequest } from '../../proto/hello_pb';
import { Paper, Typography } from '@material-ui/core';
const MyComponent: FC<{}> = () => {
const [message, setMessage] = useState<string>('');
const [error, setError] = useState<string>();
useEffect(() => {
const client = new HelloPromiseClient('http://localhost:8080');
const request = new HelloRequest();
request.setName('Spotify');
client.hello(request).then(
reply => {
setMessage(reply.getMessage() ?? '');
},
err => {
setError(err.message);
},
);
}, []);
return (
<Button
variant="contained"
color="primary"
onClick={() => window.location.reload()}
>
Hello!
</Button>
<Paper square>
<Typography variant="body1">{message}</Typography>
<Typography variant="body1" color="error">
{error}
</Typography>
<Button
variant="contained"
color="primary"
onClick={() => window.location.reload()}
>
Hello!
</Button>
</Paper>
);
};
@@ -0,0 +1,32 @@
import * as grpcWeb from 'grpc-web';
import {
HelloReply,
HelloRequest} from './hello_pb';
export class HelloClient {
constructor (hostname: string,
credentials?: null | { [index: string]: string; },
options?: null | { [index: string]: string; });
hello(
request: HelloRequest,
metadata: grpcWeb.Metadata | undefined,
callback: (err: grpcWeb.Error,
response: HelloReply) => void
): grpcWeb.ClientReadableStream<HelloReply>;
}
export class HelloPromiseClient {
constructor (hostname: string,
credentials?: null | { [index: string]: string; },
options?: null | { [index: string]: string; });
hello(
request: HelloRequest,
metadata?: grpcWeb.Metadata
): Promise<HelloReply>;
}
@@ -0,0 +1,153 @@
/**
* @fileoverview gRPC-Web generated client stub for spotify.backstage.hello.v1alpha1
* @enhanceable
* @public
*/
// GENERATED CODE -- DO NOT EDIT!
const grpc = {};
grpc.web = require('grpc-web');
const proto = {};
proto.spotify = {};
proto.spotify.backstage = {};
proto.spotify.backstage.hello = {};
proto.spotify.backstage.hello.v1alpha1 = require('./hello_pb.js');
/**
* @param {string} hostname
* @param {?Object} credentials
* @param {?Object} options
* @constructor
* @struct
* @final
*/
proto.spotify.backstage.hello.v1alpha1.HelloClient =
function(hostname, credentials, options) {
if (!options) options = {};
options['format'] = 'text';
/**
* @private @const {!grpc.web.GrpcWebClientBase} The client
*/
this.client_ = new grpc.web.GrpcWebClientBase(options);
/**
* @private @const {string} The hostname
*/
this.hostname_ = hostname;
};
/**
* @param {string} hostname
* @param {?Object} credentials
* @param {?Object} options
* @constructor
* @struct
* @final
*/
proto.spotify.backstage.hello.v1alpha1.HelloPromiseClient =
function(hostname, credentials, options) {
if (!options) options = {};
options['format'] = 'text';
/**
* @private @const {!grpc.web.GrpcWebClientBase} The client
*/
this.client_ = new grpc.web.GrpcWebClientBase(options);
/**
* @private @const {string} The hostname
*/
this.hostname_ = hostname;
};
/**
* @const
* @type {!grpc.web.MethodDescriptor<
* !proto.spotify.backstage.hello.v1alpha1.HelloRequest,
* !proto.spotify.backstage.hello.v1alpha1.HelloReply>}
*/
const methodDescriptor_Hello_Hello = new grpc.web.MethodDescriptor(
'/spotify.backstage.hello.v1alpha1.Hello/Hello',
grpc.web.MethodType.UNARY,
proto.spotify.backstage.hello.v1alpha1.HelloRequest,
proto.spotify.backstage.hello.v1alpha1.HelloReply,
/**
* @param {!proto.spotify.backstage.hello.v1alpha1.HelloRequest} request
* @return {!Uint8Array}
*/
function(request) {
return request.serializeBinary();
},
proto.spotify.backstage.hello.v1alpha1.HelloReply.deserializeBinary
);
/**
* @const
* @type {!grpc.web.AbstractClientBase.MethodInfo<
* !proto.spotify.backstage.hello.v1alpha1.HelloRequest,
* !proto.spotify.backstage.hello.v1alpha1.HelloReply>}
*/
const methodInfo_Hello_Hello = new grpc.web.AbstractClientBase.MethodInfo(
proto.spotify.backstage.hello.v1alpha1.HelloReply,
/**
* @param {!proto.spotify.backstage.hello.v1alpha1.HelloRequest} request
* @return {!Uint8Array}
*/
function(request) {
return request.serializeBinary();
},
proto.spotify.backstage.hello.v1alpha1.HelloReply.deserializeBinary
);
/**
* @param {!proto.spotify.backstage.hello.v1alpha1.HelloRequest} request The
* request proto
* @param {?Object<string, string>} metadata User defined
* call metadata
* @param {function(?grpc.web.Error, ?proto.spotify.backstage.hello.v1alpha1.HelloReply)}
* callback The callback function(error, response)
* @return {!grpc.web.ClientReadableStream<!proto.spotify.backstage.hello.v1alpha1.HelloReply>|undefined}
* The XHR Node Readable Stream
*/
proto.spotify.backstage.hello.v1alpha1.HelloClient.prototype.hello =
function(request, metadata, callback) {
return this.client_.rpcCall(this.hostname_ +
'/spotify.backstage.hello.v1alpha1.Hello/Hello',
request,
metadata || {},
methodDescriptor_Hello_Hello,
callback);
};
/**
* @param {!proto.spotify.backstage.hello.v1alpha1.HelloRequest} request The
* request proto
* @param {?Object<string, string>} metadata User defined
* call metadata
* @return {!Promise<!proto.spotify.backstage.hello.v1alpha1.HelloReply>}
* A native promise that resolves to the response
*/
proto.spotify.backstage.hello.v1alpha1.HelloPromiseClient.prototype.hello =
function(request, metadata) {
return this.client_.unaryCall(this.hostname_ +
'/spotify.backstage.hello.v1alpha1.Hello/Hello',
request,
metadata || {},
methodDescriptor_Hello_Hello);
};
module.exports = proto.spotify.backstage.hello.v1alpha1;
@@ -0,0 +1,38 @@
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 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 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,
}
}
@@ -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);
+8
View File
@@ -0,0 +1,8 @@
#!/bin/bash
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
OUT='src/proto'
mkdir -p "$OUT"
exec protoc -I="$DIR/../../protos" --js_out=import_style=commonjs:"$OUT" --grpc-web_out=import_style=commonjs+dts,mode=grpcwebtext:"$OUT" "$@"
+10
View File
@@ -7467,6 +7467,11 @@ globby@^9.2.0:
pify "^4.0.1"
slash "^2.0.0"
google-protobuf@^3.11.2:
version "3.11.2"
resolved "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.11.2.tgz#43272974521a5cec35a21f62730cf517a5a8e38c"
integrity sha512-T4fin7lcYLUPj2ChUZ4DvfuuHtg3xi1621qeRZt2J7SvOQusOzq+sDT4vbotWTCjUXJoR36CA016LlhtPy80uQ==
got@^6.7.1:
version "6.7.1"
resolved "https://registry.npmjs.org/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0"
@@ -7494,6 +7499,11 @@ growly@^1.3.0:
resolved "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081"
integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=
grpc-web@^1.0.7:
version "1.0.7"
resolved "https://registry.npmjs.org/grpc-web/-/grpc-web-1.0.7.tgz#9e4fbcf63d3734515332ab59e42baa7d0d290015"
integrity sha512-Fkbz1nyvvt6GC6ODcxh9Fen6LLB3OTCgGHzHwM2Eni44SUhzqPz1UQgFp9sfBEfInOhx3yBdwo9ZLjZAmJ+TtA==
gzip-size@5.1.1:
version "5.1.1"
resolved "https://registry.npmjs.org/gzip-size/-/gzip-size-5.1.1.tgz#cb9bee692f87c0612b232840a873904e4c135274"