diff --git a/Makefile b/Makefile index b8133625..41f78f62 100644 --- a/Makefile +++ b/Makefile @@ -43,10 +43,14 @@ gen-cascade: gen-supernode: protoc \ --proto_path=proto \ + --proto_path=$$(go list -m -f '{{.Dir}}' github.com/grpc-ecosystem/grpc-gateway)/third_party/googleapis \ --go_out=gen \ --go_opt=paths=source_relative \ --go-grpc_out=gen \ --go-grpc_opt=paths=source_relative \ + --grpc-gateway_out=gen \ + --grpc-gateway_opt=paths=source_relative \ + --openapiv2_out=gen \ proto/supernode/supernode.proto # Define the paths diff --git a/gen/supernode/supernode.pb.go b/gen/supernode/supernode.pb.go index 0b3610f1..167c03bd 100644 --- a/gen/supernode/supernode.pb.go +++ b/gen/supernode/supernode.pb.go @@ -7,6 +7,7 @@ package supernode import ( + _ "google.golang.org/genproto/googleapis/api/annotations" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" @@ -56,21 +57,163 @@ func (*StatusRequest) Descriptor() ([]byte, []int) { return file_supernode_supernode_proto_rawDescGZIP(), []int{0} } +type ListServicesRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ListServicesRequest) Reset() { + *x = ListServicesRequest{} + mi := &file_supernode_supernode_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListServicesRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListServicesRequest) ProtoMessage() {} + +func (x *ListServicesRequest) ProtoReflect() protoreflect.Message { + mi := &file_supernode_supernode_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListServicesRequest.ProtoReflect.Descriptor instead. +func (*ListServicesRequest) Descriptor() ([]byte, []int) { + return file_supernode_supernode_proto_rawDescGZIP(), []int{1} +} + +type ListServicesResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Services []*ServiceInfo `protobuf:"bytes,1,rep,name=services,proto3" json:"services,omitempty"` + Count int32 `protobuf:"varint,2,opt,name=count,proto3" json:"count,omitempty"` +} + +func (x *ListServicesResponse) Reset() { + *x = ListServicesResponse{} + mi := &file_supernode_supernode_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListServicesResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListServicesResponse) ProtoMessage() {} + +func (x *ListServicesResponse) ProtoReflect() protoreflect.Message { + mi := &file_supernode_supernode_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListServicesResponse.ProtoReflect.Descriptor instead. +func (*ListServicesResponse) Descriptor() ([]byte, []int) { + return file_supernode_supernode_proto_rawDescGZIP(), []int{2} +} + +func (x *ListServicesResponse) GetServices() []*ServiceInfo { + if x != nil { + return x.Services + } + return nil +} + +func (x *ListServicesResponse) GetCount() int32 { + if x != nil { + return x.Count + } + return 0 +} + +type ServiceInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Methods []string `protobuf:"bytes,2,rep,name=methods,proto3" json:"methods,omitempty"` +} + +func (x *ServiceInfo) Reset() { + *x = ServiceInfo{} + mi := &file_supernode_supernode_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ServiceInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServiceInfo) ProtoMessage() {} + +func (x *ServiceInfo) ProtoReflect() protoreflect.Message { + mi := &file_supernode_supernode_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServiceInfo.ProtoReflect.Descriptor instead. +func (*ServiceInfo) Descriptor() ([]byte, []int) { + return file_supernode_supernode_proto_rawDescGZIP(), []int{3} +} + +func (x *ServiceInfo) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *ServiceInfo) GetMethods() []string { + if x != nil { + return x.Methods + } + return nil +} + // The StatusResponse represents system status. type StatusResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Cpu *StatusResponse_CPU `protobuf:"bytes,1,opt,name=cpu,proto3" json:"cpu,omitempty"` - Memory *StatusResponse_Memory `protobuf:"bytes,2,opt,name=memory,proto3" json:"memory,omitempty"` - Services []*StatusResponse_ServiceTasks `protobuf:"bytes,3,rep,name=services,proto3" json:"services,omitempty"` - AvailableServices []string `protobuf:"bytes,4,rep,name=available_services,json=availableServices,proto3" json:"available_services,omitempty"` + Cpu *StatusResponse_CPU `protobuf:"bytes,1,opt,name=cpu,proto3" json:"cpu,omitempty"` + Memory *StatusResponse_Memory `protobuf:"bytes,2,opt,name=memory,proto3" json:"memory,omitempty"` + RunningTasks []*StatusResponse_ServiceTasks `protobuf:"bytes,3,rep,name=running_tasks,json=runningTasks,proto3" json:"running_tasks,omitempty"` // Services with currently running tasks + RegisteredServices []string `protobuf:"bytes,4,rep,name=registered_services,json=registeredServices,proto3" json:"registered_services,omitempty"` // All registered/available services } func (x *StatusResponse) Reset() { *x = StatusResponse{} - mi := &file_supernode_supernode_proto_msgTypes[1] + mi := &file_supernode_supernode_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -82,7 +225,7 @@ func (x *StatusResponse) String() string { func (*StatusResponse) ProtoMessage() {} func (x *StatusResponse) ProtoReflect() protoreflect.Message { - mi := &file_supernode_supernode_proto_msgTypes[1] + mi := &file_supernode_supernode_proto_msgTypes[4] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -95,7 +238,7 @@ func (x *StatusResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use StatusResponse.ProtoReflect.Descriptor instead. func (*StatusResponse) Descriptor() ([]byte, []int) { - return file_supernode_supernode_proto_rawDescGZIP(), []int{1} + return file_supernode_supernode_proto_rawDescGZIP(), []int{4} } func (x *StatusResponse) GetCpu() *StatusResponse_CPU { @@ -112,16 +255,16 @@ func (x *StatusResponse) GetMemory() *StatusResponse_Memory { return nil } -func (x *StatusResponse) GetServices() []*StatusResponse_ServiceTasks { +func (x *StatusResponse) GetRunningTasks() []*StatusResponse_ServiceTasks { if x != nil { - return x.Services + return x.RunningTasks } return nil } -func (x *StatusResponse) GetAvailableServices() []string { +func (x *StatusResponse) GetRegisteredServices() []string { if x != nil { - return x.AvailableServices + return x.RegisteredServices } return nil } @@ -137,7 +280,7 @@ type StatusResponse_CPU struct { func (x *StatusResponse_CPU) Reset() { *x = StatusResponse_CPU{} - mi := &file_supernode_supernode_proto_msgTypes[2] + mi := &file_supernode_supernode_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -149,7 +292,7 @@ func (x *StatusResponse_CPU) String() string { func (*StatusResponse_CPU) ProtoMessage() {} func (x *StatusResponse_CPU) ProtoReflect() protoreflect.Message { - mi := &file_supernode_supernode_proto_msgTypes[2] + mi := &file_supernode_supernode_proto_msgTypes[5] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -162,7 +305,7 @@ func (x *StatusResponse_CPU) ProtoReflect() protoreflect.Message { // Deprecated: Use StatusResponse_CPU.ProtoReflect.Descriptor instead. func (*StatusResponse_CPU) Descriptor() ([]byte, []int) { - return file_supernode_supernode_proto_rawDescGZIP(), []int{1, 0} + return file_supernode_supernode_proto_rawDescGZIP(), []int{4, 0} } func (x *StatusResponse_CPU) GetUsage() string { @@ -192,7 +335,7 @@ type StatusResponse_Memory struct { func (x *StatusResponse_Memory) Reset() { *x = StatusResponse_Memory{} - mi := &file_supernode_supernode_proto_msgTypes[3] + mi := &file_supernode_supernode_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -204,7 +347,7 @@ func (x *StatusResponse_Memory) String() string { func (*StatusResponse_Memory) ProtoMessage() {} func (x *StatusResponse_Memory) ProtoReflect() protoreflect.Message { - mi := &file_supernode_supernode_proto_msgTypes[3] + mi := &file_supernode_supernode_proto_msgTypes[6] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -217,7 +360,7 @@ func (x *StatusResponse_Memory) ProtoReflect() protoreflect.Message { // Deprecated: Use StatusResponse_Memory.ProtoReflect.Descriptor instead. func (*StatusResponse_Memory) Descriptor() ([]byte, []int) { - return file_supernode_supernode_proto_rawDescGZIP(), []int{1, 1} + return file_supernode_supernode_proto_rawDescGZIP(), []int{4, 1} } func (x *StatusResponse_Memory) GetTotal() uint64 { @@ -261,7 +404,7 @@ type StatusResponse_ServiceTasks struct { func (x *StatusResponse_ServiceTasks) Reset() { *x = StatusResponse_ServiceTasks{} - mi := &file_supernode_supernode_proto_msgTypes[4] + mi := &file_supernode_supernode_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -273,7 +416,7 @@ func (x *StatusResponse_ServiceTasks) String() string { func (*StatusResponse_ServiceTasks) ProtoMessage() {} func (x *StatusResponse_ServiceTasks) ProtoReflect() protoreflect.Message { - mi := &file_supernode_supernode_proto_msgTypes[4] + mi := &file_supernode_supernode_proto_msgTypes[7] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -286,7 +429,7 @@ func (x *StatusResponse_ServiceTasks) ProtoReflect() protoreflect.Message { // Deprecated: Use StatusResponse_ServiceTasks.ProtoReflect.Descriptor instead. func (*StatusResponse_ServiceTasks) Descriptor() ([]byte, []int) { - return file_supernode_supernode_proto_rawDescGZIP(), []int{1, 2} + return file_supernode_supernode_proto_rawDescGZIP(), []int{4, 2} } func (x *StatusResponse_ServiceTasks) GetServiceName() string { @@ -315,50 +458,72 @@ var File_supernode_supernode_proto protoreflect.FileDescriptor var file_supernode_supernode_proto_rawDesc = []byte{ 0x0a, 0x19, 0x73, 0x75, 0x70, 0x65, 0x72, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x73, 0x75, 0x70, 0x65, 0x72, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x09, 0x73, 0x75, 0x70, - 0x65, 0x72, 0x6e, 0x6f, 0x64, 0x65, 0x22, 0x0f, 0x0a, 0x0d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x85, 0x04, 0x0a, 0x0e, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x03, 0x63, 0x70, - 0x75, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x6e, - 0x6f, 0x64, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x2e, 0x43, 0x50, 0x55, 0x52, 0x03, 0x63, 0x70, 0x75, 0x12, 0x38, 0x0a, 0x06, 0x6d, - 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x73, 0x75, + 0x65, 0x72, 0x6e, 0x6f, 0x64, 0x65, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, + 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x0f, 0x0a, 0x0d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x15, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x60, 0x0a, 0x14, + 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x08, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x6e, 0x6f, + 0x64, 0x65, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x3b, + 0x0a, 0x0b, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x22, 0x90, 0x04, 0x0a, 0x0e, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, + 0x0a, 0x03, 0x63, 0x70, 0x75, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x52, 0x06, 0x6d, - 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x12, 0x42, 0x0a, 0x08, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x6e, - 0x6f, 0x64, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x52, - 0x08, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x2d, 0x0a, 0x12, 0x61, 0x76, 0x61, - 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, - 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x11, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x1a, 0x39, 0x0a, 0x03, 0x43, 0x50, 0x55, 0x12, - 0x14, 0x0a, 0x05, 0x75, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, - 0x75, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x6d, 0x61, 0x69, 0x6e, 0x69, - 0x6e, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x6d, 0x61, 0x69, 0x6e, - 0x69, 0x6e, 0x67, 0x1a, 0x6d, 0x0a, 0x06, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x12, 0x14, 0x0a, - 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x74, 0x6f, - 0x74, 0x61, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x04, 0x52, 0x04, 0x75, 0x73, 0x65, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x76, 0x61, 0x69, 0x6c, - 0x61, 0x62, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x61, 0x76, 0x61, 0x69, - 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x64, 0x5f, 0x70, 0x65, - 0x72, 0x63, 0x18, 0x04, 0x20, 0x01, 0x28, 0x01, 0x52, 0x08, 0x75, 0x73, 0x65, 0x64, 0x50, 0x65, - 0x72, 0x63, 0x1a, 0x6b, 0x0a, 0x0c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x54, 0x61, 0x73, - 0x6b, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x69, 0x64, - 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x74, 0x61, 0x73, 0x6b, 0x49, 0x64, 0x73, - 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x74, 0x61, 0x73, 0x6b, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x32, - 0x54, 0x0a, 0x10, 0x53, 0x75, 0x70, 0x65, 0x72, 0x6e, 0x6f, 0x64, 0x65, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x12, 0x40, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x43, 0x50, 0x55, 0x52, 0x03, 0x63, 0x70, 0x75, 0x12, + 0x38, 0x0a, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x20, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4d, 0x65, 0x6d, 0x6f, 0x72, + 0x79, 0x52, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x12, 0x4b, 0x0a, 0x0d, 0x72, 0x75, 0x6e, + 0x6e, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x61, 0x73, 0x6b, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x26, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x52, 0x0c, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, + 0x67, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x12, 0x2f, 0x0a, 0x13, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, + 0x65, 0x72, 0x65, 0x64, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x04, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x12, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x65, 0x64, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x1a, 0x39, 0x0a, 0x03, 0x43, 0x50, 0x55, 0x12, 0x14, + 0x0a, 0x05, 0x75, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x75, + 0x73, 0x61, 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x6d, 0x61, 0x69, 0x6e, 0x69, 0x6e, + 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x6d, 0x61, 0x69, 0x6e, 0x69, + 0x6e, 0x67, 0x1a, 0x6d, 0x0a, 0x06, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x12, 0x14, 0x0a, 0x05, + 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x74, 0x6f, 0x74, + 0x61, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x04, 0x75, 0x73, 0x65, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, + 0x62, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x61, 0x76, 0x61, 0x69, 0x6c, + 0x61, 0x62, 0x6c, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x64, 0x5f, 0x70, 0x65, 0x72, + 0x63, 0x18, 0x04, 0x20, 0x01, 0x28, 0x01, 0x52, 0x08, 0x75, 0x73, 0x65, 0x64, 0x50, 0x65, 0x72, + 0x63, 0x1a, 0x6b, 0x0a, 0x0c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x54, 0x61, 0x73, 0x6b, + 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x69, 0x64, 0x73, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x74, 0x61, 0x73, 0x6b, 0x49, 0x64, 0x73, 0x12, + 0x1d, 0x0a, 0x0a, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x09, 0x74, 0x61, 0x73, 0x6b, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x32, 0xd7, + 0x01, 0x0a, 0x10, 0x53, 0x75, 0x70, 0x65, 0x72, 0x6e, 0x6f, 0x64, 0x65, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x12, 0x58, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x18, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x33, 0x5a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x4c, 0x75, 0x6d, 0x65, 0x72, 0x61, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, - 0x6f, 0x6c, 0x2f, 0x73, 0x75, 0x70, 0x65, 0x72, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x67, 0x65, 0x6e, - 0x2f, 0x73, 0x75, 0x70, 0x65, 0x72, 0x6e, 0x6f, 0x64, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x16, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x10, 0x12, 0x0e, 0x2f, + 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x69, 0x0a, + 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x1e, 0x2e, + 0x73, 0x75, 0x70, 0x65, 0x72, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, + 0x73, 0x75, 0x70, 0x65, 0x72, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x18, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x12, 0x10, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x42, 0x33, 0x5a, 0x31, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x4c, 0x75, 0x6d, 0x65, 0x72, 0x61, 0x50, 0x72, 0x6f, + 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x73, 0x75, 0x70, 0x65, 0x72, 0x6e, 0x6f, 0x64, 0x65, 0x2f, + 0x67, 0x65, 0x6e, 0x2f, 0x73, 0x75, 0x70, 0x65, 0x72, 0x6e, 0x6f, 0x64, 0x65, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -373,25 +538,31 @@ func file_supernode_supernode_proto_rawDescGZIP() []byte { return file_supernode_supernode_proto_rawDescData } -var file_supernode_supernode_proto_msgTypes = make([]protoimpl.MessageInfo, 5) +var file_supernode_supernode_proto_msgTypes = make([]protoimpl.MessageInfo, 8) var file_supernode_supernode_proto_goTypes = []any{ (*StatusRequest)(nil), // 0: supernode.StatusRequest - (*StatusResponse)(nil), // 1: supernode.StatusResponse - (*StatusResponse_CPU)(nil), // 2: supernode.StatusResponse.CPU - (*StatusResponse_Memory)(nil), // 3: supernode.StatusResponse.Memory - (*StatusResponse_ServiceTasks)(nil), // 4: supernode.StatusResponse.ServiceTasks + (*ListServicesRequest)(nil), // 1: supernode.ListServicesRequest + (*ListServicesResponse)(nil), // 2: supernode.ListServicesResponse + (*ServiceInfo)(nil), // 3: supernode.ServiceInfo + (*StatusResponse)(nil), // 4: supernode.StatusResponse + (*StatusResponse_CPU)(nil), // 5: supernode.StatusResponse.CPU + (*StatusResponse_Memory)(nil), // 6: supernode.StatusResponse.Memory + (*StatusResponse_ServiceTasks)(nil), // 7: supernode.StatusResponse.ServiceTasks } var file_supernode_supernode_proto_depIdxs = []int32{ - 2, // 0: supernode.StatusResponse.cpu:type_name -> supernode.StatusResponse.CPU - 3, // 1: supernode.StatusResponse.memory:type_name -> supernode.StatusResponse.Memory - 4, // 2: supernode.StatusResponse.services:type_name -> supernode.StatusResponse.ServiceTasks - 0, // 3: supernode.SupernodeService.GetStatus:input_type -> supernode.StatusRequest - 1, // 4: supernode.SupernodeService.GetStatus:output_type -> supernode.StatusResponse - 4, // [4:5] is the sub-list for method output_type - 3, // [3:4] is the sub-list for method input_type - 3, // [3:3] is the sub-list for extension type_name - 3, // [3:3] is the sub-list for extension extendee - 0, // [0:3] is the sub-list for field type_name + 3, // 0: supernode.ListServicesResponse.services:type_name -> supernode.ServiceInfo + 5, // 1: supernode.StatusResponse.cpu:type_name -> supernode.StatusResponse.CPU + 6, // 2: supernode.StatusResponse.memory:type_name -> supernode.StatusResponse.Memory + 7, // 3: supernode.StatusResponse.running_tasks:type_name -> supernode.StatusResponse.ServiceTasks + 0, // 4: supernode.SupernodeService.GetStatus:input_type -> supernode.StatusRequest + 1, // 5: supernode.SupernodeService.ListServices:input_type -> supernode.ListServicesRequest + 4, // 6: supernode.SupernodeService.GetStatus:output_type -> supernode.StatusResponse + 2, // 7: supernode.SupernodeService.ListServices:output_type -> supernode.ListServicesResponse + 6, // [6:8] is the sub-list for method output_type + 4, // [4:6] is the sub-list for method input_type + 4, // [4:4] is the sub-list for extension type_name + 4, // [4:4] is the sub-list for extension extendee + 0, // [0:4] is the sub-list for field type_name } func init() { file_supernode_supernode_proto_init() } @@ -405,7 +576,7 @@ func file_supernode_supernode_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_supernode_supernode_proto_rawDesc, NumEnums: 0, - NumMessages: 5, + NumMessages: 8, NumExtensions: 0, NumServices: 1, }, diff --git a/gen/supernode/supernode.pb.gw.go b/gen/supernode/supernode.pb.gw.go new file mode 100644 index 00000000..65c4649a --- /dev/null +++ b/gen/supernode/supernode.pb.gw.go @@ -0,0 +1,218 @@ +// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. +// source: supernode/supernode.proto + +/* +Package supernode is a reverse proxy. + +It translates gRPC into RESTful JSON APIs. +*/ +package supernode + +import ( + "context" + "io" + "net/http" + + "github.com/golang/protobuf/descriptor" + "github.com/golang/protobuf/proto" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/grpc-ecosystem/grpc-gateway/utilities" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" +) + +// Suppress "imported and not used" errors +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray +var _ = descriptor.ForMessage +var _ = metadata.Join + +func request_SupernodeService_GetStatus_0(ctx context.Context, marshaler runtime.Marshaler, client SupernodeServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq StatusRequest + var metadata runtime.ServerMetadata + + msg, err := client.GetStatus(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_SupernodeService_GetStatus_0(ctx context.Context, marshaler runtime.Marshaler, server SupernodeServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq StatusRequest + var metadata runtime.ServerMetadata + + msg, err := server.GetStatus(ctx, &protoReq) + return msg, metadata, err + +} + +func request_SupernodeService_ListServices_0(ctx context.Context, marshaler runtime.Marshaler, client SupernodeServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ListServicesRequest + var metadata runtime.ServerMetadata + + msg, err := client.ListServices(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_SupernodeService_ListServices_0(ctx context.Context, marshaler runtime.Marshaler, server SupernodeServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ListServicesRequest + var metadata runtime.ServerMetadata + + msg, err := server.ListServices(ctx, &protoReq) + return msg, metadata, err + +} + +// RegisterSupernodeServiceHandlerServer registers the http handlers for service SupernodeService to "mux". +// UnaryRPC :call SupernodeServiceServer directly. +// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. +// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterSupernodeServiceHandlerFromEndpoint instead. +func RegisterSupernodeServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server SupernodeServiceServer) error { + + mux.Handle("GET", pattern_SupernodeService_GetStatus_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_SupernodeService_GetStatus_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_SupernodeService_GetStatus_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_SupernodeService_ListServices_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_SupernodeService_ListServices_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_SupernodeService_ListServices_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +// RegisterSupernodeServiceHandlerFromEndpoint is same as RegisterSupernodeServiceHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterSupernodeServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.Dial(endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterSupernodeServiceHandler(ctx, mux, conn) +} + +// RegisterSupernodeServiceHandler registers the http handlers for service SupernodeService to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterSupernodeServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + return RegisterSupernodeServiceHandlerClient(ctx, mux, NewSupernodeServiceClient(conn)) +} + +// RegisterSupernodeServiceHandlerClient registers the http handlers for service SupernodeService +// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "SupernodeServiceClient". +// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "SupernodeServiceClient" +// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in +// "SupernodeServiceClient" to call the correct interceptors. +func RegisterSupernodeServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client SupernodeServiceClient) error { + + mux.Handle("GET", pattern_SupernodeService_GetStatus_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_SupernodeService_GetStatus_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_SupernodeService_GetStatus_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_SupernodeService_ListServices_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_SupernodeService_ListServices_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_SupernodeService_ListServices_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_SupernodeService_GetStatus_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "status"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_SupernodeService_ListServices_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "services"}, "", runtime.AssumeColonVerbOpt(true))) +) + +var ( + forward_SupernodeService_GetStatus_0 = runtime.ForwardResponseMessage + + forward_SupernodeService_ListServices_0 = runtime.ForwardResponseMessage +) diff --git a/gen/supernode/supernode.swagger.json b/gen/supernode/supernode.swagger.json new file mode 100644 index 00000000..779075de --- /dev/null +++ b/gen/supernode/supernode.swagger.json @@ -0,0 +1,202 @@ +{ + "swagger": "2.0", + "info": { + "title": "supernode/supernode.proto", + "version": "version not set" + }, + "tags": [ + { + "name": "SupernodeService" + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "paths": { + "/api/v1/services": { + "get": { + "operationId": "SupernodeService_ListServices", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/supernodeListServicesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "tags": [ + "SupernodeService" + ] + } + }, + "/api/v1/status": { + "get": { + "operationId": "SupernodeService_GetStatus", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/supernodeStatusResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "tags": [ + "SupernodeService" + ] + } + } + }, + "definitions": { + "StatusResponseCPU": { + "type": "object", + "properties": { + "usage": { + "type": "string" + }, + "remaining": { + "type": "string" + } + } + }, + "StatusResponseMemory": { + "type": "object", + "properties": { + "total": { + "type": "string", + "format": "uint64" + }, + "used": { + "type": "string", + "format": "uint64" + }, + "available": { + "type": "string", + "format": "uint64" + }, + "usedPerc": { + "type": "number", + "format": "double" + } + } + }, + "StatusResponseServiceTasks": { + "type": "object", + "properties": { + "serviceName": { + "type": "string" + }, + "taskIds": { + "type": "array", + "items": { + "type": "string" + } + }, + "taskCount": { + "type": "integer", + "format": "int32" + } + }, + "title": "ServiceTasks contains task information for a specific service" + }, + "protobufAny": { + "type": "object", + "properties": { + "@type": { + "type": "string" + } + }, + "additionalProperties": {} + }, + "rpcStatus": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32" + }, + "message": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/protobufAny" + } + } + } + }, + "supernodeListServicesResponse": { + "type": "object", + "properties": { + "services": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/supernodeServiceInfo" + } + }, + "count": { + "type": "integer", + "format": "int32" + } + } + }, + "supernodeServiceInfo": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "methods": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "supernodeStatusResponse": { + "type": "object", + "properties": { + "cpu": { + "$ref": "#/definitions/StatusResponseCPU" + }, + "memory": { + "$ref": "#/definitions/StatusResponseMemory" + }, + "runningTasks": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/StatusResponseServiceTasks" + }, + "title": "Services with currently running tasks" + }, + "registeredServices": { + "type": "array", + "items": { + "type": "string" + }, + "title": "All registered/available services" + } + }, + "description": "The StatusResponse represents system status." + } + } +} diff --git a/gen/supernode/supernode_grpc.pb.go b/gen/supernode/supernode_grpc.pb.go index 783c3f8c..97eb3a0a 100644 --- a/gen/supernode/supernode_grpc.pb.go +++ b/gen/supernode/supernode_grpc.pb.go @@ -19,7 +19,8 @@ import ( const _ = grpc.SupportPackageIsVersion9 const ( - SupernodeService_GetStatus_FullMethodName = "/supernode.SupernodeService/GetStatus" + SupernodeService_GetStatus_FullMethodName = "/supernode.SupernodeService/GetStatus" + SupernodeService_ListServices_FullMethodName = "/supernode.SupernodeService/ListServices" ) // SupernodeServiceClient is the client API for SupernodeService service. @@ -29,6 +30,7 @@ const ( // SupernodeService provides status information for all services type SupernodeServiceClient interface { GetStatus(ctx context.Context, in *StatusRequest, opts ...grpc.CallOption) (*StatusResponse, error) + ListServices(ctx context.Context, in *ListServicesRequest, opts ...grpc.CallOption) (*ListServicesResponse, error) } type supernodeServiceClient struct { @@ -49,6 +51,16 @@ func (c *supernodeServiceClient) GetStatus(ctx context.Context, in *StatusReques return out, nil } +func (c *supernodeServiceClient) ListServices(ctx context.Context, in *ListServicesRequest, opts ...grpc.CallOption) (*ListServicesResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ListServicesResponse) + err := c.cc.Invoke(ctx, SupernodeService_ListServices_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + // SupernodeServiceServer is the server API for SupernodeService service. // All implementations must embed UnimplementedSupernodeServiceServer // for forward compatibility. @@ -56,6 +68,7 @@ func (c *supernodeServiceClient) GetStatus(ctx context.Context, in *StatusReques // SupernodeService provides status information for all services type SupernodeServiceServer interface { GetStatus(context.Context, *StatusRequest) (*StatusResponse, error) + ListServices(context.Context, *ListServicesRequest) (*ListServicesResponse, error) mustEmbedUnimplementedSupernodeServiceServer() } @@ -69,6 +82,9 @@ type UnimplementedSupernodeServiceServer struct{} func (UnimplementedSupernodeServiceServer) GetStatus(context.Context, *StatusRequest) (*StatusResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetStatus not implemented") } +func (UnimplementedSupernodeServiceServer) ListServices(context.Context, *ListServicesRequest) (*ListServicesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListServices not implemented") +} func (UnimplementedSupernodeServiceServer) mustEmbedUnimplementedSupernodeServiceServer() {} func (UnimplementedSupernodeServiceServer) testEmbeddedByValue() {} @@ -108,6 +124,24 @@ func _SupernodeService_GetStatus_Handler(srv interface{}, ctx context.Context, d return interceptor(ctx, in, info, handler) } +func _SupernodeService_ListServices_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListServicesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SupernodeServiceServer).ListServices(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: SupernodeService_ListServices_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SupernodeServiceServer).ListServices(ctx, req.(*ListServicesRequest)) + } + return interceptor(ctx, in, info, handler) +} + // SupernodeService_ServiceDesc is the grpc.ServiceDesc for SupernodeService service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -119,6 +153,10 @@ var SupernodeService_ServiceDesc = grpc.ServiceDesc{ MethodName: "GetStatus", Handler: _SupernodeService_GetStatus_Handler, }, + { + MethodName: "ListServices", + Handler: _SupernodeService_ListServices_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "supernode/supernode.proto", diff --git a/go.mod b/go.mod index b653fc76..b6f9ca6d 100644 --- a/go.mod +++ b/go.mod @@ -25,6 +25,7 @@ require ( github.com/golang/mock v1.6.0 github.com/golang/protobuf v1.5.4 github.com/google/uuid v1.6.0 + github.com/grpc-ecosystem/grpc-gateway v1.16.0 github.com/jmoiron/sqlx v1.4.0 github.com/json-iterator/go v1.1.12 github.com/klauspost/compress v1.18.0 @@ -42,6 +43,7 @@ require ( golang.org/x/crypto v0.36.0 golang.org/x/sync v0.12.0 golang.org/x/sys v0.31.0 + google.golang.org/genproto/googleapis/api v0.0.0-20250324211829-b45e905df463 google.golang.org/grpc v1.71.0 google.golang.org/protobuf v1.36.6 gopkg.in/yaml.v3 v3.0.1 @@ -113,7 +115,6 @@ require ( github.com/gorilla/mux v1.8.1 // indirect github.com/gorilla/websocket v1.5.3 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect - github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect github.com/hashicorp/go-hclog v1.5.0 // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect @@ -187,7 +188,6 @@ require ( golang.org/x/term v0.30.0 // indirect golang.org/x/text v0.23.0 // indirect google.golang.org/genproto v0.0.0-20240701130421-f6361c86f094 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250324211829-b45e905df463 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gotest.tools/v3 v3.5.1 // indirect diff --git a/proto/supernode/supernode.proto b/proto/supernode/supernode.proto index 10d72990..9e7dfb09 100644 --- a/proto/supernode/supernode.proto +++ b/proto/supernode/supernode.proto @@ -2,13 +2,37 @@ syntax = "proto3"; package supernode; option go_package = "github.com/LumeraProtocol/supernode/gen/supernode"; +import "google/api/annotations.proto"; + // SupernodeService provides status information for all services service SupernodeService { - rpc GetStatus(StatusRequest) returns (StatusResponse); + rpc GetStatus(StatusRequest) returns (StatusResponse) { + option (google.api.http) = { + get: "/api/v1/status" + }; + } + + rpc ListServices(ListServicesRequest) returns (ListServicesResponse) { + option (google.api.http) = { + get: "/api/v1/services" + }; + } } message StatusRequest {} +message ListServicesRequest {} + +message ListServicesResponse { + repeated ServiceInfo services = 1; + int32 count = 2; +} + +message ServiceInfo { + string name = 1; + repeated string methods = 2; +} + // The StatusResponse represents system status. message StatusResponse { message CPU { @@ -32,6 +56,6 @@ message StatusResponse { CPU cpu = 1; Memory memory = 2; - repeated ServiceTasks services = 3; - repeated string available_services = 4; + repeated ServiceTasks running_tasks = 3; // Services with currently running tasks + repeated string registered_services = 4; // All registered/available services } \ No newline at end of file diff --git a/sdk/adapters/supernodeservice/adapter.go b/sdk/adapters/supernodeservice/adapter.go index 8d730467..39000f37 100644 --- a/sdk/adapters/supernodeservice/adapter.go +++ b/sdk/adapters/supernodeservice/adapter.go @@ -358,9 +358,9 @@ func toSdkSupernodeStatus(resp *supernode.StatusResponse) *SupernodeStatusrespon result.Memory.UsedPerc = resp.Memory.UsedPerc } - // Convert Services data - result.Services = make([]ServiceTasks, 0, len(resp.Services)) - for _, service := range resp.Services { + // Convert RunningTasks data + result.Services = make([]ServiceTasks, 0, len(resp.RunningTasks)) + for _, service := range resp.RunningTasks { result.Services = append(result.Services, ServiceTasks{ ServiceName: service.ServiceName, TaskIDs: service.TaskIds, @@ -368,9 +368,9 @@ func toSdkSupernodeStatus(resp *supernode.StatusResponse) *SupernodeStatusrespon }) } - // Convert AvailableServices data - result.AvailableServices = make([]string, len(resp.AvailableServices)) - copy(result.AvailableServices, resp.AvailableServices) + // Convert RegisteredServices data + result.AvailableServices = make([]string, len(resp.RegisteredServices)) + copy(result.AvailableServices, resp.RegisteredServices) return result } diff --git a/supernode/cmd/init.go b/supernode/cmd/init.go index 3615ad5c..f6bcfaa1 100644 --- a/supernode/cmd/init.go +++ b/supernode/cmd/init.go @@ -29,6 +29,7 @@ var ( mnemonicFlag string supernodeAddrFlag string supernodePortFlag int + gatewayPortFlag int lumeraGrpcFlag string chainIDFlag string ) @@ -39,6 +40,7 @@ const ( DefaultKeyName = "" DefaultSupernodeAddr = "0.0.0.0" DefaultSupernodePort = 4444 + DefaultGatewayPort = 8002 DefaultLumeraGRPC = "localhost:9090" DefaultChainID = "lumera-mainnet-1" ) @@ -51,6 +53,7 @@ type InitInputs struct { Mnemonic string SupernodeAddr string SupernodePort int + GatewayPort int LumeraGRPC string ChainID string } @@ -120,7 +123,7 @@ Example: } // Update config with gathered settings and save - if err := updateAndSaveConfig(address, inputs.SupernodeAddr, inputs.SupernodePort, inputs.LumeraGRPC, inputs.ChainID); err != nil { + if err := updateAndSaveConfig(address, inputs.SupernodeAddr, inputs.SupernodePort, inputs.GatewayPort, inputs.LumeraGRPC, inputs.ChainID); err != nil { return err } @@ -230,6 +233,16 @@ func gatherUserInputs() (InitInputs, error) { } } + gatewayPort := DefaultGatewayPort + if gatewayPortFlag != 0 { + gatewayPort = gatewayPortFlag + + // Port validation + if gatewayPort < 1 || gatewayPort > 65535 { + return InitInputs{}, fmt.Errorf("invalid gateway port: %d, must be between 1 and 65535", gatewayPort) + } + } + lumeraGRPC := DefaultLumeraGRPC if lumeraGrpcFlag != "" { lumeraGRPC = lumeraGrpcFlag @@ -257,6 +270,7 @@ func gatherUserInputs() (InitInputs, error) { Mnemonic: mnemonicFlag, SupernodeAddr: supernodeAddr, SupernodePort: supernodePort, + GatewayPort: gatewayPort, LumeraGRPC: lumeraGRPC, ChainID: chainID, }, nil @@ -276,8 +290,8 @@ func gatherUserInputs() (InitInputs, error) { return InitInputs{}, fmt.Errorf("failed to configure key management: %w", err) } - inputs.SupernodeAddr, inputs.SupernodePort, inputs.LumeraGRPC, inputs.ChainID, err = - promptNetworkConfig(supernodeAddrFlag, supernodePortFlag, lumeraGrpcFlag, chainIDFlag) + inputs.SupernodeAddr, inputs.SupernodePort, inputs.GatewayPort, inputs.LumeraGRPC, inputs.ChainID, err = + promptNetworkConfig(supernodeAddrFlag, supernodePortFlag, gatewayPortFlag, lumeraGrpcFlag, chainIDFlag) if err != nil { return InitInputs{}, fmt.Errorf("failed to configure network settings: %w", err) } @@ -379,11 +393,12 @@ func createNewKey(kr consmoskeyring.Keyring, keyName string) (string, string, er } // updateAndSaveConfig updates the configuration with network settings and saves it -func updateAndSaveConfig(address, supernodeAddr string, supernodePort int, lumeraGrpcAddr string, chainID string) error { +func updateAndSaveConfig(address, supernodeAddr string, supernodePort int, gatewayPort int, lumeraGrpcAddr string, chainID string) error { // Update config with address and network settings appConfig.SupernodeConfig.Identity = address appConfig.SupernodeConfig.IpAddress = supernodeAddr appConfig.SupernodeConfig.Port = uint16(supernodePort) + appConfig.SupernodeConfig.GatewayPort = uint16(gatewayPort) appConfig.LumeraClientConfig.GRPCAddr = lumeraGrpcAddr appConfig.LumeraClientConfig.ChainID = chainID @@ -484,7 +499,7 @@ func promptKeyManagement(passedKeyName string, recover bool, passedMnemonic stri return keyName, shouldRecover, mnemonic, nil } -func promptNetworkConfig(passedAddrs string, passedPort int, passedGRPC, passedChainID string) (supernodeAddr string, supernodePort int, lumeraGrpcAddr string, chainID string, err error) { +func promptNetworkConfig(passedAddrs string, passedPort int, passedGatewayPort int, passedGRPC, passedChainID string) (supernodeAddr string, supernodePort int, gatewayPort int, lumeraGrpcAddr string, chainID string, err error) { if passedAddrs != "" { supernodeAddr = passedAddrs } else { @@ -496,6 +511,13 @@ func promptNetworkConfig(passedAddrs string, passedPort int, passedGRPC, passedC } else { port = fmt.Sprintf("%d", DefaultSupernodePort) } + + var gPort string + if passedGatewayPort != 0 { + gPort = fmt.Sprintf("%d", passedGatewayPort) + } else { + gPort = fmt.Sprintf("%d", DefaultGatewayPort) + } if passedGRPC != "" { lumeraGrpcAddr = passedGRPC } else { @@ -515,12 +537,12 @@ func promptNetworkConfig(passedAddrs string, passedPort int, passedGRPC, passedC } err = survey.AskOne(supernodePrompt, &supernodeAddr) if err != nil { - return "", 0, "", "", err + return "", 0, 0, "", "", err } // Validate IP address format if err := validateIPAddress(supernodeAddr); err != nil { - return "", 0, "", "", err + return "", 0, 0, "", "", err } // Supernode port @@ -532,12 +554,29 @@ func promptNetworkConfig(passedAddrs string, passedPort int, passedGRPC, passedC } err = survey.AskOne(supernodePortPrompt, &portStr) if err != nil { - return "", 0, "", "", err + return "", 0, 0, "", "", err } supernodePort, err = strconv.Atoi(portStr) if err != nil || supernodePort < 1 || supernodePort > 65535 { - return "", 0, "", "", fmt.Errorf("invalid supernode port: %s", portStr) + return "", 0, 0, "", "", fmt.Errorf("invalid supernode port: %s", portStr) + } + + // Gateway port + var gatewayPortStr string + gatewayPortPrompt := &survey.Input{ + Message: "Enter HTTP gateway port:", + Default: gPort, + Help: "Port for the HTTP gateway to listen on (1-65535), Ctrl-C for exit", + } + err = survey.AskOne(gatewayPortPrompt, &gatewayPortStr) + if err != nil { + return "", 0, 0, "", "", err + } + + gatewayPort, err = strconv.Atoi(gatewayPortStr) + if err != nil || gatewayPort < 1 || gatewayPort > 65535 { + return "", 0, 0, "", "", fmt.Errorf("invalid gateway port: %s", gatewayPortStr) } // Lumera GRPC address (full address with port) @@ -548,12 +587,12 @@ func promptNetworkConfig(passedAddrs string, passedPort int, passedGRPC, passedC } err = survey.AskOne(lumeraPrompt, &lumeraGrpcAddr) if err != nil { - return "", 0, "", "", err + return "", 0, 0, "", "", err } // Validate GRPC address format if err := validateGRPCAddress(lumeraGrpcAddr); err != nil { - return "", 0, "", "", err + return "", 0, 0, "", "", err } // Chain ID @@ -564,10 +603,10 @@ func promptNetworkConfig(passedAddrs string, passedPort int, passedGRPC, passedC } err = survey.AskOne(chainPrompt, &chainID, survey.WithValidator(survey.Required)) if err != nil { - return "", 0, "", "", err + return "", 0, 0, "", "", err } - return supernodeAddr, supernodePort, lumeraGrpcAddr, chainID, nil + return supernodeAddr, supernodePort, gatewayPort, lumeraGrpcAddr, chainID, nil } // validateKeyringBackend checks if the provided keyring backend is valid @@ -673,6 +712,7 @@ func init() { initCmd.Flags().StringVar(&mnemonicFlag, "mnemonic", "", "Mnemonic phrase for key recovery (only used with --recover)") initCmd.Flags().StringVar(&supernodeAddrFlag, "supernode-addr", "", "IP address for the supernode to listen on") initCmd.Flags().IntVar(&supernodePortFlag, "supernode-port", 0, "Port for the supernode to listen on") + initCmd.Flags().IntVar(&gatewayPortFlag, "gateway-port", 0, "Port for the HTTP gateway to listen on") initCmd.Flags().StringVar(&lumeraGrpcFlag, "lumera-grpc", "", "GRPC address of the Lumera node (host:port)") initCmd.Flags().StringVar(&chainIDFlag, "chain-id", "", "Chain ID of the Lumera network") } diff --git a/supernode/cmd/start.go b/supernode/cmd/start.go index ddeb4168..ae274d03 100644 --- a/supernode/cmd/start.go +++ b/supernode/cmd/start.go @@ -18,6 +18,7 @@ import ( "github.com/LumeraProtocol/supernode/pkg/storage/rqstore" "github.com/LumeraProtocol/supernode/supernode/config" "github.com/LumeraProtocol/supernode/supernode/node/action/server/cascade" + "github.com/LumeraProtocol/supernode/supernode/node/supernode/gateway" "github.com/LumeraProtocol/supernode/supernode/node/supernode/server" cascadeService "github.com/LumeraProtocol/supernode/supernode/services/cascade" "github.com/LumeraProtocol/supernode/supernode/services/common" @@ -106,6 +107,8 @@ The supernode will connect to the Lumera network and begin participating in the // Create supernode status service statusService := supernodeService.NewSupernodeStatusService() statusService.RegisterTaskProvider(cService) + + // Create supernode server supernodeServer := server.NewSupernodeServer(statusService) // Configure server @@ -121,9 +124,19 @@ The supernode will connect to the Lumera network and begin participating in the return fmt.Errorf("failed to create gRPC server: %w", err) } + // Create HTTP gateway server that directly calls the supernode server + gatewayPort := appConfig.SupernodeConfig.GatewayPort + if gatewayPort == 0 { + gatewayPort = 8002 // Default fallback + } + gatewayServer, err := gateway.NewServer(int(gatewayPort), supernodeServer) + if err != nil { + return fmt.Errorf("failed to create gateway server: %w", err) + } + // Start the services go func() { - if err := RunServices(ctx, grpcServer, cService, *p2pService); err != nil { + if err := RunServices(ctx, grpcServer, cService, *p2pService, gatewayServer); err != nil { logtrace.Error(ctx, "Service error", logtrace.Fields{"error": err.Error()}) } }() diff --git a/supernode/config.yml b/supernode/config.yml index 301347e5..5bf122c5 100644 --- a/supernode/config.yml +++ b/supernode/config.yml @@ -4,7 +4,7 @@ supernode: identity: "lumera1ccmw5plzuldntum2rz6kq6uq346vtrhrvwfzsa" # Identity of the supernode, lumera address ip_address: "0.0.0.0" port: 4444 - + gateway_port: 8002 # Port for the HTTP gateway # Keyring Configuration keyring: diff --git a/supernode/config/config.go b/supernode/config/config.go index ed1f89b6..9b16c716 100644 --- a/supernode/config/config.go +++ b/supernode/config/config.go @@ -11,10 +11,11 @@ import ( ) type SupernodeConfig struct { - KeyName string `yaml:"key_name"` - Identity string `yaml:"identity"` - IpAddress string `yaml:"ip_address"` - Port uint16 `yaml:"port"` + KeyName string `yaml:"key_name"` + Identity string `yaml:"identity"` + IpAddress string `yaml:"ip_address"` + Port uint16 `yaml:"port"` + GatewayPort uint16 `yaml:"gateway_port"` } type KeyringConfig struct { diff --git a/supernode/config/save.go b/supernode/config/save.go index 8cdd0c3e..0e537aab 100644 --- a/supernode/config/save.go +++ b/supernode/config/save.go @@ -42,10 +42,11 @@ func CreateDefaultConfig(keyName, identity, chainID string, keyringBackend, keyr return &Config{ SupernodeConfig: SupernodeConfig{ - KeyName: keyName, - Identity: identity, - IpAddress: "0.0.0.0", - Port: 4444, + KeyName: keyName, + Identity: identity, + IpAddress: "0.0.0.0", + Port: 4444, + GatewayPort: 8002, }, KeyringConfig: KeyringConfig{ Backend: keyringBackend, diff --git a/supernode/node/supernode/gateway/server.go b/supernode/node/supernode/gateway/server.go new file mode 100644 index 00000000..b0f304f3 --- /dev/null +++ b/supernode/node/supernode/gateway/server.go @@ -0,0 +1,112 @@ +package gateway + +import ( + "context" + "fmt" + "net/http" + "time" + + "github.com/grpc-ecosystem/grpc-gateway/runtime" + + pb "github.com/LumeraProtocol/supernode/gen/supernode" + "github.com/LumeraProtocol/supernode/pkg/logtrace" +) + +// Server represents the HTTP gateway server +type Server struct { + port int + server *http.Server + supernodeServer pb.SupernodeServiceServer +} + +// NewServer creates a new HTTP gateway server that directly calls the service +func NewServer(port int, supernodeServer pb.SupernodeServiceServer) (*Server, error) { + if supernodeServer == nil { + return nil, fmt.Errorf("supernode server is required") + } + + return &Server{ + port: port, + supernodeServer: supernodeServer, + }, nil +} + +// Run starts the HTTP gateway server (implements service interface) +func (s *Server) Run(ctx context.Context) error { + // Create gRPC-Gateway mux with custom JSON marshaler options + mux := runtime.NewServeMux( + runtime.WithMarshalerOption(runtime.MIMEWildcard, &runtime.JSONPb{ + EmitDefaults: true, // This ensures zero values are included + OrigName: true, // Use original proto field names + }), + ) + + // Register the service handler directly + err := pb.RegisterSupernodeServiceHandlerServer(ctx, mux, s.supernodeServer) + if err != nil { + return fmt.Errorf("failed to register gateway handler: %w", err) + } + + // Create HTTP mux for custom endpoints + httpMux := http.NewServeMux() + + // Register gRPC-Gateway endpoints + httpMux.Handle("/api/", mux) + + // Register Swagger endpoints + httpMux.HandleFunc("/swagger.json", s.serveSwaggerJSON) + httpMux.HandleFunc("/swagger-ui/", s.serveSwaggerUI) + httpMux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + if r.URL.Path == "/" { + http.Redirect(w, r, "/swagger-ui/", http.StatusFound) + } else { + http.NotFound(w, r) + } + }) + + // Create HTTP server + s.server = &http.Server{ + Addr: fmt.Sprintf(":%d", s.port), + Handler: s.corsMiddleware(httpMux), + ReadTimeout: 15 * time.Second, + WriteTimeout: 15 * time.Second, + IdleTimeout: 60 * time.Second, + } + + logtrace.Info(ctx, "Starting HTTP gateway server", logtrace.Fields{ + "port": s.port, + }) + + // Start server + if err := s.server.ListenAndServe(); err != nil && err != http.ErrServerClosed { + return fmt.Errorf("gateway server failed: %w", err) + } + + return nil +} + +// Stop gracefully stops the HTTP gateway server (implements service interface) +func (s *Server) Stop(ctx context.Context) error { + if s.server == nil { + return nil + } + + logtrace.Info(ctx, "Shutting down HTTP gateway server", nil) + return s.server.Shutdown(ctx) +} + +// corsMiddleware adds CORS headers for web access +func (s *Server) corsMiddleware(h http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Access-Control-Allow-Origin", "*") + w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS") + w.Header().Set("Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Accept-Encoding, Authorization") + + if r.Method == "OPTIONS" { + w.WriteHeader(http.StatusOK) + return + } + + h.ServeHTTP(w, r) + }) +} \ No newline at end of file diff --git a/supernode/node/supernode/gateway/swagger.go b/supernode/node/supernode/gateway/swagger.go new file mode 100644 index 00000000..d86d0ad9 --- /dev/null +++ b/supernode/node/supernode/gateway/swagger.go @@ -0,0 +1,69 @@ +package gateway + +import ( + _ "embed" + "html/template" + "net/http" +) + +//go:embed swagger.json +var swaggerSpec []byte + +// swaggerUIHTML contains the Swagger UI HTML template +const swaggerUIHTML = ` + + +
+ +