How to upload file to remote FTP Server in grails - file

I am new to Grails framework. I have a requirement to upload text file to remote FTP Server through batch application in Grails. Request if anyone has a suggestion, step by step process to how to connect to remote server and upload the file.
Thanks in advance.

First, include commons-net in your BuildConfig.groovy (Grails 2.x) or build.gradle (Grails 3.x):
compile 'commons-net:commons-net:3.3'
Secondly add a service:
class UploadService {
GrailsApplication grailsApplication
String upload(String fileName, InputStream inputStream) {
String status
new FTPClient().with {
connect grailsApplication.config.getProperty('ftp.host')
login grailsApplication.config.getProperty('ftp.username'), grailsApplication.config.getProperty('ftp.password')
enterLocalPassiveMode()
setFileType(BINARY_FILE_TYPE)
changeWorkingDirectory grailsApplication.config.getProperty('ftp.uploadDir')
storeFile(fileName, inputStream)
status = replyString
disconnect()
}
return status
}
}
Update:
I forgot to add the configuration that needs to go into grails-app/conf/Config.groovy (Grails 2.x) or grails-app/config/application.groovy:
ftp {
host = 'some.host'
username = 'myuser'
password = '*****'
uploadDir = 'Uploads'
}
It would also be possible to create the FTPClient() instance in resources.groovy and use dependency injection instead.
bean = {
ftpClient(FTPClient)
}
and then have this in the service:
class UploadService {
GrailsApplication grailsApplication
FTPClient ftpClient // Will be injected
String upload(String fileName, InputStream inputStream) {
String status
ftpClient.with {
// Same as above
}
}
}
Which would allow you to unit-test the class, where you simply mock out FTPClient

Related

Spring Integration + file reading message source _ Inbound Channel Adapter + Outbound Gateway

For File reading message source Inbound Adapter and transformer
with annotations is configured as below
#Bean
#InboundChannelAdapter(autoStartup = "false", value = "incomingchannel", poller = #Poller("custompoller"))
public MessageSource<File> fileReadingMessageSource() {
}
#Transformer(inputChannel = "incomingchannel", outputChannel = "jobLaunchChannel")
public JobLaunchRequest toRequest(Message<File> message) throws Exception {
}
Now I want to change the Transformer to refer to a reply channel of outbound gateway i.e. which moves the files from one directory to another directory i.e. move the file from incomingchannel directory to a different directory and the process or transform he file or perform some validations
<file:outbound-gateway id="mover" request-channel="incomingchannel" reply-channel="newdirectory" directory="<<path to new directory file to be moved" delete-source-files="true"/>
Anyone has converted above XML configuration to annotation configurations or any ideas?
After annotation configurations I will have to change the transformer input channel to refer to newdirectory channel i.e. which is a reply channel of messaging gateway...
Thanks in advance for any help ot suggestions regarding this
--- Update 1 after trying out the snippet provided in link by Artem
#Bean
#ServiceActivator(inputChannel = "incomingchannel")
public MessageHandler fileWritingMessageHandler() {
FileWritingMessageHandler handler = new FileWritingMessageHandler(new File(newdirectorypath));
handler.setFileExistsMode(FileExistsMode.APPEND);
handler.setDeleteSourceFiles(true);
return handler;
}
#MessagingGateway(defaultRequestChannel = "incomingchannel", defaultReplyChannel = "newdirectorychannel")
public interface MyGateway {
void writeToFile(#Header(FileHeaders.FILENAME) String fileName, #Header(FileHeaders.FILENAME) File directory,
String data);
}
But there are two problems encountered
Inbound Adapter is trying to poll the directory also as file (Recursive Directory scanner is used) - How to ensure that directory is not polled as a file
nested exception is org.springframework.messaging.core.DestinationResolutionException: no output-channel or replyChannel header available, failedMessage=GenericMessage [payload=C
Ok. Since it looks like you would like to place the FileWritingMessageHandler after #InboundChannelAdapter and before #Transformer, so this should like:
#Bean
#InboundChannelAdapter(autoStartup = "false", value = "incomingchannel", poller = #Poller("custompoller"))
public MessageSource<File> fileReadingMessageSource() {
}
#Bean
#ServiceActivator(inputChannel = "incomingchannel")
public MessageHandler fileWritingMessageHandler() {
FileWritingMessageHandler handler = new FileWritingMessageHandler(new File(newdirectorypath));
handler.setFileExistsMode(FileExistsMode.APPEND);
handler.setDeleteSourceFiles(true);
handler.setOutputChannelName("jobLaunchTransfromerCannel");
return handler;
}
#Transformer(inputChannel = "jobLaunchTransfromerCannel", outputChannel = "jobLaunchChannel")
public JobLaunchRequest toRequest(Message<File> message) throws Exception {
}
This way an #InboundChannelAdapter sends a File into a FileWritingMessageHandler for its logic, which produces a result file for the next in flow #Transformer to convert a result file into a JobLaunchRequest. And only after that a message is going to be sent to the jobLaunchChannel to file a Spring Batch Job.

MSF4J: Serving static content

Can MSF4J application serve static content without using the Mustache template engine. I have developed a REST service which will be consumed by an already developed angular web app. Now I need to package the same angular app with the micro service so it will render in the browser and will consume the service via ajax calls.
MSF4J does not directly support serving static content. From your question what I understood is that you want to point the MSF4J server to a directory and serve resources in that directory by their relative path or something similar. In this case what you can do is to write an MSF4J service method with a wildcard path and serve the static content that matches the path of the request.
#Path("/")
public class FileServer {
private static final String BASE_PATH = "/your/www/dir";
#GET
#Path("/**")
public Response serveFiles(#Context Request request) {
String uri = request.getUri();
System.out.println("Requested: " + uri);
File file = Paths.get(BASE_PATH, uri).toFile();
if (file.exists()) {
return Response.ok().entity(file).build();
} else {
return Response.status(404).entity("<h1>Not Found</h1>").build();
}
}
}

How to write logs data in a local txt file?

I have an AIR-app and I want it to write down logs to a txt file in its application directory.
I have this class:
public class Logger
{
public static function log(message:String):void
{
var logFile:File = File.applicationDirectory;
logFile = logFile.resolvePath("log/Logs.txt");
var fileStream:FileStream = new FileStream();
fileStream.open(logFile, FileMode.APPEND);
fileStream.writeUTFBytes("\n" + message);
fileStream.close();
}
}
}
After installation my app has this file structure
log
--Logs.txt
META-INF
xml
airapp.exe
airapp.swf
mimetype
So the path I'm using is correct.
But no writes happen to the file!
Could you help me with that please?
Thanks
Upd. Ok, I'm stupid. I should have read documentation properly first.
You cannot edit data in application directory.
So I should use applicationStorageDirectory.
But how can I create a file in that directory once (on app installation) and then append logs in it?
Try the following....
function saveLog(logStr:String):void
{
var myFile:File = File.applicationStorageDirectory.resolvePath("my_logs.txt");
var fs:FileStream = new FileStream();
if(!myFile.exists){
fs.open(myFile, FileMode.WRITE);
}
else{
fs.open(myFile, FileMode.APPEND);
}
fs.writeUTFBytes("\n" + logStr);
fs.close();
}
call this function on creation complete and then from where to add logs.
If you want the real log than you should use third party installer rather than native run time of adobe air. Try Wixedit(opensource) or install aware .
You have to export your project into captive run time format that is provided in flash builder.
try this link
http://www.adobe.com/devnet/air/articles/customize-setup-for-AIR-app-with-captive-runtime.html
Try something like:
function saveLog(content:String):void
{
var data:ByteArray = new ByteArray();
data.writeMultiByte(content, "utf-8");
file.save(data, "Logs.txt");
}
saveLog('testing :)');
To open and edit your log file, try to follow this tutorial

Using Windows Credentials to instantiate OrganizationServiceProxy in CRM 2011

Has anybody tried to use the Windows credentials to create an instance of OrganizationServiceProxy in CRM 2011 (On-Premise) ? I have a WCF service that uses
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows"/>
</security>
and I am able to confirm that the user is authenticated (OperationContext.Current.ServiceSecurityContext.WindowsIdentity.IsAuthenticated) but I don't know how to generate/pass the ClientCredentials to create an instance of the CRM service. This is called from a Silverlight application that does not live in an IFrame inside CRM.
Thanks.
What you need to use separate user account to log into the OrganizationServiceProxy.
You wont be able retrieve the windows credentials to pass to the proxy for authentication.
The user that you do use needs prvActOnBehalfOfAnotherUser privilege associated with it.
Once this is done and you can successfullly login and retrieve a valid OrganizationServiceProxy, what you need to do as a consumer of the service is specify the CallerId whenever you are calling operations on it. This token you should retrieve from the xrm model using Xrm.Page.context.getUserId. See. http://msdn.microsoft.com/en-us/library/gg334511.aspx.
Then from silverlight you would use the System.Windows.Browser.ScriptObject bridge to execute client side javascript to retrieve the userid of current user logged into crm.
Preferably do this at application bootstrap time and save the value into an applicationdata variable so so can access it globally from within your silverlight app.
Eg. of client side script.
function CrmContext() {
}
var context = null;
with (window.parent) {
context = Xrm.Page.context;}
CrmContext.prototype.ReadUserId = function () {
var userId = context.getUserId();
return userId;
}
Once you have the user token set the Proxy CallerId with this value
Eg.
private OrganizationServiceProxy Proxy { get; set; }
public Guid Create(CreateEntity request)
{
if (request == null || request.UserId == Guid.Empty || request.Entity == null)
{
throw new InvalidMessageException("Invalid reqest message. Please provide compulsory criteria");
}
var result = Guid.Empty;
try
{
if (Proxy != null)
{
Proxy.CallerId = request.UserId;
using (Proxy)
{
result = Proxy.Create(request.Entity);
}
}
}
catch (FaultException<OrganizationServiceFault> e)
{
Log.Error(e.Message);
throw new IntegrationException(e.Message);
}
return result;
}
The approach ive taken to solve this was to create a crm adapter encapsulating the crm proxy and sending request object to service interface that includes the user token.
public OrganizationServiceAdapter(ICrmConfigurationContext crmConfigurationConext)
{
try
{
Proxy = new OrganizationServiceProxy(
crmConfigurationConext.OrganizationServiceConfiguration,
crmConfigurationConext.Credentials);
}
catch (Exception e)
{
//// TODO: Add local proxy pattern implementation for failover
Proxy = null;
Log.Error(e.Message);
throw new IntegrationException(ExceptionMessages.CouldNotLoginToOrganizationService());
}
}

Example of testing a RPC call using GWT-TestCase with GAE

How is that for a lot of acronyms!
I am having trouble testing GWT's RPC mechanism using GWT's GWTTestCase. I created a class for testing using the junitCreator tool included with GWT. I am attempting to test using the built in Google App Engine using the created "hosted mode" testing profile created by junitCreator. When I run the test, I keep getting errors saying things like
Starting HTTP on port 0
HTTP listening on port 49569
The development shell servlet received a request for 'greet' in module 'com.google.gwt.sample.stockwatcher.StockWatcher.JUnit.gwt.xml'
[WARN] Resource not found: greet; (could a file be missing from the public path or a <servlet> tag misconfigured in module com.google.gwt.sample.stockwatcher.StockWatcher.JUnit.gwt.xml ?)
com.google.gwt.user.client.rpc.StatusCodeException: Cannot find resource 'greet' in the public path of module 'com.google.gwt.sample.stockwatcher.StockWatcher.JUnit'
I hope that someone somewhere has successfully run junit test (using GWTTestCase or just plain TestCase) that will allow for the testing of gwt RPC. If this is the case, could you please mention the steps you took, or better yet, just post code that works. Thanks.
SyncProxy allows you to make GWT RPC call from Java. So you can test your GWT RPC with regular Testcase (and faster than GwtTestcase)
See
http://www.gdevelop.com/w/blog/2010/01/10/testing-gwt-rpc-services/
http://www.gdevelop.com/w/blog/2010/03/13/invoke-gwt-rpc-services-deployed-on-google-app-engine/
I got this working. This answer assume's you're using Gradle, but this could easily be adopted to run from ant. First, you'll have to make sure that you separate your GWT tests from your regular JUnit tests. I created 'tests/standalone' for the regular tests, and 'tests/gwt' for my GWT tests. I still get 1 single HTML report in the end that has all of the info.
Next, you need to make sure JUnit is part of your ant classpath, as described here:
http://gradle.1045684.n5.nabble.com/Calling-ant-test-target-fails-with-junit-classpath-issue-newbie-td4385167.html
Then, use something similar to this to compile your GWT tests and run them:
task gwtTestCompile(dependsOn: [compileJava]) << {
ant.echo("Copy the test sources in so they're part of the source...");
copy {
from "tests/gwt"
into "$buildDir/src"
}
gwtTestBuildDir = "$buildDir/classes/test-gwt";
(new File(gwtTestBuildDir)).mkdirs()
(new File("$buildDir/test-results")).mkdirs()
ant.echo("Compile the tests...");
ant.javac(srcdir: "tests/gwt", destdir: gwtTestBuildDir) {
classpath {
pathElement(location: "$buildDir/src")
pathElement(location: "$buildDir/classes/main")
pathElement(path: configurations.runtime.asPath)
pathElement(path: configurations.testCompile.asPath)
pathElement(path: configurations.gwt.asPath)
pathElement(path: configurations.gwtSources.asPath)
}
}
ant.echo("Run the tests...");
ant.junit(haltonfailure: "true", fork: "true") {
classpath {
pathElement(location: "$buildDir/src")
pathElement(location: "$buildDir/classes/main")
pathElement(location: gwtTestBuildDir)
pathElement(path: configurations.runtime.asPath)
pathElement(path: configurations.testCompile.asPath)
pathElement(path: configurations.gwt.asPath)
pathElement(path: configurations.gwtSources.asPath)
}
jvmarg(value: "-Xmx512m")
jvmarg(line: "-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005")
test(name: "com.onlyinsight.client.LoginTest", todir: "$buildDir/test-results")
formatter(type: "xml")
}
}
test.dependsOn(gwtTestCompile);
Finally, here's a simple GWT test:
public class LoginTest extends GWTTestCase
{
public String getModuleName()
{
return "com.onlyinsight.ConfModule";
}
public void testRealUserLogin()
{
UserServiceAsync userService = UserService.App.getInstance();
userService.login("a", "a", new AsyncCallback<User>()
{
public void onFailure(Throwable caught)
{
throw new RuntimeException("Unexpected Exception occurred.", caught);
}
public void onSuccess(User user)
{
assertEquals("a", user.getUserName());
assertEquals("a", user.getPassword());
assertEquals(UserRole.Administrator, user.getRole());
assertEquals("Test", user.getFirstName());
assertEquals("User", user.getLastName());
assertEquals("canada#onlyinsight.com", user.getEmail());
// Okay, now this test case can finish.
finishTest();
}
});
// Tell JUnit not to quit the test, so it allows the asynchronous method above to run.
delayTestFinish(10 * 1000);
}
}
If your RPC instance doesn't have a handy getInstance() method, then add one:
public interface UserService extends RemoteService {
public User login(String username, String password) throws NotLoggedInException;
public String getLoginURL(OAuthProviderEnum provider) throws NotLoggedInException;
public User loginWithOAuth(OAuthProviderEnum provider, String email, String authToken) throws NotLoggedInException;
/**
* Utility/Convenience class.
* Use UserService.App.getInstance() to access static instance of UserServiceAsync
*/
public static class App {
private static final UserServiceAsync ourInstance = (UserServiceAsync) GWT.create(UserService.class);
public static UserServiceAsync getInstance()
{
return ourInstance;
}
}
}
I hope that helps.

Resources