diff --git a/services/front/design/design.go b/services/front/design/design.go index 0b4a556..e586fad 100644 --- a/services/front/design/design.go +++ b/services/front/design/design.go @@ -69,11 +69,13 @@ var _ = Service("front", func() { Payload(String) Result(Empty) Error("NotFound") + Error("BadRequest") HTTP(func() { DELETE("/item/{name}") Response(StatusOK) Response("NotFound", StatusNotFound) + Response("BadRequest", StatusBadRequest) }) }) diff --git a/services/front/front.go b/services/front/front.go index 2c1cdff..95e579a 100644 --- a/services/front/front.go +++ b/services/front/front.go @@ -10,6 +10,7 @@ import ( genItemClient "crossnokaye-interview-assignment/services/item/gen/grpc/item/client" genItem "crossnokaye-interview-assignment/services/item/gen/item" "errors" + "fmt" "github.com/golang/protobuf/ptypes/empty" goa "goa.design/goa/v3/pkg" "google.golang.org/grpc" @@ -33,9 +34,11 @@ type characterClient struct { } type inventoryClient struct { - addItem goa.Endpoint - removeItem goa.Endpoint - listInventoryItems goa.Endpoint + addItem goa.Endpoint + removeItem goa.Endpoint + removeAll goa.Endpoint + listInventoryItems goa.Endpoint + listCharactersWithItem goa.Endpoint } // front service example implementation. @@ -71,7 +74,9 @@ func NewFront(logger *log.Logger, itemClientConnection *grpc.ClientConn, charact inventoryClient: &inventoryClient{ icc.AddItem(), icc.RemoveItem(), + icc.RemoveAll(), icc.ListInventory(), + icc.ListCharactersWithItem(), }} } @@ -130,6 +135,18 @@ func (s *frontsrvc) UpdateItem(ctx context.Context, p *front.Item) (res *front.I // DeleteItem implements deleteItem. func (s *frontsrvc) DeleteItem(ctx context.Context, p string) (err error) { s.logger.Print("front.deleteItem") + + characterResponse, err := s.inventoryClient.listCharactersWithItem(ctx, &genInventory.ListCharactersWithItemPayload{ItemName: &p}) + if err != nil { + return err + } + + characters := characterResponse.([]string) + + if len(characters) > 0 { + return front.MakeBadRequest(fmt.Errorf("item '%s' is referenced by character(s) %v", p, characters)) + } + _, err = s.itemClient.deleteItem(ctx, &genItem.DeleteItemPayload{Name: &p}) if err != nil { return err @@ -200,6 +217,11 @@ func (s *frontsrvc) DeleteCharacter(ctx context.Context, name string) (err error return err } + _, err = s.inventoryClient.removeAll(ctx, &genInventory.RemoveAllPayload{CharacterName: &name}) + if err != nil { + return err + } + return } @@ -245,7 +267,7 @@ func (s *frontsrvc) ListInventoryItems(ctx context.Context, payload *front.ListI } itemNames := listInventoryResponse.([]string) - if itemNames == nil { + if len(itemNames) == 0 { return } itemResponse, err := s.itemClient.listItems(ctx, &genItem.ListItemsPayload{NameFilter: itemNames}) diff --git a/services/inventory/design/design.go b/services/inventory/design/design.go index a2a567c..779f569 100644 --- a/services/inventory/design/design.go +++ b/services/inventory/design/design.go @@ -21,9 +21,24 @@ var _ = Service("inventory", func() { Field(1, "characterName", String) }) Result(ArrayOf(String)) + Error("NotFound") GRPC(func() { Response(CodeOK) + Response("NotFound", CodeNotFound) + }) + }) + + Method("listCharactersWithItem", func() { + Payload(func() { + Field(1, "itemName", String) + }) + Result(ArrayOf(String)) + Error("NotFound") + + GRPC(func() { + Response(CodeOK) + Response("NotFound", CodeNotFound) }) }) @@ -46,4 +61,17 @@ var _ = Service("inventory", func() { Response("NotFound", CodeNotFound) }) }) + + Method("removeAll", func() { + Payload(func() { + Field("1", "characterName", String) + }) + Result(Empty) + Error("NotFound") + + GRPC(func() { + Response(CodeOK) + Response("NotFound", CodeNotFound) + }) + }) }) diff --git a/services/inventory/inventory.go b/services/inventory/inventory.go index e624e9f..86429d6 100644 --- a/services/inventory/inventory.go +++ b/services/inventory/inventory.go @@ -57,15 +57,43 @@ func (s *inventorysrvc) RemoveItem(ctx context.Context, p *inventory.InventoryRe return } +func (s *inventorysrvc) RemoveAll(ctx context.Context, payload *inventory.RemoveAllPayload) (err error) { + s.logger.Print("inventory.removeAll") + + itemList := (*s.inventories)[*payload.CharacterName] + if itemList == nil { + s.logger.Printf("inventory for character with name '%s' not found", payload.CharacterName) + return inventory.MakeNotFound(fmt.Errorf("inventory for character with name '%s' not found", + *payload.CharacterName)) + } + delete(*s.inventories, *payload.CharacterName) + return +} + func (s *inventorysrvc) ListInventory(ctx context.Context, payload *inventory.ListInventoryPayload) (res []string, err error) { + s.logger.Print("inventory.listInventory") if (*s.inventories)[*payload.CharacterName] == nil { - return nil, nil + s.logger.Printf("inventory for character with name '%s' not found", payload.CharacterName) + return nil, inventory.MakeNotFound(fmt.Errorf("inventory for character with name '%s' not found", + *payload.CharacterName)) } res = *((*s.inventories)[*payload.CharacterName]) return } +func (s *inventorysrvc) ListCharactersWithItem(ctx context.Context, payload *inventory.ListCharactersWithItemPayload) (res []string, err error) { + s.logger.Print("inventory.listCharactersWithItem") + + for character := range *(s.inventories) { + idxOfItem := indexOf(*payload.ItemName, *(*s.inventories)[character]) + if idxOfItem != -1 { + res = append(res, character) + } + } + return +} + func (s *inventorysrvc) initCharacterInventory(characterName string) (itemList *[]string) { list := make([]string, 0) itemList = &list