Downloading files from Alfresco with MuleSoft CMIS connector - alfresco

I have a little problem with the MuleSoft CMIS connector. I have an application that uploads and downloads files from Alfresco. I connect to Alfresco through AtomPub and use CMIS for all actions towards the Alfresco.
The problem is this:
I used to get the object from the repository and it worked fine. In my flow I added one component that takes the object from the flow, which is of type DocumentImpl, get InputStream, cast it to an Object and return it. The browser starts the download of the file but it has no idea what the file is because it has no extension attached to it.
And finally the question: How do I attach the extension to the file being downloaded?
EDIT some code added
#Override
public Object onCall(MuleEventContext eventContext) throws Exception {
MuleMessage mes = eventContext.getMessage();
System.out.println("Message is :" +mes);
DocumentImpl doc = mes.getPayload(DocumentImpl.class);
HttpResponse res = new HttpResponse();
InputStream a = doc.getContentStream().getStream();
String m = doc.getContentStreamMimeType();
String n = doc.getContentStreamFileName();
res.setBody(mes);
return a;
}

Ok i solved the problem. Basically the best way to do this is to change the flow to this:
<set-payload value ="#[payload.getContentStream()]" />
<set-variable value="#[payload.getMimeType()]" variableName="mime" doc:name="Variable" />
<set-variable value="#[payload.getFileName()]" variableName="name" doc:name="Variable" />
<!-- Set Content-Type to stored mimetype -->
<set-property value="#[flowVars['mime']]" propertyName="Content-Type" />
<set-property propertyName="File-Name" value="#[flowVars['name']]"/>
<set-property value="attachment; filename=#[flowVars['name']]" propertyName="Content-Disposition" />
this should be in the Mule Flow after
This takes mime type and file name from the payload and returns it!

Related

How to add new sub resource to a standard Intershop AbstractResourceObject

I want to introduce a new sub resource to standard Intershop ProductResource
without loosing the product resource context.
E.g In my resource's code, I want to know about the product to which a REST client is referring to /product/SOME/my-sub-resource
How can I do this ?
There is a recipe in "Cookbook - REST Framework":
Add a Resource to an Existing REST API
https://support.intershop.com/kb/index.php/Display/28269L
You need to add a new java class extending com.intershop.component.rest.capi.resource.AbstractRestResource
Register the implementation in a component file
<implementation name="YOUR_NAME"
implements="AbstractRestResource"
class="YOUR_FQNAME_TO_IMPL_CLASS"
factory="JavaBeanFactory">
<requires name="name" contract="String" cardinality="1..1" />
<requires name="subResource" contract="RestResource" cardinality="0..n" />
</implementation>
Instantiate the implementation in a component file
<instance with="YOUR_NAME" name="YOUR_INSTANCE_NAME">
<fulfill requirement="name" value="YOUR_SUBRESOUCE_NAME" />
</instance>
Add as subResource to intershop.WebShop.RESTAPI.ProductResource instance
<fulfill requirement="subResource"
of="intershop.WebShop.RESTAPI.ProductResource"
with="YOUR_INSTANCE_NAME"/>
After that your resource is available under /product/SKU/YOUR_SUBRESOURCE_NAME. Make sure your impl class has a public method and that method is annotated with javax.ws.rs.GET and javax.ws.rs.Produces
#GET
#Produces("application/json")
public SomeRO get()
{
ApplicationBO applicationBO = provider.get();
ProductBORepository productBORep = applicationBO.getRepository(ProductBORepositoryExtension.EXTENSION_ID);
ProductBO product = productBORep.getProductBOBySKU(getParent().getName());
// Do the stuff you want with the product
}

Acces-Control-Allow-Origin works with Web.config (IIS7) but not with (WebApiConfig.cs) ASP.NET Cross Origin support

For a project i want to load and view a pdf file with angular-pdfjs. The team uses ASP.net Cross Origin, to Allow-Acces-Control, Headers, Credentials etc.
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Replace the default implementation of the ITraceWriter with our custom logger.
config.Services.Replace(typeof (ITraceWriter), new GlobalTraceLogger());
// Replace the default exception logger to be able to log exceptions with NLog
config.Services.Replace(typeof (IExceptionLogger), new GlobalExceptionLogger());
// Replace the default exceptionhandler to be able to handle exceptions globally
config.Services.Replace(typeof (IExceptionHandler), new GlobalExceptionHandler());
// We must enable cors, because otherwise we are not able to commuincate with a java script client
// TODO: We need to restirct the requested resource. Do not allow every origin!
// Do not run this in prodocutive environment
var cors = new EnableCorsAttribute("*", "*", "*", "*");
cors.SupportsCredentials = true;
config.EnableCors(cors);
config.MapHttpAttributeRoutes();
// Make the default return type JSON
var appXmlType =
config.Formatters.XmlFormatter.SupportedMediaTypes.FirstOrDefault(t => t.MediaType == "application/xml");
config.Formatters.XmlFormatter.SupportedMediaTypes.Remove(appXmlType);
This works good so far, but if i want to load my pdf file with angular-pdfjs, i get a Cross Origin Error, because Allow-Acces-Control-Origin "*" didn't works for my pdf-url.
(https://img3.picload.org/image/roirrgcw/corsworksnot.png)
But if i using instead of ASP.net Cross Origin Support the Allow-Access-Control of IIS7 in Web.config:
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Origin, X-Requested- With, Content-Type, Accept" />
<add name="Access-Control-Allow-Methods" value="GET,POST,PUT,DELETE,OPTIONS" />
<add name="Access-Control-Allow-Credentials" value="true" />
</customHeaders>
</httpProtocol>
it works and the pdf will be loaded correctly.
(https://picload.org/image/roirrgci/corsworks.jpg)
But the problem is, at the moment the page is loaded via "file://" and so i get
an error because there is no Access-Control-Allow-Origin for 'null'. That means, my pdf is loading correctly this way, but the login, pictures... won't be loaded anymore. So my question is, if someone knows how i can change the WebApiConfig-Implementation that my pdf-file get an Access-Controll-Allow as well. Or maybe can someone tell where the error could be.
For information:
Thats the way i'm loading the pdf with angular-pdfjs:
<!---------------------------THE PDF VIEWER DIRECTIVE------------------------->
<div pdf-viewer="options" pdf-url="pdfUrl" id="my-viewer" class="col col-lg-10"></div>
<!---------------------------THE PDF VIEWER DIRECTIVE------------------------->
and thats the url, i'm using:
function PdfviewController(ebmGuideLineService, mediaService, $scope, $window) {
var vm = this;
$scope.pdfUrl = 'http://localhost:3787/NCCN_Evidence_Blocks_Melanoma.pdf';
$scope.options = { mouseZoom: false, mousePan: false };
Please tell me, if you need more informations and thank you for your help.

ASP.NET MVC5 Customised Inbound Routing

I'm "playing" around with custom inbound URL routing and have came across a problem.
When I pass my custom route a URL to examine, that ends in *.+, my class is not fired when i submit the request.
An example URL would be "~/old/windows.html"
When I step through this in the debugger, my RouteBase implementation doesn't fire. If i edit the url that i pass to the constructor of my route to try to match against "~/old/windows", my implemetation is fired as expected.
Again, If i change the url ro examine to "~/old/windows." the problem reoccurs.
My Route Implementation is below :-
public class LegacyRoute : RouteBase
{
private string[] _urls;
public LegacyRoute(string[] targetUrls)
{
_urls = targetUrls;
}
public override RouteData GetRouteData(HttpContextBase httpContext)
{
RouteData result = null;
string requestedURL = httpContext.Request.AppRelativeCurrentExecutionFilePath;
if (_urls.Contains(requestedURL, StringComparer.OrdinalIgnoreCase))
{
result = new RouteData(this, new MvcRouteHandler());
result.Values.Add("controller", "Legacy");
result.Values.Add("action","GetLegacyURL");
result.Values.Add("legacyURL", requestedURL);
}
return result;
}
public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
{
return null;
}
}
In the RoutesConfig file I have registered my route like so :-
routes.MapMvcAttributeRoutes();
routes.Add(new LegacyRoute(new[]{"~/articles/windows.html","~/old/.Net_1.0_Class_Library"}));
Can anyone point out why there is a problem?
By default, the .html extension is not handled by .NET, it is handled by IIS directly. You can override by adding the following section in Web.config under <system.webServer> -
<handlers>
<add name="HtmlFileHandler" path="*.html" verb="GET" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
As pointed out here. The above will route EVERY .html file request to .NET, you might want to be more specific by providing a more complete path if you don't want your routing to handle every .html file.
I've found the problem, and I'm sure this will help out a lot of fellow developers.
The problem is with IIS Express that is running via Visual Studio.
There is a module configured in the applicationhost.config called :-
UrlRoutingModule-4.0
This is how it looks in file :-
<add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" preCondition="managedHandler,runtimeVersionv4.0" />
You need to set the preCondition Parameter to "".
To do this :-
Run you app via Visual Studio
Right click on IIS Express in your system tray, select "Show All Applications"
Click on the project you wish to edit, then click the config URL.
Open the file with Visual Studio, Locate the module and ammend.
Hope this helps anyone else, who ran into a similar problem.

MuleESB - get file from http post

In Mule I need to manipulate via java an xlsx file sent via http post.
How can I get the file posted via java?
I thought it was reachable via Mule message but
eventContext.getMessage().getOutboundAttachmentNames()
and neither
eventContext.getMessage().getInboundAttachmentNames()
give results.
Any ideas?
to make http post test I use curl in this way:
curl --form upload=#filename --form press=OK http://localhost:8088/HttpController
The flow is simply something like this:
<flow name="xlsx_to_xls_converterFlow1" doc:name="xlsx_to_xls_converterFlow1">
<http:inbound-endpoint exchange-pattern="request-response" doc:name="HTTP" address="http://localhost:8088/HttpController"/>
<logger level="INFO" doc:name="Logger"/>
<component class="Convert_XLSXtoXLS" doc:name="Java"/>
</flow>
Thank you
UPDATED
To let the flagged solution work occurs to override extractPayloadFromHttpRequest of HttpMultipartMuleMessageFactory to choose the proper input file name.
In fact with the current HttpMultipartMuleMessageFactory implementation the file is uploaded only if input file name = "payload"
You need to configure your HTTP connector to handle multipart requests to receive them in attachments. Add the following inside its XML configuration:
<service-overrides messageFactory="org.mule.transport.http.HttpMultipartMuleMessageFactory"/>
( if you think this is cumbersome, please upvote https://www.mulesoft.org/jira/browse/MULE-6862 )
Putting a Java component behind an http:inbound-endpoint results in an InputStream as argument to the method in the component.
You have to work with the input stream or just put an echo in between:
<flow name="FileUpload" doc:name="FileUpload">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="9090" doc:name="HTTP"/>
<echo-component doc:name="Echo"/>
<component class="de.codecentric.basics.FileUploadComponent" doc:name="Java"/>
</flow>
The component has one method:
package de.codecentric.basics;
public class FileUploadComponent {
public String process(String message) {
System.out.println("message: " + message);
return "OK";
}
}
You still have to parse the multipart form data in this case.
Or try to use the REST component, see: http://www.javaroots.com/2013/05/createfileuploadmulejerseyrest.html

Basic Auth for WSO2 EI API service

I am using WSO2-EI 6.4.0. I have tried this development with link. It work for me. But I need to get user name and password from other back end service. In this example was showed the hard corded user and password. I have added that code for your reference. Please help me to get those user name and password from property file.
public boolean processSecurity(String credentials) {
String decodedCredentials = new String(new Base64().decode(credentials.getBytes()));
String usernName = decodedCredentials.split(":")[0];
String password = decodedCredentials.split(":")[1];
if ("admin".equals(username) && "admin".equals(password)) {
return true;
} else {
return false;
}
}
I have added WSO2 EI handler like following. I need to pass the value from back service or call other sequence and load.
<api context="/test">
<resource methods="POST">
<inSequence>
................
</inSequence>
<outSequence>
................
</outSequence>
</resource>
<handlers>
<handler class="rezg.ride.common.BasicAuthHandler">
<property name="cm_password" value="admin"/>
<property name="cm_userName" value="admin"/>
</handler>
</handlers>
</api>
When we run the above API, handlers are running first and then running in and out sequences. So I need to get user name and password calling Sequence or any other method before run this BasicAuthHandler.
If you need to read the property file from the class mediator it's just straight forward java property file reading. Please refer the following call sample of reading a property file. In this scenario, Just read the carbon.properties file exists in the conf directory.
public boolean mediate(MessageContext context) {
String passwordFileLocation = System.getProperty("conf.location")+"/carbon.properties";
try (FileInputStream input = new FileInputStream(passwordFileLocation)) {
Properties prop = new Properties();
// load a properties file
prop.load(input);
log.info("------org.wso2.CipherTransformation : " + prop.getProperty("org.wso2.CipherTransformation"));
} catch (IOException ex) {
ex.printStackTrace();
}
return true;
}
To get the server location and the conf locating, There are JAVA system properties are set at the time wso2 server starts. Following are some of the useful System system properties.
carbon.local.ip
carbon.home
conf.location

Resources