Skip to content

Commit 934f931

Browse files
committed
servers - introduced new restx-server-jetty7 for servlet 2.5 compatible embedded jetty server
1 parent 9a93edf commit 934f931

File tree

9 files changed

+447
-0
lines changed

9 files changed

+447
-0
lines changed

pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,11 @@
233233
<artifactId>restx-specs-tests-java8</artifactId>
234234
<version>${restx.version}</version>
235235
</dependency>
236+
<dependency>
237+
<groupId>io.restx</groupId>
238+
<artifactId>restx-server-jetty7</artifactId>
239+
<version>${restx.version}</version>
240+
</dependency>
236241
<dependency>
237242
<groupId>io.restx</groupId>
238243
<artifactId>restx-server-jetty8</artifactId>
@@ -581,6 +586,7 @@
581586
<module>restx-jongo</module>
582587
<module>restx-jongo-specs-tests</module>
583588
<module>restx-servlet</module>
589+
<module>restx-server-jetty7</module>
584590
<module>restx-server-jetty8</module>
585591
<module>restx-server-tomcat</module>
586592
<module>restx-server-simple</module>

restx-server-jetty7/md.restx.json

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"parent": "io.restx:restx-parent:${restx.version}",
3+
"module": "io.restx:restx-server-jetty7:${restx.version}",
4+
5+
"properties": {
6+
"@files": ["../restx.build.properties.json"]
7+
},
8+
9+
"dependencies": {
10+
"compile": [
11+
"io.restx:restx-factory:${restx.version}",
12+
"io.restx:restx-core:${restx.version}",
13+
"javax.servlet:servlet-api:2.5",
14+
"io.restx:restx-servlet:${restx.version}",
15+
"org.eclipse.jetty:jetty-server:${jetty7.version}",
16+
"org.eclipse.jetty:jetty-servlet:${jetty7.version}",
17+
"org.eclipse.jetty:jetty-security:${jetty7.version}",
18+
"org.eclipse.jetty:jetty-util:${jetty7.version}",
19+
"org.eclipse.jetty:jetty-webapp:${jetty7.version}",
20+
"org.eclipse.jetty:jetty-servlets:${jetty7.version}"
21+
]
22+
}
23+
}

restx-server-jetty7/module.ivy

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<ivy-module version="2.0" xmlns:ea="http://www.easyant.org">
2+
<info organisation="io.restx" module="restx-server-jetty7" revision="0.35" status="integration">
3+
<ea:build organisation="org.apache.easyant.buildtypes" module="build-std-java" revision="0.9"
4+
compile.java.source.version="1.7"
5+
compile.java.target.version="1.7"
6+
/>
7+
</info>
8+
<configurations>
9+
<conf name="default"/>
10+
<conf name="runtime"/>
11+
<conf name="test"/>
12+
</configurations>
13+
<publications>
14+
<artifact type="jar"/>
15+
</publications>
16+
<dependencies>
17+
<dependency org="io.restx" name="restx-factory" rev="latest.integration" conf="default" />
18+
<dependency org="io.restx" name="restx-core" rev="latest.integration" conf="default" />
19+
<dependency org="javax.servlet" name="servlet-api" rev="2.5" conf="default" />
20+
<dependency org="io.restx" name="restx-servlet" rev="latest.integration" conf="default" />
21+
<dependency org="org.eclipse.jetty" name="jetty-server" rev="7.6.21.v20160908" conf="default" />
22+
<dependency org="org.eclipse.jetty" name="jetty-servlet" rev="7.6.21.v20160908" conf="default" />
23+
<dependency org="org.eclipse.jetty" name="jetty-security" rev="7.6.21.v20160908" conf="default" />
24+
<dependency org="org.eclipse.jetty" name="jetty-util" rev="7.6.21.v20160908" conf="default" />
25+
<dependency org="org.eclipse.jetty" name="jetty-webapp" rev="7.6.21.v20160908" conf="default" />
26+
<dependency org="org.eclipse.jetty" name="jetty-servlets" rev="7.6.21.v20160908" conf="default" />
27+
</dependencies>
28+
</ivy-module>

restx-server-jetty7/pom.xml

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
7+
<parent>
8+
<groupId>io.restx</groupId>
9+
<artifactId>restx-parent</artifactId>
10+
<version>0.35-SNAPSHOT</version>
11+
</parent>
12+
13+
<artifactId>restx-server-jetty7</artifactId>
14+
<name>restx-server-jetty7</name>
15+
16+
<properties>
17+
<jetty7.version>7.6.21.v20160908</jetty7.version>
18+
<servlet-api.version>2.5</servlet-api.version>
19+
</properties>
20+
21+
<dependencies>
22+
<dependency>
23+
<groupId>io.restx</groupId>
24+
<artifactId>restx-factory</artifactId>
25+
</dependency>
26+
<dependency>
27+
<groupId>io.restx</groupId>
28+
<artifactId>restx-core</artifactId>
29+
</dependency>
30+
<dependency>
31+
<groupId>io.restx</groupId>
32+
<artifactId>restx-servlet</artifactId>
33+
</dependency>
34+
<dependency>
35+
<groupId>javax.servlet</groupId>
36+
<artifactId>servlet-api</artifactId>
37+
<version>${servlet-api.version}</version>
38+
<scope>provided</scope>
39+
</dependency>
40+
41+
<!-- Jetty -->
42+
<dependency>
43+
<groupId>org.eclipse.jetty</groupId>
44+
<artifactId>jetty-server</artifactId>
45+
<version>${jetty7.version}</version>
46+
</dependency>
47+
<dependency>
48+
<groupId>org.eclipse.jetty</groupId>
49+
<artifactId>jetty-servlet</artifactId>
50+
<version>${jetty7.version}</version>
51+
</dependency>
52+
<dependency>
53+
<groupId>org.eclipse.jetty</groupId>
54+
<artifactId>jetty-security</artifactId>
55+
<version>${jetty7.version}</version>
56+
</dependency>
57+
<dependency>
58+
<groupId>org.eclipse.jetty</groupId>
59+
<artifactId>jetty-util</artifactId>
60+
<version>${jetty7.version}</version>
61+
</dependency>
62+
<dependency>
63+
<groupId>org.eclipse.jetty</groupId>
64+
<artifactId>jetty-webapp</artifactId>
65+
<version>${jetty7.version}</version>
66+
</dependency>
67+
<dependency>
68+
<groupId>org.eclipse.jetty</groupId>
69+
<artifactId>jetty-servlets</artifactId>
70+
<version>${jetty7.version}</version>
71+
</dependency>
72+
</dependencies>
73+
</project>
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package restx.server;
2+
3+
import com.google.common.base.Charsets;
4+
import com.google.common.hash.Hashing;
5+
import restx.factory.Module;
6+
import restx.factory.Provides;
7+
8+
import javax.inject.Named;
9+
10+
/**
11+
* @author fcamblor
12+
*/
13+
@Module(priority = 1000)
14+
public class JettyServerModule {
15+
@Provides
16+
@Named("restx.server.jetty.webxml.default.location")
17+
public String restxServerJettyWebXmlDefaultLocation(@Named("restx.server.jetty.appbase.default.location") String appBase) {
18+
return appBase+"/WEB-INF/web.xml";
19+
}
20+
21+
22+
@Provides
23+
@Named("restx.server.jetty.appbase.default.location")
24+
public String restxServerJettyAppBaseDefaultLocation() {
25+
return "src/main/webapp";
26+
}
27+
28+
@Provides
29+
@Named("restx.server.jetty")
30+
public WebServerSupplier jettyWebServerSupplier(
31+
@Named("restx.server.jetty.appbase.default.location") String appBase,
32+
@Named("restx.server.jetty.webxml.default.location") String webxml){
33+
return JettyWebServer.jettyWebServerSupplier(webxml, appBase);
34+
}
35+
}
Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
package restx.server;
2+
3+
import com.google.common.base.Strings;
4+
import org.eclipse.jetty.security.DefaultIdentityService;
5+
import org.eclipse.jetty.security.HashLoginService;
6+
import org.eclipse.jetty.server.Handler;
7+
import org.eclipse.jetty.server.Server;
8+
import org.eclipse.jetty.server.handler.HandlerCollection;
9+
import org.eclipse.jetty.server.handler.HandlerList;
10+
import org.eclipse.jetty.server.nio.SelectChannelConnector;
11+
import org.eclipse.jetty.util.component.AbstractLifeCycle;
12+
import org.eclipse.jetty.util.component.LifeCycle;
13+
import org.eclipse.jetty.util.thread.QueuedThreadPool;
14+
import org.eclipse.jetty.util.thread.ThreadPool;
15+
import org.eclipse.jetty.webapp.WebAppContext;
16+
import org.slf4j.Logger;
17+
import org.slf4j.LoggerFactory;
18+
import restx.common.Version;
19+
20+
import java.util.concurrent.atomic.AtomicLong;
21+
22+
import static com.google.common.base.Preconditions.checkNotNull;
23+
import static restx.common.MoreFiles.checkFileExists;
24+
import static restx.common.MoreIO.checkCanOpenSocket;
25+
26+
public class JettyWebServer implements WebServer {
27+
private static final AtomicLong SERVER_ID = new AtomicLong();
28+
29+
private static final Logger logger = LoggerFactory.getLogger(JettyWebServer.class);
30+
31+
private Server server;
32+
private int port;
33+
private String bindInterface;
34+
private String appBase;
35+
private String webInfLocation;
36+
private String serverId;
37+
38+
39+
public JettyWebServer(String appBase, int aPort) {
40+
this(null, appBase, aPort, null);
41+
}
42+
43+
public JettyWebServer(String webInfLocation, String appBase, int port, String bindInterface) {
44+
checkFileExists(checkNotNull(appBase));
45+
46+
if (webInfLocation != null) {
47+
checkFileExists(webInfLocation);
48+
}
49+
50+
this.port = port;
51+
this.bindInterface = bindInterface;
52+
this.appBase = appBase;
53+
this.webInfLocation = webInfLocation;
54+
this.serverId = "Jetty#" + SERVER_ID.incrementAndGet();
55+
}
56+
57+
/**
58+
* Sets the serverId used by this server.
59+
*
60+
* Must not be called when server is started.
61+
*
62+
* The serverId is used to uniquely identify the main Factory used by REST main router in this server.
63+
* It allows to access the Factory with Factory.getInstance(serverId).
64+
*
65+
* @param serverId the server id to set. Must be unique in the JVM.
66+
*
67+
* @return current server
68+
*/
69+
public synchronized JettyWebServer setServerId(final String serverId) {
70+
if (isStarted()) {
71+
throw new IllegalStateException("can't set server id when server is started");
72+
}
73+
this.serverId = serverId;
74+
return this;
75+
}
76+
77+
@Override
78+
public String getServerId() {
79+
return serverId;
80+
}
81+
82+
@Override
83+
public int getPort() {
84+
return port;
85+
}
86+
87+
@Override
88+
public String baseUrl() {
89+
return WebServers.baseUri("127.0.0.1", port);
90+
}
91+
92+
@Override
93+
public String getServerType() {
94+
return "Jetty " + Version.getVersion("org.eclipse.jetty", "jetty-server") + ", embedded";
95+
}
96+
97+
@Override
98+
public synchronized void start() throws Exception {
99+
checkCanOpenSocket(port);
100+
101+
server = new Server();
102+
WebServers.register(this);
103+
104+
server.setThreadPool(createThreadPool());
105+
server.addConnector(createConnector());
106+
server.setHandler(createHandlers(createContext()));
107+
server.setStopAtShutdown(true);
108+
109+
server.start();
110+
}
111+
112+
@Override
113+
public void startAndAwait() throws Exception {
114+
start();
115+
await();
116+
}
117+
118+
@Override
119+
public void await() throws InterruptedException {
120+
server.join();
121+
}
122+
123+
@Override
124+
public synchronized void stop() throws Exception {
125+
server.stop();
126+
server = null;
127+
WebServers.unregister(serverId);
128+
}
129+
130+
@Override
131+
public synchronized boolean isStarted() {
132+
return server != null;
133+
}
134+
135+
protected ThreadPool createThreadPool() {
136+
QueuedThreadPool threadPool = new QueuedThreadPool();
137+
threadPool.setMinThreads(1);
138+
threadPool.setMaxThreads(Math.max(10, Runtime.getRuntime().availableProcessors()));
139+
return threadPool;
140+
}
141+
142+
protected SelectChannelConnector createConnector() {
143+
SelectChannelConnector connector = new SelectChannelConnector();
144+
connector.setPort(port);
145+
connector.setHost(bindInterface);
146+
return connector;
147+
}
148+
149+
protected HandlerCollection createHandlers(WebAppContext webAppContext) {
150+
151+
HandlerList contexts = new HandlerList();
152+
contexts.setHandlers(new Handler[]{webAppContext});
153+
154+
HandlerCollection result = new HandlerCollection();
155+
result.setHandlers(new Handler[]{contexts});
156+
157+
return result;
158+
}
159+
160+
protected WebAppContext createContext() {
161+
final WebAppContext ctx = new WebAppContext();
162+
ctx.setContextPath("/");
163+
ctx.setWar(appBase);
164+
if(!Strings.isNullOrEmpty(webInfLocation)) {
165+
ctx.setDescriptor(webInfLocation);
166+
}
167+
// configure security to avoid err println "Null identity service, trying login service:"
168+
// but I've found no way to get rid of LoginService=xxx log on system err :(
169+
HashLoginService loginService = new HashLoginService();
170+
loginService.setIdentityService(new DefaultIdentityService());
171+
ctx.getSecurityHandler().setLoginService(loginService);
172+
ctx.getSecurityHandler().setIdentityService(loginService.getIdentityService());
173+
174+
ctx.addLifeCycleListener(new AbstractLifeCycle.AbstractLifeCycleListener() {
175+
@Override
176+
public void lifeCycleStarting(LifeCycle event) {
177+
ctx.getServletContext().setInitParameter("restx.baseServerUri", baseUrl());
178+
ctx.getServletContext().setInitParameter("restx.serverId", getServerId());
179+
}
180+
});
181+
182+
return ctx;
183+
}
184+
185+
public static WebServerSupplier jettyWebServerSupplier(final String webInfLocation, final String appBase) {
186+
return new WebServerSupplier() {
187+
@Override
188+
public WebServer newWebServer(int port) {
189+
return new JettyWebServer(webInfLocation, appBase, port, "0.0.0.0");
190+
}
191+
};
192+
}
193+
194+
public static void main(String[] args) throws Exception {
195+
if (args.length == 0) {
196+
System.err.println("usage: jetty-run <appbase> [<port>]");
197+
System.exit(1);
198+
}
199+
200+
String appBase = args[0];
201+
int port = args.length > 1 ? Integer.parseInt(args[1]) : 8086;
202+
new JettyWebServer(appBase + "WEB-INF/web.xml", appBase, port, "0.0.0.0").startAndAwait();
203+
}
204+
}

0 commit comments

Comments
 (0)