Block unknown json properties on certain classes - java

I have a configuration which if enables blocks unknown variables from passing through.
#Value("${json.failOnUnknown:false}")
private boolean failOnUnknown;
Jackson2ObjectMapperBuilder build = new Jackson2ObjectMapperBuilder();
if(!failOnUnknown) {
build.featuresToDisable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
}
else {
build.featuresToEnable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
}
I want this so if someone sends a bad property to my service I block them. However, my service connects to other services and if they send in an unknown variable it fails as well. I want unknown variables to be ignored when my other services talk to my current service.
I have tried using
#JsonIgnoreProperties(ignoreUnknown=true)
To overwrite the FAIL_ON_UNKNOWN_PROPERTIES but it doesn't work.
Any ideas on how to block unknown variables in some classes and not others?

One solution you might get into is to create two separate ObjectMappers, one that ignores unknown properties and the other one that throws exceptions. You can disable fail on unknow property directly on your Object Mapper scope as following: objectMapper.disable(FAIL_ON_UNKNOWN_PROPERTIES);.
The idea is that you could still create a global scoped object mapper as shown in your example you use almost everywhere except for those services that needs to fail on unknown properties whatever the context is.

Related

Use placeholders in feature files

I would like to use placeholders in a feature file, like this:
Feature: Talk to two servers
Scenario: Forward data from Server A to Server B
Given MongoDb collection "${db1}/foo" contains the following record:
"""
{"key": "value"}
"""
When I send GET "${server1}/data"
When I forward the respone to PUT "${server2}/data"
Then MongoDB collection "${db2}/bar" MUST contain the following record:
"""
{"key": "value"}
"""
The values of ${server1} etc. would depend on the environment in which the test is to be executed (dev, uat, stage, or prod). Therefore, Scenario Outlines are not applicable in this situation.
Is there any standard way of doing this? Ideally there would be something which maintains a Map<String, String> that can be filled in a #Before or so, and runs automatically between Cucumber and the Step Definition so that inside the step definitions no code is needed.
Given the following step definitions
public class MyStepdefs {
#When("^I send GET "(.*)"$)
public void performGET(final String url) {
// …
}
}
And an appropriate setup, when performGET() is called, the placeholder ${server1} in String uri should already be replaced with a lookup of a value in a Map.
Is there a standard way or feature of Cucumber-Java of doing this? I do not mind if this involves dependency injection. If dependency injection is involved, I would prefer Spring, as Spring is already in use for other reasons in my use case.
The simple answer is that you can't.
The solution to your problem is to remove the incidental details from your scenario all together and access specific server information in the step defintions.
The server and database obviously belong together so lets describe them as a single entity, a service.
The details about the rest calls doesn't really help to convey what you're
actually doing. Features don't describe implementation details, they describe behavior.
Testing if records have been inserted into the database is another bad practice and again doesn't describe behavior. You should be able to replace that by an other API call that fetches the data or some other process that proves the other server has received the information. If there are no such means to extract the data available you should create them. If they can't be created you can wonder if the information even needs to be stored (your service would then appear to have the same properties as a black hole :) ).
I would resolve this all by rewriting the story such that:
Feature: Talk to two services
Scenario: Forward foobar data from Service A to Service B
Given "Service A" has key-value information
When I forward the foobar data from "Service A" to "Service B"
Then "Service B" has received the key-value information
Now that we have two entities Service A and Service B you can create a ServiceInformationService to look up information about Service A and B. You can inject this ServiceInformationService into your step definitions.
So when ever you need some information about Service A, you do
Service a = serviceInformationService.lookup("A");
String apiHost = a.getApiHost():
String dbHost = a.getDatabaseHOst():
In the implementation of the Service you look up the property for that service System.getProperty(serviceName + "_" + apiHostKey) and you make sure that your CI sets A_APIHOST and A_DBHOST, B_APIHOST, B_DBHOST, ect.
You can put the name of the collections in a property file that you look up in a similar way as you'd look up the system properties. Though I would avoid direct interaction with the DB if possible.
The feature you are looking for is supported in gherkin with qaf. It supports to use properties defined in properties file using ${prop.key}. In addition it offers strong resource configuration features to work with different environments. It also supports web-services

Guice injection for dynamically creating objects

I have a "Handler" interface for a message queue, something that has methods:
boolean canHandle(message);
void handle(message);
I then have multiple implementations for this interface, each of them canHandle() certain types of messages
When a message arrive, I do something like:
for (Handler handler : handlers) {
if handler.canHandle(message)
handle(message)
So, I need to build a list of "enabled handlers" that must be specified in a config file.
I could either specify the enabled handlers by class name (FQCN) or annotating the class by some name and referencing this name on the config.
For instance:
enabledHandlers = ("com.domain.handlers.HandlerA", "com.domain.handlers.HandlerB", )
#or
enabledHandlers = ("HandlerAAnnotation", "HandlerBAnnotation", )
in any case, somehow I will need to build those handlers inside my service, and they require injected parameters.
I believe something injector.getInstance(clazz) would work to build those objects, but it doesn't make much sense to have the "injector" going around my service when I need to create those classes.
I could also create them by reflection "manually" by clazz.getConstructor(...).newInstance(...), but it seems pretty dirty.
Any other ideas?
Thanks!

How to Mock the Property File in Junit

I am creating a Unit test case using Junit . Now My application is Maven Based with many profile Also I am using the Values from configuration file (Property File ) which Varies from one profile to other. I want that Unit Test run will have specified properties only not the profile one when it is running the test cases.
These can be done in 2 ways
1) Either i Mock the Property File for Unit Test .( which i dont know How) .
2) Or during run time i change the property file parameter values.(Again difficult to answer) . Any help will be appreciated .
One option: use dependency injection in order to acquire a java.util.Properties object for example.
Meaning: your production code simply holds a Properties object; like:
class Foo {
private final Properties properties;
public Foo(Properties) {
this.properties = properties;
At runtime, when the class that creates Foo objects reads property files from disk, turns them into a Properties object and gives it to the Foo constructor.
In your unit test, your test code creates a Properties object and adds whatever values you require upon creating a Foo object.
The less elegant detour: make sure that your production code reads its properties from a location that gets defined at runtime. That would allow you to create custom property files in some temp directory, and then you instruct your code under test to work with those files.
Did not got your question exactly - In one side, you are saying: you don't want to use profile related values and other side you are saying: you'll need to run with specific values (do you mean runtime values or test specific values).
Now, To answer your 1st question:
1) Either i Mock the Property File for Unit Test:
you can instantiate and load a property file(test specific) and keep the required values there in that file.
2) Or during run time i change the property file parameter values:
you can mock specific property keys with values. like below:
public void shouldBuyBread() throws Exception {
//given
given(mypropertyUtil.getProperty("NUMBER_OF_BREADS")).willReturn(10);
//when
Goods goods = shop.buyBread();
//then
assertThat(goods, containBread());
}

Is it a good idea to replace java.net.URL URLStreamHandlerFactory using reflection?

In Java we can register a custom protocol handler in at least two ways:
by setting system property 'java.protocol.handler.pkgs'
using URL.setURLStreamHandlerFactory
For more details please check http://accu.org/index.php/journals/1434
I can not go with the first option, as i would have to add a lot of jar files to the server (tomcat) classpath, to make the handler implementaion visible for bootstrap classloader. Moreover some initialization is needed, which has to be done in an application context.
The problem with the second option is that the Factory can be registered only once (check java.net.URL#setURLStreamHandlerFactory), and unfortunately it is done by Tomcat.
What i can do is to create a decorator factory which will extend the existing one by my protocol handler. Than using relfection set the static field URL#factory to null and register (again?) my "decoratorFactory" in a standard way using URL#setURLStreamHandlerFactory. I'm just wondering if it is a good idea to use the reflection here...? How about the security?
I would like to do something like that:
try {
Field factoryField = URL.class.getDeclaredField("factory");
factoryField.setAccessible(true);
// get current factory
Object currentFactory = factoryField.get(null);
// define a decorator factory
MyFactoryDecorator mfd = new MyFactoryDecorator(currentFactory);
// set the factory to null and register MyFactoryDecorator using URL#setURLStreamHandlerFactory.
factoryField.set(null, null);
URL.setURLStreamHandlerFactory(mfd);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
Idk if this would work, but what if you create a new URLStreamHandlerFactory that doesn't actually contain the implementation? It just sits there and then instantiates the real implementation at runtime when it is called via an app context lookup. Then in theory you can instantiate this new proxy handler via the system property at the beginning, but also use the one you want when it is actually called.
UPDATE:
Actually, I think your link above mentions this strategy:
Another approach is to use the factory registration, but to provide a factory class that itself supports registration of multiple different stream handlers using different names.
This approach supports code using the java.net.URL class but it does require a registration call for each protocol and so hence changes are needed to an application before it can make use of the new URLs. However the approach gets around the problems discussed above with multiple class loaders since the factory is loaded by the user code class loader rather than by the class loader for the URL class.
I'm not super familiar with what all you're doing and how the registration works, so this could be more or less complicated depending on what you're doing. Idk if you even need the extra registration or not, but it sounds like it might solve the .jar/app context problem.

Remove a JMS message property

I am writing a Java batch which is listening messages from a queue (Oracle AQ) and sending them to another queue (Tibco EMS), where they are processed by a Tibco process (BW).
The problem is that the Oracle AQ driver automatically add some properties to messages (JMSXGroupID, JMSXGroupSeq) which cause errors when they are processed by Tibco process because they have bad values : JMSXGroupSeq should be an int but is set to null. Tibco falls into error when trying to parse message properties...
So I would like to remove only these 2 properties from all messages but it seems that the jms api only offers a clearProperties() method but no single property remove method (I'm using ths javax.jms.Message interface).
For now, I can see two solutions :
set a correct value to these 2 properties, as I'm assuming they will
not be used further by Tibco
read all properties and reconstruct the messages without the 2 which cause problem. But this approach is very ugly...
Does anyone have any other solution?
It is not possible to edit/clear some properties. We need to call clearProperties method as described here to get write access :
Once a message is produced (sent), its properties become read-only; the properties cannot be changed. While consumers can read the properties using the property accessor methods (getProperty( )), they cannot modify the properties using any of the mutator methods (setProperty( )). If the consumer attempts to set a property, the mutator method throws a javax.jms.MessageNotWriteableException.
Once a message is received, the only way its properties can be changed is by clearing out all the properties using the clearProperties( ) method. This removes all the properties from the message so that new ones can be added. Individual properties cannot be modified or removed once a message is sent.
There will be a function public void removeProperty(String name) in the concrete class implementation of javax.jms.Message interface. This classs is provider specific(Tibco EMS in your case). As it is closed source I cannot be for sure about the existence of that function. But it is present in HornetQ.It can be used to reset particular header property.
Other than that I thing option 1 is the best. You set it to some non null value acceptable by Message header parser of Tibco EMS.

Categories

Resources