for a simple microservices, to migrate from java 8 to java 17, could be as simple as 1) upgrading jdk 2) upgrade necessary libraries
however, for a monolithic application upgrade, it would require a lot of effort to fix the library compatibility issue.
At the moment, the application I am trying to migrate has a lot of code smell and anti patterns, for example, there are circular definition in the spring XML definition:
the service bean has a reference to a schedler bean, which circular back for a reference to the service bean.
the fix/hack for this problem is to force spring to allow circular reference (due to the implementation, lazy init is also not working)
similarly, due to the implementation, bean definition overriding has also to be enaled
import the spring stub runner and wiremock library
2. config the sub mode (local or remote), and where/what to download if remote
3. Spring Stub runner would then download the stub, and start the wiremock server with the contract. The test class could then use the wiremock server for testing:
there is a need to add in further logging, to assist the developer for troubleshooting an API call.
however, with such a simple logging statement, it broke the pipeline because a bug in the implementation with easyMock.
the new log line:
if the response is not null, log the status and header. otherwise log as null.
above small code changes however broke the CI/CD. after some investigation, it is found the original developer who coded the unit test, which supposed to protect the application, would break if the status method is not called 2 (a magic number) times.
The fix is, it really doesn’t need to hard code the times the method is called, instead it should use andStubReturn instead of andReturn method.
the fix
the problem with easyMock is (beside the clear no-go with replay/replayAll), the default andReturn method expect times of the call, which default is 1. the developer when implement the unit test at the time, has called the getStatus method 2 times, hence hardCode it with 2. this will break if any developer or use case, that the method needs to be called 1 or any times more.
While the correct method for easyMock to use is `andStubReturn
in newer versions of camunda engine, it’s able to invoke the external task through “`something called topic, similar concept as MQ/Kafka. (in addition to old approach of REST calls.)
However, to integrate camunda external client with Spring boot took me something to figure out. The integration with standalone java process is working fine, something like
Note: it seems like running multiple ExternalTaskClient with same engine (HTTP://localhost:8080/engine-rest here) on same JVM seems like not working.
however, with spring integration, it’s not able to subscribe to the topic. Where on camunda cockpit, the task would show messages # posted not yet consumed:
In Java, subscribe to the topic:
in config, tell where is the engine:
on cockpit, it would show # of messages posted, however, pending for consumption (2 messages here for example).
for each process instance, its pointing Extneral Tasks, which is the topic
turns out the problem and the solution is with the in-compataility between spring boot (an in-hour built library which is a wrapper of Spring boot) version and camunda external client.
The only needed dependency from camunda side:
to make it work, the spring boot version worked is 2.7.10 and below, version 3 above is not working:
in the beginning, i was confused by why it’s called CDC (consumer driven testing). because in the end, the contract is put at the producer side, and protect the producer making any changes to break the contract.
after looking into this into more detail, then it turns out the contract is supposed to be written by consumer, hence the name of consumer driven.
anyway, its ultimately stopping the producer from making any breaking change which violate the contract.
the gist of the changes:
on the producer side:
add the dependency
org.springframework.cloud
spring-cloud-starter-contract-verifier
test
2. add the plugin, this generates the test, which bind the producer to the contract
I was trying to add some spring contract library onto classpath, however, after adding it to pom, did the refresh, and restarted the intellij all resulted in nothing.
finally realized I was putting the dependency into “`<dependencyManagement>`. section.
I’m fashionably late to this question, but I think it’s worth a clearer response than the accepted one (which is correct, but doesn’t emphasize the actual important part, which you need to deduce yourself).
In the parent POM, the main difference between the <dependencies> and <dependencyManagement> is this:
Artifacts specified in the <dependencies> section will ALWAYS be included as a dependency of the child module(s).
Artifacts specified in the <dependencyManagement> section, will only be included in the child module if they were also specified in the <dependencies> section of the child module itself. Why is it good you ask? Because you specify the version and/or scope in the parent, and you can leave them out when specifying the dependencies in the child POM. This can help you use unified versions for dependencies for child modules, without specifying the version in each child module.