Commit 94587262 authored by tammam.alsoleman's avatar tammam.alsoleman

create addition service using go

parent 0c540ce5
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.36.10
// protoc v6.33.0
// source: calculator.proto
package generated
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
unsafe "unsafe"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type Numbers struct {
state protoimpl.MessageState `protogen:"open.v1"`
A int32 `protobuf:"varint,1,opt,name=a,proto3" json:"a,omitempty"`
B int32 `protobuf:"varint,2,opt,name=b,proto3" json:"b,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Numbers) Reset() {
*x = Numbers{}
mi := &file_calculator_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Numbers) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Numbers) ProtoMessage() {}
func (x *Numbers) ProtoReflect() protoreflect.Message {
mi := &file_calculator_proto_msgTypes[0]
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 Numbers.ProtoReflect.Descriptor instead.
func (*Numbers) Descriptor() ([]byte, []int) {
return file_calculator_proto_rawDescGZIP(), []int{0}
}
func (x *Numbers) GetA() int32 {
if x != nil {
return x.A
}
return 0
}
func (x *Numbers) GetB() int32 {
if x != nil {
return x.B
}
return 0
}
type Result struct {
state protoimpl.MessageState `protogen:"open.v1"`
Value int32 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"`
Operation string `protobuf:"bytes,2,opt,name=operation,proto3" json:"operation,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Result) Reset() {
*x = Result{}
mi := &file_calculator_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Result) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Result) ProtoMessage() {}
func (x *Result) ProtoReflect() protoreflect.Message {
mi := &file_calculator_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 Result.ProtoReflect.Descriptor instead.
func (*Result) Descriptor() ([]byte, []int) {
return file_calculator_proto_rawDescGZIP(), []int{1}
}
func (x *Result) GetValue() int32 {
if x != nil {
return x.Value
}
return 0
}
func (x *Result) GetOperation() string {
if x != nil {
return x.Operation
}
return ""
}
type OperationHistory struct {
state protoimpl.MessageState `protogen:"open.v1"`
ServiceName string `protobuf:"bytes,1,opt,name=service_name,json=serviceName,proto3" json:"service_name,omitempty"`
Operations []*Operation `protobuf:"bytes,2,rep,name=operations,proto3" json:"operations,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *OperationHistory) Reset() {
*x = OperationHistory{}
mi := &file_calculator_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *OperationHistory) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*OperationHistory) ProtoMessage() {}
func (x *OperationHistory) ProtoReflect() protoreflect.Message {
mi := &file_calculator_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 OperationHistory.ProtoReflect.Descriptor instead.
func (*OperationHistory) Descriptor() ([]byte, []int) {
return file_calculator_proto_rawDescGZIP(), []int{2}
}
func (x *OperationHistory) GetServiceName() string {
if x != nil {
return x.ServiceName
}
return ""
}
func (x *OperationHistory) GetOperations() []*Operation {
if x != nil {
return x.Operations
}
return nil
}
type Operation struct {
state protoimpl.MessageState `protogen:"open.v1"`
Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"`
A int32 `protobuf:"varint,2,opt,name=a,proto3" json:"a,omitempty"`
B int32 `protobuf:"varint,3,opt,name=b,proto3" json:"b,omitempty"`
Result int32 `protobuf:"varint,4,opt,name=result,proto3" json:"result,omitempty"`
Timestamp string `protobuf:"bytes,5,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Operation) Reset() {
*x = Operation{}
mi := &file_calculator_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Operation) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Operation) ProtoMessage() {}
func (x *Operation) ProtoReflect() protoreflect.Message {
mi := &file_calculator_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 Operation.ProtoReflect.Descriptor instead.
func (*Operation) Descriptor() ([]byte, []int) {
return file_calculator_proto_rawDescGZIP(), []int{3}
}
func (x *Operation) GetType() string {
if x != nil {
return x.Type
}
return ""
}
func (x *Operation) GetA() int32 {
if x != nil {
return x.A
}
return 0
}
func (x *Operation) GetB() int32 {
if x != nil {
return x.B
}
return 0
}
func (x *Operation) GetResult() int32 {
if x != nil {
return x.Result
}
return 0
}
func (x *Operation) GetTimestamp() string {
if x != nil {
return x.Timestamp
}
return ""
}
type Empty struct {
state protoimpl.MessageState `protogen:"open.v1"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Empty) Reset() {
*x = Empty{}
mi := &file_calculator_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Empty) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Empty) ProtoMessage() {}
func (x *Empty) ProtoReflect() protoreflect.Message {
mi := &file_calculator_proto_msgTypes[4]
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 Empty.ProtoReflect.Descriptor instead.
func (*Empty) Descriptor() ([]byte, []int) {
return file_calculator_proto_rawDescGZIP(), []int{4}
}
var File_calculator_proto protoreflect.FileDescriptor
const file_calculator_proto_rawDesc = "" +
"\n" +
"\x10calculator.proto\x12\n" +
"calculator\"%\n" +
"\aNumbers\x12\f\n" +
"\x01a\x18\x01 \x01(\x05R\x01a\x12\f\n" +
"\x01b\x18\x02 \x01(\x05R\x01b\"<\n" +
"\x06Result\x12\x14\n" +
"\x05value\x18\x01 \x01(\x05R\x05value\x12\x1c\n" +
"\toperation\x18\x02 \x01(\tR\toperation\"l\n" +
"\x10OperationHistory\x12!\n" +
"\fservice_name\x18\x01 \x01(\tR\vserviceName\x125\n" +
"\n" +
"operations\x18\x02 \x03(\v2\x15.calculator.OperationR\n" +
"operations\"q\n" +
"\tOperation\x12\x12\n" +
"\x04type\x18\x01 \x01(\tR\x04type\x12\f\n" +
"\x01a\x18\x02 \x01(\x05R\x01a\x12\f\n" +
"\x01b\x18\x03 \x01(\x05R\x01b\x12\x16\n" +
"\x06result\x18\x04 \x01(\x05R\x06result\x12\x1c\n" +
"\ttimestamp\x18\x05 \x01(\tR\ttimestamp\"\a\n" +
"\x05Empty2\xbb\x01\n" +
"\n" +
"Calculator\x12.\n" +
"\x03Add\x12\x13.calculator.Numbers\x1a\x12.calculator.Result\x123\n" +
"\bMultiply\x12\x13.calculator.Numbers\x1a\x12.calculator.Result\x12H\n" +
"\x13GetOperationHistory\x12\x11.calculator.Empty\x1a\x1c.calculator.OperationHistory0\x01B8\n" +
"'com.calculator.multiplication.generatedP\x01Z\v./generatedb\x06proto3"
var (
file_calculator_proto_rawDescOnce sync.Once
file_calculator_proto_rawDescData []byte
)
func file_calculator_proto_rawDescGZIP() []byte {
file_calculator_proto_rawDescOnce.Do(func() {
file_calculator_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_calculator_proto_rawDesc), len(file_calculator_proto_rawDesc)))
})
return file_calculator_proto_rawDescData
}
var file_calculator_proto_msgTypes = make([]protoimpl.MessageInfo, 5)
var file_calculator_proto_goTypes = []any{
(*Numbers)(nil), // 0: calculator.Numbers
(*Result)(nil), // 1: calculator.Result
(*OperationHistory)(nil), // 2: calculator.OperationHistory
(*Operation)(nil), // 3: calculator.Operation
(*Empty)(nil), // 4: calculator.Empty
}
var file_calculator_proto_depIdxs = []int32{
3, // 0: calculator.OperationHistory.operations:type_name -> calculator.Operation
0, // 1: calculator.Calculator.Add:input_type -> calculator.Numbers
0, // 2: calculator.Calculator.Multiply:input_type -> calculator.Numbers
4, // 3: calculator.Calculator.GetOperationHistory:input_type -> calculator.Empty
1, // 4: calculator.Calculator.Add:output_type -> calculator.Result
1, // 5: calculator.Calculator.Multiply:output_type -> calculator.Result
2, // 6: calculator.Calculator.GetOperationHistory:output_type -> calculator.OperationHistory
4, // [4:7] is the sub-list for method output_type
1, // [1:4] is the sub-list for method input_type
1, // [1:1] is the sub-list for extension type_name
1, // [1:1] is the sub-list for extension extendee
0, // [0:1] is the sub-list for field type_name
}
func init() { file_calculator_proto_init() }
func file_calculator_proto_init() {
if File_calculator_proto != nil {
return
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_calculator_proto_rawDesc), len(file_calculator_proto_rawDesc)),
NumEnums: 0,
NumMessages: 5,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_calculator_proto_goTypes,
DependencyIndexes: file_calculator_proto_depIdxs,
MessageInfos: file_calculator_proto_msgTypes,
}.Build()
File_calculator_proto = out.File
file_calculator_proto_goTypes = nil
file_calculator_proto_depIdxs = nil
}
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.5.1
// - protoc v6.33.0
// source: calculator.proto
package generated
import (
context "context"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
)
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
// Requires gRPC-Go v1.64.0 or later.
const _ = grpc.SupportPackageIsVersion9
const (
Calculator_Add_FullMethodName = "/calculator.Calculator/Add"
Calculator_Multiply_FullMethodName = "/calculator.Calculator/Multiply"
Calculator_GetOperationHistory_FullMethodName = "/calculator.Calculator/GetOperationHistory"
)
// CalculatorClient is the client API for Calculator service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type CalculatorClient interface {
Add(ctx context.Context, in *Numbers, opts ...grpc.CallOption) (*Result, error)
Multiply(ctx context.Context, in *Numbers, opts ...grpc.CallOption) (*Result, error)
GetOperationHistory(ctx context.Context, in *Empty, opts ...grpc.CallOption) (grpc.ServerStreamingClient[OperationHistory], error)
}
type calculatorClient struct {
cc grpc.ClientConnInterface
}
func NewCalculatorClient(cc grpc.ClientConnInterface) CalculatorClient {
return &calculatorClient{cc}
}
func (c *calculatorClient) Add(ctx context.Context, in *Numbers, opts ...grpc.CallOption) (*Result, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(Result)
err := c.cc.Invoke(ctx, Calculator_Add_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *calculatorClient) Multiply(ctx context.Context, in *Numbers, opts ...grpc.CallOption) (*Result, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(Result)
err := c.cc.Invoke(ctx, Calculator_Multiply_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *calculatorClient) GetOperationHistory(ctx context.Context, in *Empty, opts ...grpc.CallOption) (grpc.ServerStreamingClient[OperationHistory], error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
stream, err := c.cc.NewStream(ctx, &Calculator_ServiceDesc.Streams[0], Calculator_GetOperationHistory_FullMethodName, cOpts...)
if err != nil {
return nil, err
}
x := &grpc.GenericClientStream[Empty, OperationHistory]{ClientStream: stream}
if err := x.ClientStream.SendMsg(in); err != nil {
return nil, err
}
if err := x.ClientStream.CloseSend(); err != nil {
return nil, err
}
return x, nil
}
// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
type Calculator_GetOperationHistoryClient = grpc.ServerStreamingClient[OperationHistory]
// CalculatorServer is the server API for Calculator service.
// All implementations must embed UnimplementedCalculatorServer
// for forward compatibility.
type CalculatorServer interface {
Add(context.Context, *Numbers) (*Result, error)
Multiply(context.Context, *Numbers) (*Result, error)
GetOperationHistory(*Empty, grpc.ServerStreamingServer[OperationHistory]) error
mustEmbedUnimplementedCalculatorServer()
}
// UnimplementedCalculatorServer must be embedded to have
// forward compatible implementations.
//
// NOTE: this should be embedded by value instead of pointer to avoid a nil
// pointer dereference when methods are called.
type UnimplementedCalculatorServer struct{}
func (UnimplementedCalculatorServer) Add(context.Context, *Numbers) (*Result, error) {
return nil, status.Errorf(codes.Unimplemented, "method Add not implemented")
}
func (UnimplementedCalculatorServer) Multiply(context.Context, *Numbers) (*Result, error) {
return nil, status.Errorf(codes.Unimplemented, "method Multiply not implemented")
}
func (UnimplementedCalculatorServer) GetOperationHistory(*Empty, grpc.ServerStreamingServer[OperationHistory]) error {
return status.Errorf(codes.Unimplemented, "method GetOperationHistory not implemented")
}
func (UnimplementedCalculatorServer) mustEmbedUnimplementedCalculatorServer() {}
func (UnimplementedCalculatorServer) testEmbeddedByValue() {}
// UnsafeCalculatorServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to CalculatorServer will
// result in compilation errors.
type UnsafeCalculatorServer interface {
mustEmbedUnimplementedCalculatorServer()
}
func RegisterCalculatorServer(s grpc.ServiceRegistrar, srv CalculatorServer) {
// If the following call pancis, it indicates UnimplementedCalculatorServer was
// embedded by pointer and is nil. This will cause panics if an
// unimplemented method is ever invoked, so we test this at initialization
// time to prevent it from happening at runtime later due to I/O.
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
t.testEmbeddedByValue()
}
s.RegisterService(&Calculator_ServiceDesc, srv)
}
func _Calculator_Add_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(Numbers)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(CalculatorServer).Add(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Calculator_Add_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(CalculatorServer).Add(ctx, req.(*Numbers))
}
return interceptor(ctx, in, info, handler)
}
func _Calculator_Multiply_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(Numbers)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(CalculatorServer).Multiply(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Calculator_Multiply_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(CalculatorServer).Multiply(ctx, req.(*Numbers))
}
return interceptor(ctx, in, info, handler)
}
func _Calculator_GetOperationHistory_Handler(srv interface{}, stream grpc.ServerStream) error {
m := new(Empty)
if err := stream.RecvMsg(m); err != nil {
return err
}
return srv.(CalculatorServer).GetOperationHistory(m, &grpc.GenericServerStream[Empty, OperationHistory]{ServerStream: stream})
}
// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
type Calculator_GetOperationHistoryServer = grpc.ServerStreamingServer[OperationHistory]
// Calculator_ServiceDesc is the grpc.ServiceDesc for Calculator service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var Calculator_ServiceDesc = grpc.ServiceDesc{
ServiceName: "calculator.Calculator",
HandlerType: (*CalculatorServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "Add",
Handler: _Calculator_Add_Handler,
},
{
MethodName: "Multiply",
Handler: _Calculator_Multiply_Handler,
},
},
Streams: []grpc.StreamDesc{
{
StreamName: "GetOperationHistory",
Handler: _Calculator_GetOperationHistory_Handler,
ServerStreams: true,
},
},
Metadata: "calculator.proto",
}
module addition-service
go 1.21
require (
google.golang.org/grpc v1.59.0
google.golang.org/protobuf v1.31.0
)
\ No newline at end of file
package main
import (
"context"
"fmt"
"log"
"net"
"os"
"sync"
"time"
"addition-service/generated"
"google.golang.org/grpc"
)
type additionServer struct {
generated.UnimplementedCalculatorServer
operations []*generated.Operation
mutex sync.RWMutex
}
func (s *additionServer) Add(ctx context.Context, req *generated.Numbers) (*generated.Result, error) {
result := req.A + req.B
op := &generated.Operation{
Type: "ADDITION",
A: req.A,
B: req.B,
Result: result,
Timestamp: time.Now().Format("2006-01-02 15:04:05"),
}
s.mutex.Lock()
s.operations = append(s.operations, op)
s.mutex.Unlock()
go s.logToFile(op)
fmt.Printf(" Addition operation: %d + %d = %d\n", req.A, req.B, result)
return &generated.Result{
Value: result,
Operation: "ADDITION",
}, nil
}
func (s *additionServer) GetOperationHistory(req *generated.Empty, stream generated.Calculator_GetOperationHistoryServer) error {
s.mutex.RLock()
defer s.mutex.RUnlock()
history := &generated.OperationHistory{
ServiceName: "Addition Service",
Operations: s.operations,
}
if err := stream.Send(history); err != nil {
return err
}
return nil
}
func (s *additionServer) logToFile(op *generated.Operation) {
file, err := os.OpenFile("operation_log.txt", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
log.Printf("Failed to open log file: %v", err)
return
}
defer file.Close()
logEntry := fmt.Sprintf("[%s] %s: %d + %d = %d\n",
op.Timestamp, op.Type, op.A, op.B, op.Result)
if _, err := file.WriteString(logEntry); err != nil {
log.Printf("Failed to write to log file: %v", err)
}
}
func main() {
lis, err := net.Listen("tcp", ":50052")
if err != nil {
log.Fatalf("Failed to listen: %v", err)
}
server := grpc.NewServer()
additionServer := &additionServer{
operations: make([]*generated.Operation, 0),
}
generated.RegisterCalculatorServer(server, additionServer)
fmt.Println(" Addition Service running on port 50052")
fmt.Println(" Ready to receive addition requests...")
if err := server.Serve(lis); err != nil {
log.Fatalf("Failed to serve: %v", err)
}
}
\ No newline at end of file
......@@ -2,6 +2,8 @@ syntax = "proto3";
package calculator;
option go_package = "./generated";
option java_package = "com.calculator.multiplication.generated";
option java_multiple_files = true;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment