Exemple #1
0
 /**
  * Get all of the resources in the registry, and resolve all of their relationships
  * to other assets, participants, and transactions. The result is a JavaScript
  * object, and should only be used for visualization purposes. You cannot use
  * the {@link #add add} or {@link #update update} functions with a resolved resource.
  *
  * @return {Promise} A promise that will be resolved with an array of JavaScript
  * objects representing the resources and all of their resolved relationships.
  */
 resolveAll() {
     Util.securityCheck(this.securityContext);
     return Util.queryChainCode(this.securityContext, 'resolveAllResourcesInRegistry', [this.registryType, this.id])
         .then((buffer) => {
             return JSON.parse(buffer.toString());
         });
 }
Exemple #2
0
 /**
  * Updates a resource in the registry.
  *
  * @param {Resource} resource The resource to be updated in the registry.
  * @return {Promise} A promise that will be resolved when the resource is
  * updated in the registry.
  */
 update(resource) {
     Util.securityCheck(this.securityContext);
     if (!resource) {
         throw new Error('resource not specified');
     }
     let serializedResource = this.serializer.toJSON(resource);
     return Util.invokeChainCode(this.securityContext, 'updateResourceInRegistry', [this.registryType, this.id, JSON.stringify(serializedResource)]);
 }
Exemple #3
0
 /**
  * Execute a query against all resources in the registry. The JSONata
  * expression is applied to each resource in the registry, and the result
  * of the JSONata expression is returned if the result is truthy. The result
  * is a JavaScript object, and should only be used for visualization
  * purposes. You cannot use the {@link add} or {@link update} functions with
  * data returned by this function.
  *
  * @param {string} expression The JSONata expression.
  * @return {Promise} A promise that will be resolved with an array of JavaScript
  * objects representing the resources and all of their resolved relationships.
  */
 query(expression) {
     Util.securityCheck(this.securityContext);
     if (!expression) {
         throw new Error('expression not specified');
     }
     return Util.queryChainCode(this.securityContext, 'queryResourcesInRegistry', [this.registryType, this.id, expression])
         .then((buffer) => {
             return JSON.parse(buffer.toString());
         });
 }
Exemple #4
0
 /**
  * Get a list of all existing registries.
  *
  * @protected
  * @param {SecurityContext} securityContext The user's security context.
  * @param {string} registryType The type of this registry.
  * @return {Promise} A promise that will be resolved with an array of JSON
  * objects representing the registries.
  */
 static getAllRegistries(securityContext, registryType) {
     Util.securityCheck(securityContext);
     if (!registryType) {
         throw new Error('registryType not specified');
     }
     return Util.queryChainCode(securityContext, 'getAllRegistries', [registryType])
         .then((buffer) => {
             return JSON.parse(buffer.toString());
         });
 }
Exemple #5
0
 /**
  * Get a specific resource in the registry, and resolve all of its relationships
  * to other assets, participants, and transactions. The result is a JavaScript
  * object, and should only be used for visualization purposes. You cannot use
  * the  {@link #add add} or {@link #update update} functions with a resolved resource.
  *
  * @param {string} id The unique identifier of the asset.
  * @return {Promise} A promise that will be resolved with a JavaScript object
  * representing the resource and all of its resolved relationships.
  */
 resolve(id) {
     Util.securityCheck(this.securityContext);
     if (!id) {
         throw new Error('id not specified');
     }
     return Util.queryChainCode(this.securityContext, 'resolveResourceInRegistry', [this.registryType, this.id, id])
         .then((buffer) => {
             return JSON.parse(buffer.toString());
         });
 }
Exemple #6
0
 /**
  * Updates a list of resources in the registry.
  *
  * @param {Resource[]} resources The resources to be updated in the asset registry.
  * @return {Promise} A promise that will be resolved when the resource is
  * added to the registry.
  */
 updateAll(resources) {
     Util.securityCheck(this.securityContext);
     if (!resources) {
         throw new Error('resources not specified');
     }
     let serializedResources = resources.map((resource) => {
         return this.serializer.toJSON(resource);
     });
     return Util.invokeChainCode(this.securityContext, 'updateAllResourcesInRegistry', [this.registryType, this.id, JSON.stringify(serializedResources)]);
 }
Exemple #7
0
 /**
  * Determines whether a registry exists.
  *
  * @protected
  * @param {SecurityContext} securityContext The user's security context.
  * @param {string} registryType The type of this registry.
  * @param {string} id The unique identifier of the registry.
  * @return {Promise} A promise that will be resolved with true/false depending on whether the registry exists
  */
 static existsRegistry(securityContext, registryType, id) {
     Util.securityCheck(securityContext);
     if (!registryType) {
         throw new Error('registryType not specified');
     } else if (!id) {
         throw new Error('id not specified');
     }
     return Util.queryChainCode(securityContext, 'existsRegistry', [registryType, id])
     .then((buffer) => {
         return JSON.parse(buffer.toString());
     });
 }
Exemple #8
0
 /**
  * Get all of the resources in the registry.
  *
  * @return {Promise} A promise that will be resolved with an array of JSON
  * objects representing the resources.
  */
 getAll() {
     Util.securityCheck(this.securityContext);
     return Util.queryChainCode(this.securityContext, 'getAllResourcesInRegistry', [this.registryType, this.id])
         .then((buffer) => {
             return JSON.parse(buffer.toString());
         })
         .then((resources) => {
             return resources.map((resource) => {
                 return this.serializer.fromJSON(resource);
             });
         });
 }
Exemple #9
0
 /**
  * Remove an asset with a given type and id from the registry.
  *
  * @param {(Resource|string)} resource The resource, or the unique identifier of the resource.
  * @return {Promise} A promise that will be resolved when the resource is
  * removed from the registry.
  */
 remove(resource) {
     Util.securityCheck(this.securityContext);
     if (!resource) {
         throw new Error('resource not specified');
     }
     let id;
     if (resource instanceof Resource) {
         id = resource.getIdentifier();
     } else {
         id = resource;
     }
     return Util.invokeChainCode(this.securityContext, 'removeResourceFromRegistry', [this.registryType, this.id, id]);
 }
 /**
  * Revoke the specified identity by removing any existing mapping to a participant.
  * @param {string} identity The identity, for example the enrollment ID.
  * @return {Promise} A promise that will be fulfilled when the identity has
  * been removed from the specified participant. The promise will be rejected if
  * the participant does not exist, or if the identity is not mapped to the
  * participant.
  */
 revokeIdentity(identity) {
     const method = 'revokeIdentity';
     LOG.entry(method, identity);
     if (!identity) {
         throw new Error('identity not specified');
     }
     Util.securityCheck(this.securityContext);
     // It is not currently possible to revoke the certificate, so we just call
     // the runtime to remove the mapping.
     return Util.invokeChainCode(this.securityContext, 'removeIdentity', [identity])
       .then(() => {
           LOG.exit(method);
       });
 }
Exemple #11
0
 /**
  * Removes a list of resources from the registry.
  *
  * @param {(Resource[]|string[])} resources The resources, or the unique identifiers of the resources.
  * @return {Promise} A promise that will be resolved when the resource is
  * added to the registry.
  */
 removeAll(resources) {
     Util.securityCheck(this.securityContext);
     if (!resources) {
         throw new Error('resources not specified');
     }
     let data = resources.map((resource) => {
         if (resource instanceof Resource) {
             return resource.getIdentifier();
         } else {
             return resource;
         }
     });
     return Util.invokeChainCode(this.securityContext, 'removeAllResourcesFromRegistry', [this.registryType, this.id, JSON.stringify(data)]);
 }
 .then((identity) => {
     return Util.invokeChainCode(this.securityContext, 'addParticipantIdentity', [participantFQI, userID])
         .then(() => {
             LOG.exit(method, identity);
             return identity;
         });
 });
Exemple #13
0
 /**
  * Remove an asset with a given type and id from the registry.
  *
  * @param {(Resource|string)} resource The resource, or the unique identifier of the resource.
  * @return {Promise} A promise that will be resolved when the resource is
  * removed from the registry.
  */
 remove(resource) {
     Util.securityCheck(this.securityContext);
     if (!resource) {
         throw new Error('resource not specified');
     }
     return this.removeAll([resource]);
 }
 /**
  * Execute a query defined in a Composer query file, or execute a query built with buildQuery.
  *
  * This functionality is Blockchain platform dependent. For example, when a Composer
  * business network is deployed to Hyperledger Fabric v1.0, Hyperledger Fabric must be
  * configured with the CouchDB database for the world state.
  * @example
  * // Execute the query.
  * var businessNetwork = new BusinessNetworkConnection();
  * return businessNetwork.connect('testprofile', 'businessNetworkIdentifier', 'WebAppAdmin', 'DJY27pEnl16d')
  *   .then(function () {
  *     return query('Q1', { inputValue: 'blue' })
  *   })
  *   .then(function (assets) {
  *     assets.forEach(function (asset) {
  *       // Process each asset.
  *     });
  *   })
  *   .catch(function (error) {
  *     // Add optional error handling here.
  *   });
  * @param {string|Query} query The name of the query, or a built query.
  * @param {Object} [parameters] The parameters for the query.
  * @return {Promise} A promise that will be resolved with an array of
  * {@link module:composer-common.Resource Resource} representing the
  * resources returned by the query.
  */
 query(query, parameters) {
     const method = 'query';
     LOG.entry(method, query, parameters);
     let queryType, identifier;
     if (query instanceof Query) {
         queryType = 'build';
         identifier = query.getIdentifier();
     } else if (typeof query === 'string') {
         queryType = 'named';
         identifier = query;
     } else {
         throw new Error('Invalid query; expecting a built query or the name of a query');
     }
     parameters = parameters || {};
     return Util.queryChainCode(this.securityContext, 'executeQuery', [queryType, identifier, JSON.stringify(parameters)])
         .then((buffer) => {
             return JSON.parse(buffer.toString());
         })
         .then((resources) => {
             const result = resources.map((resource) => {
                 return this.getBusinessNetwork().getSerializer().fromJSON(resource);
             });
             LOG.exit(method, result);
             return result;
         });
 }
Exemple #15
0
 /**
  * Internal method to check the security context
  * @param {SecurityContext} securityContext - The user's security context
  * @throws {SecurityException} if the user context is invalid
  */
 static securityCheck(securityContext) {
     if (Util.isNull(securityContext)) {
         throw new SecurityException(Globalize.formatMessage('util-securitycheck-novalidcontext'));
     } else if (!(securityContext instanceof HFCSecurityContext)) {
         throw new SecurityException(Globalize.formatMessage('util-securitycheck-novalidcontext'));
     }
 }
Exemple #16
0
 /**
  * Add a new asset registry.
  *
  * @protected
  * @param {SecurityContext} securityContext The user's security context.
  * @param {string} registryType The type of this registry.
  * @param {string} id The unique identifier of the registry.
  * @param {string} name The name of the registry.
  * @return {Promise} A promise that will be resolved with a JSON object
  * representing the registry.
  */
 static addRegistry(securityContext, registryType, id, name) {
     Util.securityCheck(securityContext);
     if (!registryType) {
         throw new Error('registryType not specified');
     } else if (!id) {
         throw new Error('id not specified');
     } else if (!name) {
         throw new Error('name not specified');
     }
     return Util.invokeChainCode(securityContext, 'addRegistry', [registryType, id, name])
         .then(() => {
             return {
                 id: id,
                 name: name
             };
         });
 }
Exemple #17
0
 /**
  * Reset the business network to its initial state.
  * @return {Promise} - a promise that will be resolved when complete.
  */
 static resetBusinessNetwork() {
     if (!client) {
         return Promise.resolve();
     }
     // TODO: hack hack hack, this should be in the admin API.
     let securityContext = client.securityContext;
     if (!securityContext) {
         return Promise.resolve();
     }
     return Util.invokeChainCode(client.securityContext, 'resetBusinessNetwork', []);
 }
 /**
  * Invoke a "invoke" chaincode function with the specified name and arguments.
  * @param {SecurityContext} securityContext The participant's security context.
  * @param {string} functionName The name of the chaincode function to invoke.
  * @param {string[]} args The arguments to pass to the chaincode function.
  * @param {Object} [additionalConnectorOptions] Additional connector specific options for this transaction.
  * @return {Buffer} A buffer containing the data returned by the chaincode function,
  * or null if no data was returned.
  */
 async invokeChainCode(securityContext, functionName, args, additionalConnectorOptions = {}) {
     if (!this.businessNetworkIdentifier) {
         throw new Error('No business network has been specified for this connection');
     }
     let identity = securityContext.getIdentity();
     let chaincodeUUID = securityContext.getChaincodeID();
     let chaincode = EmbeddedConnection.getChaincode(chaincodeUUID);
     let context = new EmbeddedContext(chaincode.engine, identity, this, chaincode.installedBusinessNetwork, additionalConnectorOptions);
     const data = await chaincode.engine.invoke(context, functionName, args);
     return !Util.isNull(data) ? Buffer.from(JSON.stringify(data)) : null;
 }
 /**
  * Get the transaction registry.
  * @example
  * // Get the transaction registry
  * var businessNetwork = new BusinessNetworkConnection();
  * return businessNetwork.connect('testprofile', 'businessNetworkIdentifier', 'WebAppAdmin', 'DJY27pEnl16d')
  * .then(function(businessNetworkDefinition){
  *     return businessNetworkDefinition.getTransactionRegistry();
  * })
  * .then(function(transactionRegistry){
  *     // Retrieved Transaction Registry
  * });
  * @return {Promise} - A promise that will be resolved to the {@link TransactionRegistry}
  */
 getTransactionRegistry() {
     Util.securityCheck(this.securityContext);
     return TransactionRegistry
         .getAllTransactionRegistries(this.securityContext, this.getBusinessNetwork().getModelManager(), this.getBusinessNetwork().getFactory(), this.getBusinessNetwork().getSerializer())
         .then((transactionRegistries) => {
             if (transactionRegistries.length >= 1) {
                 return transactionRegistries[0];
             } else {
                 throw new Error('Failed to find the default transaction registry');
             }
         });
 }
Exemple #20
0
 /**
  * Updates a list of resources in the registry.
  *
  * @param {Resource[]} resources The resources to be updated in the asset registry.
  * @return {Promise} A promise that will be resolved when the resource is
  * added to the registry.
  */
 updateAll(resources) {
     Util.securityCheck(this.securityContext);
     if (!resources) {
         throw new Error('resources not specified');
     }
     let txName = 'Update'+this.registryType;
     const transaction = this.factory.newTransaction('org.hyperledger.composer.system',txName);
     // target registry is the registry that this the client 'shadow' of
     transaction.targetRegistry = this.factory.newRelationship('org.hyperledger.composer.system',this.registryType+'Registry', this.id);
     transaction.resources = resources;
     return this.bnc.submitTransaction(transaction);
 }
Exemple #21
0
 /**
  * Updates a list of resources in the registry.
  *
  * @param {Resource[]} resources The resources to be updated in the asset registry.
  * @return {Promise} A promise that will be resolved when the resource is
  * added to the registry.
  */
 updateAll(resources) {
     Util.securityCheck(this.securityContext);
     if (!resources) {
         throw new Error('resources not specified');
     }
     let txName = 'Update'+this.registryType;
     const transaction = this.factory.newTransaction('org.hyperledger.composer.system',txName);
     transaction.resources = resources;
     transaction.registryType = this.registryType;
     transaction.registryId = this.id;
     return this.bnc.submitTransaction(transaction);
 }
 /**
  * Determine whether a participant registry exists.
  *
  * @protected
  * @param {SecurityContext} securityContext The user's security context.
  * @param {string} id The unique identifier of the asset registry.
  * @param {ModelManager} modelManager The ModelManager to use for this asset registry.
  * @param {Factory} factory The factory to use for this asset registry.
  * @param {Serializer} serializer The Serializer to use for this asset registry.
  * @param {BusinessNetworkConnection} bnc BusinessNetworkConnection to use
  * @return {Promise} A promise that will be resolved with a boolean indicating whether the asset registry exists
  */
 static participantRegistryExists(securityContext, id, modelManager, factory, serializer, bnc) {
     Util.securityCheck(securityContext);
     if (!id) {
         throw new Error('id not specified');
     } else if (!modelManager) {
         throw new Error('modelManager not specified');
     } else if (!factory) {
         throw new Error('factory not specified');
     } else if (!serializer) {
         throw new Error('serializer not specified');
     }
     return Registry.existsRegistry(securityContext, REGISTRY_TYPE, id);
 }
Exemple #23
0
 /**
  * Adds a list of new resources to the registry.
  *
  * @param {Resource[]} resources The resources to be added to the registry.
  * @return {Promise} A promise that will be resolved when the resource is
  * added to the registry.
  */
 addAll(resources) {
     Util.securityCheck(this.securityContext);
     if (!resources) {
         throw new Error('resources not specified');
     }
     let txName = 'Add'+this.registryType;
     const transaction = this.factory.newTransaction('org.hyperledger.composer.system',txName);
     // This code is retained as there was a suggesstion that the transaction should include
     // a relationship to the registry not the type/id. Time ran out to get this implemented
     // transaction.targetRegistry = this.factory.newRelationship(ModelUtil.getNamespace(this.id),this.registryType, this.id);
     transaction.registryType = this.registryType;
     transaction.registryId = this.id;
     transaction.resources = resources;
     return this.bnc.submitTransaction(transaction);
 }
 /**
  * Get an existing participant registry.
  *
  * @protected
  * @param {SecurityContext} securityContext The user's security context.
  * @param {string} id The unique identifier of the participant registry.
  * @param {ModelManager} modelManager The ModelManager to use for this participant registry.
  * @param {Factory} factory The factory to use for this participant registry.
  * @param {Serializer} serializer The Serializer to use for this participant registry.
  * @param {BusinessNetworkConnection} bnc BusinessNetworkConnection to use
  * @return {Promise} A promise that will be resolved with a {@link ParticipantRegistry}
  * instance representing the participant registry.
  */
 static getParticipantRegistry(securityContext, id, modelManager, factory, serializer, bnc) {
     Util.securityCheck(securityContext);
     if (!id) {
         throw new Error('id not specified');
     } else if (!modelManager) {
         throw new Error('modelManager not specified');
     } else if (!factory) {
         throw new Error('factory not specified');
     } else if (!serializer) {
         throw new Error('serializer not specified');
     }
     return Registry.getRegistry(securityContext, REGISTRY_TYPE, id)
         .then((registry) => {
             return new ParticipantRegistry(registry.id, registry.name, securityContext, modelManager, factory, serializer, bnc);
         });
 }
 /**
  * Get a list of all existing participant registries.
  *
  * @protected
  * @param {SecurityContext} securityContext The user's security context.
  * @param {ModelManager} modelManager The ModelManager to use for this participant registry.
  * @param {Factory} factory The factory to use for this participant registry.
  * @param {Serializer} serializer The Serializer to use for this participant registry.
  * @param {BusinessNetworkConnection} bnc BusinessNetworkConnection to use
  * @param {Boolean} [includeSystem] Should system registries be included? (optional, default to false)
  * @return {Promise} A promise that will be resolved with a list of {@link ParticipantRegistry}
  * instances representing the participant registries.
  */
 static getAllParticipantRegistries(securityContext, modelManager, factory, serializer, bnc, includeSystem) {
     Util.securityCheck(securityContext);
     if (!modelManager) {
         throw new Error('modelManager not specified');
     } else if (!factory) {
         throw new Error('factory not specified');
     } else if (!serializer) {
         throw new Error('serializer not specified');
     }
     return Registry.getAllRegistries(securityContext, REGISTRY_TYPE,includeSystem)
         .then((participantRegistries) => {
             return participantRegistries.map((participantRegistry) => {
                 return new ParticipantRegistry(participantRegistry.id, participantRegistry.name, securityContext, modelManager, factory, serializer, bnc);
             });
         });
 }
 /**
  * Get a list of all existing asset registries.
  *
  * @protected
  * @param {SecurityContext} securityContext The user's security context.
  * @param {ModelManager} modelManager The ModelManager to use for this asset registry.
  * @param {Factory} factory The factory to use for this asset registry.
  * @param {Serializer} serializer The Serializer to use for this asset registry.
  * @return {Promise} A promise that will be resolved with a list of {@link AssetRegistry}
  * instances representing the asset registries.
  */
 static getAllAssetRegistries(securityContext, modelManager, factory, serializer) {
     Util.securityCheck(securityContext);
     if (!modelManager) {
         throw new Error('modelManager not specified');
     } else if (!factory) {
         throw new Error('factory not specified');
     } else if (!serializer) {
         throw new Error('serializer not specified');
     }
     return Registry.getAllRegistries(securityContext, REGISTRY_TYPE)
         .then((assetRegistries) => {
             return assetRegistries.map((assetRegistry) => {
                 return new AssetRegistry(assetRegistry.id, assetRegistry.name, securityContext, modelManager, factory, serializer);
             });
         });
 }
 /**
  * Add a new asset registry.
  *
  * @protected
  * @param {SecurityContext} securityContext The user's security context.
  * @param {string} id The unique identifier of the asset registry.
  * @param {string} name The name of the asset registry.
  * @param {ModelManager} modelManager The ModelManager to use for this asset registry.
  * @param {Factory} factory The factory to use for this asset registry.
  * @param {Serializer} serializer The Serializer to use for this asset registry.
  * @return {Promise} A promise that will be resolved with a {@link AssetRegistry}
  * instance representing the new asset registry.
  */
 static addAssetRegistry(securityContext, id, name, modelManager, factory, serializer) {
     Util.securityCheck(securityContext);
     if (!id) {
         throw new Error('id not specified');
     } else if (!name) {
         throw new Error('name not specified');
     } else if (!modelManager) {
         throw new Error('modelManager not specified');
     } else if (!factory) {
         throw new Error('factory not specified');
     } else if (!serializer) {
         throw new Error('serializer not specified');
     }
     return Registry.addRegistry(securityContext, REGISTRY_TYPE, id, name)
         .then(() => {
             return new AssetRegistry(id, name, securityContext, modelManager, factory, serializer);
         });
 }
Exemple #28
0
    /**
     * Removes a list of resources from the registry.
     *
     * @param {(Resource[]|string[])} resources The resources, or the unique identifiers of the resources.
     * @return {Promise} A promise that will be resolved when the resource is
     * added to the registry.
     */
    removeAll(resources) {
        Util.securityCheck(this.securityContext);
        if (!resources) {
            throw new Error('resources not specified');
        }
        let txName = 'Remove'+this.registryType;
        const transaction = this.factory.newTransaction('org.hyperledger.composer.system',txName);
        transaction.resources = [];
        transaction.registryType = this.registryType;
        transaction.registryId = this.id;

        transaction.resourceIds = resources.map((resource) => {
            if (resource instanceof Resource) {
                return resource.getIdentifier();
            } else {
                return resource;
            }
        });
        return this.bnc.submitTransaction(transaction);
    }
Exemple #29
0
    /**
     * Removes a list of resources from the registry.
     *
     * @param {(Resource[]|string[])} resources The resources, or the unique identifiers of the resources.
     * @return {Promise} A promise that will be resolved when the resource is
     * added to the registry.
     */
    removeAll(resources) {
        Util.securityCheck(this.securityContext);
        if (!resources) {
            throw new Error('resources not specified');
        }
        let txName = 'Remove'+this.registryType;
        const transaction = this.factory.newTransaction('org.hyperledger.composer.system',txName);
        transaction.resources = [];
        // target registry is the registry that this the client 'shadow' of
        transaction.targetRegistry = this.factory.newRelationship('org.hyperledger.composer.system',this.registryType+'Registry', this.id);

        transaction.resourceIds = resources.map((resource) => {
            if (resource instanceof Resource) {
                return resource.getIdentifier();
            } else {
                return resource;
            }
        });
        return this.bnc.submitTransaction(transaction);
    }
 /**
  * Issue an identity with the specified user ID and map it to the specified
  * participant.
  * @param {Resource|string} participant The participant, or the fully qualified
  * identifier of the participant. The participant must already exist.
  * @param {string} userID The user ID for the identity.
  * @param {object} [options] Options for the new identity.
  * @param {boolean} [options.issuer] Whether or not the new identity should have
  * permissions to create additional new identities. False by default.
  * @return {Promise} A promise that will be fulfilled when the identity has
  * been added to the specified participant. The promise will be rejected if
  * the participant does not exist, or if the identity is already mapped to
  * another participant.
  */
 issueIdentity(participant, userID, options) {
     const method = 'issueIdentity';
     LOG.entry(method, participant, userID);
     if (!participant) {
         throw new Error('participant not specified');
     } else if (!userID) {
         throw new Error('userID not specified');
     }
     let participantFQI;
     if (participant instanceof Resource) {
         participantFQI = participant.getFullyQualifiedIdentifier();
     } else {
         participantFQI = participant;
     }
     Util.securityCheck(this.securityContext);
     return this.connection.createIdentity(this.securityContext, userID, options)
         .then((identity) => {
             return Util.invokeChainCode(this.securityContext, 'addParticipantIdentity', [participantFQI, userID])
                 .then(() => {
                     LOG.exit(method, identity);
                     return identity;
                 });
         });
 }