Corda - Get State Machine Feed from ServiceHub - corda

CordaRPCOps provides a mechanism to access the state machine feed
ops.stateMachinesFeed().updates.subscribe {
...
}
I want to be able to access the state machine feed from a Corda service. Is there an equivalent to this using ServiceHub or AppServiceHub?

You can't do it at the moment. It requires accessing an instance of StateMachineManager and there is not a way to wire that into a service.

Related

Corda 4 - Querying vault by specific transactionid

We are building a POC using Corda 4 and Springboot web server.
We are currently using the following code to retrieve all the states from the vault via RPC -
val vaultStatesAndRefs = services.proxy.vaultQueryBy<State>().states
val vaultStates = vaultStatesAndRefs.map { it.state.data }
We want - to retrieve a state from the vault via RPC using the transactionId.
Kindly guide in achieving this.
Please note that Corda doesn't guarantee the set of transactions retrieved via any method would remain consistent across future versions of Corda. This is because the future version of Corda would use SGX-encrypted format to exchange transaction chain between nodes. Thus the transactions can only be decrypted in a secure SGX enclave.
Having said that there is no direct API exposed which could be used to obtain state based on transactionId via RPC. The one you could use (internalFindVerifiedTransaction) have been deprecated and would likely be removed in the future versions of Corda.
The way to do this I suppose would be to use flow. You could retrieve the output states based on the transactionId.
SignedTransaction tx = getServiceHub().getValidatedTransactions().getTransaction(
SecureHash.parse(txId));
tx.toLedgerTransaction(getServiceHub()).getOutputStates();
You could then trigger the flow from your client using RPC and get the result from the FlowHandle object returned.
FlowHandle<List<ContractState>> flowHandle =
proxy.startFlowDynamic(GetStateFlow.class, txId);
List<ContractState> list = flowHandle.getReturnValue().get();

Not able to connect to Azure Key Vault when using Service Identity

I am trying to retrieve secrets from Azure Key Vault using Service Identity in an ASPNet 4.6.2 web application. I am using the code as outlined in this article. Locally, things are working fine, though this is because it is using my identity. When I deploy the application to Azure I get an exception when keyVaultClient.GetSecretAsync(keyUrl) is called.
As best as I can tell everything is configured correctly. I created a User assigned identity so it could be reused and made sure that identity had get access to secrets and keys in the KeyVault policy.
The exception is an AzureServiceTokenProviderException. It is verbose and outlines how it tried four methods to authenticate. The information I'm concerned about is when it tries to use Managed Service Identity:
Tried to get token using Managed Service Identity. Access token could
not be acquired. MSI ResponseCode: BadRequest, Response:
I checked application insights and saw that it tried to make the following connection with a 400 result error:
http://127.0.0.1:41340/MSI/token/?resource=https://vault.azure.net&api-version=2017-09-01
There are two things interesting about this:
Why is it trying to connect to a localhost address? This seems wrong.
Could this be getting a 400 back because the resource parameter isn't escaped?
In the MsiAccessTokenProvider source, it only uses that form of an address when the environment variables MSI_ENDPOINT and MSI_SECRET are set. They are not set in application settings, but I can see them in the debug console when I output environment variables.
At this point I don't know what to do. The examples online all make it seem like magic, but if I'm right about the source of the problem then there's some obscure automated setting that needs fixing.
For completeness here is all of my relevant code:
public class ServiceIdentityKeyVaultUtil : IDisposable
{
private readonly AzureServiceTokenProvider azureServiceTokenProvider;
private readonly Uri baseSecretsUri;
private readonly KeyVaultClient keyVaultClient;
public ServiceIdentityKeyVaultUtil(string baseKeyVaultUrl)
{
baseSecretsUri = new Uri(new Uri(baseKeyVaultUrl, UriKind.Absolute), "secrets/");
azureServiceTokenProvider = new AzureServiceTokenProvider();
keyVaultClient = new KeyVaultClient(
new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback));
}
public async Task<string> GetSecretAsync(string key, CancellationToken cancellationToken = new CancellationToken())
{
var keyUrl = new Uri(baseSecretsUri, key).ToString();
try
{
var secret = await keyVaultClient.GetSecretAsync(keyUrl, cancellationToken);
return secret.Value;
}
catch (Exception ex)
{
/** rethrows error with extra details */
}
}
/** IDisposable support */
}
UPDATE #2 (I erased update #1)
I created a completely new app or a new service instance and was able to recreate the error. However, in all instances I was using a User Assigned Identity. If I remove that and use a System Assigned Identity then it works just fine.
I don't know why these would be any different. Anybody have an insight as I would prefer the user assigned one.
One of the key differences of a user assigned identity is that you can assign it to multiple services. It exists as a separate asset in azure whereas a system identity is bound to the life cycle of the service to which it is paired.
From the docs:
A system-assigned managed identity is enabled directly on an Azure service instance. When the identity is enabled, Azure creates an identity for the instance in the Azure AD tenant that's trusted by the subscription of the instance. After the identity is created, the credentials are provisioned onto the instance. The lifecycle of a system-assigned identity is directly tied to the Azure service instance that it's enabled on. If the instance is deleted, Azure automatically cleans up the credentials and the identity in Azure AD.
A user-assigned managed identity is created as a standalone Azure resource. Through a create process, Azure creates an identity in the Azure AD tenant that's trusted by the subscription in use. After the identity is created, the identity can be assigned to one or more Azure service instances. The lifecycle of a user-assigned identity is managed separately from the lifecycle of the Azure service instances to which it's assigned.
User assigned identities are still in preview for App Services. See the documentation here. It may still be in private preview (i.e. Microsoft has to explicitly enable it on your subscription), it may not be available in the region you have selected, or it could be a defect.
To use a user-assigned identity, the HTTP call to get a token must include the identity's id.
Otherwise it will attempt to use a system-assigned identity.
Why is it trying to connect to a localhost address? This seems wrong.
Because the MSI endpoint is local to App Service, only accessible from within the instance.
Could this be getting a 400 back because the resource parameter isn't escaped?
Yes, but I don't think that was the reason here.
In the MsiAccessTokenProvider source, it only uses that form of an address when the environment variables MSI_ENDPOINT and MSI_SECRET are set. They are not set in application settings, but I can see them in the debug console when I output environment variables.
These are added by App Service invisibly, not added to app settings.
As for how to use the user-assigned identity,
I couldn't see a way to do that with the AppAuthentication library.
You could make the HTTP call manually in Azure: https://learn.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/how-to-use-vm-token#get-a-token-using-http.
Then you gotta take care of caching yourself though!
Managed identity endpoints can't handle a lot of queries at one time :)

Is there a way to update the ESB ALL.Exceptions send port to use the WCF.SQL adapter?

The ESB Toolkit 2.1 has the ALL.Exceptions send port using the old SQL adapter.
But the BizTalk Health Monitor reports ...
Non WCF SQL adapter used in some Send Ports
Prefer to use the WCF one which is more performant !
Is there any way to update to the WCF.SQL adapter?
Yes this is possible. It will however include some custom development.
You will need to create a map between the FaultMessage schema (in Microsoft.Practices.ESB.ExceptionHandling.Schemas.Reporting.dll) and the usp_insert_Fault schema (created using the Consume Adapter Service in Visual Studio, from the usp_insert_Fault SP in the EsbExceptionDb database), as the old SQL Adapter uses a different schema layout to execute a stored procedure.
Required Steps:
Change the Transport Type of the ALL.Exceptions port to WCF-SQL
Set the Address: mssql://SQLServer:1433/SQLInstance/EsbExceptionDb?
Set the Action: TypedProcedure/dbo/usp_insert_Fault
Change the ESBFaultProcessor Send Pipeline to use your custom map in the ESB Transform Component
EDIT: Note: The solution described here does not include the Message and its Context like the map with the SQL Adapter does. To accomplish this, you should make use of Composite Operation to insert into multiple tables in one transaction.

Bluez profile and device connect callback

I am developing custom profile with GATT service server (acting as peripheral). I define profile via structure btd_profile, and there are function pointers to adapter_probe, device_probe, connect ...
When bluez deamon started adapter_probe is called and there I create GATT service.
After I connect to server via gatttool I see my services and characteristics, but device_probe function is not called. How can I then get nofication about device connection/disconnection, when some device is connected/disconnected to my server? And how works this device_probe and connect callback functions? When are they called then?
Thanks for help
While registering profile if we pass Role as "server" then only server related function will be called i.e adapter_probe etc. if we pass Role as "client" then device_probe will be called.
By default bluez enables both the thing but if you pass role as "server" or "client" then it will change accordingly. While registering profile pass role as NULL then both will be enabled

Weblogic Stateless Session methods invoked from different cluster member servers

My environment is Weblogic 10.3.5 on Solaris box. EJB is version 3 and there is anotation in the Bean class. Sorry for the confusion as the code is new to me and they also have deployment descriptor to generate ejb2 client code for another client to call, so it's not straigtforward.
I have a stateless session bean deployed to a cluster which has 2 server members say they are member1 and member2.
The session bean is deployed as clusterable as this is in the anotation:
homeIsClusterable = Constants.Bool.TRUE
This is how my Stand alone Java client lookup and call the EJB methods:
private void testBean(){
bean.methodA();
bean.methodB();
}
In the provider URL I ONLY specify the provider URL to ONE server member:
env.put(Context.PROVIDER_URL, "t3://member1:7005");
env.lookup("remote#the.bean.qulified.remoteinterface")
The Jndi name above is using the "mapped name + qualified remote interface class name", the mapped name is defined in the anotation.
Now the problem is, I found out, bean.methodA() got invoked in member1, and methodB() got invoked on member2, I found this from the logs of each server member. So it's always like this, member1 log will only show debug information from methodA, and member2 will only show debug information from methodB.
So here is my conceptual question - is this possible at all ? Are the above 2 methods supposed to be called on member1 only ? I know it's possible when you lookup through home interface you could possibly get a bean from either server, but in this case the ejb3 lookup is not going through the home interface(like in ejb2 we get a home and then call create method) but directly getting a remote object.
This caused issue as our methodB has a dependancy on methodA(methodA is doing some cleanup job, and then method re-initialize the cache), we need to do this on each cluster member.
This is just extra info but please focus on the above question from a concept perspective.
From the documentation:
When home-is-clusterable is True, the EJB can be deployed from multiple WebLogic Servers in a cluster. Calls to the home stub are load-balanced between the servers on which this bean is deployed, and if a server hosting the bean is unreachable, the call automatically fails over to another server hosting the bean.
I believe this is the case even when you explicitly only connect to a single member. This has some pretty good info in the Replica-Aware Home section:
http://www.informit.com/articles/article.aspx?p=101737&seqNum=8
It's more or less the whole point of clustering... a cluster appears as if it's a single server instance to a client.

Resources