Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[productcatalog] - generate error on feature flag #245

Merged
merged 13 commits into from
Aug 17, 2022
1 change: 1 addition & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ services:
- "${PRODUCT_CATALOG_SERVICE_PORT}:${PRODUCT_CATALOG_SERVICE_PORT}"
environment:
- PRODUCT_CATALOG_SERVICE_PORT
- FEATURE_FLAG_GRPC_SERVICE_ADDR
- OTEL_EXPORTER_OTLP_TRACES_ENDPOINT
- OTEL_SERVICE_NAME=productcatalogservice
depends_on:
Expand Down
49 changes: 49 additions & 0 deletions src/productcatalogservice/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"context"
"flag"
"fmt"
"google.golang.org/grpc/credentials/insecure"
"io/ioutil"
"net"
"os"
Expand Down Expand Up @@ -150,6 +151,7 @@ func run(port string) string {
)

svc := &productCatalog{}
mustMapEnv(&svc.featureFlagSvcAddr, "FEATURE_FLAG_GRPC_SERVICE_ADDR")

pb.RegisterProductCatalogServiceServer(srv, svc)
healthpb.RegisterHealthServer(srv, svc)
Expand All @@ -158,6 +160,7 @@ func run(port string) string {
}

type productCatalog struct {
featureFlagSvcAddr string
pb.UnimplementedProductCatalogServiceServer
}

Expand Down Expand Up @@ -223,6 +226,15 @@ func (p *productCatalog) GetProduct(ctx context.Context, req *pb.GetProductReque
)

time.Sleep(extraLatency)

// conditional break if feature flag is enabled on a specific product
if p.checkProductFailure(ctx, req.Id) {
msg := fmt.Sprintf("interal error: product catalog feature flag for failure is enabled")
span.SetStatus(otelcodes.Error, msg)
span.AddEvent(msg)
return nil, status.Errorf(codes.Internal, msg)
}

var found *pb.Product
for i := 0; i < len(parseCatalog()); i++ {
if req.Id == parseCatalog()[i].Id {
Expand Down Expand Up @@ -261,3 +273,40 @@ func (p *productCatalog) SearchProducts(ctx context.Context, req *pb.SearchProdu
)
return &pb.SearchProductsResponse{Results: ps}, nil
}

func (p *productCatalog) checkProductFailure(ctx context.Context, id string) bool {

if id == "OLJCESPC7Z" {
conn, err := createClient(ctx, p.featureFlagSvcAddr)
if err != nil {
//report the error but don't fail
span := trace.SpanFromContext(ctx)
span.AddEvent("error", trace.WithAttributes(attribute.String("message", "failed to connect to feature flag service")))
return false
}
defer conn.Close()

ffResponse, err := pb.NewFeatureFlagServiceClient(conn).GetFlag(ctx, &pb.GetFlagRequest{
Name: "productCatalogFailure",
})
if err != nil {
span := trace.SpanFromContext(ctx)
span.AddEvent("error", trace.WithAttributes(attribute.String("message", "failed to retrieve product catalog feature flag")))
return false
}

if ffResponse.GetFlag().Enabled {
return true
}

}
return false
}

func createClient(ctx context.Context, svcAddr string) (*grpc.ClientConn, error) {
return grpc.DialContext(ctx, svcAddr,
grpc.WithTransportCredentials(insecure.NewCredentials()),
grpc.WithUnaryInterceptor(otelgrpc.UnaryClientInterceptor()),
grpc.WithStreamInterceptor(otelgrpc.StreamClientInterceptor()),
)
}