/
profilesservice.go
129 lines (114 loc) · 3.27 KB
/
profilesservice.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package grpcservice
import (
"context"
"errors"
"github.com/Falokut/cinema_orders_service/internal/config"
"github.com/Falokut/cinema_orders_service/internal/models"
profiles_service "github.com/Falokut/profiles_service/pkg/profiles_service/v1/protos"
"github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc"
"github.com/opentracing/opentracing-go"
"github.com/sirupsen/logrus"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/types/known/emptypb"
)
type ProfilesService struct {
conn *grpc.ClientConn
client profiles_service.ProfilesServiceV1Client
logger *logrus.Logger
}
func NewProfilesService(addr string, cfg config.ConnectionSecureConfig, logger *logrus.Logger) (*ProfilesService, error) {
creds, err := cfg.GetGrpcTransportCredentials()
if err != nil {
return nil, err
}
conn, err := grpc.Dial(addr, creds,
grpc.WithUnaryInterceptor(
otgrpc.OpenTracingClientInterceptor(opentracing.GlobalTracer())),
grpc.WithStreamInterceptor(
otgrpc.OpenTracingStreamClientInterceptor(opentracing.GlobalTracer())),
)
if err != nil {
return nil, err
}
return &ProfilesService{
client: profiles_service.NewProfilesServiceV1Client(conn),
conn: conn,
logger: logger,
}, nil
}
func (s *ProfilesService) Shutdown() error {
if s.conn == nil {
return nil
}
return s.conn.Close()
}
// in metadata must be header X-Account-Id
func (s *ProfilesService) GetEmail(ctx context.Context) (email string, err error) {
defer s.handleError(ctx, &err, "GetEmail")
md, ok := metadata.FromIncomingContext(ctx)
if !ok {
err = models.Error(models.Unauthenticated, "")
return
}
ctx = metadata.NewOutgoingContext(ctx, md)
res, err := s.client.GetEmail(ctx, &emptypb.Empty{})
if err != nil {
return
}
return res.Email, nil
}
func (s *ProfilesService) logError(err error, functionName string) {
if err == nil {
return
}
var sericeErr = &models.ServiceError{}
if errors.As(err, &sericeErr) {
s.logger.WithFields(
logrus.Fields{
"error.function.name": functionName,
"error.msg": sericeErr.Msg,
"code": sericeErr.Code,
},
).Error("profiles service error occurred")
} else {
s.logger.WithFields(
logrus.Fields{
"error.function.name": functionName,
"error.msg": err.Error,
},
).Error("profiles service error occurred")
}
}
func (s *ProfilesService) handleError(ctx context.Context, err *error, functionName string) {
if ctx.Err() != nil {
var code models.ErrorCode
switch {
case errors.Is(ctx.Err(), context.Canceled):
code = models.Canceled
case errors.Is(ctx.Err(), context.DeadlineExceeded):
code = models.DeadlineExceeded
}
*err = models.Error(code, ctx.Err().Error())
return
}
if err == nil || *err == nil {
return
}
s.logError(*err, functionName)
e := *err
switch status.Code(*err) {
case codes.Canceled:
*err = models.Error(models.Canceled, e.Error())
case codes.DeadlineExceeded:
*err = models.Error(models.DeadlineExceeded, e.Error())
case codes.Internal:
*err = models.Error(models.Internal, "profiles service internal error")
case codes.NotFound:
*err = models.Error(models.NotFound, "account not found")
default:
*err = models.Error(models.Unknown, e.Error())
}
}