hyperledger composer deploy example code fails - hyperledger-composer

Currently working with the latest releases of the hyperledger development environment and am working through the admin services. The example code for admin -> deploy is documented as:
// Deploy a Business Network Definition
var adminConnection = new AdminConnection();
var businessNetworkDefinition = BusinessNetworkDefinition.fromArchive(myArchive);
return adminConnection.deploy(businessNetworkDefinition)
.then(function(){
// Business network definition deployed
})
.catch(function(error){
// Add optional error handling here.
});
In the code as provided, the second line fails as BusinessNetworkDefinition is not a part of the composer-admin node module. I have two options for creating a BusinessNetworkDefinition, one is to use composer-client. This fails with the following message: TypeError: composerClient.BusinessNetworkDefinition is not a constructor
The code used for this attempt is summarized here:
'use strict';
var fs = require('fs');
var path = require('path');
var composer = require('composer-admin');
var composerClient = require('composer-client');
var composerCommon = require('composer-common');
var businessNetworkDefinition = new composerClient.BusinessNetworkDefinition();
The other option is to use composer-common, which fails with the following message: TypeError: businessNetworkDefinition.fromArchive is not a function
The code used for this attempt is:
var fs = require('fs');
var path = require('path');
var composer = require('composer-admin');
var composerClient = require('composer-client');
var composerCommon = require('composer-common');
var net_identifier = "zerotoblockchain-network#0.1.6";
var net_description = "Z2B network";
var net_package = require("../../../../network/package.json");
var net_readme = "../../../../README.md";
var businessNetworkDefinition = new composerCommon.BusinessNetworkDefinition(net_identifier, net_description, net_package, net_readme);
var archive = businessNetworkDefinition.fromArchive(req.body.myArchive);
where req.body.myArchive is the name of the archive file to be used in the fromArchive method. Inspecting the BusinessNetworkDefinition created via the new command shows the following:
object property: modelManager
object property: aclManager
object property: queryManager
object property: scriptManager
object property: introspector
object property: factory
object property: serializer
object property: metadata
So, two questions:
One: What was created with the new command and
Two: How do I correctly create a BusinessNetworkDefinition object which as a fromArchive() function in it?

The example code in the hyperledger composer documentation is flawed. Following is code which will successfully execute a business network deploy.
(1) Required definitions:
let fs = require('fs');
let path = require('path');
let composerAdmin = require('composer-admin');
const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition;
The following is written as an exportable, routable routine in nodejs and has been tested through from client (browser). Client passes in name of network to deploy. File layout is:
root/network/dist/network-archive-file.bna
(2) Read in the archive file and create an admin connection:
/**
* Deploys a new BusinessNetworkDefinition to the Hyperledger Fabric. The connection must be connected for this method to succeed.
* #param {express.req} req - the inbound request object from the client
* req.body.myArchive: _string - string name of object
* req.body.deployOptions: _object - string name of object
* #param {express.res} res - the outbound response object for communicating back to client
* #param {express.next} next - an express service to enable post processing prior to responding to the client
* returns composerAdmin.connection - either an error or a connection object
* #function
*/
exports.deploy = function(req, res, next) {
let newFile = path.join(path.dirname(require.main.filename),'network/dist',req.body.myArchive);
let archiveFile = fs.readFileSync(newFile);
let adminConnection = new composerAdmin.AdminConnection();
(3) Invoke the (asynchronous) fromArchive function and then deploy the result of the fromArchive invocation.
return BusinessNetworkDefinition.fromArchive(archiveFile)
.then(function(archive) {
adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW)
.then(function(){
adminConnection.deploy(archive)
(4). Respond to the (browser based) request:
.then(function(){
console.log('business network deploy successful: ');
res.send({deploy: 'succeeded'});
})
.catch(function(error){
console.log('business network deploy failed: ',error);
res.send({deploy: error});
});
... (5) and for anyone copying all the code, a few closing braces:
});
});
};

Related

Why is there an error in this contract call?

new to nearprotocol! Trying to do a little hello world using near-api-js, here is my issue ...
const { keyStores, connect } = require("near-api-js");
const fs = require("fs");
const path = require("path");
const homedir = require("os").homedir();
const CREDENTIALS_DIR = ".near-credentials";
const ACCOUNT_ID = "acct.testnet";
const WASM_PATH = "./contract/target/wasm32-unknown-unknown/release/counter.wasm";
const credentialsPath = path.join(homedir, CREDENTIALS_DIR);
const keyStore = new keyStores.UnencryptedFileSystemKeyStore(credentialsPath);
const config = {
keyStore,
networkId: "testnet",
nodeUrl: "https://rpc.testnet.near.org",
};
deployContract(ACCOUNT_ID, WASM_PATH);
async function deployContract(accountId, wasmPath) {
const near = await connect(config);
const account = await near.account(accountId);
const result = await account.deployContract(fs.readFileSync(wasmPath));
}
I am deploying a wasm contract with this methodology, however, when I try to call the contract using
const nearAPI = require("near-api-js");
const keyStores = nearAPI.keyStores;
const connect = nearAPI.connect;
const homedir = require("os").homedir();
const CREDENTIALS_DIR = ".near-credentials";
const credentialsPath = require("path").join(homedir, CREDENTIALS_DIR);
const keyStore = new keyStores.UnencryptedFileSystemKeyStore(credentialsPath);
const config = {
networkId: "testnet",
keyStore,
nodeUrl: "https://rpc.testnet.near.org",
walletUrl: "https://wallet.testnet.near.org",
helperUrl: "https://helper.testnet.near.org",
explorerUrl: "https://explorer.testnet.near.org",
};
call();
async function call() {
// gets the state of the account
const near = await connect(config);
const account = await near.account("acct.testnet");
const contract = new nearAPI.Contract(
account, // the account object that is connecting
"acct.testnet",
{
contractID : "counter.acct.testnet",
changeMethods: ["increment", "decrement", "reset"], // view methods do not change state but usually return a value
viewMethods: ["get_num"], // change methods modify state
sender: account, // account object to initialize and sign transactions.
}
);
let response = await contract.reset(
{
args: {
//arg_name: "value" // argument name and value - pass empty object if no args required
},
gas: 300000000000000 // attached GAS (optional)
}
);
console.log(response);
}
Now, the response says that the contract does not exist: ServerTransactionError: Can't complete the action because account counter.acct.testnet doesn't exist.
However, when using acct.testnet, instead of counter.acct.testnet, it works.
Which leaves the question: how can I specify the exact contract that I want to interact with, on the near blockchain, under a specific account?
Thanks!
There are two different ways you can go about using NAJ (near-api-js) and interacting with contracts. The first way, which is the one you're using, is to create a contract object (new nearAPI.Contract()) and connect to the contract using an account object (either from a wallet connection or the native near.account() method):
const contract = new nearAPI.Contract(
accountObject, // the account object that is connecting
...
This method allows you to pass in the account ID of the contract you wish to interact with:
const contract = new nearAPI.Contract(
accountObject,
"CONTRACT_ACCOUNT_ID_HERE.testnet",
...
In your case, simply change that account ID to be whatever you want and that will allow you to interact with different contracts. These account IDs must exist and also have a contract deployed to them otherwise you'll run into errors. Don't forget that the methods you outline when creating the nearAPI contract object must also live on the contract or else when you try to use them, it will throw as well.
The second way you can interact with contracts, which is my preferred way of doing things, is to create the account object in the same manner as you did previously but instead of creating a contract object and doing contract.methodName, you just take the account object and do account.functionCall or account.viewFunction where you can pass in the contract ID, method name etc...
This allows you to interact with any contract on-chain without having to create a new contract object for each contract you want to interact with.

How do I use Hl7.Fhir.Rest client to search for HealthCareService's

I am completely new to FHIR and have stumbled upon this NuGet package "Hl7.Fhir.STU3" and want to use it to search for Healthcare Services as defined here: https://digital.nhs.uk/developer/api-catalogue/e-referral-service-fhir#api-Default-a010-patient-service-search.
I so far have this limited code and understand I need to pass some form of search criteria but have no idea how to proceed. All I ever get back from the NHS client is:
"Root object has no type indication (resourceType) and therefore cannot be used to construct an FhirJsonNode. Alternatively, specify a nodeName using the parameter."
My code is:
var settings = new FhirClientSettings
{
Timeout = 10,
PreferredFormat = ResourceFormat.Json,
PreferredReturn = Prefer.ReturnMinimal,
};
var client = new FhirClient("https://sandbox.api.service.nhs.uk/referrals/FHIR/STU3/HealthcareService/$ers.searchHealthcareServicesForPatient", settings);
client.RequestHeaders.Add("Authorization", "Bearer g1112R_ccQ1Ebbb4gtHBP1aaaNM");
client.RequestHeaders.Add("nhsd-ers-ods-code", "R69");
client.RequestHeaders.Add("nhsd-ers-business-function", "REFERRING_CLINICIAN");
client.RequestHeaders.Add("X-Correlation-Id", Guid.NewGuid().ToString());
var services = client.Search<HealthcareService>();
I would really appreciate any assistance.
The URL you have set as your FHIR server endpoint is actually the URL for the operation call, so that will not work. If you set the server URL to "https://sandbox.api.service.nhs.uk/referrals/FHIR/STU3/", you should be able to use the FhirClient to do an operation call:
// Note that you have to send parameters in with your request, so set them up first:
var params = new Parameters();
params.Add("requestType", new Coding("https://fhir.nhs.uk/STU3/CodeSystem/eRS-RequestType-1", "APPOINTMENT_REQUEST"));
// etc...
var result = c.TypeOperation<HealthcareService>("ers.searchHealthcareServicesForPatient", params);
The $ sign in the original url is not part of the operation name, so I have omitted that in the request. The FhirClient will add the $ on the outgoing request.

Function app not waiting for Promise returned from web3 contract.getpastevents

I am new to using function app as well as JS. Below is what i am trying to do :
we have a internal quorum cluster using Azure blockchain service. we have deployed a contract on it and need to check the events for this contract. And in general, want to interact with this contract.
For interacting with this contract, we plan to use a node js app which will be hosted using Azure Function app.
I have created a test script which creates contract instance and logs the output of getpastevents method.
The script is working fine on my local node setup but on function app, the execution does not wait for the promise to finish and capture the final result. Rather, it just logs 'promise pending' and moves on.
please ignore the myBlob input, i am just testing this function in a Blob trigger.
code :
module.exports = async function (context, myBlob) {
context.log("JavaScript blob trigger function processed blob \n Blob:", context.bindingData.blobTrigger, "\n Blob Size:", myBlob.length, "Bytes");
var Web3 = require('web3')
const rpcURL = "https://<myapp>.blockchain.azure.com:port/key"
const web3 = new Web3(rpcURL)
const account = <validAccount>
var privateKey = Buffer.from(<validkey>, 'hex')
var abi=,Validabi>
var contractAddress=<contractaddress>;
var contract = new web3.eth.Contract(abi, contractAddress);
contract.getPastEvents('allEvents', {fromBlock : 0, toBlock :'latest'}).then((events) => { result = events;
context.log(result)}).catch((error)=>{context.log('error')});
};
Got the answer through Quorum Slack channel. below is the working code:
module.exports = async function (context, myBlob) {
context.log("JavaScript blob trigger function processed blob \n Blob:", context.bindingData.blobTrigger, "\n Blob Size:", myBlob.length, "Bytes");
var Web3 = require('web3')
const rpcURL = "https://<myapp>.blockchain.azure.com:port/key"
const web3 = new Web3(rpcURL)
const account = <validAccount>
var privateKey = Buffer.from(<validkey>, 'hex')
var abi=,Validabi>
var contractAddress=<contractaddress>;
var contract = new web3.eth.Contract(abi, contractAddress);
let events = contract.getPastEvents('allEvents', {fromBlock : 0, toBlock :'latest'})
.catch((error)=>{context.log('error')});
context.log(events);
};

Access GlideRecord from within service portal widget

How can I run a Glide query from in a widget? (Service Portal)
This code runs fine in the script-background editor, but it doesn't work in the Server-script section of my widget:
var grTask = new GlideRecord('task');
grTask.get('number', "REQ0323232"); // hardcoded good sample
destination_sys_id = grTask.sys_id;
When I run the code in Scripts, I get:
*** Script: sys_id: 0f4d[...]905
When I run it in the widget, I get:{}
To elaborate on my Widget code:
Body HTML template
data.destination_sys_id = {{data.destination_sys_id }}
Server script
(function(){
var destination_sys_id = "initialized";
var grTask = new GlideRecord('task');
grTask.get('number', "REQ0323232");
destination_sys_id = grTask.sys_id;
data.destination_sys_id = destination_sys_id;
})()
you can add it as c.data.destination_sys_id nad at the time of assigning the value to object always use .toString() in order to stringify the field value.
I needed a .toString(); in my server script:
(function(){
var destination_sys_id = "initialized";
var grTask = new GlideRecord('task');
grTask.get('number', "REQ0323232");
destination_sys_id = grTask.sys_id.toString(); // <- note the addition of .toString()
data.destination_sys_id = destination_sys_id;
})()
Another way is to use grTask.getUniqueValue() instead of grTask.sys_id.toString().
Also, getters and setters are recommended with GlideRecord, so use grTask.getValue('sys_id') instead of grTask.sys_id.toString().

fhir-net-api (STU3) - Validating

I have been using the Hl7.org tool org.hl7.fhir.validator.jar file to validate my messages but I would like to add this function it to my .Net project. Once I parse the message is there a class I can call to validate the Structure.
Is there a validate FHIR class in fhir-net-api that will display the same results has org.hl7.fhir.validator.jar?
string HL7FilePath = string.Format("{0}\\{1}", System.IO.Directory.GetCurrentDirectory(), "Sample.xml");
string HL7FileData = File.ReadAllText(HL7FilePath)
var b = new FhirXmlParser().Parse<PlanDefinition>(HL7FileData);
FHIR Validator Build ??
Arguments: C:\HL7Tools\validator\REC78_1.xml -version 3.0
.. connect to tx server # http://tx.fhir.org
.. definitions from hl7.fhir.core#3.0.1
(v3.0.1-null)
.. validate [C:\HL7Tools\validator\Sample.xml]
Terminology server: Check for supported code systems for http://www.nlm.nih.gov/research/umls/rxnorm
Success.
Yes, there is. You need to add the Hl7.Fhir.Specification.STU3 package, and can then use the validation methods like this:
using Hl7.Fhir.Specification.Source;
using Hl7.Fhir.Validation;
... your code, reading the PlanDefinition from file and parsing it ...
// setup the resolver to use specification.zip, and a folder with custom profiles
var source = new CachedResolver(new MultiResolver(
new DirectorySource(#"<path_to_profile_folder>"),
ZipSource.CreateValidationSource()));
// prepare the settings for the validator
var ctx = new ValidationSettings()
{
ResourceResolver = source,
GenerateSnapshot = true,
Trace = false,
EnableXsdValidation = true,
ResolveExteralReferences = false
}
var validator = new Validator(ctx);
// validate the resource; optionally enter a custom profile url as 2nd parameter
var result = validator.Validate(b);
The result will be an OperationOutcome resource containing the details of the validation.

Resources