Spring cloud sample Eureka server - spring-cloud

Is there any documentation available related to deploying eureka server on web container like tomcat. I use the spring provided sample and created a war, also renamed it to 'eureka.war' but the dashboard is not displayed..
The code works fine with spring boot but looks some configuration is required for deploying it as war.

See this commit: https://github.com/spring-cloud-samples/eureka/commit/1de7c89cf3f79e4707dbabe91ea60eb06f2268aa
In pom.xml
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
In EurekaApplication.java
public class EurekaApplication extends SpringBootServletInitializer { /*...*/ }

Related

Spring Boot Admin Server and Client in the same application

I am using spring boot 2.5.1 with Java 11.
I am trying to create a SpringBoot Admin Server and Client in the same application, however when I start it, I get the following error in the console.
Ref: https://github.com/codecentric/spring-boot-admin
Error
Failed to register application as Application(name=PowWow,
managementUrl=http://localhost:8085/actuator,
healthUrl=http://localhost:8085/actuator/health,
serviceUrl=http://localhost:8085/) at spring-boot-admin
([http://localhost:8085/instances]): 401 : [no body]. Further attempts
are logged on DEBUG level
I have the following code in the Spring Boot application:
pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-server</artifactId>
<version>2.5.1</version>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
<version>2.5.1</version>
</dependency>
application.properties
server.port=8085
spring.application.name=PowWow
logging.file.name=powwow-logfile.log
logging.logback.rollingpolicy.max-history=3
logging.logback.rollingpolicy.max-file-size=5MB
spring.boot.admin.client.url=http://localhost:8085
management.endpoints.web.exposure.include=*
management.endpoints.health.show-details=always
PowWowApplication.java
#SpringBootApplication
#EnableScheduling
#EnableAdminServer
public class PowWowApplication {
More info
I can access the following url, but it does not load the application: http://localhost:8085/applications
Question
Do you know why the application is not being registered? Is it because you cannot have a spring-boot-admin-starter-server and a spring-boot-admin-starter-client in the same application?
More info
I realised that the application.properties has:
web.access.username=user
web.access.password=password
So I also add the following to allow the client access:
spring.boot.admin.client.username=user
spring.boot.admin.client.password=password
This removes the above error, i.e. there is no longer a 401 error when starting the server, but the application console reports that the server is down:
Console log: No Errors
http://localhost:8085/actuator/health {"status":"UP"}
However, the details show there is a 401.
I resolved this by adding /actuator/** to the following:
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.authorizeRequests().antMatchers("/soapWS/**").permitAll().and()
.authorizeRequests().antMatchers("/actuator/**").permitAll()
.anyRequest().authenticated().and()
.httpBasic().and()
.csrf().disable();
}

How to add standard Spring security to Spring Boot Admin (2.1.4)

Followed reference guide to add security to spring boot admin (https://codecentric.github.io/spring-boot-admin/current/), but upon launching app always get standard login page, which I am unable to bypass (and unsure also how to do so - where to add add login credentials etc). Would like to set up for now Spring Boot Admin with basic security.
Created a standard boot app with "Spring Boot Admin" and "Spring Security" dependency
Imported project into IDE and added #EnableAdminServer annotation to main class and ran
NOTE:
1)did NOT add anything to application.properties
2)also tried approach of using https://www.baeldung.com/spring-boot-admin , where a login page is displayed using WebSecurity config , but that causes 2 login window to appear (one as popup and second as main page)
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import de.codecentric.boot.admin.server.config.EnableAdminServer;
#EnableAdminServer
#SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
Pom :
http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.1.4.RELEASE
com.example
demo
0.0.1-SNAPSHOT
demo
Demo project for Spring Boot
<properties>
<java.version>1.8</java.version>
<spring-boot-admin.version>2.1.4</spring-boot-admin.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-dependencies</artifactId>
<version>${spring-boot-admin.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
Would like to have Spring Boot Admin secure by most basic spring security (using spring boot 2.x)
but that causes 2 login window to appear (one as popup and second as main page)
I have faced this problem and i fixed it by changing the version of spring-boot-admin.
You are using 2.1.4 when 2.1.6 is available.
Try changing the version numbers.

jersey with spring-boot 1.5.14 not working

i am trying to make a jersey jax-rs rest project with spring-boot 1.5.14.
i have used spring jersey starter in dependency. but not working.
Please see my pom beolow.
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.14.BUILD-SNAPSHOT</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<dependences>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jersey</artifactId>
</dependency>
</dependences>
Its not working. #Path #Get those all jax-rs anotation is not resolved.
i have added
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
<version>2.1</version>
</dependency>
then it is resolved. another issue has come.
register(RequestContextFilter.class); is not solved.
then i added---
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-common</artifactId>
<version>2.24.1</version>
</dependency>
now it is solved but new error comming at runtime.
org/jvnet/hk2/spring/bridge/api/SpringBridge class def not found.
again i have added---
<dependency>
<groupId>org.glassfish.hk2</groupId>
<artifactId>spring-bridge</artifactId>
<version>2.2.0-b14</version>
</dependency>
now different error has come---
org/glassfish/hk2/api/ServiceLocatorFactory$CreatePolicy class def not found.
again i have added.
<dependency>
<groupId>org.glassfish.hk2</groupId>
<artifactId>hk2-api</artifactId>
<version>2.1.9</version>
</dependency>
now it is giving----
org/glassfish/hk2/utilities/binding/AbstractBinder class def not found
i have added h2k api
again it is giving
java.lang.NoClassDefFoundError: org/glassfish/hk2/api/ServiceLocator.
i upgraded hk2 api version . then comming class not found jersey.repackaged.com.google.common.base.Function
i added
<dependency>
<groupId>org.glassfish.jersey.bundles.repackaged</groupId>
<artifactId>jersey-guava</artifactId>
<version>2.25.1</version>
now t last it is giving-"No generator was provided and there is no default generator registered-IllegalArgs exception.
if i ad jeresy all. then it is throwing no implementation found for hibernate validator
Probably because you're using BUILD-SNAPSHOT for the Spring Boot parent version. If you're going to use a snapshot version, then you need to configure a snapshot repository in your pom. That's why the Jersey starter dependency can't be resolved. What you want to use is the RELEASE version. All Spring release version end with this suffix.
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.14.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>

Java-ee REST server with IntelliJ and Tomcat

I'm trying to implement a REST Server API using Java-ee following this tutorial. Instead of Glassfish, I use Tomcat.
I could develop a servlet
#WebServlet(name = "hello", urlPatterns = "/")
public class HelloWorld extends HttpServlet {
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().write("=)");
}
}
And join http://localhost:9080/ I can see the smiling face. But when I try to access to the api path (http://localhost:9080/api/recommend/all) I also get the face. If I remove the servlet class, I get a 404 error. I suppose I need something else to build automatically the api but I don't know what.
Could someone tell my what is missing? What should I do?
Update:
In Intellij's Java Enterprise View I see:
Web > HelloWorld
RESTful WS > recommend > all
These are my api classes:
#ApplicationPath("/api")
public class REST_Config extends Application {
}
And the specific method
#Path("recommend")
public class RecommenderController {
#Path("/all")
#GET
#Produces("application/json")
public JsonArray getAll(){
JsonArrayBuilder builder = Json.createArrayBuilder();
builder.add(Json.createObjectBuilder().add("1", "2.5"));
return builder.build();
}
}
And the pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>TestREST</groupId>
<artifactId>TestREST</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
</dependency>
</dependencies>
<build>
<finalName>TestREST</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
</plugin>
</plugins>
</build>
</project>
"Instead of Glassfish, I use Tomcat."
Look at this
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
</dependency>
This is nothing more than basically a bunch of interfaces for the EE spec. There is no implementation. Java EE servers will have the implementation. Tomcat is not an EE server. The only part of the EE spec it will definitely implements is the Servlet Specification. You are trying to work with the JAX-RS spec, where Tomcat for sure by default does not have an implementation for. So you need to add that implementation.
The easiest IMO to get started with, is Jersey. You can simple add this dependency
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>2.17</version>
</dependency>
And it will get you up and running. Keep the Jersey User Guide handy. It will come in use.
Also I don't know what JsonArray is, but what will happen when you run this is you will get some error similar to "No MessageBodyWriter found for JsonArray and media type application/json". You need to provider. If you are going to use the Java EE JSONP API, then you should add the this provider
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-processing</artifactId>
<version>2.17</version>
</dependency>
As you get to working alot with JSON, you wil find this API to be difficult to maintain. I'd recommend using Jackson. If you don't already know it, I'd suggest learning it. It offers simple POJO to JSON mapping. For Jackson, you can add this dependency
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.17</version>
</dependency>

Arquillian integration tests and OpenJPA enhancement

I'm working on a set of integration tests using arquillian and dbunit. I can run some of my tests just fine, but not the ones involving entities which have oneToMany relations with data in them. When running my tests I then get a PersistenceException:
Caused by: java.lang.NullPointerException
at org.apache.openjpa.jdbc.kernel.JDBCStoreManager.setInverseRelation(JDBCStoreManager.java:451)
My test looks like this:
#RunWith(Arquillian.class)
#CreateSchema("sql/masterplanCreateTables.sql")
public class MasterPlanManagerBeanDbIT {
#Rule
public PersistenceUnitRule rule = new PersistenceUnitRule();
#Inject
private MasterplanManager instance;
#PersistenceContext
EntityManager entityManager;
#Deployment
public static WebArchive createDeployment() throws Exception {
return ShrinkWrap
.create(WebArchive.class, .....
}
#Test
#UsingDataSet("/data/integration/uttrans/masterplan/validData_dbInput.xml")
public void updateTrip_givenValidInput_expectsTripToBeUpdated() {
Trip input = givenTrips().get(0);
input.setNote("updated value");
Trip updated = instance.updateTrip(input);
checkEquality(input, updated);//checks field by field for equality
}
}
My pom.xml looks like this:
...
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.jboss.arquillian</groupId>
<artifactId>arquillian-bom</artifactId>
<version>1.0.1.Final</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
...
<dependencies>
<dependency>
<groupId>org.jboss.arquillian.junit</groupId>
<artifactId>arquillian-junit-container</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.openejb</groupId>
<artifactId>arquillian-tomee-embedded</artifactId>
<version>${tomee.version}</version>
<scope>test</scope>
</dependency>
...
</dependencies>
...
I did try the openjpa-maven-plugin to enhance the entities at build-time, but this will afaik alter the compiled entities which later will be deployed to our production environment (using deploy-time enhancement).
With that in mind, is it possible to enable deploy-time enhancement in my arquillian tests?
As I'm using openJpa, I found this link very helpful:
http://openejb.apache.org/javaagent.html
I am simply providing the openejb java-agent to the maven surefire plugin.
If you are using eclipse add -javaagent:{your java agent path} to the VM arguments for the test.
In my case I took the java agent directly from a TomEE installation.