Why typecasting is required in below code? - casting

I have a snipped as mentioned below for step processing.
#Bean
#JobScope
public Step readStep(StepBuilderFactory sbf,
ItemReader reader,ItemWriter writer, TaskExecutor taskExecutor,
RefFileReaderComponentFactory componentFactory, String file){
final Step step = sbf.get(file)
.chunk(100)
.reader(reader)
.faultTolerant()
.skipPolicy(new SkipPolicy()) //dummy skip policy for representation purpose
.writer(writer)
.faultTolerant()
.skipPolicy(new SkipPolicy())
.listener(new NewStepExecutionListener()) //This dummy listener is implementation of the StepExecutionListener
//.listener(new NewItemWrtieListener) //This dummy listener is implementation of the ItemWriteListener
.taskExecutor(taskExecutor)
.build();
return step;
}
But the above code throws compile time error - The method taskExecutor(TaskExecutor) is undefined for the type StepBuilderHelper.
Interestingly, this error is only shown when I put NewStepExecutionListener listener but if I comment it out and uncomment NewItemWrtieListener then it works fine.
Post typecasting, code looks like this:
#Bean
#JobScope
public Step readStep(StepBuilderFactory sbf,
ItemReader reader,ItemWriter writer, TaskExecutor taskExecutor,
RefFileReaderComponentFactory componentFactory, String file){
final Step step = ((AbstractTaskletStepBuilder<SimpleStepBuilder<Object, Object>>) sbf.get(file)
.chunk(100)
.reader(reader)
.faultTolerant()
.skipPolicy(new SkipPolicy()) //dummy skip policy for representation purpose
.writer(writer)
.faultTolerant()
.skipPolicy(new SkipPolicy())
.listener(new NewStepExecutionListener())) //This dummy listener is implementation of the StepExecutionListener
//.listener(new NewItemWrtieListener) //This dummy listener is implementation of the ItemWriteListener
.taskExecutor(taskExecutor)
.build();
return step;
}
I tried finding reason behind this but cannot understand why a change in Listener Type would require typecasting for step processing.
Can someone explain why ?

The order of method calls matters because some methods may change the builder type. For example, when you call faultTolerant(), the builder type is changed from SimpleStepBuilder to FaultTolerantStepBuilder, adding new methods to configure fault tolerance (skip, retry, etc).
So you need to check the order and return type of each method and make sure the builder type returned defines the next method you want to call.

Related

How are aggregates instantiated to test other aggregates with?

Suppose I have an aggregate that, for some operation, requires the existence of another aggregate. Let's assume I have a car and a garage. There might be a command called ParkInGarage that looks like this:
public class ParkInGarage {
#TargetAggregateIdentifier
public final UUID carId;
public final Garage garage;
//... constructor omitted
}
I've read that to validate the existence of an aggregate, it is good practice to use the loaded aggregate in commands since that already implies its existence (as opposed to passing a garageId).
Now when unit-testing the Car using Axon's fixtures, I can not simply instantiate my Garage by saying new Garage(buildGarageCmd). It will say:
java.lang.IllegalStateException: Cannot request current Scope if none is active
Because no infrastructure was set up.
How would I test such a case, or should I design the aggregate differently?
Abstracted, real-world example
The aggregate root I am working with may have a reference to itself to form a tree-structure of said aggregate root. Let's call it Node.
#Aggregate
public class Node {
private Node parentNode;
}
Upon creation, I can pass an Optional<Node> as parent, or set the parent at a later time using a separate command. Whether the parent should be defined as instance or by ID is part of the question.
public class AttachNodeCmd {
#TargetAggregateIdentifier
public final UUID nodeId;
public final Optional<Node> parentNode;
}
In the command handler, I need to check if attaching the node to given parent would introduce a cycle (the structure is supposed to be a tree, not a common graph).
#CommandHandler
public Node(AttachNodeCmd command) {
if (command.parentNode.isPresent()) {
Node currentNode = command.parentNode.get();
while (currentNode != null) {
if (currentNode.equals(this)) throw new RecursionException();
currentNode = currentNode.parentNode.orElse(null);
}
}
//Accept the command by applying() an Event
}
At some point, the parent needs to be instantiated to perform those checks. This could either be done by supplying the aggregate instance in the command (discouraged), or by supplying a Repository<Node> and the nodeId to the command handler, which is the aggregate itself and also discouraged. Currently I don't see a right way to do this and further down the road a way to test it.
I wouldn't put AR instances in commands. Command schemas should be stable and easy to serialize/reserialize as they are message contracts.
What you could do instead is resolving the dependency in the command handler.
//ParkInGarage command handler
Garage garage = garageRepository.garageOfId(command.garageId);
Car car = carRepository.carOfId(command.carId);
car.parkIn(garage);
I don't know Axon Framework at all, but that should be relatively easy to test now.
I think #plalx is putting you on the right track. Commands are part of your API/Message Contract and exposing the Aggregate in there isn't that great an idea.
Additionally I'd like to note that the AggregateFixtures in Axon are there to test a single Aggregate, not the coordination of operations between Aggregates.
Coordination between aggregates/bounded contexts is typically where you see sagas coming in to play. Now to be honest, I am a bit in doubt whether this use case justifies a Saga, but I could imagine that if the ParkCarInGarageCommand fails because the Garage Aggregate is full (for example), that you need to instruct the Car Aggregate through another command telling it it's a no-go. The Saga set up in Axon might help you with this as you can easily catch (1) the exception from handling the command or (2) handle the event notifying the operation wasn't successful.

Javassist - addMethod that returns an Object[][]

My goal is to create in runtime an additional method inside a specific .class file.
A method that returns an Object[][].
For that I found an amazing framework called - Javassist, a bytecode modifier framework, which helps you modify your compiled class in runtime in order to add more bytecode that represents a new method.
Managed to create a void method, and a method that returns a string but, for some reason, I'm unable to generate a method that returns an array or a matrix.
So far I've been struggling to find the proper way of creating such method, and got a continuous CannotCompileException.
Code:
private static CtMethod generateMethod1(CtClass declaringClass)
throws CannotCompileException {
StringBuffer sb = new StringBuffer();
sb.append("public ").append(Object[][].class.getName()).append(" ").append("method1").append("(){")
.append("return new").append(Object[][].class.getName()).append("{{ 1,2 }}").append("; }");
System.out.println(sb.toString());
return CtMethod.make(sb.toString(), declaringClass);
}
The toString of the generated method above is:
public [[Ljava.lang.Object; method1(){return [[Ljava.lang.Object;{{ 1,2 }}; }
Probably fails due to false jni syntax.
Well, solved it by just replacing the Object[][].class.getName() with Object[][] literally...

getting InvalidUseOfMatchersException in a proper use of matchers

Everything sounds correct but I get org.mockito.exceptions.misusing.InvalidUseOfMatchersException, when I try to mock a protected method.How Can I solve it ?
private Service service;
private System system;
#BeforeMethod
public void setupMocks() throws Exception {
service = powerMock.mock(Service.class);
system = powerMock.mock(System.class);
}
public void sample_Test() {
PowerMockito.doReturn(system).when(service, "getValidatedDto",
Matchers.any(Long.class), Matchers.any(Date.class));
// some code
}
I suspect you are seeing this exception:
org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
Invalid use of argument matchers!
4 matchers expected, 2 recorded:
With this additional context:
This exception may occur if matchers are combined with raw values:
//incorrect:
someMethod(anyObject(), "raw String");
If so, then this is because you are mixing parameters in the form of matchers (Matchers.any(Long.class), Matchers.any(Date.class)) with parameters in the form of raw values (service, "getValidatedDto").
The signature of the method under test is unclear to me but I think it might be something like
System getValidatedDto(Long aLong, Date aDate);
If so, then the correct invocation would be:
PowerMockito.doReturn(system).when(service).getValidatedDto(
Matchers.any(Long.class), Matchers.any(Date.class));

Setting up setCharging for Linea Pro device in Swift

I want to set up the Linea Pro to charge the phone if the phone's battery gets low and I'm having a tough time mainly because all the examples are shown in objective-C still and not in Swift.
The manual says:
#param enabled TRUE to enable charging, FALSE to disable/stop it
#param error pointer to NSError object, where error information is stored in case function fails. You can pass nil if you don't want that information
#return TRUE if function succeeded, FALSE otherwise
*/
and the code provided is the following:
-(BOOL)setCharging:(BOOL)enabled error:(NSError **)error;
So in Swift I first tried this:
self.scanner.setCharging = true
but that gives me the following error:
Cannot assign to property: 'setCharging' is a method
So I tried this:
self.scanner.setCharging(true)
which gives me this error:
Call can throw, but it is not marked with 'try' and the error is not handled
Interesting because apparently I have to build it in a function called "setCharging" I think, but I have no idea what and how it wants me to set up the try and catch to, and quite frankly where am I opposed to get this information from?
I think it should be along these lines or something, but I'm not clear on the specifics :
func setCharging(_ enabled: Bool) throws -> Bool {
do {
try
//something goes here I'm not sure what
} catch {
//and then maybe something here on that to do with error
print("some error")
}
}
The answer was provided to me by the manufacturer. It is unnecessary to create a function with the same name as the API, APIs can be called anywhere in the code with the exception of handling error. So in this case I just have this directly in my code not in a function and it just works. (Since I have my scanner.connect code inside a viewWillAppear block, the code to start charging was too early to be called in there, so I placed it inside of a viewDidAppear block).
The following is the code:
do{
try self.scanner.setCharging(true)
}catch let error as NSError{
NSLog("Operation \(error as Error)")
}

Mockito - Invalid use of argument matchers

I have Junit test that is testing jms message sending. I am using Spring jmsTemplate to to do this. Here I as in the following code I want to check whether the JMS template has called send message regardless what is it in the values of actuall parameters that are passed.
my publisher method the uses the jmsTemplate to send method looks like following inside..
jmsTemplate.send(jmsQueueProperties.getProperty(key), new MessageCreator()
{
public Message createMessage(Session session) throws JMSException
{
ObjectMessage obj = session.createObjectMessage(dialogueServiceResponse);
return obj;
}
});
in My tests..
JmsTemplate mockTemplate = Mockito.mock(JmsTemplate.class);
...
publisher.publishServiceMessage(response);
....
Mockito.verify(mockTemplate,
Mockito.times(1)).send("appointment.queue",
Mockito.any(MessageCreator.class));
But when in the execution i get
org.mockito.exceptions.misusing.InvalidUseOfMatchersException: Invalid use of argument matchers!
....
Cause is due to Mockito.any(MessageCreator.class) , but isn't there a way to test my send method is getting executed without creating an actual object in the MessageCreator.
Update
And is there a way to check my session.createObjectMessage(dialogueServiceResponse) is getting called as well
I think the rest of the message tells you what the problem is. When you use an argument matcher for one of the arguments, all the other arguments must also use an argument matcher:
Mockito.verify(mockTemplate, Mockito.times(1)).send(
Mockito.eq("appointment.queue"),
Mockito.any(MessageCreator.class));
For future readers. This will save you a lot of time.
We cannot use argument matcher and primitive/raw values together.
when(fooService.getResult("string",any(MyClass.class))).thenReturn(1); // will give error
when(fooService.getResult(anyString(),any(MyClass.class))).thenReturn(1); // correct
I think you cannot use argument matchers outside stubbing. I also got the same error but when I return, I had to do new string() instead of Mockito.anyString() and the error goes away.
Example:
Mockito.when(mockedBean.mockedMethod(Mockito.anyString(),
Mockito.anyInt(),
Mockito.anyInt(),
Mockito.anyInt(),
Mockito.anyBoolean())).thenReturn(new String());
I can see that this question is about Java code, but I will share this because we use Mockito in Scala as well.
I had this exception thrown from the following code that mocks Play.api configurations
"Configurations Service" should {
"return all dataset configurations" in {
val configs = mock[Configuration]
val testData = Seq("SOME VALUE")
val loader = any[ConfigLoader[Seq[String]]]
when(configs.get[Seq[String]](any[String])).thenReturn(testData) // EXCEPTIONN HERE !
val configuration: ConfigurationsService = new ConfigurationsService(configs)
assert(configuration.getSupportedDatasets() == testData)
}
}
In Scala methods can have Implicit parameters configs.get method has one explicit param and an Implicit one I passed a mock object and when an exception was thrown I was wondering what is going on as I didn't MIX params and mocks, it turned out that I had to pass mocks to implicit parameters as well, and this solved the problem.
val loader = any[ConfigLoader[Seq[String]]] // configs.get has one implicit parameter that accepts ConfigLoader[Seq[String]]
when(configs.get[Seq[String]](any[String])(loader)).thenReturn(testData)
I was seeing this error about a mismatched # of arguments, despite having the correct number...
I realized this was because method being stubbed was static. When I converted it to non-static, it worked as expected.