Spring Integration SFTP - Getting configurations from XML - java

Let say I have these configurations in my xml,
<int-sftp:outbound-channel-adapter id="sftpOutbound"
channel="sftpChannel"
auto-create-directory="true"
remote-directory="/path/to/remote/directory/"
session-factory="cachingSessionFactory">
<int-sftp:request-handler-advice-chain>
<int:retry-advice />
</int-sftp:request-handler-advice-chain>
</int-sftp:outbound-channel-adapter>
How can I retrieve the attributes i.e, remote-directory in Java class ?
I tried to use context.getBean('sftpOutbound') but it returns EventDrivenConsumer class which doesn't have methods to get the configurations.
I'm using spring-integration-sftp v 4.0.0.

I am actually more concerned with why you wan to access it. I mean the remote directory and other attributes will come with the headers of each message, so you will have access to it at the Message level, but not at the level of Event Driven Consumer and that is by design, hence my question.

Related

Create a not connected PublishSubscribeChannel with subflows

Long story short: I need to have something like below.
PublishSubscribeChannel firstChannel = new PublishSubscribeSpec(executor).subscribe(subFlow -> ...).get();
Is there a way to create a pubsub channel with subflows which is not (yet) connected to any other flow?
The snippet is not working because of PublishSubscribeSpec(Executor) has protected access in PublishSubscribeSpec.
I will need to register channels like this dynamically without any information about which flow(s) will be using these channels.
has protected access in PublishSubscribeSpec
That was exactly a reason to make it protected - to avoid an unusual configuration problem like your. The subflow cannot be provided like this in the plain PublishSubscribeChannel definition. It is part of Java DSL parser in the framework to determine such a configuration and register respective beans in the application context. With that explicit get() call you just fully eliminate a hook for Java DSL parser to understand your configuration.
without any information about which flow(s) will be using these channels.
That's not true according your .subscribe(subFlow -> intention. Adding a subflow to the PublishSubscribeSpec is indeed "an information which flow will be using these channel".
Perhaps we need to look into your business requirement from another angle. There is no reason to be stuck with subflows approach when we simply can use a PublishSubscribeChannel from any other place where a MessageChannel is needed as an input. I mean if you just create a plain PublishSubscribeChannel and then use it for example for the IntegrationFlows.from(MessageChannel) factory, you'll get the same runtime result as you would expect from those .subscribe(subFlow -> connections.

How to get UpsertResult when using Mongo Outbound channel adapter?

I'm using spring integration to store data in a mongo database. I'm using the java classes (MongoDbStoringMessageHandler), not the xml configuration and I can't find the way to get the results when adding some data in the database...
Is it possible ? How ?
The MongoDbStoringMessageHandler is a one-way component and it doesn't return anything.
Consider to use a MongoDbOutboundGateway instead with the CollectionCallback injected where you can perform an updateMany() and get UpdateResult as a reply from this gateway.
See more info in the Reference Manual: https://docs.spring.io/spring-integration/reference/html/mongodb.html#mongodb-outbound-gateway
UPDATE
but I don't know what parameter to put for the function to insert the Message payload.... Since there is no reference of the message in the ServiceActivator
Oh! I see. That a bug. We can't get access to the message from that context. Please, raise a JIRA on the matter: https://jira.spring.io/projects/INT/
Meanwhile as a workaround I suggest you ti write a custom POJO with injected MongoOperations and ther you can build any possible logic against a requestMessage.
The JIRA is here: https://jira.spring.io/browse/INT-4570

How to modify a camel endpoint at runtime

The problem
I have a spring mvc application that uses apache camel. I am confused on the role that the RouteBuilder class plays and how it actually gets initialized. I know that the docs say that the configure() method is:
Called on initialization to build the routes using the fluent builder syntax.
but when does this initialization occur? Does it occur at application startup or some time later when the route is about to be used?
The purpose of this question is ultimately to ask how I can modify the route at runtime. I want to be able to build different routes as needed.
Examples
xml definitions:
<service name="myService" tier="3">
<requestType>my.package.RequestType</requestType>
<responseType>my.package.ResponseType</responseType>
<endpoint>
<httpEndpoint>
<url default="true" value="someUrl"/>
<timeout value="5000"/>
</httpEndpoint>
</endpoint>
</service>
Route Builder template:
public class myRouteBuilder extends RouteBuilder {
#Override
public void configure() throws Exception {
// When does this method get executed?
}
}
Questions
When does configure() execute?
How can I dynamically set the endpoint url?
You are able to use toD to dynamically change the endpoint at runtime based on an expression. See the documentation
If you want to change more of the route or add a completely new route then look at the API on the CamelContext. This Stackoverflow question has an example of adding a completely new route.
The lifecycle of the Camel service is documented here : https://camel.apache.org/lifecycle.html
Camel uses a simple lifecycle interface called Service which has a single start() and stop() method.
Various classes implement Service such as CamelContext along with a number of Component and Endpoint classes.
When you use Camel you typically have to start the CamelContext which will start all the various components and endpoints and activate the routing rules until the context is stopped again.
It is when the context starts that the various components start. Not sure i understand the dynamic url part. If it is to indicate a dynamic endpoint (if the data is this , then queue1 else queue2) you should be able to use something like the DynamicRouter EIP which is as explained here (https://camel.apache.org/dynamic-router.html)
You have several options.
Inject them as spring properties.
Inject them from external properties source.
Inject them from some bean method.
Then you can put the property value in a header and later put the value in the .toD("$header.routeEndpoint"). This can take care of dynamic endpoints.
Off course to rebuild the entire route you need to play with the API.

Get parameter from static context in axis2

While trying to move an axis2 web-app from glassfish3 to tomcat6, I can't seem to find a way to get a config parameter from a static context.
In glassfish3, a system property was defined in a far away place and read from the application using System.getProperty(String name). Not only does the web agree that this is not the way to go for a web application, this trick is just not feasible for tomcat (tomcat docs).
Reading parameters from the ServletContext is also not feasible as the app uses axis2 and I can't seem to find a way to access any kind of servlet voodoo from the static context that initializes the app's configuration.
services.xml (the file containing the service description for axis2) can contain <parameter> nodes, so that seems a nice place to configure the configuration location, but I can't seem to find a way to read these parameters from the application.
So in short: any ideas on how to get a value configured outside the application's code available from a static context?
(answer listed here as StackOverflow does not allow me to answer my own question...)
After scouring the Internet some more, a solution was found using an implementation of org.apache.axis2.engine.ServiceLifeCycle, which could read a parameter in the startUp-method as such:
Parameter param = service.getParameter("name");
if (param != null) {
saveParamValue(param.getValue().toString());
} else {
// log warning on falling back to System.getProperty()
}
The life cycle class is attached using class="fully.qualified.ClassName" on the <service> node of the services.xml file used by axis2.
This works, now the application just crashes on something else (but that has little to with this issue).
The parameters in services.xml can be accessed by getting the ServiceContext object for the service, then calling ServiceContext.getParameter(). If your service implementation class implements the Lifecycle interface, then Axis2 will call Lifecycle.init() every time it creates a new instance of the service class. The argument to Lifecycle.init() is the service's ServiceContext. Your init() implementation could save the context object or look up the parameters that you're interested in.

Secure Module across multiple controllers

Using Play 1.2.3 I am trying to implement the Secure Module across multiple controllers.
I have added - play -> secure to my dependencies and the secure module appears in my project. I have imported the default secure routes * / module:secure, customised the authenitcation method and annotated all of my controllers using the #With(Secure.class).
The problem that I am having is that when I move between controllers I receive a Null Pointer Exception thrown from the secure:module at line 193: return Java.invokeStaticOrParent(security, m, args);
A second issue that I am having is that when methods are called from within the same controller, some calls can take up to 20 seconds to complete where they would normally be instant without the secure module included. Edit: this was unrelated - the secure module has no visible effect on loading time
My question is has anyone else implemented the secure module in Play across multiple controllers, and if so, did they come across any of these issues?
Edit
The problem was down to the use of a tag in my template - not in the implementation of the secure module. See below for reason and how to resolve.
The reason the null pointer exception was being thrown was because in my template I was calling:
#{secure.check}
<li>Logout</li>
#{/secure.check}
I had oddly thought this was a template tag to check whether there was security enabled - but it actually needs be followed by a 'profile' type - which is not something I specified nor have implemented (hence the exception).
To get around this, I added a basic template tag that checks whether the security associated session is in use:
#{if session.username}
#{doBody /}
#{/if}
And can simply implement as follows:
#{secure.secure}
<li>Logout</li>
#{/secure.secure}

Categories