Skip to content

Commit

Permalink
implement and test createOnFirstUpdate
Browse files Browse the repository at this point in the history
Put the redirection scheme back into the iot contract platform and
ensure that you can set and clear it with the monitoring UI.
  • Loading branch information
kletkeman committed Nov 13, 2016
1 parent 9e6438e commit 39dae85
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 49 deletions.
9 changes: 6 additions & 3 deletions contracts/platform/iotcontractplatform/ctasset.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,18 +161,21 @@ func (c *AssetClass) UpdateAsset(stub shim.ChaincodeStubInterface, args []string
}
assetBytes, exists, err := c.getAssetFromWorldState(stub, assetKey)
if err != nil {
err := fmt.Errorf("UpdateAsset for class %s asset %s read from world state returned error %s", c.Name, a.AssetKey, err)
err := fmt.Errorf("UpdateAsset for class %s asset %s read from world state returned error %s", c.Name, assetKey, err)
log.Errorf(err.Error())
return nil, err
}
if !exists {
err := fmt.Errorf("UpdateAsset for class %s asset %s asset does not exist", c.Name, a.AssetKey)
if CanCreateOnFirstUpdate(stub) {
return c.CreateAsset(stub, args, caller, inject)
}
err := fmt.Errorf("UpdateAsset for class %s asset %s asset does not exist", c.Name, assetKey)
log.Errorf(err.Error())
return nil, err
}
err = json.Unmarshal(assetBytes, &a)
if err != nil {
err := fmt.Errorf("UpdateAsset for class %s asset %s Unmarshal failed with err %s", c.Name, a.AssetKey, err)
err := fmt.Errorf("UpdateAsset for class %s asset %s Unmarshal failed with err %s", c.Name, assetKey, err)
log.Errorf(err.Error())
return nil, err
}
Expand Down
55 changes: 29 additions & 26 deletions contracts/platform/iotcontractplatform/ctconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ func SetContractLogger(logger *shim.ChaincodeLogger) {
log = logger
}

// CREATEONFIRSTUPDATEKEY is used to store can create on update status, which if true by default
const CREATEONFIRSTUPDATEKEY string = "IOTCP:CreateOnFirstUpdate"

// readWorldState read everything in the database for debugging purposes ...
var readWorldState ChaincodeFunc = func(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) {
var err error
Expand Down Expand Up @@ -153,76 +156,76 @@ var setLoggingLevel ChaincodeFunc = func(stub shim.ChaincodeStubInterface, args
return nil, nil
}

// CreateOnUpdate is a shared parameter structure for the use of
// CreateOnFirstUpdate is a shared parameter structure for the use of
// the createonupdate feature
type CreateOnUpdate struct {
CreateOnUpdate bool `json:"createOnUpdate"`
type CreateOnFirstUpdate struct {
SetCreateOnFirstUpdate bool `json:"setCreateOnFirstUpdate"`
}

// ************************************
// setCreateOnUpdate
// setCreateOnFirstUpdate
// ************************************
var setCreateOnUpdate ChaincodeFunc = func(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) {
var createOnUpdate CreateOnUpdate
var setCreateOnFirstUpdate ChaincodeFunc = func(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) {
var createOnFirstUpdate CreateOnFirstUpdate
var err error
if len(args) != 1 {
err = errors.New("setCreateOnUpdate expects a single parameter")
err = errors.New("setCreateOnFirstUpdate expects a single parameter")
log.Errorf(err.Error())
return nil, err
}
err = json.Unmarshal([]byte(args[0]), &createOnUpdate)
err = json.Unmarshal([]byte(args[0]), &createOnFirstUpdate)
if err != nil {
err = fmt.Errorf("setCreateOnUpdate failed to unmarshal arg: %s", err)
err = fmt.Errorf("setCreateOnFirstUpdate failed to unmarshal arg: %s", err)
log.Errorf(err.Error())
return nil, err
}
err = PUTcreateOnUpdate(stub, createOnUpdate)
err = PUTcreateOnFirstUpdate(stub, createOnFirstUpdate)
if err != nil {
err = fmt.Errorf("setCreateOnUpdate failed to PUT setting: %s", err)
err = fmt.Errorf("setCreateOnFirstUpdate failed to PUT setting: %s", err)
log.Errorf(err.Error())
return nil, err
}
return nil, nil
}

// PUTcreateOnUpdate marshals the new setting and writes it to the ledger
func PUTcreateOnUpdate(stub shim.ChaincodeStubInterface, createOnUpdate CreateOnUpdate) (err error) {
createOnUpdateBytes, err := json.Marshal(createOnUpdate)
// PUTcreateOnFirstUpdate marshals the new setting and writes it to the ledger
func PUTcreateOnFirstUpdate(stub shim.ChaincodeStubInterface, createOnFirstUpdate CreateOnFirstUpdate) (err error) {
createOnFirstUpdateBytes, err := json.Marshal(createOnFirstUpdate)
if err != nil {
err = errors.New("PUTcreateOnUpdate failed to marshal")
err = errors.New("PUTcreateOnFirstUpdate failed to marshal")
log.Errorf(err.Error())
return err
}
err = stub.PutState("CreateOnUpdate", createOnUpdateBytes)
err = stub.PutState(CREATEONFIRSTUPDATEKEY, createOnFirstUpdateBytes)
if err != nil {
err = fmt.Errorf("PUTSTATE createOnUpdate failed: %s", err)
err = fmt.Errorf("PUTSTATE createOnFirstUpdate failed: %s", err)
log.Errorf(err.Error())
return err
}
return nil
}

// CanCreateOnUpdate retrieves the setting from the ledger and returns it to the calling function
func CanCreateOnUpdate(stub shim.ChaincodeStubInterface) bool {
var createOnUpdate CreateOnUpdate
createOnUpdateBytes, err := stub.GetState("CreateOnUpdate")
// CanCreateOnFirstUpdate retrieves the setting from the ledger and returns it to the calling function
func CanCreateOnFirstUpdate(stub shim.ChaincodeStubInterface) bool {
var createOnFirstUpdate CreateOnFirstUpdate
createOnFirstUpdateBytes, err := stub.GetState(CREATEONFIRSTUPDATEKEY)
if err != nil {
err = fmt.Errorf("GETSTATE for canCreateOnUpdate failed: %s", err)
err = fmt.Errorf("GETSTATE for canCreateOnFirstUpdate failed: %s", err)
log.Errorf(err.Error())
return true // true is the default
}
err = json.Unmarshal(createOnUpdateBytes, &createOnUpdate)
err = json.Unmarshal(createOnFirstUpdateBytes, &createOnFirstUpdate)
if err != nil {
err = fmt.Errorf("canCreateOnUpdate failed to marshal: %s", err)
err = fmt.Errorf("canCreateOnFirstUpdate failed to marshal: %s", err)
log.Errorf(err.Error())
return true // true is the default
}
return createOnUpdate.CreateOnUpdate
return createOnFirstUpdate.SetCreateOnFirstUpdate
}

func init() {
AddRoute("deleteWorldState", "invoke", SystemClass, deleteWorldState)
AddRoute("readWorldState", "query", SystemClass, readWorldState)
AddRoute("setLoggingLevel", "invoke", SystemClass, setLoggingLevel)
AddRoute("setCreateOnUpdate", "invoke", SystemClass, setCreateOnUpdate)
AddRoute("setCreateOnFirstUpdate", "invoke", SystemClass, setCreateOnFirstUpdate)
}
2 changes: 1 addition & 1 deletion contracts/platform/iotcontractplatformsample/generate.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"readAssetHistoryContainer",
"readRecentStates",
"setLoggingLevel",
"setCreateOnUpdate"
"setCreateOnFirstUpdate"
],
"goSchemaElements": [
"container",
Expand Down
15 changes: 5 additions & 10 deletions contracts/platform/iotcontractplatformsample/payloadschema.json
Original file line number Diff line number Diff line change
Expand Up @@ -460,30 +460,25 @@
}
}
},
"setCreateOnUpdate": {
"setCreateOnFirstUpdate": {
"type": "object",
"description": "Allow updateAsset to create a container upon receipt of its first event",
"properties": {
"method": "invoke",
"function": {
"type": "string",
"enum": [
"setCreateOnUpdate"
"setCreateOnFirstUpdate"
]
},
"args": {
"type": "array",
"items": {
"type": "object",
"properties": {
"setCreateOnUpdate": {
"type": "object",
"description": "Allows updates to create missing assets on first event",
"properties": {
"createOnUpdate": {
"type": "boolean"
}
}
"setCreateOnFirstUpdate": {
"type": "boolean",
"description": "Allows updates to create missing assets on first event"
}
}
},
Expand Down
13 changes: 4 additions & 9 deletions contracts/platform/iotcontractplatformsample/schemas.go
Original file line number Diff line number Diff line change
Expand Up @@ -1582,20 +1582,15 @@ var schemas = `
},
"type": "object"
},
"setCreateOnUpdate": {
"setCreateOnFirstUpdate": {
"description": "Allow updateAsset to create a container upon receipt of its first event",
"properties": {
"args": {
"items": {
"properties": {
"setCreateOnUpdate": {
"setCreateOnFirstUpdate": {
"description": "Allows updates to create missing assets on first event",
"properties": {
"createOnUpdate": {
"type": "boolean"
}
},
"type": "object"
"type": "boolean"
}
},
"type": "object"
Expand All @@ -1606,7 +1601,7 @@ var schemas = `
},
"function": {
"enum": [
"setCreateOnUpdate"
"setCreateOnFirstUpdate"
],
"type": "string"
},
Expand Down

0 comments on commit 39dae85

Please sign in to comment.