How to take param values from Task Queue url.? - google-app-engine

Queue queue = QueueFactory.getDefaultQueue();
queue.add(("/worker").param("key", "ABC"));
how to take key value .? using below code or any other approach.
request.getParameter("key");

Absolutely. The /worker endpoint is configured in your web.xml as a Servlet. The request object will be passed to your Servlet method and you can use the standard methods like the one you have specified i.e. getParameter(...)

Related

camel not knowing amount of endpoints in loadbalancer

Is it possible to loadbalance in a camel route without knowing the amount of endpoints before runtime?
As an example, certain incoming requests has to loadbalance over certain servers and the servers are configured.
using .loadBalance().failover().to() how can I dynamically set the amount of to() endpoints?
I have tried it with toD() and sending a string of comma seperated endpoints but it sends the request to all servers and does not loadbalance.
To do this, you'll need to use the Java DSL.
//Setup dynamic list of endpoints
List<String> toDefs = new ArrayList<String>();
toDefs.add("mock:a");
toDefs.add("mock:b");
//We need to modify the definition, so get the reference
LoadBalanceDefinition loadBalanceDefinition =
from("dirct:start")
.loadBalance()
.failover();
//Dynamically add the list of endpoints
for (String toDef: toDefs){
loadBalanceDefinition = loadBalanceDefinition.to(toDef);
}
//Finalize the route
loadBalanceDefinition.to("direct:end");

Declare response queue with specific name for Request/Response pattern in EasyNetQ

When using the Request/Response messaging pattern within EasyNetQ I need to declare a private response queue (with a specific name) before sending the message on the request queue?
I presume the framework declares the response queue in the background but how can I give this response queue a specific name?
I don't see any information on this within the documentation at https://github.com/EasyNetQ/EasyNetQ/wiki/Request-Response
This is the default implementation of the naming conventions:
https://github.com/EasyNetQ/EasyNetQ/blob/develop/Source/EasyNetQ/Conventions.cs
So perhaps you can try something like this:
bus.Advanced.Conventions.RpcReturnQueueNamingConvention = () => "MyReturnQueue";
In the lastest EasyNetQ ,bus.Advanced.Conventions.RpcReturnQueueNamingConvention is readonly, can't be set
Maybe you can set queue name when using the RPC method like
bus.Rpc.Respond<RequestMsg, RepsonseMsg>(request => {//...},x=>x.WithQueueName("your queue name"));
or
var msg = bus.Rpc.Request<RequestMsg, RepsonseMsg>(request, x => x.WithQueueName("your queue name"));

Get query(search handler) configuration for a query using SolrJ

Is it possible to get the query configuration values(default + request parameters) using SolrJ ?
For example: If I direct a request to the RequestHandler using SolrJ, I would like to get a list of parameters(default + overridden request parameters) used on the query. I need this to log the current configuration when the query was made.
Try adding the parameter echoParams=all.
The echoParams parameter tells Solr what kinds of Request parameters
should be included in the response for debugging purposes, legal
values include:
none - don't include any request parameters for debugging
explicit -
include the parameters explicitly specified by the client in the
request
all - include all parameters involved in this request, either
specified explicitly by the client, or implicit because of the request
handler configuration.
Take a look at Common Query Parameters

How to split a message do some extra processing on one of them and aggregate them back

I need to configure some camel routes based on some configuration files.
All configured routes will need to split a message into one or two sub messages then do some JMS integration work on the first one and then aggregate together the JMS reply with the optional second message. In a simplified picture it will look like below:
message -- > split --> message 1 --> JMS request/reply --> aggregate --> more processing
\--> message 2 /
The aggregation will be done on completion size which I am able to know upfront if it is going to be 1 or 2 depending of the route meta data. When the second message is present no other processing is needed before being merged back with the JMS reply.
Si in short I need a split followed by a routing followed by an aggregation which is quite a common pattern. The only particularity is is that in case the second split message is present I don't need to do anything on it before aggregating it back.
In java DSL it will looks something like this:
from("direct:abc")
// The splitter below will set the JmsIntegration flag
.split().method(MySplitter.class, "split")
.choice()
.when(header("JmsIntegration"))
.inOut("jms:someQueue"))
.otherwise()
// what should I have on here?
.to(???)
.end()
.aggregate(...)to(...);
So my questions would be:
What should I put on the otherwise branch?
What I need in fact is an if: if the split message needs JMS go to JMS and then move to aggregator if it is not just go straight to the aggregator. I am considering creating a dummy processor which will actually do nothing but this seems to me a naive approach.
Am I on a wrong path. If so what would be the alternative
Initially I was thinking about a message enricher but I would not like to sent the original message to the JMS
I also considered putting my aggregation strategy inside my splitter but again I could not put it all together.
Based off your post it looks like you are trying to have the return of your enrichment merge with the original message, but you want to send a custom message to the jms endpoint. I would recommend storing your original message in either a bean or a cache or something of the sort, leveraging all of your conversions with camel and then have your aggregation strategy leverage your storage to return your desired format.
from("direct:abc")
.split().method(MySplitter.class, "split")
.choice()
.when(header("JmsIntegration"))
.beanRef("MyStorageBean", "storeOriginal")
.convertBodyTo(MyJmsFormat.class)
//This aggregation strategy could have a reference
//to your storage bean and retrieve the instance
.enrich("jms:someQueue", myCustomAggreationStrategyInstance)
.otherwise()
.end()
.aggregate(...)
.to("direct:continueProcessing");
Option #2: Based off of your comment saying you needed the "original message that the direct:abc endpoint received this can be simplified a lot. In this example we can use camel's existing Original message store to retrieve the message that was passed into direct:abc. If Your message after the split has a JmsIntegration header we will convert the body to the desired format for the jms call, leverage the enrich statement to make the jms call and a custom aggregator that gives you access to the message used to call the jms endpoint, the message that came back, and the original message direct:abc has. If your flow does not have a JmsIntegration header the message will go to the Otherwise statement in your route which does no additional processing before ending the choice statement and then the spit messages are aggregated back together with whatever custom strategy you need.
from("direct:abc")
.split().method(MySplitter.class, "split")
.choice()
.when(header("JmsIntegration"))
.convertBodyTo(MyJmsFormat.class)
//See aggregationStrategy sample below
.enrich("jms:someQueue", myAggStrat)
.otherwise()
//Non JmsIntegration header messages come here,
//but receive no work and are passed on.
.end()
.aggregate(...)
.to("direct:continueProcessing");
//Your Custom Aggregator
public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
//This logic will retrieve the original message passed into direct:abc
Message originalMessage =(Message)exchange.getUnitOfWork().getOriginalInMessage();
//TODO logic for manipulating your exchanges and returning the desired result
}
You said you considered using Enricher, but you don't want to send raw message. You can resolve this neatly by using a pre-JMS route:
from("direct:abc")
.enrich("direct:sendToJms", new MyAggregation());
.to("direct:continue");
from("direct:sendToJms")
// do marshalling or conversion here as necessary
.convertBodyTo(MyJmsRequest.class)
.to("jms:someQueue");
public class MyAggregation implements AggregationStrategy {
public Exchange aggregate(Exchange original, Exchange resource) {
MyBody originalBody = original.getIn().getBody(MyBody.class);
MyJmsResponse resourceResponse = resource.getIn().getBody(MyJmsResponse.class);
Object mergeResult = ... // combine original body and resource response
original.getIn().setBody(mergeResult);
return original;
}
}
Splitter automatically aggregates split exchanges back together. However, default (since 2.3) aggregation strategy is to return the original exchange. You can easily override the default strategy with your own by specifying it directly on the Splitter. Furthermore, if you don't have an alternative flow for your Choice, then it's much easier to use Filter. Example:
from("direct:abc")
.split().method(MySplitter.class, "split").aggregationStrategy(new MyStrategy())
.filter(header("JmsIntegration"))
.inOut("jms:someQueue"))
.end()
.end()
.to(...);
You still need to implement MyStrategy to combine the two messages.

Using CloudSolrServer as SolrJ client

My question is when we are using CloudSolrServer, we specify single zkHost address and LBHttpSolrServer. Now CloudSolrServer does extracts information about alive and dead nodes from zookeeper (zkHost) and serves the requests.
But what if the zkHost specified as argument it self goes down ? I think CloudSolrServer should accept more then one zkHost, as the case with LBHttpSolrServer, which accepts more then one solr server urls.
Any idea ?
Thanks
According to this: http://comments.gmane.org/gmane.comp.jakarta.lucene.solr.user/71075
You can pass a comma-delimited list of Zk addresses in your ensemble, such as:
zk1:2181,zk2:2181,zk3:2181, etc.

Resources