Currently I am unable to grab -> archive -> decrypt a file from an SFTP server. I have tested the logic using local directories but with no success using SFTP.
The connection appears to be established to the server as neglecting to pass the private key will result in a connection exception. When the key is being passed no exception is given from the route itself but no files are copied. What would be a potential solution or next steps to help in troubleshooting this issue?
I am using the absolute directory's in which the files would be stored from the sftp location.
CamelContext camelContext = new DefaultCamelContext();
camelContext.getRegistry().bind("SFTPPrivateKey",Byte[].class,privateKey.getBytes());
String sftpInput = buildURISFTP(input,inputOptions,connectionConfig);
String sfpOutput = buildURISFTP(output,outputOptions,connectionConfig);
String sfpArchive = buildURISFTP(archive,archiveOptions,connectionConfig);
camelContext.addRoutes(new RouteBuilder() {
public void configure() throws Exception {
PGPDataFormat pgpDataFormat = new PGPDataFormat();
pgpDataFormat.setKeyFileName(pPgpSecretKey);
pgpDataFormat.setKeyUserid(pgpUserId);
pgpDataFormat.setPassword(pgpPassword);
pgpDataFormat.setArmored(true);
from(sftpInput)
.to(sfpArchive);
//tested decryption local with file to file routing
.unmarshal(pgpDataFormat)
.to(sfpOutput);
}
});
camelContext.start();
Thread.sleep(timeout);
camelContext.stop();
public String buildURISFTP(String directory, String options, ConnectionConfig connectionConfig){
StringBuilder uri = new StringBuilder();
uri.append("sftp://");
uri.append(connectionConfig.getSftpHost());
uri.append(":");
uri.append(connectionConfig.getSftpPort());
uri.append(directory);
uri.append("?username=");
uri.append(connectionConfig.getSftpUser());
if(!StringUtils.isEmpty(connectionConfig.getSftpPassword())){
uri.append("&password=");
uri.append(connectionConfig.getSftpPassword());
}
uri.append("&privateKey=#SFTPPrivateKey");
if(!StringUtils.isEmpty(options)){
uri.append(options);
}
return uri.toString();
}
Issue was due to lack of knowledge around FTP component
https://camel.apache.org/components/3.18.x/ftp-component.html
Where it is specified that absolute paths are not supported, unfortunately I did not read this page and only referenced the SFTP component page where it is not specified.
https://camel.apache.org/components/3.18.x/sftp-component.html
Issue was resolved by backtracking directories with /../../ before giving the absolute path.
Related
I have the following prefix:
String prefix = TemplatesReader.class.getClassLoader().getResource("templates/").getPath();
and have method
public byte[] read(String pathToTemplate) {
return Files.readAllBytes(Paths.get(prefix + pathToTemplate));
}
in intellij idea works correctly, but when starting jar an error occurs:
java.nio.file.NoSuchFileException: file:/app.jar!/BOOT-INF/classes!/templates/request-orders/unmarked/RequestOrderUnmarked.pdf
You must not assume that a resource is a file. When the resource is inside a .jar file, it is a part of that .jar file; it is no longer a separate file at all.
You cannot use Files or Paths to read the resource.
You cannot use the getPath() method of URL. It does not return a file name. It only returns the path portion of the URL (that is, everything between the URL’s scheme/authority and its query portion), which is not a file path at all.
Instead, read the resource using getResourceAsStream:
private static final String RESOURCE_PREFIX = "/templates/";
public byte[] read(String pathToTemplate)
throws IOException {
try (InputStream stream = TemplatesReader.class.getResource(
RESOURCE_PREFIX + pathToTemplate)) {
return stream.readAllBytes();
}
}
I checked all over the internet and still cannot find the correct answer. I want to upload a file to the resources folder from Spring. So I can get the file from the heroku server when I deploy it.
For example applicationname/herokuapp.com/image.jpg
The structure of my app:
I tried and got a few problems :
File not found exception
Illegal char <:> at index 2
The file path I get is in the target folder??
Can't find path
I just need to get the correct path to the resources folder but I can't get it.
My controller with the following method looks like this:
#PostMapping(value = "/sheetmusic")
public SheetMusic create(HttpServletRequest request, #RequestParam("file") MultipartFile file, #RequestParam("title") String title, #RequestParam("componist") String componist, #RequestParam("key") String key, #RequestParam("instrument") String instrument) throws IOException {
URL s = ResourceUtils.getURL("classpath:static/");
String path = s.getPath();
fileService.uploadFile(file,path);
SheetMusic sheetMusic = new SheetMusic(title,componist,key,instrument,file.getOriginalFilename());
return sheetMusicRepository.save(sheetMusic);
}
The FileService:
public void uploadFile(MultipartFile file, String uploadDir) {
try {
Path copyLocation = Paths
.get(uploadDir + File.separator + StringUtils.cleanPath(file.getOriginalFilename()));
Files.copy(file.getInputStream(), copyLocation, StandardCopyOption.REPLACE_EXISTING);
} catch (Exception e) {
e.printStackTrace();
}
}
I read something about jar but I don't understand it. I did not think it was this hard to just upload a file to a folder but I hope you guys can help me out!
EDIT :
When I add this :
String filePath = ResourceUtils.getFile("classpath:static").toString();
It will upload to the target folder which is not right.
EDIT 2 : IT IS FIXED
This is the right way to get the correct path :
String path = new File(".").getCanonicalPath() + "/src/main/webapp/WEB-INF/images/";
fileService.uploadFile(file,path);
My folder structure is the following:
main
-java
- webapp
- WEB-INF
- images
Then I had to put this code into my MainApplicationClass
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// Register resource handler for images
// Register resource handler for images
registry.addResourceHandler("/images/**").addResourceLocations("/WEB-INF/images/")
.setCacheControl(CacheControl.maxAge(2, TimeUnit.HOURS).cachePublic());
}
What you are trying to do here (replacing a file/uploading a file INTO a package .jar file) does not work, it is literally impossible.
You need to upload your file somewhere else, be that S3, some network drive etc, so that you application can reference it.
I'm trying to use AntiSamy to prevent XSS attacks on my site. I downloaded the following jars and added them to "/WEB-INF/lib"
antisamy-1.5.3.jar
nekohtml.jar
xercesImpl-2.5.0.jar
along with a policy file antisamy-slashdot-1.4.4.xml in "/WEB-INF".
I tried to implement a filter through web.xml. A snippet of the servlet I'm using is
public class AntiSamyFilter implements Filter {
private static final Logger LOG = Logger.getLogger(AntiSamyFilter.class);
private final AntiSamy antiSamy;
public AntiSamyFilter() {
try {
URL url = this.getClass().getClassLoader().getResource("antisamy-slashdot-1.4.4.xml");
LOG.info("After getResource");
Policy policy = Policy.getInstance(url.getFile()); //Deployment fails
LOG.info("After Policy");
antiSamy = new AntiSamy(policy);
LOG.info("After antiSamy");
} catch (PolicyException e) {
throw new IllegalStateException(e.getMessage(), e);
}
}
}
The deployment fails after Policy policy = Policy.getInstance(url.getFile());. It's probably because of the path of the policy file.
Can someone please tell me where the policy file should be kept?
The url.getFile part fails because it couldn't find the antisamy-slashdot-1.4.4.xml file. I created a package in src/my/package and changed
URL url = this.getClass().getClassLoader().getResource("antisamy-slashdot-1.4.4.xml");
to
URL url = this.getClass().getClassLoader().getResource("/my/package/antisamy-slashdot-1.4.4.xml");
I also added batik.jar along with the other jar files. It solved my problem
I have a very basic question. I need a URL object but the file is in the previous directory relative to the project.
For instance, if I do
File testFile = new File("../../data/myData.xml");
works perfectly fine, it finds the file
However,
URL testURL = new URL("file:///../../data/myData.xml")
gives an
Exception in thread "main" java.io.FileNotFoundException: /../../data/myData.xml
Any idea, how to solve, work around this? without changing the position of the data?
Thanks a lot in advance
Altober
you can use this
URL testURL = new File("../../data/myData.xml").toURI().toURL();
/**
* #param args
*/
public static void main(String[] args) {
try {
URL testUrl = new URL("file://C:/Users/myName/Desktop/abc.txt");
System.out.println(testUrl.toString());
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
}
The above code is working file, just tested it, so you need to use file:// and if possible try full path
Exception in thread "main" java.io.FileNotFoundException: /../../data/myData.xml
Note that it is looking for parent directory of root directory, not of current directory.
I dont know if File URLs can refer to relative paths, try
‘new URL("file://../../data/myData.xml")'‘
I am using org.apache.commons.net.ftp.FTPClient in one of my applications to work with a FTP server. I am able to connect, login, pwd and cwd. However, when I try to list the files it doesn't return the list of files in that directory, where I know for sure that there are files. I am using the method FTPFile[] listFiles(), it returns an empty array of FTPFile.
Please find below the code snippet where I am trying this:
String hostname = properties.getProperty("FTP_SERVER");
String user = properties.getProperty("FTP_USER");
String passwd = properties.getProperty("FTP_PASSWD");
FTPClient client = new FTPClient();
client.connect(hostname);
client.login(user, passwd);
String reply = client.getStatus();
System.out.println(reply);
client.enterRemotePassiveMode();
client.changeWorkingDirectory("/uploads");
FTPFile[] files = client.listFiles();
System.out.println(files.length);
for (FTPFile file : files) {
System.out.println(file.getName());
}
String[] fileNames = client.listNames();
if (fileNames != null) {
for (String file : fileNames) {
System.out.println(file);
}
}
client.disconnect();
This seems like the same issue I had (and solved), see this answer:
Apache Commons Net FTPClient and listFiles()
After I set the mode as PASV it is working fine now!
Thanks for all your efforts and suggestions!
I added client.enterLocalPassiveMode() and it works:
client.connect("xxx.com");
boolean login = client.login("xxx", "xxx");
client.enterLocalPassiveMode();
Just a silly suggestion... can you do a listing on the /uploads folder using a normal FTP client. I ask this because some FTP servers are setup to not display the listing of an upload folder.
First, make sure the listing works in other programs. If so, one possibility is that the file listing isn't being parsed correctly. You can try explicitly specifying the parser to use with initiateListParsing.
I had to same problem and it turned out to be that it couldn't parse what the server was returning for a file listing. I this line after connecting to the ftp server ftpClient.setParserFactory(new MyFTPFileEntryParserFactory());
public class MyFTPFileEntryParserFactory implements FTPFileEntryParserFactory {
private final static FTPFileEntryParser parser = new UnixFTPEntryParser() {
#Override public FTPFile parseFTPEntry(String entry) {
FTPFile ftpFile = new FTPFile();
ftpFile.setTimestamp(getCalendar(entry));
ftpFile.setSize(get(entry));
ftpFile.setName(getName(entry));
return ftpFile;
}
};
#Override public FTPFileEntryParser createFileEntryParser(FTPClientConfig config) throws ParserInitializationException {
return parser;
}
#Override public FTPFileEntryParser createFileEntryParser(String key) throws ParserInitializationException {
return parser;
}
}
In my case, on top of applying enterLocalPassiveMode and indicating correct operation system, I also need to set UnparseableEntries to true to make the listFile method work.
FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_UNIX);
conf.setUnparseableEntries(true);
f.configure(conf);
boolean isLoginSuccess = client.login(username, password);