Camel route multiple if condition - apache-camel

I have to write to multiple if condition in camel and I need help to go around.
if(token is NULL)
if(condition is NULL)
if(Dates does not match)
Then execute this...
What I am trying is
.choice
.when(token is NULL)
.when(condition is NULL)
.when(Dates does not match)
.log(update DB)
.endchoice()
which dont work..
Please help

Two conditions:
Predicate p1 = header("token").isEqualTo("001"):
Predicate p2 = header("condition").isEqualTo("002");
Combine these conditions:
Predicate cond = PredicateBuilder.and(p1, p2);
Then In Camel:
.choice
.when(cond)
.log(update DB)
.endchoice()

The best way to do this is to use Predicates.
You can define Predicates as private field if you are using Java DSL, by using expression builder, to build multiple conditions, then use the predicate in your when(), your route would looks much cleaner and easier to read.
private static final Predicate invalidHeaders = or(header(XXX).isNull(), header(YYY).isNull());
...
.when(invalidHeaders)

You need to do this in a single when and use and &&
.when(token is NULL && condition is NULL && XXX)
There are various ways to do this.
If you use Java code then you can append multiple predicates together: http://www.davsclaus.com/2009/02/apache-camel-and-using-compound.html

Related

Boolean condition in camel route

Is there a way to do smth like this to work? I am talking about the condition inside when.
.choice()
.when(Exchange::isFailed)
.to(direct(URI_DEADLETTER))
I tried:
.when(method(Exchange.class, "isFailed"))
.when().exchange(Exchange::isFailed)
For the first solution an error is thrown and the second is not working.
I know that I can create a new class and a method inside, from here: How do i use java boolean condition in camel route?
And I read about the predicat here: http://www.davsclaus.com/2009/02/apache-camel-and-using-compound.html.
But without using a new class or predicat, is there a way that I can achieve this?
A lazy solution is to use Camel simple language (http://camel.apache.org/simple.html) which allows you to access anything (headers, properties, body, method, etc..) of current exchange
.choice()
.when( simple("${exception} != null") )
A more OO solution would be to use Camel Predicate (Builder):
Predicate condition1 = ...
Predicate condition2 = ...;
Predicate isFailed = PredicateBuilder.or(condition1, condition2);
.choice()
.when( isFailed )

Django - would these query sets be cached?

class UnassignedThread(models.Manager):
def get_queryset(self):
return super(UnassignedThread,
self).get_queryset().filter(
_irc_name__isnull=True)
Would results = ThreadVault.unassigned_threads.all() be cached? I am not certain if _isnull=True counts as being a evaluated(since the evaluation causes the cache).
Also, if have a model called ThreadVault, and I want to look up if threads #777 and #888 exist in the database, which way is the best to utilize cache to do the look up?
ThreadVault.objects.get(thread_id="777")
ThreadVault.objects.get(thread_id="888")
or
results = ThreadVault.objects.all()
for ticket in results:
if ticket.thread_id == "777" or ticket.thread_id == "888":
do something
No, querysets are lazy until they are sliced or iterated. filter simply adds conditions to the query, but does not evaluate it.
For your second question, neither of these are great, although the first is vastly preferable to the second (which involves loading and iterating through every object in the table). Instead, you should use exists() in conjunction with an __in filter:
ThreadVault.objects.filter(thread_id__in=["777", "888"].exists()
Neither of these questions has anything to do with caching.
th_ids = ["777","888"]
ThreadVault.objects.filter(thread_id__in=th_ids).exists()
for caching your view
from django.views.decorators.cache import cache_page
#cache_page(60 * 15)
def my_view(request):

On Google App Engine (GAE), how do I search on the Key/ID field?

I've got this code (Java, GAE):
// Much earlier:
playerKey = KeyFactory.keyToString(somePlayer.key);
// Then, later...
PersistenceManager pm = assassin.PMF.get().getPersistenceManager();
Key targetKey = KeyFactory.stringToKey(playerKey);
Query query = pm.newQuery(Player.class);
query.setFilter("__key__ == keyParam");
query.declareParameters("com.google.appengine.api.datastore.Key keyParam");
List<Player> players = (List<Player>) query.execute(targetKey); // <-- line 200
which generates this error:
javax.jdo.JDOFatalUserException: Unexpected expression type while parsing query. Are you certain that a field named __key__ exists on your object?
at org.datanucleus.jdo.NucleusJDOHelper.getJDOExceptionForNucleusException(NucleusJDOHelper.java:354)
at org.datanucleus.jdo.JDOQuery.execute(JDOQuery.java:252)
at myapp.Player.validPlayerWithKey(Player.java:200)
// [etc., snip]
But I'm not sure what it wants. I'm trying to search on the JDO id field, which I I thought I read had the special name __key__, in the documentation.
I've tried it with both
query.setFilter("__key__ == keyParam");
and
query.setFilter("ID == keyParam");
with the same results. So, what am I doing wrong? Or, more importantly, how do I do it correctly?
Thanks!
Edit: For completeness's sake, here is the final, working code (based on Gordon's answer, which I have accepted as correct):
Player result = null;
if (playerKey == null)
{
log.log(Level.WARNING, "Tried to find player with null key.");
}
else
{
PersistenceManager pm = assassin.PMF.get().getPersistenceManager();
try {
result = (Player) pm.getObjectById(Player.class, playerKey);
} catch (javax.jdo.JDOObjectNotFoundException notFound) {
// Player not found; we will return null.
result = null;
}
pm.close();
}
return result;
If your objective is to get an object by key, then you should use the PersistenceManager's getObjectByID() method. More details here.
As an aside, trying to construct a query to get something by it's key is something you shouldn't need to do. Although this is how you would work with an SQL database, the Google Data Store does things differently, and this is one of those cases where rather than go through the trouble of constructing a query, Google App Engine lets you get what you want directly. After all, you should only have one entity in the database with a particular key, so there's nothing in the rest of the machinery of a GQL query that you need in this case, hence it can all be skipped for efficiency.
I would recommend you to use the JPA ( http://code.google.com/appengine/docs/java/datastore/usingjpa.html ) to access your data in GAE, it has the very important advantage that you can use the widely known and documented JPA standard (and its JPAQL querying language) to do this kind of things, in portable way (if you stick to the JPA standard, your code will work for GAE, for Hibernate or with EclipseLink without modification)

Using CONTAINS from HQL / Criteria API

I'm using NHibernate 2.1.2.4000GA. I'm trying to use SQL Server's CONTAINS function from within HQL and the criteria APIs. This works fine in HQL:
CONTAINS(:value)
However, I need to qualify the table in question. This works fine:
CONTAINS(table.Column, :value)
However, I need to search across all indexed columns in my table. I tried this:
CONTAINS(table.*, :value)
But I get:
NHibernate.Hql.Ast.ANTLR.QuerySyntaxException : Exception of type 'Antlr.Runtime.MissingTokenException' was thrown. near line ... [select table.Id from Entities.Table table where CONTAINS(table.*,:p0) order by table.Id asc]
at NHibernate.Hql.Ast.ANTLR.ErrorCounter.ThrowQueryException()
at NHibernate.Hql.Ast.ANTLR.HqlParseEngine.Parse()
at NHibernate.Hql.Ast.ANTLR.QueryTranslatorImpl.Parse(Boolean isFilter)
at NHibernate.Hql.Ast.ANTLR.QueryTranslatorImpl.DoCompile(IDictionary`2 replacements, Boolean shallow, String collectionRole)
at NHibernate.Hql.Ast.ANTLR.QueryTranslatorImpl.Compile(IDictionary`2 replacements, Boolean shallow)
at NHibernate.Engine.Query.HQLQueryPlan..ctor(String hql, String collectionRole, Boolean shallow, IDictionary`2 enabledFilters, ISessionFactoryImplementor factory)
at NHibernate.Engine.Query.QueryPlanCache.GetHQLQueryPlan(String queryString, Boolean shallow, IDictionary`2 enabledFilters)
at NHibernate.Impl.AbstractSessionImpl.GetHQLQueryPlan(String query, Boolean shallow)
at NHibernate.Impl.AbstractSessionImpl.CreateQuery(String queryString)
So it would seem the HQL parser chokes on the asterisk. I thought of doing this:
CONTAINS(table.Column1, :value) or CONTAINS(table.Column2, :value)
Not only is this inefficient, it can also yields incorrect results depending on the full text predicate in :value.
I tried customizing my dialect as per these instructions, but that doesn't help because you're still left with the same problem: specifying table.* causes the HQL parser to fall over.
I thought of specifying query substitutions:
<property name="query.substitutions">TABLECONTAINS(=CONTAINS(table.*,</property>
And then simply doing:
TABLECONTAINS(:value)
But that does not work. I'm not sure why - judging by the resultant error, the substitution just doesn't take place because "TABLECONTAINS" is still present in the query. Besides, this wouldn't work for all cases because I'd need to know the alias of the table and dynamically substitute it in.
Therefore, I rolled an interception-based approach:
using System;
using NHibernate;
using NHibernate.SqlCommand;
public class ContainsInterceptor : EmptyInterceptor
{
public override SqlString OnPrepareStatement(SqlString sql)
{
var indexOfTableContains = sql.IndexOfCaseInsensitive("TABLECONTAINS(");
if (indexOfTableContains != -1)
{
var sqlPart = sql.ToString();
var aliasIndex = sqlPart.LastIndexOf("Table ", indexOfTableContains, StringComparison.Ordinal);
if (aliasIndex == -1)
{
return sql;
}
aliasIndex += "Table ".Length;
var alias = sqlPart.Substring(aliasIndex, sqlPart.IndexOf(" ", aliasIndex, StringComparison.Ordinal) - aliasIndex);
sql = sql.Replace("TABLECONTAINS(", "CONTAINS(" + alias + ".*,");
}
return base.OnPrepareStatement(sql);
}
}
This works and I will now be able to sleep tonight, but I do feel a sudden desire to attend London's impending papal procession and shout out a confession.
Can anyone suggest a better way to achieve this?
Why not use an ISQLQuery instead?
You can still retrieve entities, see http://nhibernate.info/doc/nh/en/index.html#querysql-creating
I would think that a custom dialect would be the appropriate way to handle this. You can find some guidance in this article. I've used this approach to register SQL Server-specific functions like ISNULL for use in our projects.

Using Mono.Addins local conditions

As described here how do you " register an instance of the ConditionType" on the AddinManager?
You found a gap in the documentation. It is now updated.
To use extension points with local conditions, you have to create an Extension Context, setup the conditions, and then query the extension point. For example:
// Create an extension context to be used to query the extension point using
// a specific set of conditions.
ExtensionContext ctx = AddinManager.CreateExtensionContext ();
// Create and register the extension point condition
OpenFileLocalCondition condition = new OpenFileLocalCondition (someFileName);
ctx.RegisterCondition (condition);
// Query the extension point
foreach (ExtensionNode node in ctx.GetExtensionNodes ("/TextEditor/ContextMenu"))
(...)
The conditions you register on a context only apply to that context, so you can have several contexts with different sets of conditions.

Resources