Implemented first pass of character and inventory services
This commit is contained in:
@ -19,4 +19,9 @@ var Character = Type("character", func() {
|
|||||||
Field(3, "description", String)
|
Field(3, "description", String)
|
||||||
Field(4, "class", String)
|
Field(4, "class", String)
|
||||||
Required("name", "description", "class")
|
Required("name", "description", "class")
|
||||||
})
|
})
|
||||||
|
|
||||||
|
var InventoryRecord = Type("inventoryRecord", func() {
|
||||||
|
Field(1, "characterId", Int)
|
||||||
|
Field(2, "itemId", Int)
|
||||||
|
})
|
||||||
|
@ -3,43 +3,82 @@ package characterapi
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
character "crossnokaye-interview-assignment/services/character/gen/character"
|
character "crossnokaye-interview-assignment/services/character/gen/character"
|
||||||
|
"errors"
|
||||||
"log"
|
"log"
|
||||||
)
|
)
|
||||||
|
|
||||||
// character service example implementation.
|
// character service example implementation.
|
||||||
// The example methods log the requests and return zero values.
|
// The example methods log the requests and return zero values.
|
||||||
type charactersrvc struct {
|
type charactersrvc struct {
|
||||||
logger *log.Logger
|
logger *log.Logger
|
||||||
|
characters map[int]*character.Character
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewCharacter returns the character service implementation.
|
// NewCharacter returns the character service implementation.
|
||||||
func NewCharacter(logger *log.Logger) character.Service {
|
func NewCharacter(logger *log.Logger) character.Service {
|
||||||
return &charactersrvc{logger}
|
characterMap := make(map[int]*character.Character)
|
||||||
|
return &charactersrvc{logger, characterMap}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCharacter implements getCharacter.
|
// GetCharacter implements getCharacter.
|
||||||
func (s *charactersrvc) GetCharacter(ctx context.Context, p int) (res *character.Character, err error) {
|
func (s *charactersrvc) GetCharacter(ctx context.Context, p *character.GetCharacterPayload) (res *character.Character, err error) {
|
||||||
res = &character.Character{}
|
|
||||||
s.logger.Print("character.getCharacter")
|
s.logger.Print("character.getCharacter")
|
||||||
|
|
||||||
|
itemToGet := s.characters[*p.ID]
|
||||||
|
if itemToGet == nil {
|
||||||
|
s.logger.Printf("character with id %d not found", &p.ID)
|
||||||
|
return nil, errors.New("character not found")
|
||||||
|
}
|
||||||
|
res = s.characters[*p.ID]
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateCharacter implements createCharacter.
|
// CreateCharacter implements createCharacter.
|
||||||
func (s *charactersrvc) CreateCharacter(ctx context.Context, p *character.Character) (res *character.Character, err error) {
|
func (s *charactersrvc) CreateCharacter(ctx context.Context, p *character.Character) (res *character.Character, err error) {
|
||||||
res = &character.Character{}
|
|
||||||
s.logger.Print("character.createCharacter")
|
s.logger.Print("character.createCharacter")
|
||||||
|
id := -1
|
||||||
|
|
||||||
|
// Using this method of assigning IDs means they will
|
||||||
|
// potentially be non-sequential if ids are deleted
|
||||||
|
if p.ID != nil {
|
||||||
|
id = *p.ID
|
||||||
|
} else {
|
||||||
|
id = len(s.characters)
|
||||||
|
}
|
||||||
|
|
||||||
|
p.ID = &id
|
||||||
|
s.characters[id] = p
|
||||||
|
res = s.characters[id]
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateCharacter implements updateCharacter.
|
// UpdateCharacter implements updateCharacter.
|
||||||
func (s *charactersrvc) UpdateCharacter(ctx context.Context, p *character.Character) (res *character.Character, err error) {
|
func (s *charactersrvc) UpdateCharacter(ctx context.Context, p *character.Character) (res *character.Character, err error) {
|
||||||
res = &character.Character{}
|
|
||||||
s.logger.Print("character.updateCharacter")
|
s.logger.Print("character.updateCharacter")
|
||||||
|
|
||||||
|
itemToUpdate := s.characters[*p.ID]
|
||||||
|
if itemToUpdate == nil {
|
||||||
|
s.logger.Printf("characters with id %d not found", &p.ID)
|
||||||
|
return nil, errors.New("characters not found")
|
||||||
|
}
|
||||||
|
s.characters[*p.ID] = p
|
||||||
|
res = s.characters[*p.ID]
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteCharacter implements deleteCharacter.
|
// DeleteCharacter implements deleteCharacter.
|
||||||
func (s *charactersrvc) DeleteCharacter(ctx context.Context, p int) (err error) {
|
func (s *charactersrvc) DeleteCharacter(ctx context.Context, p *character.DeleteCharacterPayload) (err error) {
|
||||||
s.logger.Print("character.deleteCharacter")
|
s.logger.Print("character.deleteCharacter")
|
||||||
|
|
||||||
|
itemToDelete := s.characters[*p.ID]
|
||||||
|
if itemToDelete == nil {
|
||||||
|
s.logger.Printf("characters with id %d not found", &p.ID)
|
||||||
|
return errors.New("characters not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
delete(s.characters, *p.ID)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -9,17 +9,19 @@ import (
|
|||||||
var _ = API("character", func() {
|
var _ = API("character", func() {
|
||||||
Title("Character Srvice")
|
Title("Character Srvice")
|
||||||
Server("character", func() {
|
Server("character", func() {
|
||||||
Host("localhost", func() {
|
Host("localhost", func() {
|
||||||
URI("grpc://localhost:8083")
|
URI("grpc://localhost:8083")
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
var _ = Service("character", func() {
|
var _ = Service("character", func() {
|
||||||
Description("A GRPC back service that handles CRUD operations for the characters and their attributes")
|
Description("A GRPC back service that handles CRUD operations for the characters and their attributes")
|
||||||
|
|
||||||
Method("getCharacter", func() {
|
Method("getCharacter", func() {
|
||||||
Payload(Int)
|
Payload(func() {
|
||||||
|
Field(1, "id", Int)
|
||||||
|
})
|
||||||
Result(Character)
|
Result(Character)
|
||||||
Error("NotFound")
|
Error("NotFound")
|
||||||
Error("BadRequest")
|
Error("BadRequest")
|
||||||
@ -61,7 +63,9 @@ var _ = Service("character", func() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
Method("deleteCharacter", func() {
|
Method("deleteCharacter", func() {
|
||||||
Payload(Int)
|
Payload(func() {
|
||||||
|
Field(1, "id", Int)
|
||||||
|
})
|
||||||
Result(Empty)
|
Result(Empty)
|
||||||
Error("NotFound")
|
Error("NotFound")
|
||||||
Error("BadRequest")
|
Error("BadRequest")
|
||||||
|
@ -21,14 +21,14 @@ func main() {
|
|||||||
// Define command line flags, add any other flag required to configure the
|
// Define command line flags, add any other flag required to configure the
|
||||||
// service.
|
// service.
|
||||||
var (
|
var (
|
||||||
hostF = flag.String("host", "localhost", "Server host (valid values: localhost)")
|
hostF = flag.String("host", "localhost", "Server host (valid values: localhost)")
|
||||||
domainF = flag.String("domain", "", "Host domain name (overrides host domain specified in service design)")
|
domainF = flag.String("domain", "", "Host domain name (overrides host domain specified in service design)")
|
||||||
httpPortF = flag.String("http-port", "", "HTTP port (overrides host HTTP port specified in service design)")
|
httpPortF = flag.String("http-port", "", "HTTP port (overrides host HTTP port specified in service design)")
|
||||||
secureF = flag.Bool("secure", false, "Use secure scheme (https or grpcs)")
|
secureF = flag.Bool("secure", false, "Use secure scheme (https or grpcs)")
|
||||||
dbgF = flag.Bool("debug", false, "Log request and response bodies")
|
dbgF = flag.Bool("debug", false, "Log request and response bodies")
|
||||||
itemAddr = flag.String("locator-addr", ":8082", "Item service address")
|
itemAddr = flag.String("item-addr", ":8082", "Item service address")
|
||||||
//characterAddr = flag.String("locator-addr", ":8080", "Item service address")
|
characterAddr = flag.String("character-addr", ":8083", "Character service address")
|
||||||
//inventoryAddr = flag.String("locator-addr", ":8081", "Item service address")
|
inventoryAddr = flag.String("inventory-addr", ":8081", "Inventory service address")
|
||||||
)
|
)
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
@ -49,12 +49,29 @@ func main() {
|
|||||||
}
|
}
|
||||||
defer itemClientConnection.Close()
|
defer itemClientConnection.Close()
|
||||||
|
|
||||||
|
inventoryClientConnection, err := grpc.Dial(*inventoryAddr,
|
||||||
|
grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("failed to connect to inventory service", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
defer inventoryClientConnection.Close()
|
||||||
|
|
||||||
|
characterClientConnection, err := grpc.Dial(*characterAddr,
|
||||||
|
grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("failed to connect to character service", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
defer characterClientConnection.Close()
|
||||||
|
|
||||||
// Initialize the services.
|
// Initialize the services.
|
||||||
var (
|
var (
|
||||||
frontSvc front.Service
|
frontSvc front.Service
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
frontSvc = frontapi.NewFront(logger, itemClientConnection)
|
frontSvc = frontapi.NewFront(logger, itemClientConnection, characterClientConnection,
|
||||||
|
inventoryClientConnection)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wrap the services in endpoints that can be invoked from other services
|
// Wrap the services in endpoints that can be invoked from other services
|
||||||
|
@ -100,7 +100,6 @@ var _ = Service("front", func() {
|
|||||||
|
|
||||||
HTTP(func() {
|
HTTP(func() {
|
||||||
POST("/character")
|
POST("/character")
|
||||||
Body(Character)
|
|
||||||
Response(StatusBadRequest)
|
Response(StatusBadRequest)
|
||||||
Response(StatusOK)
|
Response(StatusOK)
|
||||||
Response(StatusInternalServerError)
|
Response(StatusInternalServerError)
|
||||||
@ -115,7 +114,6 @@ var _ = Service("front", func() {
|
|||||||
|
|
||||||
HTTP(func() {
|
HTTP(func() {
|
||||||
PUT("/character/{id}")
|
PUT("/character/{id}")
|
||||||
Body(Character)
|
|
||||||
Response(StatusOK)
|
Response(StatusOK)
|
||||||
Response(StatusBadRequest)
|
Response(StatusBadRequest)
|
||||||
Response(StatusNotFound)
|
Response(StatusNotFound)
|
||||||
@ -129,7 +127,7 @@ var _ = Service("front", func() {
|
|||||||
Error("BadRequest")
|
Error("BadRequest")
|
||||||
|
|
||||||
HTTP(func() {
|
HTTP(func() {
|
||||||
POST("/character/{id}")
|
DELETE("/character/{id}")
|
||||||
Response(StatusOK)
|
Response(StatusOK)
|
||||||
Response(StatusBadRequest)
|
Response(StatusBadRequest)
|
||||||
Response(StatusNotFound)
|
Response(StatusNotFound)
|
||||||
@ -137,26 +135,26 @@ var _ = Service("front", func() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
Method("addItemToInventory", func() {
|
Method("addItemToInventory", func() {
|
||||||
Payload(Int)
|
Payload(InventoryRecord)
|
||||||
Result(Empty)
|
Result(Empty)
|
||||||
Error("NotFound")
|
Error("NotFound")
|
||||||
Error("BadRequest")
|
Error("BadRequest")
|
||||||
|
|
||||||
HTTP(func() {
|
HTTP(func() {
|
||||||
POST("/inventory/{CharacterId}")
|
POST("/character/{characterId}/item")
|
||||||
Response(StatusOK)
|
Response(StatusOK)
|
||||||
Response(StatusBadRequest)
|
Response(StatusBadRequest)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
Method("removeItemFromInventory", func() {
|
Method("removeItemFromInventory", func() {
|
||||||
Payload(Int)
|
Payload(InventoryRecord)
|
||||||
Result(Empty)
|
Result(Empty)
|
||||||
Error("NotFound")
|
Error("NotFound")
|
||||||
Error("BadRequest")
|
Error("BadRequest")
|
||||||
|
|
||||||
HTTP(func() {
|
HTTP(func() {
|
||||||
PUT("/inventory/{CharacterId}")
|
DELETE("/character/{characterId}/item/{itemId}")
|
||||||
Response(StatusOK)
|
Response(StatusOK)
|
||||||
Response(StatusBadRequest)
|
Response(StatusBadRequest)
|
||||||
})
|
})
|
||||||
|
@ -2,7 +2,11 @@ package frontapi
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
genCharacter "crossnokaye-interview-assignment/services/character/gen/character"
|
||||||
|
genCharacterClient "crossnokaye-interview-assignment/services/character/gen/grpc/character/client"
|
||||||
front "crossnokaye-interview-assignment/services/front/gen/front"
|
front "crossnokaye-interview-assignment/services/front/gen/front"
|
||||||
|
genInventoryClient "crossnokaye-interview-assignment/services/inventory/gen/grpc/inventory/client"
|
||||||
|
genInventory "crossnokaye-interview-assignment/services/inventory/gen/inventory"
|
||||||
genItemClient "crossnokaye-interview-assignment/services/item/gen/grpc/item/client"
|
genItemClient "crossnokaye-interview-assignment/services/item/gen/grpc/item/client"
|
||||||
genItem "crossnokaye-interview-assignment/services/item/gen/item"
|
genItem "crossnokaye-interview-assignment/services/item/gen/item"
|
||||||
goa "goa.design/goa/v3/pkg"
|
goa "goa.design/goa/v3/pkg"
|
||||||
@ -17,24 +21,50 @@ type itemClient struct {
|
|||||||
deleteItem goa.Endpoint
|
deleteItem goa.Endpoint
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type characterClient struct {
|
||||||
|
getCharacter goa.Endpoint
|
||||||
|
createCharacter goa.Endpoint
|
||||||
|
updateCharacter goa.Endpoint
|
||||||
|
deleteCharacter goa.Endpoint
|
||||||
|
}
|
||||||
|
|
||||||
|
type inventoryClient struct {
|
||||||
|
addItem goa.Endpoint
|
||||||
|
removeItem goa.Endpoint
|
||||||
|
}
|
||||||
|
|
||||||
// front service example implementation.
|
// front service example implementation.
|
||||||
// The example methods log the requests and return zero values.
|
// The example methods log the requests and return zero values.
|
||||||
type frontsrvc struct {
|
type frontsrvc struct {
|
||||||
logger *log.Logger
|
logger *log.Logger
|
||||||
|
|
||||||
itemClient *itemClient
|
itemClient *itemClient
|
||||||
|
characterClient *characterClient
|
||||||
|
inventoryClient *inventoryClient
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFront returns the front service implementation.
|
// NewFront returns the front service implementation.
|
||||||
func NewFront(logger *log.Logger, itemClientConnection *grpc.ClientConn) front.Service {
|
func NewFront(logger *log.Logger, itemClientConnection *grpc.ClientConn, characterClientConnection *grpc.ClientConn,
|
||||||
|
inventoryClientConnection *grpc.ClientConn) front.Service {
|
||||||
|
|
||||||
ic := genItemClient.NewClient(itemClientConnection)
|
ic := genItemClient.NewClient(itemClientConnection)
|
||||||
return &frontsrvc{logger: logger, itemClient: &itemClient{
|
cc := genCharacterClient.NewClient(characterClientConnection)
|
||||||
ic.GetItem(),
|
icc := genInventoryClient.NewClient(inventoryClientConnection)
|
||||||
ic.CreateItem(),
|
return &frontsrvc{logger: logger,
|
||||||
ic.UpdateItem(),
|
itemClient: &itemClient{
|
||||||
ic.DeleteItem()}}
|
ic.GetItem(),
|
||||||
|
ic.CreateItem(),
|
||||||
|
ic.UpdateItem(),
|
||||||
|
ic.DeleteItem()},
|
||||||
|
characterClient: &characterClient{
|
||||||
|
cc.GetCharacter(),
|
||||||
|
cc.CreateCharacter(),
|
||||||
|
cc.UpdateCharacter(),
|
||||||
|
cc.DeleteCharacter()},
|
||||||
|
inventoryClient: &inventoryClient{
|
||||||
|
icc.AddItem(),
|
||||||
|
icc.RemoveItem(),
|
||||||
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetItem implements getItem.
|
// GetItem implements getItem.
|
||||||
@ -86,40 +116,73 @@ func (s *frontsrvc) DeleteItem(ctx context.Context, p int) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetCharacter implements getCharacter.
|
// GetCharacter implements getCharacter.
|
||||||
func (s *frontsrvc) GetCharacter(ctx context.Context, p int) (res *front.Character, err error) {
|
func (s *frontsrvc) GetCharacter(ctx context.Context, id int) (res *front.Character, err error) {
|
||||||
res = &front.Character{}
|
|
||||||
s.logger.Print("front.getCharacter")
|
s.logger.Print("front.getCharacter")
|
||||||
|
getCharacterResponse, err := s.characterClient.getCharacter(ctx, &genCharacter.GetCharacterPayload{ID: &id})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
character := getCharacterResponse.(*genCharacter.Character)
|
||||||
|
res = (*front.Character)(character)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateCharacter implements createCharacter.
|
// CreateCharacter implements createCharacter.
|
||||||
func (s *frontsrvc) CreateCharacter(ctx context.Context, p *front.Character) (res *front.Character, err error) {
|
func (s *frontsrvc) CreateCharacter(ctx context.Context, p *front.Character) (res *front.Character, err error) {
|
||||||
res = &front.Character{}
|
|
||||||
s.logger.Print("front.createCharacter")
|
s.logger.Print("front.createCharacter")
|
||||||
|
createCharacterResponse, err := s.characterClient.createCharacter(ctx, (*genCharacter.Character)(p))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
character := createCharacterResponse.(*genCharacter.Character)
|
||||||
|
res = (*front.Character)(character)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateCharacter implements updateCharacter.
|
// UpdateCharacter implements updateCharacter.
|
||||||
func (s *frontsrvc) UpdateCharacter(ctx context.Context, p *front.Character) (res *front.Character, err error) {
|
func (s *frontsrvc) UpdateCharacter(ctx context.Context, p *front.Character) (res *front.Character, err error) {
|
||||||
res = &front.Character{}
|
|
||||||
s.logger.Print("front.updateCharacter")
|
s.logger.Print("front.updateCharacter")
|
||||||
|
updateCharacterResponse, err := s.characterClient.updateCharacter(ctx, (*genCharacter.Character)(p))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
character := updateCharacterResponse.(*genCharacter.Character)
|
||||||
|
res = (*front.Character)(character)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteCharacter implements deleteCharacter.
|
// DeleteCharacter implements deleteCharacter.
|
||||||
func (s *frontsrvc) DeleteCharacter(ctx context.Context, p int) (err error) {
|
func (s *frontsrvc) DeleteCharacter(ctx context.Context, p int) (err error) {
|
||||||
s.logger.Print("front.deleteCharacter")
|
s.logger.Print("front.deleteCharacter")
|
||||||
|
|
||||||
|
_, err = s.characterClient.deleteCharacter(ctx, &genCharacter.DeleteCharacterPayload{ID: &p})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddItemToInventory implements addItemToInventory.
|
// AddItemToInventory implements addItemToInventory.
|
||||||
func (s *frontsrvc) AddItemToInventory(ctx context.Context, p int) (err error) {
|
func (s *frontsrvc) AddItemToInventory(ctx context.Context, p *front.InventoryRecord) (err error) {
|
||||||
s.logger.Print("front.addItemToInventory")
|
s.logger.Print("front.addItemToInventory")
|
||||||
|
_, err = s.inventoryClient.addItem(ctx, (*genInventory.InventoryRecord)(p))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoveItemFromInventory implements removeItemFromInventory.
|
// RemoveItemFromInventory implements removeItemFromInventory.
|
||||||
func (s *frontsrvc) RemoveItemFromInventory(ctx context.Context, p int) (err error) {
|
func (s *frontsrvc) RemoveItemFromInventory(ctx context.Context, p *front.InventoryRecord) (err error) {
|
||||||
s.logger.Print("front.removeItemFromInventory")
|
s.logger.Print("front.removeItemFromInventory")
|
||||||
|
_, err = s.inventoryClient.removeItem(ctx, (*genInventory.InventoryRecord)(p))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,17 @@
|
|||||||
package design
|
package design
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crossnokaye-interview-assignment/design"
|
||||||
. "goa.design/goa/v3/dsl"
|
. "goa.design/goa/v3/dsl"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ = API("inventory", func() {
|
var _ = API("inventory", func() {
|
||||||
Title("Inventory Service")
|
Title("Inventory Service")
|
||||||
Server("inventory", func() {
|
Server("inventory", func() {
|
||||||
Host("localhost", func() {
|
Host("localhost", func() {
|
||||||
URI("grpc://localhost:8081")
|
URI("grpc://localhost:8081")
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
var _ = Service("inventory", func() {
|
var _ = Service("inventory", func() {
|
||||||
@ -19,7 +20,7 @@ var _ = Service("inventory", func() {
|
|||||||
// })
|
// })
|
||||||
|
|
||||||
Method("addItem", func() {
|
Method("addItem", func() {
|
||||||
Payload(Int)
|
Payload(design.InventoryRecord)
|
||||||
Result(Empty)
|
Result(Empty)
|
||||||
Error("NotFound")
|
Error("NotFound")
|
||||||
Error("BadRequest")
|
Error("BadRequest")
|
||||||
@ -30,7 +31,7 @@ var _ = Service("inventory", func() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
Method("removeItem", func() {
|
Method("removeItem", func() {
|
||||||
Payload(Int)
|
Payload(design.InventoryRecord)
|
||||||
Result(Empty)
|
Result(Empty)
|
||||||
Error("NotFound")
|
Error("NotFound")
|
||||||
Error("BadRequest")
|
Error("BadRequest")
|
||||||
|
@ -3,28 +3,76 @@ package inventoryapi
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
inventory "crossnokaye-interview-assignment/services/inventory/gen/inventory"
|
inventory "crossnokaye-interview-assignment/services/inventory/gen/inventory"
|
||||||
|
"errors"
|
||||||
"log"
|
"log"
|
||||||
)
|
)
|
||||||
|
|
||||||
// inventory service example implementation.
|
// inventory service example implementation.
|
||||||
// The example methods log the requests and return zero values.
|
// The example methods log the requests and return zero values.
|
||||||
type inventorysrvc struct {
|
type inventorysrvc struct {
|
||||||
logger *log.Logger
|
logger *log.Logger
|
||||||
|
inventories map[int]*[]int //key = characterId, value = array of itemIds
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewInventory returns the inventory service implementation.
|
// NewInventory returns the inventory service implementation.
|
||||||
func NewInventory(logger *log.Logger) inventory.Service {
|
func NewInventory(logger *log.Logger) inventory.Service {
|
||||||
return &inventorysrvc{logger}
|
inventoryMap := make(map[int]*[]int)
|
||||||
|
return &inventorysrvc{logger, inventoryMap}
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddItem implements addItem.
|
// AddItem implements addItem.
|
||||||
func (s *inventorysrvc) AddItem(ctx context.Context, p int) (err error) {
|
func (s *inventorysrvc) AddItem(ctx context.Context, p *inventory.InventoryRecord) (err error) {
|
||||||
s.logger.Print("inventory.addItem")
|
s.logger.Print("inventory.addItem")
|
||||||
|
|
||||||
|
itemList := s.inventories[*p.CharacterID]
|
||||||
|
if itemList == nil {
|
||||||
|
itemList = s.initCharacterInventory(p.CharacterID)
|
||||||
|
}
|
||||||
|
newItemList := append(*itemList, *p.ItemID)
|
||||||
|
s.inventories[*p.CharacterID] = &newItemList
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoveItem implements removeItem.
|
// RemoveItem implements removeItem.
|
||||||
func (s *inventorysrvc) RemoveItem(ctx context.Context, p int) (err error) {
|
func (s *inventorysrvc) RemoveItem(ctx context.Context, p *inventory.InventoryRecord) (err error) {
|
||||||
s.logger.Print("inventory.removeItem")
|
s.logger.Print("inventory.removeItem")
|
||||||
|
|
||||||
|
itemList := s.inventories[*p.CharacterID]
|
||||||
|
if itemList == nil {
|
||||||
|
s.logger.Printf("inventory for character with id %d not found", p.CharacterID)
|
||||||
|
return errors.New("item not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
idx := indexOf(*p.ItemID, *itemList)
|
||||||
|
if idx != -1 {
|
||||||
|
newItemList := remove(*itemList, idx)
|
||||||
|
s.inventories[*p.CharacterID] = &newItemList
|
||||||
|
} else {
|
||||||
|
s.logger.Printf("character with id %d does not have item %d in inventory", &p.CharacterID, &p.ItemID)
|
||||||
|
return errors.New("item not found for character")
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *inventorysrvc) initCharacterInventory(characterId *int) (itemList *[]int) {
|
||||||
|
list := make([]int, 0)
|
||||||
|
itemList = &list
|
||||||
|
s.inventories[*characterId] = &list
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func indexOf(element int, data []int) int {
|
||||||
|
for k, v := range data {
|
||||||
|
if element == v {
|
||||||
|
return k
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1 //not found.
|
||||||
|
}
|
||||||
|
|
||||||
|
func remove(s []int, i int) []int {
|
||||||
|
s[i] = s[len(s)-1]
|
||||||
|
return s[:len(s)-1]
|
||||||
|
}
|
||||||
|
@ -26,7 +26,7 @@ func (s *itemsrvc) GetItem(ctx context.Context, p *item.GetItemPayload) (res *it
|
|||||||
|
|
||||||
itemToGet := s.items[*p.ID]
|
itemToGet := s.items[*p.ID]
|
||||||
if itemToGet == nil {
|
if itemToGet == nil {
|
||||||
s.logger.Printf("itemToGet with id %d not found", p.ID)
|
s.logger.Printf("item with id %d not found", &p.ID)
|
||||||
return nil, errors.New("item not found")
|
return nil, errors.New("item not found")
|
||||||
}
|
}
|
||||||
res = s.items[*p.ID]
|
res = s.items[*p.ID]
|
||||||
@ -59,7 +59,7 @@ func (s *itemsrvc) UpdateItem(ctx context.Context, p *item.Item) (res *item.Item
|
|||||||
s.logger.Print("itemToGet.updateItem")
|
s.logger.Print("itemToGet.updateItem")
|
||||||
itemToUpdate := s.items[*p.ID]
|
itemToUpdate := s.items[*p.ID]
|
||||||
if itemToUpdate == nil {
|
if itemToUpdate == nil {
|
||||||
s.logger.Printf("itemToGet with id %d not found", p.ID)
|
s.logger.Printf("item with id %d not found", &p.ID)
|
||||||
return nil, errors.New("item not found")
|
return nil, errors.New("item not found")
|
||||||
}
|
}
|
||||||
s.items[*p.ID] = p
|
s.items[*p.ID] = p
|
||||||
@ -73,7 +73,7 @@ func (s *itemsrvc) DeleteItem(ctx context.Context, p *item.DeleteItemPayload) (e
|
|||||||
s.logger.Print("item.deleteItem")
|
s.logger.Print("item.deleteItem")
|
||||||
itemToDelete := s.items[*p.ID]
|
itemToDelete := s.items[*p.ID]
|
||||||
if itemToDelete == nil {
|
if itemToDelete == nil {
|
||||||
s.logger.Printf("itemToGet with id %d not found", p.ID)
|
s.logger.Printf("item with id %d not found", &p.ID)
|
||||||
return errors.New("item not found")
|
return errors.New("item not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user