SpringBoot Rest Application + Arquillian - rest

I want to test my Rest Application that uses SpringBoot to test with Arquillian but none of the online examples work i am not able to test a GET call and facing difficulties deploying to Jboss EAP-6.4. Can anyone guide me on how to achieve this. Any simple Examples ???

I think that here there are a lot of things to check, so I would say 1) have you tried to deploy the spring boot app to EAP 6.4 to check that it works (not using Arquillian)? and 2) is it possible to share a simple github project so we can check?

This link helped me to solve the issue : Adding all Maven dependencies to Arquillian.
The code that works :
#Deployment
public static Archive<?> createTestArchive() {
File[] files = Maven.resolver()
.loadPomFromFile("pom.xml")
.importRuntimeDependencies()
.resolve().withTransitivity()
.asFile();
return ShrinkWrap.create(WebArchive.class, "FileUploadIssue.war")
.addPackages(true,"com.example")
.addAsLibraries(files);
}
#Test
#RunAsClient
public void shouldGetFileContents() {
String result = restTemplate.getForObject(contextPath + "upload/sayhello", String.class);
System.out.println( "Test : " + result);
}
Is there any way to refactor this code even more ??

Related

Embedded Kafka in micronaut app not finding beans

I'm using the embedded Kafka server in my test described here: https://micronaut-projects.github.io/micronaut-kafka/latest/guide/#kafkaEmbedded. The problem is I'm getting this io.micronaut.context.exceptions.BeanContextException: Error processing bean [Definition: org.app.messaging.TestConsumer] method definition [void receive(String msg)]: Failed to inject value for parameter [testService] of method [setTestService] of class: org.app.messaging.TestConsumer when I run the test. Any ideas how to fix this?
Here's what the test looks like:
void "test run kafka embedded server"() {
given:
ApplicationContext applicationContext = ApplicationContext.run(
Collections.singletonMap(
AbstractKafkaConfiguration.EMBEDDED, true
)
)
when:
AbstractKafkaConsumerConfiguration config = applicationContext.getBean(AbstractKafkaConsumerConfiguration)
Properties props = config.getConfig()
then:
props[ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG] == 9091
when:
KafkaEmbedded kafkaEmbedded = applicationContext.getBean(KafkaEmbedded)
then:
kafkaEmbedded.kafkaServer.isPresent()
kafkaEmbedded.zkPort.isPresent()
cleanup:
applicationContext.close()
}
Placing a test anywhere other than the root package seem to be causing multiple "bean definition not found" issues. There's no ComponentScan support in the framework so the only thing that worked for me was to move the test file to the root package. There's some ideas here: https://github.com/micronaut-projects/micronaut-core/issues/511 if you're experiencing similar issues with a CLI app. However, it didn't work when using the embedded server and embedded kafka.

Unable to download embedded MongoDB, behind proxy, using automatic configuration script

I have a Spring Boot project, built using Maven, where I intend to use embedded mongo db. I am using Eclipse on Windows 7.
I am behind a proxy that uses automatic configuration script, as I have observed in the Connection tab of Internet Options.
I am getting the following exception when I try to run the application.
java.io.IOException: Could not open inputStream for https://downloads.mongodb.org/win32/mongodb-win32-i386-3.2.2.zip
at de.flapdoodle.embed.process.store.Downloader.downloadInputStream(Downloader.java:131) ~[de.flapdoodle.embed.process-2.0.1.jar:na]
at de.flapdoodle.embed.process.store.Downloader.download(Downloader.java:69) ~[de.flapdoodle.embed.process-2.0.1.jar:na]
....
MongoDB gets downloaded just fine, when I hit the following URL in my web browser:
https://downloads.mongodb.org/win32/mongodb-win32-i386-3.2.2.zip
This leads me to believe that probably I'm missing some configuration in my Eclipse or may be the maven project itself.
Please help me to find the right configuration.
What worked for me on a windows machine:
Download the zip file (https://downloads.mongodb.org/win32/mongodb-win32-i386-3.2.2.zip)
manually and put it (not unpack) into this folder:
C:\Users\<Username>\.embedmongo\win32\
Indeed the problem is about your proxy (a corporate one I guess).
If the proxy do not require authentication, you can solve your problem easily just by adding the appropriate -Dhttp.proxyHost=... and -Dhttp.proxyPort=... (or/and the same with "https.[...]") as JVM arguments in your eclipse junit Runner, as suggested here : https://github.com/learning-spring-boot/learning-spring-boot-2nd-edition-code/issues/2
One solution to your problem is to do the following.
Download MongoDB and place it on a ftp server which is inside your corporate network (for which you would not need proxy).
Then write a configuration in your project like this
#Bean
#ConditionalOnProperty("mongo.proxy")
public IRuntimeConfig embeddedMongoRuntimeConfig() {
final Command command = Command.MongoD;
final IRuntimeConfig runtimeConfig = new RuntimeConfigBuilder()
.defaults(command)
.artifactStore(new ExtractedArtifactStoreBuilder()
.defaults(command)
.download(new DownloadConfigBuilder()
.defaultsForCommand(command)
.downloadPath("your-ftp-path")
.build())
.build())
.build();
return runtimeConfig;
}
With the property mongo.proxy you can control whether Spring Boot downloads MongoDB from your ftp server or from outside. If it is set to true then it downloads from the ftp server. If not then it tries to download from the internet.
The easiest way seems to me to customize the default configuration:
#Bean
DownloadConfigBuilderCustomizer mongoProxyCustomizer() {
return configBuilder -> {
configBuilder.proxyFactory(new HttpProxyFactory(host, port));
};
}
Got the same issue (with Spring Boot 2.6.1 the spring.mongodb.embedded.version property is mandatory).
To configure the proxy, I've added the configuration bean by myself:
#Value("${spring.mongodb.embedded.proxy.domain}")
private String proxyDomain;
#Value("${spring.mongodb.embedded.proxy.port}")
private Integer proxyPort;
#Bean
RuntimeConfig embeddedMongoRuntimeConfig(ObjectProvider<DownloadConfigBuilderCustomizer> downloadConfigBuilderCustomizers) {
Logger logger = LoggerFactory.getLogger(this.getClass().getPackage().getName() + ".EmbeddedMongo");
ProcessOutput processOutput = new ProcessOutput(Processors.logTo(logger, Slf4jLevel.INFO), Processors.logTo(logger, Slf4jLevel.ERROR), Processors.named("[console>]", Processors.logTo(logger, Slf4jLevel.DEBUG)));
return Defaults.runtimeConfigFor(Command.MongoD, logger).processOutput(processOutput).artifactStore(this.getArtifactStore(logger, downloadConfigBuilderCustomizers.orderedStream())).isDaemonProcess(false).build();
}
private ExtractedArtifactStore getArtifactStore(Logger logger, Stream<DownloadConfigBuilderCustomizer> downloadConfigBuilderCustomizers) {
de.flapdoodle.embed.process.config.store.ImmutableDownloadConfig.Builder downloadConfigBuilder = Defaults.downloadConfigFor(Command.MongoD);
downloadConfigBuilder.progressListener(new Slf4jProgressListener(logger));
downloadConfigBuilderCustomizers.forEach((customizer) -> {
customizer.customize(downloadConfigBuilder);
});
DownloadConfig downloadConfig = downloadConfigBuilder
.proxyFactory(new HttpProxyFactory(proxyDomain, proxyPort)) // <--- HERE
.build();
return Defaults.extractedArtifactStoreFor(Command.MongoD).withDownloadConfig(downloadConfig);
}
In my case, I had to add the HTTPS corporate proxy to Intellij Run Configuration.
Https because it was trying to download:
https://downloads.mongodb.org/win32/mongodb-win32-x86_64-4.0.2.zip
application.properties:
spring.data.mongodb.database=test
spring.data.mongodb.port=27017
spring.mongodb.embedded.version=4.0.2
Please keep in mind this is a (DEV) setup.

host more than one app under one website entry in IIS

i have created sample rest service which just return xml
its work fine in my development environment
[RouteAttributes(UriTemplate = "{appname}/adfsapi/mex")]
public class SAMLMexRouteHandler : IRouteHandler
{
}
where app name will be change, and my url
http://localhost:64219/test/adfsapi/mex
till here everything fine
but when i hosting app to IIS
than trying to call my rest service url
http://localhost:8089/testapp1/adfsapi/mex
its throwing 404 not found error .
any suggestion which step i am doing wrong.
Thanks
i solved the issue by converting to application for every directory .
and my URI will be like this -
[RouteAttributes(UriTemplate = "adfsapi/mex")]
public class SAMLMexRouteHandler : IRouteHandler
{
}

Quartz scheduled job on Liberty app-server calling REST throwing exception

I'm having real hassle getting a quartz job in an application server to call a REST service - totally puzzled (:
I have quartz (v 2.2.2) deployed & working on an IBM Liberty Application Server (v 8.5.5.8) with Java 1.8
It scans a directory for files and then calls my Dummy Task.
However, when I replace the Dummy Task with a REST WebClient call - I get a pretty odd stacktrace.
java.lang.NullPointerException
[err] at com.ibm.ws.jaxrs20.client.bus.LibertyJAXRSClientBusFactory.getClientScopeBus(LibertyJAXRSClientBusFactory.java:89)
[err] at com.ibm.ws.jaxrs20.client.JAXRSClientImpl.target(JAXRSClientImpl.java:109)
[err] at org.apache.cxf.jaxrs.client.spec.ClientImpl.target(ClientImpl.java:100)
[err] at notification.server.rest.MyIBMHandler.testClient4(MyIBMHandler.java:61)
the last line is mine and the code I wrote is simply based on this: https://www.ibm.com/support/knowledgecenter/was_beta_liberty/com.ibm.websphere.wlp.nd.multiplatform.doc/ae/twlp_jaxrs2.0_clientconfig.html
When I googled the exception above, I didn't see much except for one stacktrace related one:-
NullPointerException when running CXF JAX-RS 2.0 client "target" method in Liberty Profile under a Thread
Which leads me to believe there may be some form of a threading conflict here.
To prove my REST client code was ok on my Liberty app-server, I did put my REST methodinto a servlet and call it there and it did work fine.
i.e.
public void testClient4() {
javax.ws.rs.client.ClientBuilder cb = ClientBuilder.newBuilder();
javax.ws.rs.client.Client c = cb.build();
String res = null;
try {
String resourceURL = "http://localhost:9080/SampleRest/sample/";
res = c.target(resourceURL).path("Greeting").request().get(String.class);
System.out.println("res:" + res);
} catch (Exception e) {
res = "[Error]:" + e.toString();
System.err.println("error:" + e.getMessage());
e.printStackTrace();
} finally {
if (c != null)
c.close();
System.out.println("res:" + res);
}
}
My Quartz props are close to out of the box, here is the threadpool section:-
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 4
org.quartz.threadPool.threadPriority = 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true
My job class uses the annotation - #DisallowConcurrentExecution
I'm using the jersey 2.17 libs & jackson libs
I've added lots of features to my Liberty profile - i.e.
<featureManager>
<feature>jsp-2.3</feature>
<feature>jaxrs-2.0</feature>
<feature>servlet-3.1</feature>
<feature>apiDiscovery-1.0</feature>
<feature>jaxrsClient-2.0</feature>
</featureManager>
For now, the REST service being called is a simple one.
When running quartz within an app-server, do I need to do anyconfig to be able to call a REST service? - anyone got this working?
It appears we fixed this NPE in the latest Liberty fixpack, looking here, the 8.5.5.9 fixpack is planned to be available on March 18. Once released, please test and determine if it fixes this problem, and if not let us know.

Has anyone successfully deployed a GWT app on Heroku?

Heroku recently began supporting Java apps. Looking through the docs, it seems to resemble the Java Servlet Standard. Does anyone know of an instance where a GWT app has been successfully deployed on Heroku? If so, are there any limitations?
Yes, I've got a successful deployment using the getting started with Java instructions here:
http://devcenter.heroku.com/articles/java
I use the Maven project with appassembler plugin approach but added gwt-maven-plugin to compile a GWT app during the build.
When you push to heroku you see the GWT compile process running, on one thread only so quite slow but it works fine.
The embedded Jetty instance is configured to serve up static resources at /static from src/main/resources/static and I copy the compiled GWT app to this location during the build and then reference the .nocache.js as normal.
What else do you want to know?
You've got a choice, either build the Javascript representation of your GWT app locally into your Maven project, commit it and the read it from your app, or to generate it inside Heroku via the gwt-maven-plugin as I mentioned.
The code to serve up files from a static location inside your jar via embedded Jetty is something like this inside a Guice ServletModule:
(See my other answer below for a simpler and less Guice-driven way to do this.)
protected void configureServlets() {
bind(DefaultServlet.class).in(Singleton.class);
Map<String, String> initParams = new HashMap<String, String>();
initParams.put("pathInfoOnly", "true");
initParams.put("resourceBase", staticResourceBase());
serve("/static/*").with(DefaultServlet.class, initParams);
}
private String staticResourceBase() {
try {
return WebServletModule.class.getResource("/static").toURI().toString();
}
catch (URISyntaxException e) {
e.printStackTrace();
return "couldn't resolve real path to static/";
}
}
There's a few other tricks to getting embedded Jetty working with guice-servlet, let me know if this isn't enough.
My first answer to this turned out to have problems when GWT tried to read its serialization policy. In the end I went for a simpler approach that was less Guice-based. I had to step through the Jetty code to understand why setBaseResource() was the way to go - it's not immediately obvious from the Javadoc.
Here's my server class - the one with the main() method that you point Heroku at via your app-assembler plugin as per the Heroku docs.
public class MyServer {
public static void main(String[] args) throws Exception {
if (args.length > 0) {
new MyServer().start(Integer.valueOf(args[0]));
}
else {
new MyServer().start(Integer.valueOf(System.getenv("PORT")));
}
}
public void start(int port) throws Exception {
Server server = new Server(port);
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setBaseResource(createResourceForStatics());
context.setContextPath("/");
context.addEventListener(new AppConfig());
context.addFilter(GuiceFilter.class, "/*", null);
context.addServlet(DefaultServlet.class, "/");
server.setHandler(context);
server.start();
server.join();
}
private Resource createResourceForStatics() throws MalformedURLException, IOException {
String staticDir = getClass().getClassLoader().getResource("static/").toExternalForm();
Resource staticResource = Resource.newResource(staticDir);
return staticResource;
}
}
AppConfig.java is a GuiceServletContextListener.
You then put your static resources under src/main/resources/static/.
In theory, one should be able to run GWT using the embedded versions of Jetty or Tomcat, and bootstrap the server in main as described in the Heroku Java docs.