jms message selectors - properties

I am using ActiveMQ 5.5 and JMS. I have created a topic consumer with a message selector of
key<>'aValue'
meaning that the consumer will only receive messages that have a property called "key" that does not have the value 'aValue'.
Then I send a message with no property called "key" (Note that the case is NOT that there is a property with a null value, there is no property.)
What puzzles me is that the message is delivered.
This is not the case if I use the operator NOT LIKE:
key NOT LIKE 'aVal%'.
In this case the consumer does not receive the message. This is inconsistent in my mind.
This is what the JMS spec says:
A message selector matches a message when the selector evaluates to true when the message's header field and property values are substituted for their corresponding identifiers in the selector.
According to the SQL92 spec (which JMS message selectors syntax is based on) comparing anything to NULL results in NULL rather than to a value (TRUE or FALSE in this case). If this is the case the first case should not result in the message being received.
Has anybody come across this? Which result, the <> case or the NOT LIKE case, is the correct one when the producer has not specified the property and the consumer has a selector? Any ideas how this can be worked around?

Based on my limited reading, my understanding is this, first from the JMS spec:
If a property that does not exist in a message is referenced, its
value is NULL.
So in your case the key identifier when substituted for property values will evaluate to NULL
The first expression will essentially be NULL<>'aValue', which is true in my mind
The second expression will be NULL NOT LIKE '%aVal' which the spec says will have an unknown outcome and ActiveMQ seems to have gone with true as the outcome:
If identifier of a LIKE or NOT LIKE operation is NULL, the value of
the operation is unknown.
I think the fix will be to make the selector very explicit:
(key NOT NULL) AND ...

Related

Can I overrid the message in the NOTIFICATIONS AFTER JOB COMPLETION in job definition?

I'd like to override the message that was coded for the 'Notifications after job completion' when submitting a job to control-m, by setting a variable at the time. I haven't found if that 'message' is a type of variable that can be defined.
No, the message field is not a variable. However, you can use lots of variables to construct the message.
You can also create multiple messages that are triggered on (for example) output text or exit codes. You can even update variables based on output/RC (which can be used in the message).

References to IDs in APIs responses, null or 0?

I consider myself that 0 is not a good thing to do when returning information from an API
e.g.
{
userId: int|null
}
I have a colleague that insists in that userId should be 0 or -1, but that forces a system to know that the 0 means "not set", instead of null which is universally known as not set.
The same happens with string params, like logoUrl. However, in this case I think it is acceptable to have an empty string instead of null if the variable is not set or was unset.
Is there bibliography, standards, etc, that I can refer to?
I'm not aware of any standard around that, but the way I take those kind of decisions is by thinking about the way consumer services would read this response, the goal being to provide a very smooth and clean consuming workflow. This exercise can even be transformed into a documentation for your API consumers.
In your case, instead of returning a null/0 field, I would simply remove that field altogether when it's empty and let the consumers explicitly mark that field as optional in the model they use to deserialize this response.
In that way, they'll explicitly have to deal with those optional fields, than relying on the API to always provide a value for them.

Boolean for API Get request, with default. Y/N/All or true/false/all

I'm implementing a filter for a boolean value, but I want to have a default value, so for example.
parameter omitted - returns where isPublished=true
isPublished=true - return's where isPublished=true
isPublished=false - return's where isPublished=false
What If I want to return everything? I could do isPublished=all but some have complained that this is confusing as its not then a true boolean.
I could also go with Y/N/All or Either or Both
What are others views?
Instead of a boolean that restricts the values to true and false, you could consider using an enumeration and a parameter called status or something similar to send its value to the server:
status = PUBLISHED | NOT_PUBLISHED | ALL
If the status parameter is ommited, assume its value is PUBLISHED. Otherwise, use the value provided in the parameter.
In the long run, using an enumeration will give you the possibility of expanding the available status.

Enforcing to supply a completion block

I'm wondering about whether or not this is good practice:
I have a method that takes in parameters and a callback block, let's say something along the lines of:
-(void)loginWithUsername:(NSString *)username andPassword:(NSString *)password withCompletion:(LoginManagerCompletionBlock)completionHandler;
Now in this specific case, there is no use in calling this method without a completion handler, as it triggers a redundant call to a login web service (also, it does not change the state of anything - not client side nor server side). I would like to avoid these situations by actively enforcing the requirement of passing me a completion block in order to make this web service call. I sort of think of this as a "#required" method in an Objective C protocol. So my questions are:
Is requiring a completion block in order to perform an action good practice in Objective C?
(Edit: Answered) How do I enforce this requirement? Is there built-in language syntax that can help me out here?
Thanks
You can use the function attribute nonnull(params), where params is 1 or more comma-separated parameter numbers, to indicate that a parameter should not be null (nonnull without parentheses means all pointer parameters should not be null). For your example:
- (void) loginWithUsername:(NSString *)username
andPassword:(NSString *)password
withCompletion:(LoginManagerCompletionBlock)completionHandler
__attribute__((nonnull(3)));
However, while this is a compile time check and produces a warning it will only do so if null is passed directly. If the argument value is an expression which evaluates to null, e.g. a variable with a null value, then this will not be caught.
If a parameter being null is an error you can add a runtime check within the method itself using NSParameterAssert(parameter), where parameter is the name of one of the method's parameters, to check for this condition. This call is defined to print an error message and throw an exception if its argument evaluates to false, and null evaluates to false.
This is exactly what NSParameterAssert is for. Use it to check that parameters aren't nil.
NSParameterAssert( completionParameter );
Though, in this specific case, it's probably best to log the completion handler being nil and return. There is no point doing any additional work. You probably want the assertion during development to make it obvious that you have an issue that needs to be resolved.

Passing a default Integer value to a WCF service in Biztalk

I have consumed WCF service in biztalk through "Add generated items". There is a method in WCF which takes an integer parameter. In orchestration I want to pass that method a default value or say I want to hard code input value. How I can achieve this. I have googled this question but didn't get any adequate result.
What I have done is declared an integer variable assign it a value, then I assigned that variable to a message of Integer type.
Now how I can assign this message to WebService Request type message?
or how I can transform integer type message to WebService Request type message?
There are a bunch of ways to do this:
If you are mapping the request from another message, you can hard code it in the map - click on the field in the RHS of the Map Editor and set the hard coded value in the Value in the Property box
After creating a (dummy) request message, you can set the value using xpath() in an expression message assignment shape
xpath(myRequestMessage, "//*[local-name()='NameOfFieldHere']") = 3; // Or set to it your variable
If the field is distinguished in your schema, you can use the distinguished field instead of xpath, viz in an expression message assignment shape:
myRequestMessage.NameOfFieldHere = 3;
(And note if its a multipart message, then it will be myRequestMessage.Part.NameOfFieldHere OFC)
One disclaimer: I've assumed the WCF service request message is trivial, i.e. just a single integer field. If your message is large, using //local-name() ... isn't recommended, since
There may be more than one node with with the name NameOfFieldHere
The XSL parser used by BizTalk is slow and resource intensive when evaluating large xml documents with //
Biztalk Scheduler Adapter is really helpful in this case. It generates desired XML on predefined scheduled set by the user. So fill up your XML with hard coded values and receive them through this adapter.