From 39dae85f29aa355b7cfe4ac84e8cac6e8a289818 Mon Sep 17 00:00:00 2001 From: kletkeman Date: Sun, 13 Nov 2016 17:39:32 -0500 Subject: [PATCH] implement and test createOnFirstUpdate Put the redirection scheme back into the iot contract platform and ensure that you can set and clear it with the monitoring UI. --- .../platform/iotcontractplatform/ctasset.go | 9 ++- .../platform/iotcontractplatform/ctconfig.go | 55 ++++++++++--------- .../iotcontractplatformsample/generate.json | 2 +- .../payloadschema.json | 15 ++--- .../iotcontractplatformsample/schemas.go | 13 ++--- 5 files changed, 45 insertions(+), 49 deletions(-) diff --git a/contracts/platform/iotcontractplatform/ctasset.go b/contracts/platform/iotcontractplatform/ctasset.go index b61af7e..e68aa6c 100644 --- a/contracts/platform/iotcontractplatform/ctasset.go +++ b/contracts/platform/iotcontractplatform/ctasset.go @@ -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 } diff --git a/contracts/platform/iotcontractplatform/ctconfig.go b/contracts/platform/iotcontractplatform/ctconfig.go index 067a486..042a09b 100644 --- a/contracts/platform/iotcontractplatform/ctconfig.go +++ b/contracts/platform/iotcontractplatform/ctconfig.go @@ -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 @@ -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) } diff --git a/contracts/platform/iotcontractplatformsample/generate.json b/contracts/platform/iotcontractplatformsample/generate.json index 06de263..4d03804 100644 --- a/contracts/platform/iotcontractplatformsample/generate.json +++ b/contracts/platform/iotcontractplatformsample/generate.json @@ -17,7 +17,7 @@ "readAssetHistoryContainer", "readRecentStates", "setLoggingLevel", - "setCreateOnUpdate" + "setCreateOnFirstUpdate" ], "goSchemaElements": [ "container", diff --git a/contracts/platform/iotcontractplatformsample/payloadschema.json b/contracts/platform/iotcontractplatformsample/payloadschema.json index b8e937c..c1af718 100644 --- a/contracts/platform/iotcontractplatformsample/payloadschema.json +++ b/contracts/platform/iotcontractplatformsample/payloadschema.json @@ -460,7 +460,7 @@ } } }, - "setCreateOnUpdate": { + "setCreateOnFirstUpdate": { "type": "object", "description": "Allow updateAsset to create a container upon receipt of its first event", "properties": { @@ -468,7 +468,7 @@ "function": { "type": "string", "enum": [ - "setCreateOnUpdate" + "setCreateOnFirstUpdate" ] }, "args": { @@ -476,14 +476,9 @@ "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" } } }, diff --git a/contracts/platform/iotcontractplatformsample/schemas.go b/contracts/platform/iotcontractplatformsample/schemas.go index 18d098c..32267bf 100644 --- a/contracts/platform/iotcontractplatformsample/schemas.go +++ b/contracts/platform/iotcontractplatformsample/schemas.go @@ -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" @@ -1606,7 +1601,7 @@ var schemas = ` }, "function": { "enum": [ - "setCreateOnUpdate" + "setCreateOnFirstUpdate" ], "type": "string" },