CURRENT_RPC_CONTEXT.get() must not be null - corda

Written the Integration test case for testing Corda Flows through API class as:
val api=ProjectApi(mockNode1.rpcOps)
val message = "some input message"
val resp: Response=api.publishSSI(message)
assertEquals(resp.status, 201,"Failed to publish SSI")
But getting CURRENT_RPC_CONTEXT.get() must not be null exception while starting corda flow inside api.publishSSI() method.
what could be the cause?

You need to use the RPC client API to connect to the node. You can find more details here: https://docs.corda.net/tutorial-clientrpc-api.html

You can't test the API by manually constructing it in this way. When the API is set up, some additional context is passed in, which is lacking here.

Related

Authorization failed for URI for DBMS_CLOUD.send_request

I am facing issue with running DBMS_CLOUD.send_request to invoke a function via Autonomous DB.In the credential I am giving the right API signing key but it doesn’t seem to work and keeps trowing “Authorization failed for URI” not sure what am I missing as I am able to invoke the same function with the same credentials using SDK and same invoke endpoint. Also, in the private_key parameter of DBMS_CLOUD.CREATE_CREDENTIAL i am providing the private key content without the line breaks and excluding the BEGIN and END RSA PRIVATE KEY, would like to know if this is the right way to provide the key content.
Also, Please note that my Autonomous DB workload type is "APEX" and I have given EXECUTE GRANT on DBMS_CLOUD to my APEX Principal using ADMIN
Is your private key protected with a passphrase ...? AFAIK these are not supported, so you might work without a passphrase.
Also, you might try creating an APEX Web Credential (Use the OCI type), and then use APEX_WEB_SERVICE.MAKE_REST_REQUEST to call the REST API. This would at least help to verify the credential.

Confused about health checking protocol

I have read below doc, source code and issue:
https://github.com/grpc/grpc/blob/master/doc/health-checking.md
https://github.com/grpc/grpc-node/blob/master/packages/grpc-health-check/test/health_test.js
https://github.com/grpc/grpc/issues/10428
I provide an example and try to explain:
// Import package
let health = require('grpc-health-check');
// Define service status map. Key is the service name, value is the corresponding status.
// By convention, the empty string "" key represents that status of the entire server.
const statusMap = {
"ServiceFoo": proto.grpc.health.v1.HealthCheckResponse.ServingStatus.SERVING,
"ServiceBar": proto.grpc.health.v1.HealthCheckResponse.ServingStatus.NOT_SERVING,
"": proto.grpc.health.v1.HealthCheckResponse.ServingStatus.NOT_SERVING,
};
// Construct the service implementation
let healthImpl = new health.Implementation(statusMap);
// Add the service and implementation to your pre-existing gRPC-node server
server.addService(health.service, healthImpl);
I am not clear about the following points:
Does the service name in statusMap need to be the same as the service name in the protocol buffers file? Or the service name can be arbitrarily specified. If so, how does the service name map to the service defined in the protocol buffers?
From the health checking protocol:
The server should register all the services manually and set the individual status
Why do we need to register manually? If the service code can be generated, why doesn't grpc help us automatically register the service name in statusMap? (Imagine setting the status of 100 services one by one)
The service status is hard code and cannot be changed at application runtime. If my service is unavailable at runtime for some reason such as misconfiguration, downstream service is not available, but the status of the service is always serving(because it's hard code), if so, what is the meaning of the health check?
For RESTful API, we can provide a /health-check or /ping API to check that the entire server is running normally.
Regarding the service names, the first linked document says this:
The suggested format of service name is package_names.ServiceName, such as grpc.health.v1.Health.
This does correspond to the package names and service name defined in the Protobuf definition.
The services need to be registered "manually" because the status is determined at the application level, which the grpc library does not know about, and a registered service name is only meaningful along with the corresponding status. In addition, the naming format mentioned above is just a convention; the health check service user is not constrained to it, and the actual services on the server are not constrained to use the standard /package_names.ServiceName/MethodName method naming scheme either.
Regarding the third point, the service status should not be hardcoded, and can be changed at runtime. The HealthImplementation class used in the code in the question has a setStatus method that can be used to update the status.
Also, as mentioned in a comment in the code in the question,
By convention, the empty string "" key represents that status of the entire server.
That can be used as the equivalent of the /health-check or /ping REST APIs.

How to create/simulate creation of deserialization exception when using schema registry ( in addition to brokers and zookeepers)

We are using spring-kafka-2.2.7.RELEASE to produce and consume avro messages and using schema registry for schema validation with 'FORWARD_TRANSITIVE' as the compatibility type. Now, I'm trying to use 'ErrorHandlingDeserializer2 ' from spring-kafka to handle the exception/error when a deserializer fails to deserialize a message. Now I'm trying to write a component test to test this configuration. My component test expected to have below steps.
Spin up a local kafka cluster using docker containers
Send an avro message (using KafkaTemplate) with invalid schema to re-create/simulate the deserialization exception onto a test topic
Now what's happening is, since we have schema registry in place, if i send a message with new schema (invalid schema) it's validating the schema as per the compatibility type setting we have and not letting me producer the message onto kafka by throwing an exception at the producer level itself.
Now my question is, In this scenario, how can I create/simulate the creation of deserialization exception to test my configuration. Please suggest.
Note:- I don't want to disable/stop schema registry because that wouldn't simulate our prod setup.

Why set up Serialization Context in Corda off node?

Recently, when I wanted to sign something with a certificate outside node, I got the below exceptions:
Caused by: java.lang.IllegalStateException: Expected exactly 1 of
{nodeSerializationEnv, globalSerializationEnv,
contextSerializationEnv, inheritableContextSerializationEnv} but got:
{}
https://github.com/corda/corda/blob/671a9d232cf1f29dbce4432bc91096ffd098a91c/core/src/main/kotlin/net/corda/core/serialization/internal/SerializationEnvironment.kt#L91
On debugging, I found it's first serialised and then signed. So, I had to set up the serialisation context to get it serialised and signed.
I have a limited understanding of why is it required. I understand that different contexts are required for P2P and RPC calls, but I'm not entirely sure can someone please fill me in with some background.
The internal library you are using to sign the certificate requires the certificate to be serialised first. In turn, this requires you to specify a serialisation context. A serialisation contexts defines how serialisation is performed in various situations, such as P2P, client-side RPC, server-side RPC, storage and checkpointing.
Note that these serialisation contexts are set for you automatically when running a node or a suite of node tests. You are only encountering this issue because you are using an internal library outside the context where it is expected to be used.
In your case, you should probably use globalSerializationEnv, which is the serialisation environment used for mock nodes and nodes created using the node driver. nodeSerializationEnv is used by the node itself, and contextSerializationEnv and inheritableContextSerializationEnv are used for various platform tests.
For educational purposes, it can be helpful to look at how the node sets up its serialisation framwork when it starts up (see https://github.com/corda/corda/blob/release-V3/node/src/main/kotlin/net/corda/node/internal/Node.kt):
nodeSerializationEnv = SerializationEnvironmentImpl(
SerializationFactoryImpl().apply {
registerScheme(KryoServerSerializationScheme())
registerScheme(AMQPServerSerializationScheme(cordappLoader.cordapps))
},
p2pContext = AMQP_P2P_CONTEXT.withClassLoader(classloader),
rpcServerContext = KRYO_RPC_SERVER_CONTEXT.withClassLoader(classloader),
storageContext = AMQP_STORAGE_CONTEXT.withClassLoader(classloader),
checkpointContext = KRYO_CHECKPOINT_CONTEXT.withClassLoader(classloader))

Any way to programmatically set BizTalk Message Context property?

Is there any way to set BTS.RetryCount or WCF.Action not in a Message Assignment Shape?
I have a special orchestration for dynamic message sending, its parameters are Message and ServiceName and it has a dynamic port which is easily configured with UDDI service. The thing I can't do in that orchestrations is I can't set WCF.Action for a message, I should create a new one because it's prohibited in BizTalk to modify a message anywhere outside a Construct shape. So it's very inconvenient for me to set this property every time I want to send a message, I thought I would be able to do all the UDDI & routing stuff in a one dedicated orchestration which I later can just call with parameters.
Can you not modify those properties in a pipeline component? You can then execute the pipeline inside the orchestration.
UPDATE
What I mean is you can create a pipeline component to set the context properties of the message as it passes through. Then you can create a pipeline which includes this component and execute it inside your orchestration by passing a message through it. This message will then have those context properties set.
Could you not create a new message in an assignment shape, of the same type as the message you need to modify
NewMessage = OldMessageWithTheDynamicPropertiesSet;
and copy over all the properties
NewMessage(*)* = OldMessageWithTheDynamicPropertiesSet(*);
and then set the properties you need to set. You can also set the WCF action that way.
NewMessage(WCF.Action)=....
NewMessage(BTS.REtryCount)= 666
And then you send this new message out.

Resources