I am having this error when I am calling my custom flow through my RPCClient.
#PostMapping(value="/flows/issue")
private fun issuance(#RequestBody note : Money){
val matchingParties = proxy.partiesFromName(note.owner, false)
if(matchingParties.size != 1)
throw IllegalArgumentException("Enter a valid Party name")
val recipient = matchingParties.single()
proxy.startFlow(::IssueMoney, note.currency, note.amount, recipient)
}
My custom flow is another class with the classpath net.corda.server.flows . I have annotated it as #CordaSerializable and added the "-parameters" in the java compiler.
The error at the console at my node was
Serialization failed direction="Deserialize", type="java.lang.Class", msg="Could not instantiate net.corda.server.flows.IssueMoney - not on the classpath", corda ClassChain="java.util.List<*> -> net.corda.server.flows.IssueMoney"
The error at my webserver was
java.io.NotSerializableException: net.corda.server.flows.IssueMoney was not found by the node, check the Node containing the CorDapp that implements net.corda.server.flows.IssueMoney is loaded and on the Classpath
CordaSerializable is an annotation that you put on a class that gets sent/received by your flow; for instance you have some custom class MyClass that your initiator sends to the responder; you mark MyClass with #CordaSerializable; this way when your initiator calls send, it gets checkpointed (i.e. all its data is written to disk), part of that data is your MyClass which with that annotation allows Corda to serialize it (when flow is checkpointed) and deserialize (when the flows resumes). So in summary, remove the annotation from the flow.
I assume that the error happened because somewhere in your flow you're using java.util.List (that's what shows in your error message); List is an interface, so Corda won't know how to serialize/deserialize it, instead you have to use an implementation of the List interface like ArrayList or LinkedList.
Related
I was reading a book about Learning ASP.NET Core API when I run to a part saying:
We create a private read-only field _repository that will be assigned
the injected MockCommandAPIRepo object in our constructor and used
throughout the rest of our code.
Here is some text I thought you'd better have:
Then there are some explanations related to the picture above:
Add the new using statement to reference ICommandAPIRepo.
We create a private read-only field _repository that will be assigned the injected MockCommandAPIRepo object in our constructor
and used throughout the rest of our code.
The Class constructor will be called when we want to make use of our Controller.
At the point when the constructor is called, the DI system will spring into action and inject the required dependency when we ask for
an instance of ICommandAPIRepo. This is Constructor Dependency
Injection.
We assign the injected dependency (in this case MockCommandAPIRepo) to our private field (see point 1).
And that’s pretty much it! We can then use _repository to make use of our
concrete implementation class, in this case MockCommandAPIRepo. As
I’ve stated earlier, we’ll reuse this pattern multiple times through
the rest of the tutorial; you’ll also see it everywhere in code in
other projects – take note.
Now, According to the highlighted part above in number 2, I got a little confused!
I've heard of "to be assigned by some value" before, but here, it is saying that:
that will be assigned the injected MockCommandAPIRepo object in our constructor
and as you see, there is no "by" added before the injected MockCommandAPIRepo object....
So, I have a question now. What does it mean by the highlighted part above in number 2?
Does it mean the same when we add "by" in the sentence? or not?
This is about dependency injection in Asp.Net Core. After we register service to the IOC Container, How to use it in our controller? We can inject them in controller via Constructor Injection. Once we register a service, the IoC container automatically performs constructor injection if a service type is included as a parameter in a constructor. In your question, An IoC container will automatically pass an instance of ICommandAPIRepo(MockCommandAPIRepo) to the constructor of CommandsController. Now we can use MockCommandAPIRepo in the constructor. But it can only be used in constructor, How can we use it in other method in CommandsController? Here we use:
private readonly ICommandAPIRepo _repository;
to create a global variable in CommandsController, Then in constructor, We use:
_repository = repository
assign the value of repository to _repository. Now _repository and repository has the same value, Because _repository is a global variable, So We can use _repository in other method in CommandsController. The whole process of dependency injection is done.
For example, from Scout Form execStore() method, right before executing any server services, i like to get the HttpSession and eventually get custom data from its attributes store.
As mentioned in the comments, Eclipse Scout separates the UI Layer (the HTML rendering - or the Swing client in older versions) from the client model. And while the UI Layer knows about the HttpSession, the client model, in which your form lives, does not.
You can however put the relevant attributes on the ServerSession (backend) and synchronize them to the ClientSession (model) or vice versa - depending on where your attributes come from.
This sketch should get you started:
In your Client/ServerSession class (extends AbstractServerSession) add a getter and setter.
If - and only if - you need to synchronize the values to the client implement the getter / setter like this (example for an Integer property):
public Integer getMyProperty() {
return getSharedContextVariable("myProperty", Integer.class);
}
public void setMyProperty(Integer newValue) {
setSharedContextVariable("myProperty", Integer.class, newValue);
}
You'll need to teach the application to transfer the data to your Client or ServerSession.
If your data comes from the backend side (e.g. from database): Your best guess is to override the default implementation of org.eclipse.scout.rt.server.context.HttpServerRunContextProducer.
Create a subclass of this class in your .server-part, and add the #Replace annotation. Your best place to implement it is likely in the method public IServerSession getOrCreateScoutSession(HttpServletRequest req, ServerRunContext serverRunContextForSessionStart, String scoutSessionId)
If your data comes from the UI side (e.g. passed by SAML):
This is more complicated and I have only hints where to start looking: org.eclipse.scout.rt.ui.html.UiSession.createAndStartClientSession(Locale, UserAgent, Map<String, String>) on how the ClientSession is created and if you can access your data at this location.
Apologies in advance for the basic question and please ignore the mix of kotlin/java!
I’ve spun up a very simple example building upon the example-cordapp and I wish to demonstrate the ability to override flows to put in some additional node operator specific logic from another cordapp. For example: a certain node owner may not want to do business under certain scenarios, so add in some additional checks prior to the initiating or responder signing phase.
I’ve successfully overridden the responder flow fine and I can see it being executed on the node with the extending cordapp however I’m not having much luck with initiator flow.
From reading here: https://www.corda.net/blog/extending-and-overriding-flows-from-external-cordapps/ it suggests that I would have to have my api/rpc client directly invoke the extended version directly, however I was hoping it would work similar to the responder flow and automatically pick it up based on the hops.
Base flow:
public class BondFlow {
#InitiatingFlow
#StartableByRPC
public static class Initiator extends FlowLogic<SignedTransaction> {
// Stuff
public Initiator(int bondValue, Party obligee, Party principal) {
this.bondValue = bondValue;
this.obligee = obligee;
this.principal = principal;
}
// More Stuff
Overridden (in a separate Cordapp):
public class MyCustomFlow {
#StartableByRPC
public static class Initiator extends BondFlow.Initiator {
// Stuff
public Initiator(int bondValue, Party obligee, Party principal) {
super(bondValue, obligee, principal);
}
// More stuff
My RPC client just calls the Initiator as you may expect:
val signedTx = proxy.startTrackedFlow(::Initiator, bondValue, obligeeParty, principalParty).returnValue.getOrThrow()
I could change my api/rpc client call to allow configuration of the initiator flow to be called but I'd like to understand if there is an alternative.
Many Thanks
I would honestly suggest that you give flows different names for each different flows. We had named a couple of our flows simple as initiator and responder out of the simplicity purpose.
However, it is still fine to have same names cross different CorDapps. You just need to call their full name including the package name.
Run flow list in your node shell and you should see it.
For example:
our signature YoFlow in the yo-Cordapp has a full name of net.corda.examples.yo.flows.YoFlow,
but in single cordapp scenario, you can just call it by run flow start YoFlow
My understanding of the #KafkaListener is that messages are consumed by matching the listener method's argument type with the message type.
What happens to messages that do not have a matching listener?
It's not clear what you mean. What leads you to believe that?
#KafkaListener on a Method means there is a consumer (listener container) for each method so all methods get all records (unless they are in the same consumer group or you assign partitions manually).
#KafkaListener on a Class means you have to annotate multiple methods with #KafkaHandler and the framework will find which handler method to invoke based on the deserialized payload; the value deserializer must be able to deserialize the expected multiple types.
You can designate exactly one #KafkaHandler as the default handler (which is invoked if there is no match) - usually with an Object parameter.
If there is no match and no default handler method, the record goes to the configured ErrorHandler.
The default error handler logs the failure, but you can add your own to do whatever you want.
Using Unity, I am trying to register the following interface to a model:
public interface IGenericRepository<T> : IDisposable where T : class
Is this the correct way to register this within Unity's Bootstrapper?
container.RegisterType<IGenericRepository<TypeBasedOverride>, GenericRepository<TypeBasedOverride>>(new HierarchicalLifetimeManager());
I think you want to register that interface for any concrete T.
If so, you need to register the generic types as open generic types (without the type arguments). Check this msdn entry.
In your example:
container.RegisterType(typeof(IGenericRepository<>), typeof(GenericRepository<>), new HierarchicalLifetimeManager());
This way when you request an instance of IGenericRepository<SomeClass>, Unity will provide you with an instance of GenericRepository<SomeClass>, no matter the concrete type of SomeClass.