currencyservicefake: temp replacement for currencysvc
Signed-off-by: Ahmet Alp Balkan <ahmetb@google.com>
This commit is contained in:
parent
5b3530c021
commit
fa46e85220
7 changed files with 2584 additions and 0 deletions
27
kubernetes-manifests/currencyservice.yaml
Normal file
27
kubernetes-manifests/currencyservice.yaml
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
apiVersion: extensions/v1beta1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: currencyservice
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: currencyservice
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: server
|
||||||
|
image: currencyservice
|
||||||
|
ports:
|
||||||
|
- containerPort: 7000
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: currencyservice
|
||||||
|
spec:
|
||||||
|
type: ClusterIP
|
||||||
|
selector:
|
||||||
|
app: currencyservice
|
||||||
|
ports:
|
||||||
|
- port: 7000
|
||||||
|
targetPort: 7000
|
|
@ -14,6 +14,8 @@ build:
|
||||||
workspace: src/checkoutservice
|
workspace: src/checkoutservice
|
||||||
- imageName: paymentservice
|
- imageName: paymentservice
|
||||||
workspace: src/paymentservice
|
workspace: src/paymentservice
|
||||||
|
- imageName: currencyservice
|
||||||
|
workspace: src/currencyservicetemp
|
||||||
deploy:
|
deploy:
|
||||||
kubectl:
|
kubectl:
|
||||||
manifests:
|
manifests:
|
||||||
|
|
13
src/currencyservicetemp/Dockerfile
Normal file
13
src/currencyservicetemp/Dockerfile
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
FROM golang:1.10-alpine as builder
|
||||||
|
RUN apk add --no-cache ca-certificates git
|
||||||
|
WORKDIR /src/microservices-demo/currencyservice
|
||||||
|
COPY . .
|
||||||
|
RUN go get -d ./...
|
||||||
|
RUN go build -o /currencyservice .
|
||||||
|
|
||||||
|
FROM alpine as release
|
||||||
|
RUN apk add --no-cache \
|
||||||
|
ca-certificates
|
||||||
|
COPY --from=builder /currencyservice /currencyservice
|
||||||
|
EXPOSE 7000
|
||||||
|
ENTRYPOINT ["/currencyservice"]
|
2393
src/currencyservicetemp/genproto/demo.pb.go
Normal file
2393
src/currencyservicetemp/genproto/demo.pb.go
Normal file
File diff suppressed because it is too large
Load diff
77
src/currencyservicetemp/main.go
Normal file
77
src/currencyservicetemp/main.go
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"google.golang.org/grpc/codes"
|
||||||
|
"google.golang.org/grpc/status"
|
||||||
|
|
||||||
|
"google.golang.org/grpc"
|
||||||
|
|
||||||
|
pb "./genproto"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
listenPort = "7000"
|
||||||
|
)
|
||||||
|
|
||||||
|
type currencyServer struct {
|
||||||
|
currencies []string
|
||||||
|
conversionRates map[[2]string]float64
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
port := listenPort
|
||||||
|
if os.Getenv("PORT") != "" {
|
||||||
|
port = os.Getenv("PORT")
|
||||||
|
}
|
||||||
|
|
||||||
|
svc := ¤cyServer{
|
||||||
|
currencies: []string{"USD", "EUR", "CAD"},
|
||||||
|
conversionRates: map[[2]string]float64{
|
||||||
|
{"USD", "EUR"}: 0.86,
|
||||||
|
{"EUR", "USD"}: 1 / 0.86,
|
||||||
|
|
||||||
|
{"USD", "CAD"}: 1.33,
|
||||||
|
{"CAD", "USD"}: 1 / 1.33,
|
||||||
|
|
||||||
|
{"EUR", "CAD"}: 1.54,
|
||||||
|
{"CAD", "EUR"}: 1 / 1.54,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
lis, err := net.Listen("tcp", fmt.Sprintf(":%s", port))
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
srv := grpc.NewServer()
|
||||||
|
pb.RegisterCurrencyServiceServer(srv, svc)
|
||||||
|
log.Printf("starting to listen on tcp: %q", lis.Addr().String())
|
||||||
|
log.Fatal(srv.Serve(lis))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cs *currencyServer) GetSupportedCurrencies(_ context.Context, _ *pb.Empty) (*pb.GetSupportedCurrenciesResponse, error) {
|
||||||
|
log.Printf("requesting supported currencies (%d)", len(cs.currencies))
|
||||||
|
return &pb.GetSupportedCurrenciesResponse{CurrencyCodes: cs.currencies}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cs *currencyServer) Convert(_ context.Context, req *pb.CurrencyConversionRequest) (*pb.Money, error) {
|
||||||
|
log.Printf("requesting currency conversion [%+v] --> %s", req.From, req.ToCode)
|
||||||
|
conv := [2]string{req.GetFrom().GetCurrencyCode(), req.GetToCode()}
|
||||||
|
rate, ok := cs.conversionRates[conv]
|
||||||
|
if !ok {
|
||||||
|
return nil, status.Errorf(codes.InvalidArgument, "conversion %v not supported", conv)
|
||||||
|
}
|
||||||
|
if req.From == nil {
|
||||||
|
return nil, status.Errorf(codes.InvalidArgument, "no money amount provided")
|
||||||
|
}
|
||||||
|
|
||||||
|
amount := convert(*req.From.Amount, rate)
|
||||||
|
return &pb.Money{
|
||||||
|
CurrencyCode: req.GetToCode(),
|
||||||
|
Amount: &amount}, nil
|
||||||
|
}
|
29
src/currencyservicetemp/money.go
Normal file
29
src/currencyservicetemp/money.go
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
pb "./genproto"
|
||||||
|
)
|
||||||
|
|
||||||
|
func convert(m pb.MoneyAmount, rate float64) pb.MoneyAmount {
|
||||||
|
d, f := m.Decimal, m.Fractional
|
||||||
|
lg := int(math.Max(1, math.Ceil(math.Log10(float64(f)))))
|
||||||
|
ff, _ := strconv.ParseFloat(fmt.Sprintf("%d.%d", d, f), 64)
|
||||||
|
res := ff * rate
|
||||||
|
resTxt := fmt.Sprintf("%."+strconv.Itoa(lg)+"f", res)
|
||||||
|
p := strings.Split(resTxt, ".")
|
||||||
|
|
||||||
|
ds, fs := p[0], p[1]
|
||||||
|
fs = strings.TrimSuffix(fs, "0")
|
||||||
|
if fs == "" {
|
||||||
|
fs = "0"
|
||||||
|
}
|
||||||
|
dn, _ := strconv.Atoi(ds)
|
||||||
|
fn, _ := strconv.Atoi(fs)
|
||||||
|
|
||||||
|
return pb.MoneyAmount{Decimal: uint32(dn), Fractional: uint32(fn)}
|
||||||
|
}
|
43
src/currencyservicetemp/money_test.go
Normal file
43
src/currencyservicetemp/money_test.go
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
pb "./genproto"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test_convert(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
m pb.MoneyAmount
|
||||||
|
rate float64
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
want *pb.MoneyAmount
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
"0.33*3", args{pb.MoneyAmount{Decimal: 0, Fractional: 330}, 3}, pb.MoneyAmount{Decimal: 0, Fractional: 99},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"10.00*0.5", args{pb.MoneyAmount{Decimal: 10}, 0.5}, pb.MoneyAmount{Decimal: 5},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"10.00*1.5", args{pb.MoneyAmount{Decimal: 10}, 1.5}, pb.MoneyAmount{Decimal: 15},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"32.320*0.5 (trailing zero removed)", args{pb.MoneyAmount{Decimal: 32, Fractional: 32}, 0.5}, pb.MoneyAmount{Decimal: 16, Fractional: 16},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"33.33*(1/3) (trailing zero removed)", args{pb.MoneyAmount{Decimal: 33, Fractional: 33}, 1.0 / 3}, pb.MoneyAmount{Decimal: 11, Fractional: 11},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if got := convert(tt.args.m, tt.args.rate); !reflect.DeepEqual(got, tt.want) {
|
||||||
|
t.Errorf("convert([%v]*%f) = %v, want=[%v]", tt.args.m, tt.args.rate, got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue