MAVEN Web Application with Jetty
Recently, I need to create Java Project which support servlet and running under jetty, so here is the steps.
Create the project
>mvn archetype:generate -DgroupId=com.j2c -DartifactId=healthcheckcontainer -DarchetypeArtifactId=maven-archetype-webapp -DinteractiveMode=false
After it created, I will get the pom.xml similar to following
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.sillycat.solr</groupId>
<packaging>war</packaging>
<version>1.0</version>
<name>solr-healthcheck</name>
<url>http://maven.apache.org</url>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.4.7.v20170914</version>
<configuration>
<scanIntervalSeconds>10</scanIntervalSeconds>
<webApp>
<contextPath>/healthcheck</contextPath>
<webInfIncludeJarPattern>.*/spring-[^/]*\.jar$</webInfIncludeJarPattern>
</webApp>
</configuration>
</plugin>
</plugins>
<finalName>solr-healthcheck</finalName>
</build>
<artifactId>solr-healthcheck</artifactId>
</project>
It is a very simple servlet things to support parse and monitor a JSON response, web.xml is as follow:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
id="WebApp_ID" version="3.1">
<display-name>SOLR HealthCheck</display-name>
<servlet>
<servlet-name>healthCheckServlet</servlet-name>
<servlet-class>com.sillycat.solr.HealthCheckServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>healthCheckServlet</servlet-name>
<url-pattern>/healthcheck</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>healthCheckServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
The servlet class will be as simple as follow HealthCheckServlet.java
package com.sillycat.solr;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HealthCheckServlet extends HttpServlet {
private static final long serialVersionUID = -5366378871837937127L;
private final static Logger logger = LoggerFactory.getLogger(HealthCheckServlet.class);
private String host = "localhost";
private String collection = "allJobs";
private String shard = "shard1";
public void init() throws ServletException {
super.init();
host = System.getProperty("host");
collection = System.getProperty("collection");
shard = System.getProperty("shard");
}
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
final String replicaState = ReplicaState.getReplicaState(host, collection, shard);
if (!ReplicaState.isReplicaActive(replicaState)) {
final String message = "Replica is NOT active(host=" + host + ", collection=" + collection + ", shard="
+ shard + ", state=" + replicaState + ")";
logger.info(message);
resp.setStatus(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
resp.getWriter().println(message);
} else {
String message = "Replica is active(host=" + host + ", collection=" + collection + ", shard=" + shard + ")";
logger.info(message);
resp.getWriter().println(message);
}
}
}
After all these is done, we can easily run maven command to debug and run the things
>mvn jetty:run
Good idea from my colleague, he thinks that we should run that not on maven plugin, but real jetty.
Here is the Makefile>
IMAGE=odt/solr-healthcheck
TAG=latest
NAME=solr-healthcheck
REPOSITORY=sillycat.dkr.ecr.us-east-1.amazonaws.com
# Docker Image
docker-context: target/solr-healthcheck.war
build: docker-context
docker build -t $(IMAGE):$(TAG) .
debug:
docker run -ti -p 8080:8080 --name $(NAME) $(IMAGE):$(TAG) /bin/bash
run:
docker run -p 8080:8080 --name $(NAME) $(IMAGE):$(TAG)
clean:
- docker stop ${NAME}
- docker rm ${NAME}
mvn clean
target/solr-healthcheck.war:
mvn compile package
tag:
docker tag $(IMAGE):$(TAG) $(REPOSITORY)/$(IMAGE):$(TAG)
push:
docker push $(REPOSITORY)/$(IMAGE):$(TAG)
Here is the Dockerfile>
FROM jetty:9.4.7
COPY start.sh /var/lib/jetty
COPY target/solr-healthcheck.war /var/lib/jetty/webapps
ENV JAVA_OPTIONS=-Xmx64m
CMD ["./start.sh"]
Here is the start.sh>
#!/bin/sh -ex
# Configuration
HOST_IP=${HOST_IP:-`curl "http://169.254.169.254/latest/meta-data/local-ipv4"`}
COLLECTION=${COLLECTION:-"allJobs"}
SHARD=${SHARD:-"shard1"}
JVM_PROPS="-Dhost=${HOST_IP} -Dcollection=${COLLECTION} -Dshard=${SHARD}"
java -jar /usr/local/jetty/start.jar ${JVM_PROPS}
Beside the Jetty Java Servlet, we can also directly use JAVA HTTP Server like these:
https://www.codeproject.com/Tips/1040097/Create-a-Simple-Web-Server-in-Java-HTTP-Server
https://stackoverflow.com/questions/3732109/simple-http-server-in-java-using-only-java-se-api
References:
http://www.javawebtutor.com/articles/maven/maven_web_project.php
https://github.com/mitreid-connect/simple-web-app/blob/master/pom.xml
http://www.baeldung.com/deploy-to-jetty
Recently, I need to create Java Project which support servlet and running under jetty, so here is the steps.
Create the project
>mvn archetype:generate -DgroupId=com.j2c -DartifactId=healthcheckcontainer -DarchetypeArtifactId=maven-archetype-webapp -DinteractiveMode=false
After it created, I will get the pom.xml similar to following
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.sillycat.solr</groupId>
<packaging>war</packaging>
<version>1.0</version>
<name>solr-healthcheck</name>
<url>http://maven.apache.org</url>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.4.7.v20170914</version>
<configuration>
<scanIntervalSeconds>10</scanIntervalSeconds>
<webApp>
<contextPath>/healthcheck</contextPath>
<webInfIncludeJarPattern>.*/spring-[^/]*\.jar$</webInfIncludeJarPattern>
</webApp>
</configuration>
</plugin>
</plugins>
<finalName>solr-healthcheck</finalName>
</build>
<artifactId>solr-healthcheck</artifactId>
</project>
It is a very simple servlet things to support parse and monitor a JSON response, web.xml is as follow:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
id="WebApp_ID" version="3.1">
<display-name>SOLR HealthCheck</display-name>
<servlet>
<servlet-name>healthCheckServlet</servlet-name>
<servlet-class>com.sillycat.solr.HealthCheckServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>healthCheckServlet</servlet-name>
<url-pattern>/healthcheck</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>healthCheckServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
The servlet class will be as simple as follow HealthCheckServlet.java
package com.sillycat.solr;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HealthCheckServlet extends HttpServlet {
private static final long serialVersionUID = -5366378871837937127L;
private final static Logger logger = LoggerFactory.getLogger(HealthCheckServlet.class);
private String host = "localhost";
private String collection = "allJobs";
private String shard = "shard1";
public void init() throws ServletException {
super.init();
host = System.getProperty("host");
collection = System.getProperty("collection");
shard = System.getProperty("shard");
}
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
final String replicaState = ReplicaState.getReplicaState(host, collection, shard);
if (!ReplicaState.isReplicaActive(replicaState)) {
final String message = "Replica is NOT active(host=" + host + ", collection=" + collection + ", shard="
+ shard + ", state=" + replicaState + ")";
logger.info(message);
resp.setStatus(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
resp.getWriter().println(message);
} else {
String message = "Replica is active(host=" + host + ", collection=" + collection + ", shard=" + shard + ")";
logger.info(message);
resp.getWriter().println(message);
}
}
}
After all these is done, we can easily run maven command to debug and run the things
>mvn jetty:run
Good idea from my colleague, he thinks that we should run that not on maven plugin, but real jetty.
Here is the Makefile>
IMAGE=odt/solr-healthcheck
TAG=latest
NAME=solr-healthcheck
REPOSITORY=sillycat.dkr.ecr.us-east-1.amazonaws.com
# Docker Image
docker-context: target/solr-healthcheck.war
build: docker-context
docker build -t $(IMAGE):$(TAG) .
debug:
docker run -ti -p 8080:8080 --name $(NAME) $(IMAGE):$(TAG) /bin/bash
run:
docker run -p 8080:8080 --name $(NAME) $(IMAGE):$(TAG)
clean:
- docker stop ${NAME}
- docker rm ${NAME}
mvn clean
target/solr-healthcheck.war:
mvn compile package
tag:
docker tag $(IMAGE):$(TAG) $(REPOSITORY)/$(IMAGE):$(TAG)
push:
docker push $(REPOSITORY)/$(IMAGE):$(TAG)
Here is the Dockerfile>
FROM jetty:9.4.7
COPY start.sh /var/lib/jetty
COPY target/solr-healthcheck.war /var/lib/jetty/webapps
ENV JAVA_OPTIONS=-Xmx64m
CMD ["./start.sh"]
Here is the start.sh>
#!/bin/sh -ex
# Configuration
HOST_IP=${HOST_IP:-`curl "http://169.254.169.254/latest/meta-data/local-ipv4"`}
COLLECTION=${COLLECTION:-"allJobs"}
SHARD=${SHARD:-"shard1"}
JVM_PROPS="-Dhost=${HOST_IP} -Dcollection=${COLLECTION} -Dshard=${SHARD}"
java -jar /usr/local/jetty/start.jar ${JVM_PROPS}
Beside the Jetty Java Servlet, we can also directly use JAVA HTTP Server like these:
https://www.codeproject.com/Tips/1040097/Create-a-Simple-Web-Server-in-Java-HTTP-Server
https://stackoverflow.com/questions/3732109/simple-http-server-in-java-using-only-java-se-api
References:
http://www.javawebtutor.com/articles/maven/maven_web_project.php
https://github.com/mitreid-connect/simple-web-app/blob/master/pom.xml
http://www.baeldung.com/deploy-to-jetty