How to configure parallelSolverCount in Optaplanner? - optaplanner

I'm running a batch of solutions and I'm trying to configure the parallelSolverCount using:
<solver>
<solverManagerConfig>
<parallelSolverCount>1</parallelSolverCount>
</solverManagerConfig>
....
</solver>
But it's not waiting and I'm getting:
java.lang.IllegalStateException: The problemId (1) is already solving.
at org.optaplanner.core.impl.solver.DefaultSolverManager.lambda$solve$1(DefaultSolverManager.java:116)
What's the right syntax to configure it?

The SolverManager cannot be configured via XML.
If you create a SolverManager instance yourself, you can pass a SolverManagerConfig object as the second argument to the factory method:
SolverConfig solverConfig
= SolverConfig.createFromXmlResource(".../cloudBalancingSolverConfig.xml");
SolverManager solverManager
= SolverManager.create(solverConfig, new SolverManagerConfig().withParallelSolverCount("1"));
If you use Quarkus or Spring Boot and have the SolverManager instance injected by the framework, then try setting the parallel solver count using the optaplanner.solver-manager.parallel-solver-count property either as a system property (-Doptaplanner.solver-manager.parallel-solver-count=1) or in application.properties:
optaplanner.solver-manager.parallel-solver-count=1
You can find more about SolverManager configuration in the documentation.

Related

How is the scoreDirector accessed when using the autowired SolverManager with Optaplanner?

I'm using the autowired SolverManager with the optaplanner-spring-boot-starter jar
#Autowired
private SolverManager<BatchSolution, UUID> solverManager;
And would like to report on the constraints using:
Map<Object, Indictment> indictmentMap = guiScoreDirector.getIndictmentMap();
In previous versions I used:
ScoreDirectorFactory<Solution_> scoreDirectorFactory = solver.getScoreDirectorFactory();
guiScoreDirector = scoreDirectorFactory.buildScoreDirector();
And can't see how to access the scoreDirector through the solverManager in the examples.
We're planning to expose this functionality in the ScoreManager:
#Autowired
ScoreManager<MySolution> scoreManager;
But that API doesn't support getIndictmentMap(Solution_) yet. This is an API gap.
Meanwhile, just workaround it, by autowiring the SolverFactory too and use ScolverFactory.getScoreDirectorFactory() until we deprecate that once the ScoreManager API replaces that functionality.

WebClient instrumentation in spring sleuth

I'm wondering whether sleuth has reactive WebClient instrumentation supported.
I did't find it from the document:
Instruments common ingress and egress points from Spring applications (servlet filter, async endpoints, rest template, scheduled actions, message channels, Zuul filters, and Feign client).
My case:
I may use WebClient in either a WebFilter or my rest resource to produce Mono.
And I want:
A sub span auto created as child of root span
trace info propagated via headers
If the instrumentation is not supported at the moment, Am I supposed to manually get the span from context and do it by myself like this:
OpenTracing instrumentation on reactive WebClient
Thanks
Leon
Even though this is an old question this would help others...
WebClient instrumentation will only work if new instance is created via Spring as a Bean. Check Spring Cloud Sleuth reference guide.
You have to register WebClient as a bean so that the tracing instrumentation gets applied. If you create a WebClient instance with a new keyword, the instrumentation does NOT work.
If you go to Sleuth's documentation for the Finchley release train, and you do find and you search for WebClient you'll find it - https://cloud.spring.io/spring-cloud-static/Finchley.RC2/single/spring-cloud.html#__literal_webclient_literal . In other words we do support it out of the box.
UPDATE:
New link - https://docs.spring.io/spring-cloud-sleuth/docs/current/reference/html/integrations.html#sleuth-http-client-webclient-integration
let me paste the contents
3.2.2. WebClient
This feature is available for all tracer implementations.
We inject a ExchangeFilterFunction implementation that creates a span
and, through on-success and on-error callbacks, takes care of closing
client-side spans.
To block this feature, set spring.sleuth.web.client.enabled to false.
You have to register WebClient as a bean so that the tracing
instrumentation gets applied. If you create a WebClient instance with
a new keyword, the instrumentation does NOT work.

Using javax.ws.rs.client.ClientBuilder in CXF to create Client, any route to be able to use local transport?

I work on a codebase that uses the standard "javax.ws.rs.client.ClientBuilder" class, from the CXF distribution, to configure and create a "javax.ws.rs.client.Client".
This works well enough.
I'm now trying to write tests that use JAXRSServerFactoryBean to manage a fake server using a controller defined by an inline class. I can set my host:port to localhost:something, both in the test and in the client configuration, and this works well enough to allow me to test our MessageBodyReaders and Http exception handling.
However, I think this won't be "scalable", as each fake server will have to run on a "dedicated" port (while running the test, at least). I can try to use uncommon ports, and have different tests use different ports, or use random numbers, but that's all somewhat risky. I don't really want CI builds to fail because tests running in parallel ended up using the same port.
I read about the ability in CXF (not JAX-RS) to use "local transport" (https://cwiki.apache.org/confluence/display/CXF20DOC/JAXRS+Testing). It appears that might resolve my problem. I need to verify this, but it's possible that two tests running in parallel both using local transport will not conflict.
However, I can't even get this to work yet, because our client code is using the "standard" JAX-RS client class, not the CXF one. They appear to be different and incompatible.
At the point where I create the client, I tried to do this (just to see if it can work):
WebClient.getConfig(client).getRequestContext().put(LocalConduit.DIRECT_DISPATCH, Boolean.TRUE);
Unfortunately, this fails with "Not a valid Client" in "org.apache.cxf.jaxrs.client.WebClient.getConfig(Object)" because it needs to be an instance of "org.apache.cxf.jaxrs.client.Client", not javax.ws.rs.client.Client.
Is there any easy (or even possible) path forward here?
You can use ClientRequestFilters to unit test JAX-RS clients. Basically register a custom ClientRequestFilter to your Client object (or ClientBuilder) that mocks your response using the abortWith(Response) method on the ClientRequestContext object that is passed in to the filter method.
Something like this should work:
public MyMockRequestFilter implements ClientRequestFilter {
#Override
public void filter(ClientRequestContext requestContext) {
MyEntity entity = // get the entity you want to mock as returned from the server
requestContext.abortWith(Request.ok(entity).build());
}
}
...
ClientBuilder builder = ClientBuilder.newBuilder().register(MyMockRequestFilter .class)
Hope this helps,
Andy

FOSRESTBundle: how to alter serializer metadatadirs at controller level

How can I specify a metadata dir for the serializer used by FOSRestBundle, at controller level?
I can't set it up in config.yml because in my case it depends on the request's route.
I've seen in JMSSerializer doc that I could use the following code
$serializer = JMS\Serializer\SerializerBuilder::create()
->addMetadataDir($someDir)
->build();
But how to apply it to an already instanciated serializer (or how to replace it)?
I'm afraid this isn't possible.
Directories are set to metadata drivers when calling build() in SerializerBuilder.php.
Even though you can access the metadata factory used by the Serializer it probably won't help you because the factory has nothing to do with cache directories. Only drivers work with directories.
So the only option for you is probably to create a new instance of Serializer and use that instead of the one from DI.
Edit: Creating a new Serializer works the same way as in your question. Then your DI container should be an instance of Container that has method set() which lets you override any registered service.

Mule spring bean schedule run

We have defined spring beans in Mule-config.xml. Certain public methods in this bean class needs to be periodically executed. We attempted to used spring quartz and spring task scheduler (adding beans in mule-config.xml)- but method is not executing in a schedule way - it is not triggered. Even using annotation (scheduled) does not work. Any work around for this? Any issue with spring scheduler with mule? Kindly help.
Thanks
If you want to use the Schedule annotation, take a look at this recent answer on the subject for a workaround.
Otherwise, Spring Quartz should work fine too. What have you tried? Share your config and specify the Mule version you're using. I'll review my answer accordingly.