Is there a way to get the chaincode metadata using the NodeJS or Go fabric-network SDK?
Something similar to the peer lifecycle chaincode queryinstalled command:
{
"installed_chaincodes": [
{
"package_id": "testcc_1:75afd7c4c165c56e8b8f3bd4c53cea8b420f4d94a3d53093aa0ec0229f5c738a",
"label": "testcc_1",
"references": {
"mychannel": {
"chaincodes": [
{
"name": "testcc",
"version": "1"
}
]
}
}
}
]
}
If not, then how do clients ensure which version of the chaincode they are calling??
Every SDK implements almost all the methods available in cli.
In case of go-sdk, you can implement something like this.
import (
"fmt"
"strings"
"github.com/hyperledger/fabric-sdk-go/pkg/client/resmgmt"
"github.com/hyperledger/fabric-sdk-go/pkg/common/errors/retry"
fabAPI "github.com/hyperledger/fabric-sdk-go/pkg/common/providers/fab"
lcpackager "github.com/hyperledger/fabric-sdk-go/pkg/fab/ccpackager/lifecycle"
"github.com/pkg/errors"
)
// QueryInstalledCC : query installed CC
func QueryInstalledCC(setup *OrgSetup, ccName, ccVersion, packageID string) (string, string, map[string][]resmgmt.CCReference, error) {
label, _, _ := PackageCC(ccName, ccVersion)
resp, err := setup.Resmgmt.LifecycleQueryInstalledCC(resmgmt.WithTargetEndpoints(peer1), resmgmt.WithRetry(retry.DefaultResMgmtOpts))
if err != nil {
fmt.Printf("\n Error occurred in queryInstalledCC func and error is %s", err)
}
if !strings.EqualFold(packageID, resp[0].PackageID) {
fmt.Print("Unable to match packageID in QueryInstalledCC")
return "", "", nil, nil
}
if !strings.EqualFold(label, resp[0].Label) {
fmt.Print("Unable to match labels in QueryInstalledCC")
return "", "", nil, nil
}
ref := resp[0].References
return resp[0].Label, resp[0].PackageID, ref, nil
}
Related
I would like to make comparison between two values in a OPA rule.
My OPA rule is :
package example
vm_name = input.planned_values.root_module.resources[0].values.name
vm_name_length = count(vm_name)
The output is :
~$ ./opa eval -i tfplan.json -d test1.rego "data.example"
{
"result": [
{
"expressions": [
{
"value": {
"vm_name": "XXXXXXXX",
"vm_name_length": 8
},
"text": "data.example",
"location": {
"row": 1,
"col": 1
}
}
]
}
]
}
I've tried to make a comparison between the length needed and the length of the VM name :
package example
vm_name = input.planned_values.root_module.resources[0].values.name
vm_name_length = count(vm_name)
if vm_name_length == 13 {
msg := "OK"
}
else {
msg := "Not ok"
}
But the output is :
{
"errors": [
{
"message": "unexpected assign token: non-terminated set",
"code": "rego_parse_error",
"location": {
"file": "test1.rego",
"row": 24,
"col": 7
},
"details": {
"line": " msg := \"OK\"",
"idx": 6
}
}
]
}
Does anyone know how to do that ?
Rego rules describe conditional assignment, so all conditions in the rule body (i.e. inside of the { ... }) will need to be true in order for the rule to evaluate the assignment.
package example
vm_name = input.planned_values.root_module.resources[0].values.name
vm_name_length = count(vm_name)
default msg := "Not ok"
msg := "OK" {
vm_name_length == 13
}
i am using a hlf system based on chaincode to show how smart contracts could be created.
Now i am stuck with (in my mind) a very easy problem i guess.
I want to store a data objects content as key-value pair on the chains couchDb state database.
I am doing this with a docker request looking like this:
COMMAND WRITE: docker exec -t Lane1_Zf4URs_cli peer chaincode invoke -o orderer.Zf4URs.com:7050 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/Zf4URs.com/orderers/orderer.Zf4URs.com/msp/tlscacerts/tlsca.Zf4URs.com-cert.pem -C mychannel -n 9bc7cca8-1dcd-49b0-a25c-fb639a0403cf -c '{"Args":["set", "[D1]{P1}", "data4"]}'
So as you see my args are calling set method and store key="[Di]{P1}" value="data4" this is working fine with this "set" method.
func (s *SmartContract) set(stub shim.ChaincodeStubInterface, args []string) peer.Response {
if len(args) != 2 {
return shim.Error("Incorrect arguments. Expecting a key and a value")
}
err := stub.PutState(args[0], []byte(args[1]))
if err != nil {
return shim.Error("Failed to set asset: " + string(args[0]))
}
return shim.Success([]byte(args[1]))
// return args[1]
}
Now when looking at state dB this is the stored result:
{
"_id": "[D1]{P1}",
"_rev": "2-a74269cadec50f97d34d165d60235e34",
"~version": "8:0",
"_attachments": {
"valueBytes": {
"content_type": "application/octet-stream",
"revpos": 2,
"digest": "md5-2cRbxPYpSEbldj1mVovx8Q==",
"length": 5,
"stub": true
}
}
}
Now what i want to have is to store an additional value on this state db request.
Beside of "_id" (key) i want to have another field called "_executor" which should have a value "{P1}"
Should look like this:
{
"_id": "[D1]{P1}",
"_rev": "2-a74269cadec50f97d34d165d60235e34",
"_executor": "{P1}",
"~version": "8:0",
"_attachments": {
"valueBytes": {
"content_type": "application/octet-stream",
"revpos": 2,
"digest": "md5-2cRbxPYpSEbldj1mVovx8Q==",
"length": 5,
"stub": true
}
}
}
How can i do that?
What do i have to change on the docker request or on the set method?
Is this even possible?
Many thanks for help
This should work!
You have no constrains on the second argument (args[1]) in your smart contract. And since this is a string it's stored in one column and hence doesn't depend on the table structure.
I have updated my code.
I tried to use a struct and store this.
`type DataObject struct {
Name string
Executor string
Data []byte} func (s *SmartContract) set(stub shim.ChaincodeStubInterface, args []string) peer.Response {
if len(args) != 2 {
return shim.Error("Incorrect arguments. Expecting a key and a value")
}
p := DataObject{
Name: args[0],
Executor: "p1",
Data: []byte(args[1]),
}
str, err2 := json.Marshal(p)
if err2 != nil {
fmt.Println(err2)
}
fmt.Println(string(str))
if(args[1] == "data4"){
err := stub.PutState(args[0], str)
if err != nil {
return shim.Error("Failed to set asset: " + string(args[0]))
}
return shim.Success(str)
} else {
err := stub.PutState(args[0], []byte(args[1]))
if err != nil {
return shim.Error("Failed to set asset: " + string(args[0]))
}
return shim.Success([]byte(args[1]))
}}`
Now i can store executor but my data variable gets not stored as before. I need the digest so as before it should be _attachments: [valueBytes: ....digest:md5-xxx].
It looks like this:
couchDb-doc
{
"_id": "[D1]{P1}",
"_rev": "1-69be87268fs88s788668f8s766fnkushof7",
"Data": "ZGF0YTQ=",
"Executor": "P1",
"Name": "[D1]{P1}",
"_version": "3:0"
}
I tried replacing the value for the key "Information" from the below JSON Object using the code
"itsmdata.incidentParamsJSON.IncidentContainerJson.replace("Information",option);"
but getting error as object is not defined (Attachment)
{
"ServiceName": "IM_LogOrUpdateIncident",
"objCommonParameters": {
"_ProxyDetails": {
"ProxyID": 0,
"ReturnType": "JSON",
"OrgID": 1,
"TokenID": null
},
"incidentParamsJSON": {
"IncidentContainerJson": "{\"SelectedAssets\":null,\"Ticket\":{\"Caller_EmailID\":null,\"Closure_Code_Name\":null,\"Description_Name\":\"Account Unlock\",\"Instance\":null},\"TicketInformation\":{\"Information\":\"account locked out\"},\"CustomFields\":null}"
},
"RequestType": "RemoteCall"
}
}
If you try to update properties of itsmdata you can try this
let str = itsmdata.objCommonParameters.incidentParamsJSON.IncidentContainerJson;
itsmdata.objCommonParameters.incidentParamsJSON.IncidentContainerJson = str.replace(/Information/gi, option);
I would like to test if multiple packages exist in my environment or not, based on this test I would like to generate the final catalog.
if !defined( Package[ 'apache2' ] ) {
package { 'apache2':
ensure => installed,
}
}
if !defined( Package[ 'libapache2-svn' ] ) {
package { 'libapache2-svn':
ensure => installed,
}
}
In future I would like to control in the following way:
Package { ensure => "installed" }
$packageList = [ 'apache2', 'libapache2-svn' ]
if !defined( Package[ $packageList ] ) {
package { $packageList: }
}
I have required to remove object from array that satisfies the condition, I am able to update the object of array on the basis of condition, which is as follow:
PUT twitter/twit/1
{"list":
[
{
"tweet_id": "1",
"a": "b"
},
{
"tweet_id": "123",
"a": "f"
}
]
}
POST /twitter/twit/1/_update
{"script":"foreach (item :ctx._source.list) {
if item['tweet_id'] == tweet_id) {
item['new_field'] = 'ghi';
}
}",
"params": {tweet_id": 123"}
}
this is working
for remove i am doing this
POST /twitter/twit/1/_update
{ "script": "foreach (item : ctx._source.list) {
if item['tweet_id'] == tweet_id) {
ctx._source.list.remove(item);
}
}",
"params": { tweet_id": "123" }
}
but this is not working and giving this error,
ElasticsearchIllegalArgumentException[failed to execute script];
nested: ConcurrentModificationException; Error:
ElasticsearchIllegalArgumentException[failed to execute script];
nested: ConcurrentModificationException
I am able to remove whole array or whole field using
"script": "ctx._source.remove('list')"
I am also able to remove object from array by specifying all the keys of an object using
"script":"ctx._source.list.remove(tag)",
"params" : {
"tag" : {"tweet_id": "123","a": "f"}
my node module elastic search version is 2.4.2 elastic search server is 1.3.2
You get that because you are trying to modify a list while iterating through it, meaning you want to change a list of object and, at the same time, listing those objects.
You instead need to do this:
POST /twitter/twit/1/_update
{
"script": "item_to_remove = nil; foreach (item : ctx._source.list) { if (item['tweet_id'] == tweet_id) { item_to_remove=item; } } if (item_to_remove != nil) ctx._source.list.remove(item_to_remove);",
"params": {"tweet_id": "123"}
}
If you have more than one item that matches the criteria, use a list instead:
POST /twitter/twit/1/_update
{
"script": "items_to_remove = []; foreach (item : ctx._source.list) { if (item['tweet_id'] == tweet_id) { items_to_remove.add(item); } } foreach (item : items_to_remove) {ctx._source.list.remove(item);}",
"params": {"tweet_id": "123"}
}
For people that need this working in elasticsearch 2.0 and up, the nil and foreach don't get recognized by groovy.
So here's a updated version, including a option to replace a item with the same id by a new object.
and also passing it the upsert will make sure the item gets added even if the document doesn't exist yet
{
"script": "item_to_remove = null; ctx._source.delivery.each { elem -> if (elem.id == item_to_add.id) { item_to_remove=elem; } }; if (item_to_remove != null) ctx._source.delivery.remove(item_to_remove); if (item_to_add.size() > 1) ctx._source.delivery += item_to_add;",
"params": {"item_to_add": {"id": "5", "title": "New item"}},
"upsert": [{"id": "5", "title": "New item"}]
}