Apache Camel paho socketFactory setting - security

I am have created the camel route which use camel-paho component to consume MQTT stream. It is enabled with SSL and i need to pass the socket-factory. I went through the documentation od camel-paho and below parameter is available
socketFactory (security)
Sets the SocketFactory to use. This allows an application to apply its own policies around the creation of network sockets. If using an SSL connection, an SSLSocketFactory can be used to supply application-specific security settings.
I have passed the custom socket-factory in the URL by setting the above parameter to the class name as below
from("paho:"test?brokerUrl="+MQTT_BROKER_URL+"&clientId=subX4&cleanSession=false&socketFactory=com.sample.mqttCustomSocketFactory.java")
Above setting is not working. Is that the correct way of passing the parameter ?

Whenever you set a complex object to the Camel endpoint parameter, it needs to be a bean reference. So in your case, the endpoint should look something like this:
from("paho:test?...&socketFactory=#mySocketFactory")
where the #mySocketFactory is defined in the Camel bean registry like this:
SocketFactory mySocketFactory = ...
context.getRegistry().bind("mySocketFactory", mySocketFactory);
or in Spring context XML:
<bean id="mySocketFactory" ...>

Related

How to create a CDI Interceptor which advises methods from a Feign client?

I've been trying to figure out how to intercept methods defined in a Feign client with CDI (1.2) interceptors. I need to intercept the response value the client is returning, and extract data to log and remove some data prior to it being returned to the calling process.
I'm running a Weld 2.3 container which provides CDI 1.2. In it, I would like to create a CDI interceptor which is triggered everytime a call to filter() is made.
public interface MyRepository {
#RequestLine("POST /v1/data/policy/input_data_filtered")
JsonNode filter(Body body);
}
and a matching Producer method:
#Produces
public MyRepository repositoryProducer() {
return Feign.builder()
.client(new ApacheHttpClient())
.encoder(new JacksonEncoder(mapper))
.decoder(new JacksonDecoder(mapper))
.logger(new Slf4jLogger(MyRepository.class))
.logLevel(feign.Logger.Level.FULL)
.target(MyRepository.class, "http://localhost:9999");
}
I've tried the standard CDI interceptor way by creating an #InterceptorBinding and adding it to the interface definition, but that didn't work. I suspect because the interceptor must be applied to the CDI bean(proxy) and cannot be defined in an interface. I tried applying it to the repositoryProducer() method but that too was non functional.
I've read about the javax.enterprise.inject.spi.InterceptionFactory which is availabel in CDI 2.0, but I don't have access to it.
How can I do this in CDI 1.2? Or alternatively, is there a better interceptor pattern I can use that is built into Feign somehow?
The short, somewhat incorrect answer is: you cannot. InterceptionFactory is indeed how you would do it if you could.
The longer answer is something like this:
Use java.lang.reflect.Proxy to create a proxy implementation of the MyRepository interface.
Create an InvocationHandler that performs the interception around whatever methods you want.
Target Feign at that proxy implementation.

Precompiled Azure Function and SOAP endpoints

I'm writing a precompiled Azure function that will perform a SOAP call to ServiceNow. The code works as a standalone exe but I can't seem to get it converted to a precompiled function. In know it's because my DLL can't find the app.config file but what's the best way to get around it. Error message below. ServiceNow requires I set certain bindings and endpoint configuration. The other contractors for their ServiceNowSoapClient class allow me to specify a url directly but don't seem to allow me to get to the binding settings.
Exception while executing function: Functions.TimerTriggerCSharp.
System.ServiceModel: Could not find endpoint element with name
'ServiceNowSoapDev' and contract 'ServiceNowReference.ServiceNowSoap'
in the ServiceModel client configuration section. This might be
because no configuration file was found for your application, or
because no endpoint element matching this name could be found in the
client element.
In WCF you can define your client binding and endpoint programmatically instead of using app.config. Use the constructor of the generated client with two parameters:
new ServiceNowSoapClient(binding, remoteAddress);
See more code here.

Service Activator reuse not working

In the service activator documentation it says:
Using a "ref" attribute is generally recommended if the custom Service Activator handler implementation can be reused in other definitions.
But the below snippet gives me
IllegalArgumentException: An AbstractReplyProducingMessageHandler may only be referenced once
<bean id="groupResequencer" class="com.core.flow.GroupResequencer"/>
<int:service-activator id="groupResequencer1" ref="groupResequencer"/>
<int:service-activator id="groupResequencer2" ref="groupResequencer"/>
When I change my bean definition to prototype it works but the onInit() method gets called twice, once with a generic component name and the second time with the spring integration service activator id as component name.
It doesn't matter to me whether the bean is singleton or prototype but I need a clean creation that happens only once.
We need to improve that documentation - it only applies when the ref references a POJO.
Some time ago, we added an optimization to service activator such that if the ref bean is an AbstractReplyProducingMessageHandler we reference it directly rather than wrapping it in a new handler, to avoid that overhead.
Since such a bean can only have one outputChannel we can't use it in more than one endpoint. Making it a prototype means each service activator gets its own instance.
If you change your bean to a POJO rather than extending from ARPMH you can reuse it that way.

How does the Social Business Toolkit Samples application uses managed-beans.xml?

So far I have:
installed and started sbt.sample-1.0.0.20140125-1133.ear on my WebSphere Application
Server,
added an URL resource for the SBT Properties file.
The Social Business Toolkit Samples app runs fine and I'm able to connect to my IBM Connections and retrieve some ActivityStream entries.
When I first loaded the application, I noticed this error:
Exception stack trace: com.ibm.websphere.naming.CannotInstantiateObjectException: A NameNotFoundException occurred on an indirect lookup on the name java:comp/env/url/ibmsbt-managedbeansxml. The name java:comp/env/url/ibmsbt-managedbeansxml maps to a JNDI name in deployment descriptor bindings for the application performing the JNDI lookup. Make sure that the JNDI name mapping in the deployment descriptor binding is correct. If the JNDI name mapping is correct, make sure the target resource can be resolved with the specified name relative to the default initial context.
In the Samples application's ibm-web-bnd.xml file I found this line:
<resource-ref name="url/ibmsbt-managedbeansxml" binding-name="url/ibmsbt-managedbeansxml" />
And in the web.xml:
<resource-ref>
<description>Reference to a URL resource which points to the managed bean configuration for the Social Business Toolkit.</description>
<res-ref-name>url/ibmsbt-managedbeansxml</res-ref-name>
<res-type>java.net.URL</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
I'm wondering, why should there be an URL resource to the JSF Application Configuration Resource File (managed-beans.xml) in the first place? According to the Java EE documentation the JavaServer Faces implementation will look for it in the /WEB-INF/ folder.
Does the SBT uses JavaServer Faces technology somewhere? Or can I choose not to use the managed-beans.xml file in my own applications that use the SBT?
I wouldn't recommend you consider them related. managed-beans.xml had a prior name, and it's just a set of configuration objects. The project itself does not use Java Server Faces.
I just read the documentation again, more carefully than the first time, and I think I now have a better understanding of what I asked in my second question. From the documentation:
In a web application SBTFilter (HTTP servlet filter) is responsible
for initializing the application using servlet context. Application
does the initialization like loading the managed beans and properties
factories.
The sample app is a web application. I think in my own application I can choose to use com.ibm.commons.runtime.impl.app.ApplicationStandalone instead of com.ibm.commons.runtime.impl.servlet.ApplicationServlet and then configure an endpoint programmatically. Or alternatively do not use an Application at all, like so:
RuntimeFactory runtimeFactory = new RuntimeFactoryStandalone();
Application application = runtimeFactory.initApplication(null);
Context.init(application, null, null);

Global request/response interceptor

What would be the easiest way to setup a request/response interceptor in ServiceStack that would execute for a particular service?
A request filter (IHasRequestFilter) works fine but a response filter (IHasResponseFilter) is not triggered if the service returns non 2xx status code. I need to retrieve the status code returned by the method as well as the response DTO (if any).
A custom ServiceRunner and overriding the OnBeforeExecute and OnAfterExecute methods seems to work fine but I find it pretty intrusive as the service runner need to be replaced for the entire application and I couldn't find a way clean way to isolate per functionality the tasks that need to be executed in those methods.
Is there some extension point in ServiceStack that I am missing that would allow me to execute some code before each service method and after each service method? A plugin would be ideal but how can I subscribe to some fictitious BeforeExecute and AfterExecute methods that would allow me to run some custom code?
UPDATE:
Just after posting the question I found out that global response filters are executed no matter what status code is returned by the service which is exactly what I needed. So one last question: Is it possible to retrieve the service type that will handle the request in a request filter? I need to check whether this service is decorated by some custom marker attribute.
I have found out a solution to my question about how to retrieve the service type in a custom request/response filter:
appHost.RequestFilters.Add((req, res, requestDto) =>
{
var metadata = EndpointHost.Metadata;
Type serviceType = metadata.GetServiceTypeByRequest(requestDto.GetType());
...
}
A custom ServiceRunner and overriding the OnBeforeExecute and OnAfterExecute methods seems to work fine but I find it pretty intrusive as the service runner need to be replaced for the entire application
Quick note, you can opt-in and choose only what requests should use a custom service runner, e.g:
public override IServiceRunner<TRequest> CreateServiceRunner<TRequest>(
ActionContext actionContext)
{
return useCustomRunner(actionContext.RequestType)
? new MyServiceRunner<TRequest>(this, actionContext)
: base.CreateServiceRunner<TRequest>(actionContext);
}
IHttpRequest has OperationName. I think thats what you are after.

Resources