Apache Camel - Multipart File upload - spring-mvc

Using Apache-Camel ESB, trying to upload a xlsx file to Spring Rest Web application. Upload fails from apache-camel ESB. But upload works fine from Postman. Shared code snippets below.
Processor Code in Router of Camel looks like
from("file://data/PASInput").process(new Processor() {
#Override
public void process(Exchange exchange) throws Exception {
MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
multipartEntityBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
String filename = (String) exchange.getIn().getHeader(Exchange.FILE_NAME);
File file = exchange.getIn().getBody(File.class);
multipartEntityBuilder.addPart("file",
new FileBody(file, ContentType.MULTIPART_FORM_DATA, filename));
ByteArrayOutputStream out = new ByteArrayOutputStream();
multipartEntityBuilder.build().writeTo(out);
InputStream inputStream = new ByteArrayInputStream(out.toByteArray());
exchange.getOut().setBody(inputStream);
}
}).to("http://localhost:8080/Pastel/api/convertor/pas/pastel")
.log(LoggingLevel.ERROR, "RESPONSE BODY ${body}").end();
Pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-spring-boot-starter</artifactId>
<version>2.21.0.fuse-000077-redhat-1</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-cxf</artifactId>
<version>2.21.0.fuse-000077-redhat-1</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>4.3.1</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-http</artifactId>
<version>2.21.0.fuse-000077-redhat-1</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-http4</artifactId>
<version>2.17.2</version>
</dependency>
Error
org.apache.camel.http.common.HttpOperationFailedException: HTTP operation failed invoking http://localhost:8080/Pastel/api/convertor/pas/pastel with statusCode: 500
at org.apache.camel.component.http.HttpProducer.populateHttpOperationFailedException(HttpProducer.java:274)
at org.apache.camel.component.http.HttpProducer.process(HttpProducer.java:183)
at org.apache.camel.util.AsyncProcessorConverterHelper$ProcessorToAsyncProcessorBridge.process(AsyncProcessorConverterHelper.java:61)
at org.apache.camel.processor.SendProcessor.process(SendProcessor.java:148)
at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:548)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:201)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:138)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:101)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:201)
at org.apache.camel.component.file.GenericFileConsumer.processExchange(GenericFileConsumer.java:452)
at org.apache.camel.component.file.GenericFileConsumer.processBatch(GenericFileConsumer.java:219)
at org.apache.camel.component.file.GenericFileConsumer.poll(GenericFileConsumer.java:183)
at org.apache.camel.impl.ScheduledPollConsumer.doRun(ScheduledPollConsumer.java:174)
at org.apache.camel.impl.ScheduledPollConsumer.run(ScheduledPollConsumer.java:101)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
When we hit the webservice using postman, there are no errors. Able to upload the servers successfully. Spring mvc code,
#RequestMapping(value = "/pas/pastel", method = RequestMethod.POST)
#ResponseBody
public void convertPASToPastel(HttpServletRequest request, HttpServletResponse response,
#RequestParam(value = "file") final MultipartFile pasFile) {
try {
System.out.print("Here");
}
}

You can probably see this error message in your Spring backend log:
org.springframework.web.multipart.MultipartException: Current request is not a multipart request.
You need to set correct ContentType header. Please refer this similar question for solution, if you want to implement it in this way.
But you can get out this mess, if you switch co camel-http4 component (you already have this component in pom.xml). This component contains logic for converting HttpEntity to InputStream. Then you can set HttpEntity directly to exchange body.
Then your route will look something like this:
from("file://data/PASInput").process(new Processor() {
#Override
public void process(Exchange exchange) throws Exception {
MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
multipartEntityBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
String filename = exchange.getIn().getHeader(Exchange.FILE_NAME, String.class);
File file = exchange.getIn().getBody(File.class);
multipartEntityBuilder.addPart("file",
new FileBody(file, ContentType.MULTIPART_FORM_DATA, filename));
exchange.getOut().setBody(multipartEntityBuilder.build());
}
}).to("http4://localhost:8080/Pastel/api/convertor/pas/pastel")
.log(LoggingLevel.ERROR, "RESPONSE BODY ${body}").end();
And just a note. Never mix component versions, always use for components the same version as Apache Camel version. Otherwise you can see upredictable results. And why you have annotation #ResponseBody in Spring controller, when the method is void? You don`t need that.

Related

NoClassDefFoundError: io/opencensus/trace/Tracestate thrown when StorageClient is instantiated

I have a spring boot 2.1 app and I'm just following the documentation from the Firebase site but I'm getting java.lang.NoClassDefFoundError: io/opencensus/trace/Tracestate.
public void initialize() {
InputStream serviceAccount = getClass()
.getClassLoader().getResourceAsStream(CREDENTIALS_PATH);
FirebaseOptions options = new FirebaseOptions.Builder()
.setCredentials(GoogleCredentials.fromStream(serviceAccount))
.setStorageBucket(BUCKET_NAME)
.build();
FirebaseApp.initializeApp(options);
StorageClient storageClient = StorageClient.getInstance(); // This line is throwing the exception
}
I was not able to find any info about this and I cannot figure out what is wrong here.
EDIT:
I have both dependencies in my pom.xml, firebase admin and google cloud storage, removing firebase admin the error stop happening.
<dependency>
<groupId>com.google.firebase</groupId>
<artifactId>firebase-admin</artifactId>
<version>6.8.0</version>
</dependency>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-storage</artifactId>
<version>1.74.0</version>
</dependency>

google cloud storage tried to access method com.google.cloud.ServiceOptions.getFromServiceLoader error

I am trying to test google cloud storage in local mvn jetty server.
defining the following java servlet I get the following error during servlet initiallization.
#WebServlet(name = "receiveImage", value = "receiveImage")
#SuppressWarnings("serial")
#MultipartConfig()
public class receiveImage extends HttpServlet {
private static final String BUCKET_NAME = "testbucket";
private static Storage storage = null;
#Override
public void init() {
storage = StorageOptions.defaultInstance().service();
}
HTTP ERROR 500
Problem accessing /receiveImage. Reason:
Server Error
Caused by:
java.lang.IllegalAccessError: tried to access method com.google.cloud.ServiceOptions.getFromServiceLoader(Ljava/lang/Class;Ljava/lang/Object;)Ljava/lang/Object; from class com.google.cloud.HttpServiceOptions
at com.google.cloud.HttpServiceOptions.(HttpServiceOptions.java:154)
at com.google.cloud.storage.StorageOptions.(StorageOptions.java:69)
at com.google.cloud.storage.StorageOptions.(StorageOptions.java:27)
at com.google.cloud.sto
i define the following maven dependency in pom file:
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-storage</artifactId>
<version>0.4.0</version>
</dependency>
Appreciate for helps.
I could resolve the issue:
there is a conflict between these two dependencies:
dependency>
<groupId>com.google.cloud</groupId>
<artifactId>gcloud-java-datastore</artifactId>
<version>0.2.0</version>
</dependency>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-storage</artifactId>
<version>0.5.1</version>
</dependency>
I just changed the first dependency to
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-datastore</artifactId>
<version>0.5.1</version>
</dependency>

localhost:8080/swagger-ui.html does not seem to resolve.Any Ideas?

I have a spring boot project that is structured like below:
client
build.gradle
interface
build.gradle
service
tests
main
java
resources
build.gradle
So there are three subprojects: interface,service and client.
The controllers are inside service>main>controller and the swagger is configured inside the build.gradle which is inside the service project.
When i do localhost:8080/swagger-ui.html ,i get:
No mapping found for HTTP request with URI [/swagger-ui.html] in DispatcherServlet with name 'dispatcherServlet'.
I am able to get json when i hit this url:
http://localhost:8080/v2/api-docs
I got this working,
I had a #EnableWebMVC on top of a class.Removing it fixed it.
Thanks #Sampada for your help
first, add below dependencies in spring boot pom file, then add #EnableSwagger annotation on the application class and then add webappconfig class
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.1</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.1</version>
</dependency>
#Configuration
#EnableWebMvc
public class ApplicationWebMvcConfig implements WebMvcConfigurer {
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer
configurer) {
configurer.enable();
}
}

Jawr Spring Annotations Based Sample Configuration

I wanted to implement Jawr for minification and obfuscation of CSS and JS resources. I am using a Spring MVC project where the configurations are done using Java code using annotations and XML is not used. Now able to find a documentation for the same. Can some one suggest me the configuration or a reference link.
jawr dependencies to your pom:
<dependency>
<groupId>net.jawr</groupId>
<artifactId>jawr-core</artifactId>
<version>3.6</version>
</dependency>
<dependency>
<groupId>net.jawr.extensions</groupId>
<artifactId>jawr-spring-extension</artifactId>
<version>3.6</version>
</dependency>
Build a controller like this:
#Controller
public class JsController extends JawrSpringController
{
public JsController ()
{
setType("js");
setConfigLocation("/jawr.properties");
}
#RequestMapping("/js/**")
public void javascript ( HttpServletRequest request, HttpServletResponse response ) throws Exception
{
handleRequest(request, response);
}
}

"java.lang.NoClassDefFoundError: org/springframework/core/type/AnnotatedTypeMetadata"

#Bean
public JavaMailSender mailSender() {
JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
mailSender.setDefaultEncoding("UTF-8");
mailSender.setHost("smtp.googlemail.com");
mailSender.setPort(465);
mailSender.setUsername("XXXXXXXXX#gmail.com");
mailSender.setPassword("XXXXXXXXXXXXXXX");
Properties properties = new Properties();
properties.put("mail.smtp.auth", true);
properties.put("mail.smtp.starttls.enable", true);
mailSender.setJavaMailProperties(properties);
return mailSender;
}
I am trying to send mail using javamailsender for that i configured the above code using annotations after that I get the "java.lang.NoClassDefFoundError: org/springframework/core/type/AnnotatedTypeMetadata" exception any suggestions appriciate.
It seems dependency spring-core is missing. You should add this jar.
Or using maven choose a dependency from here: http://mvnrepository.com/artifact/org.springframework/spring-core
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.0.6.RELEASE</version>
</dependency>

Resources