Spring Integration doesn't synchronize with FTP mainframe system - spring-integration

I am trying to sycronize an FTP folder with a local directory. This FTP server is running on z/OS, it's a mainframe with he MVS operating system.
So far I've had a lot of problems even to manage to connect to the folder I needed because this system doesn't have a "normal" folder system.
This is what I've done to change to the working directory where my files are:
public class DefaultFtpHostSessionFactory extends DefaultFtpSessionFactory {
protected void postProcessClientAfterConnect(FTPClient ftp) throws IOException {
ftp.changeToParentDirectory();
ftp.changeWorkingDirectory("E377D.");
}
}
Now I've defined an input-channel-adapter:
<int-ftp:inbound-channel-adapter
id="ljFtpInbound"
channel="ljFtpChannel"
session-factory="ljCachingSessionFactory"
auto-create-local-directory="true"
delete-remote-files="false"
filename-pattern="*"
remote-directory="*"
remote-file-separator=""
charset="UTF-8"
auto-startup="true"
preserve-timestamp="false"
local-filename-generator-expression="#this.toUpperCase()"
temporary-file-suffix=".writing"
local-directory="/tmp/">
<int:poller fixed-rate="1000" />
</int-ftp:inbound-channel-adapter>
As you can notice the remote directory is "*", that's for listing the directory, at least is the only way I've managed to do it.
But when FtpInboundFileSynchronizer tries to synchronize the folder I get an error because when it tries to copy the file the path is build with:
String remoteFilePath = remoteDirectoryPath + remoteFileSeparator + remoteFileName;
Which in my case would be "ASTERISK" + "BLANK" + "REMOTE_FILE_NAME", because I had to use "*" as the remote-directory, so it doesn't find the file.
¿Do you know if I can not to set the remote-directory (which I tried but didn't achieve)? Or there is another way to synchronized this weird FTP system.
Thank you.

How about this?
Starting with version 4.3, The remote-directory/remote-directory-expression attributes can be omitted assuming null. In this case, according to the FTP protocol, the Client working directory is used as a default remote directory.
That means you should try to upgrade to Spring Integration 4.3 and remove that strange * at all.

Related

How to hide Tomcat version from error messages when using embedded servers in Java

I have a java application where i'm using embedded Tomcat servers,
which looks like this
Tomcat tomcat = new Tomcat()
I'm creating an embedded tomcat server here.
Problem statement
whenever there's an error it displays information on which tomcat version i'm using,
how to hide this in java?
i have a little idea that i need to override ServerInfo.properties, but how do i do this?
I'm not sure how we can do this in java, but if you are using any build scripts like ant / gradle for distribution purpose, we can write a task to override / harden the jar file, and replace the ServerInfo.properties file with the customized value whatever we need.
the code for ant build scripts would look like
<target name="override.tomcat">
<jar destfile="path/to/tomcat-embed-core-9.0.62.jar" update="true">
<fileset dir="src/"> <!-- folder where you keep the directory/file to raplace-->
<include name="org/apache/catalina/util/ServerInfo.properties"/> <!-- file to replace within directory path in side the jar-->
</fileset>
</jar>
</target>
and in gradle
task overRideTomcat(type: Jar) {
from(zipTree(file("path/to/tomcat-embed-core-9.0.62.jar"))) {
exclude '**/org/apache/catalina/util/ServerInfo.properties'
}
from('src/') {
include('/org/apache/catalina/util/ServerInfo.properties')
}
archiveName "tomcat-embed-core-9.0.62.jar"
}
make sure you have the modified ServerInfo.properties file under src directory in the same path as you have mentioned in the include statement.

Controller Route not found in production environment

The problem: I am currently working on a custom plugin for Shopware 6 with the development template (https://github.com/shopware/development) and testing it on localhost.
The goal is to use my plugin for our online shop which runs on the production environment (https://github.com/shopware/production)
My problem is that my plugin works exactly like I want on localhost, but not anymore if I upload it to our production environment.
Example: I wrote a new API Controller that introduces a new Route, which does basically the same as the SyncController does but with a little extra logic.
* #Route("/api/v{version}/_action/my-extension/sync",
* name="api.action.my-extension.sync",
* methods={"POST"}
* )
The entry in my services.xml:
<service id="MyExtension\Api\Controller\CustomSyncController" public="true">
<argument type="service" id="Shopware\Core\Framework\Api\Sync\SyncService"/>
<argument type="service" id="serializer"/>
<call method="setContainer">
<argument type="service" id="service_container"/>
</call>
</service>
The entry in my routes.xml:
<import resource="../../Api/Controller" type="annotation" />
As I understand it, that should be sufficient to let Shopware 6 know what my Route is and I should be able to send my POST Request to this Route.
Everything works fine on localhost.
My question:
What steps do I have to take to use this plugin on our production environment, because I always get this message on production:
{"errors":[{"code":"0","status":"404","title":"Not Found","detail":"No route found for \u0022POST \/api\/v3\/_action\/my-extension\/sync\u0022"}]}
What I tried to make it work:
just ZIP the folder custom/plugins/MyExtension and upload my plugin to production.
upload my plugin to localhost, run ./psh.phar administration:build, download the folder from localhost, ZIP this folder and upload it to production.
upload my plugin to localhost, run ./psh.phar administration:build and ./psh.phar storefront:build, download the folder from localhost, ZIP this folder and upload it to production.
After uploading my plugin also start the script "build-administration.sh" and "build-storefront.sh" on our production environment.
Currently I am lost, because I can´t understand what steps are necessary to get the same results in the production environment that I get on localhost.
Meybe you try this in your routes.xml.
<import resource="../../Api/Controller/**/*.php" type="annotation" />
Also the routes.xml file must be located in src/Resources/config/routes.xml in your plugin.
Also you didn't mentioned the installation of the plugin, so you also have to install and activate it.

Could not read log4j.properties

We are having a module which contains log4j.properties and other files in it. And there is a separate module which is dependent on the 1st module(Realign). So we had made the 1st module as a jar file and placed it in the WEB-INF/lib folder of the second module(Reasign). We are running the modules in Liberty server. But still we are getting the File Not found exception as below,
log4j:ERROR Could not read configuration file
[file:/metlife/runtime/installed/wlp/usr/servers/bobr/apps/expanded/bobr.ear/BOBReassignmentWeb.war/WEB-INF/lib/Realignment.jar!/r_resources/log4j.properties].
[9/12/18 8:28:51:591 EDT] 000002de SystemErr R java.io.FileNotFoundException:
file:/metlife/runtime/installed/wlp/usr/servers/bobr/apps/expanded/bobr.ear/BOBReassignmentWeb.war/WEB-INF/lib/Realignment.jar!/r_resources/log4j.properties (No such file or directory)
It looks like your PropertiesConfigurator class is taking a file path (as a String). If you used a URL instead, I think that would work - that way, you would get a JAR URL which includes the path to the JAR (or WAR, EAR, etc.) archive and the path inside the JAR. If you have control over the PropertiesConfigurator code, then I would recommend changing it so that it loads the file via URL.
If that is not an option, then you could extract the properties files and put them on the file system directly. For example, you could create a directory in your server directory (for an example, we'll call it log4jProps). Then you could create a shared library in your server config (server.xml) like this:
<library id="log4j.props">
<fileset dir="${server.config.dir}/log4jProps" includes="r_resources/*properties"/>
</library>
then update your application configuration to use this library as a common shared library:
<application id="myApp" name="myApp" location="myApp.war"...>
<classloader commonLibraryRef ="log4j.props" />
</application>
For good measure, you should probably remove the properties file from your application archives - that way they won't be loaded from there, and then throw off the PropertiesConfigurator like it is now.
Hope this helps,
Andy

Spring integration : int-sftp:inbound-channel-adapter : How to check if the source folder is empty

I use the int-sftp:inbound-channel-adapter to download files from remote directory.
I would like to check if the remote directory is empty , so after a timeout, i stop download and shutdown application.
So how to check that remote directory is empty and how to use a timeout?
my source code:
<int-sftp:inbound-channel-adapter id="sftpInbondAdapter"
auto-startup="true" channel="receiveChannel" session-factory="sftpSessionFactory"
local-directory="file:${directory.files.local}" remote-directory="${directory.files.remote}"
auto-create-local-directory="true" delete-remote-files="true"
filename-pattern="*.txt" >
<int:poller
max-messages-per-poll="-1" error-channel="sftp.in.error.channel"/>
</int-sftp:inbound-channel-adapter>
Thanks
There is currently no indication when the remote folder is empty.
You might find it easier to use the outbound gateway instead.
You can configure one to use the ls command to list the files, and another to get (or mget) the files.

Unable to load so file from Java in Eclipse On Ubuntu

I have some code that tries to load a C library as follows :-
public ThreadAffinity() {
ctest = (CTest) Native.loadLibrary("ctest", CTest.class);
}
However I get the following error when trying to build the project; The error I get is as follows :-
UnsatisfiedLinkError: Unable to load library 'libctest': liblibctest.so: cannot open shared object file: No such file or directory
at com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:166)
at com.sun.jna.NativeLibrary.getInstance(NativeLibrary.java:239)
at com.sun.jna.Library$Handler.<init>(Library.java:140)
at com.sun.jna.Native.loadLibrary(Native.java:393)
at com.sun.jna.Native.loadLibrary(Native.java:378)
at com.threads.ThreadAffinity.<init>(ThreadAffinity.java:11)
at com.threads.ThreadAffinity.main(ThreadAffinity.java:45)
The current working directory is the root of the project and thats where the so file is located. I also tried modifying the LD_PRELOAD variable to point to my so file; however the error persists.
It works just fine on my OSX where the dylib is located exactly where the so file is currently(project root).
What am I doing wrong?
From the exception:
UnsatisfiedLinkError: Unable to load library 'libctest': liblibctest.so: cannot open shared object file: No such file or directory
It implies you used something like:
public ThreadAffinity() {
ctest = (CTest) Native.loadLibrary("libctest", CTest.class);
}
and not:
public ThreadAffinity() {
ctest = (CTest) Native.loadLibrary("ctest", CTest.class);
}
hence you see the JNA added prefix of lib and postfix of .so added to libctest (liblibctest.so)
LD_PRELOAD is used when you want to prefer one particular version of the same shared library over another, which doesn't apply here.
Define jna.library.path to point to your project root, and JNA should be able to find it.
Also make sure your library has been built as libctest.so and wasn't inadvertently named libctest.dylib.

Resources