1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package com.jmpeax.osgi.undertow.http.impl;
19
20 import io.undertow.Undertow;
21 import io.undertow.server.handlers.PathHandler;
22 import io.undertow.servlet.Servlets;
23 import io.undertow.servlet.api.*;
24 import io.undertow.servlet.util.ImmediateInstanceHandle;
25 import org.osgi.framework.BundleException;
26 import org.osgi.service.http.NamespaceException;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
29
30 import javax.servlet.Servlet;
31 import javax.servlet.ServletException;
32 import java.util.Dictionary;
33 import java.util.HashSet;
34 import java.util.Set;
35
36
37
38
39
40
41
42 public class UndertowHttpServer {
43
44
45 private final Logger log = LoggerFactory.getLogger(UndertowHttpServer.class);
46 protected Dictionary<String, ?> properties;
47 protected Undertow server;
48 protected PathHandler pathHandler;
49 protected Set<String> registeredPaths;
50
51 public UndertowHttpServer(Dictionary<String, ?> properties) {
52 this.properties = properties;
53 pathHandler = new PathHandler();
54 registeredPaths = new HashSet<>();
55 }
56
57 public void startServer() throws BundleException {
58 Undertow.Builder serverBuilder = Undertow.builder();
59 try {
60 int port = Integer.parseInt(properties.get("undertow.server.http.port").toString());
61 String host = properties.get("undertow.server.http.host").toString();
62 log.debug("Starting Http Listener {}:{}", host, port);
63 serverBuilder.addHttpListener(port, host);
64
65 } catch (NumberFormatException | NullPointerException ex) {
66 log.error("Unable to start Http Server, missing configuration for host and port");
67 log.debug("Reason:", ex);
68 throw new BundleException("Unable to start Http service, configuration invalid!");
69 }
70 serverBuilder.setHandler(pathHandler);
71 server = serverBuilder.build();
72 server.start();
73 }
74
75
76 public void addServletHandler(final String url, final Servlet servlet, final Dictionary<String, ?> props) throws NamespaceException, ServletException {
77 log.debug("Adding {} to url {} with properties {}", servlet, url, props);
78 if (registeredPaths.contains(url)) {
79 throw new NamespaceException("Url " + url + " already Exist");
80 }
81 DeploymentInfo servletBuilder = initServetHandler(url, servlet.getClass().getClassLoader());
82
83 final ServletInfo tobeAdd = Servlets.servlet(url, servlet.getClass(), new InstanceFactory<Servlet>() {
84
85 @Override
86 public InstanceHandle<Servlet> createInstance() throws InstantiationException {
87 return new ImmediateInstanceHandle<Servlet>(servlet);
88 }
89 });
90 tobeAdd.addMapping("/*");
91 servletBuilder.setContextPath(url);
92 servletBuilder.setDeploymentName("TEST");
93 servletBuilder.addServlet(tobeAdd);
94 final DeploymentManager manager = Servlets.defaultContainer().addDeployment(servletBuilder);
95 manager.deploy();
96 pathHandler.addExactPath(url, manager.start());
97 log.debug("Servlet {} was added", url);
98 registeredPaths.add(url);
99 }
100
101 public void addServletHandler(final String url, final Class<? extends Servlet> servlet,
102 final Dictionary<String, ?> props) {
103 DeploymentInfo servletBuilder = initServetHandler(url, servlet.getClassLoader());
104 Servlets.servlet(url, servlet);
105 }
106
107 protected DeploymentInfo initServetHandler(final String url, ClassLoader classloader) {
108 DeploymentInfo servletBuilder = Servlets.deployment();
109 servletBuilder.setClassLoader(classloader);
110 servletBuilder.setContextPath(url);
111 return servletBuilder;
112 }
113
114 public void removeHandler(final String path) {
115 pathHandler.removeExactPath(path);
116 registeredPaths.remove(path);
117 log.debug("{} was remove from server", path);
118 }
119
120 public void stopServer() {
121 log.info("Stopping Http Server");
122 log.debug("Clearing all paths");
123 pathHandler.clearPaths();
124 log.debug("Stopping all Http/Ajp services");
125 server.stop();
126 log.info("Http Server was shutdown");
127 }
128
129 }