View Javadoc
1   /*
2    * Copyright 2009 the original author or authors.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *     
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.openehealth.ipf.commons.ihe.ws.server;
17  
18  import org.apache.catalina.Context;
19  import org.apache.catalina.Wrapper;
20  import org.apache.catalina.authenticator.jaspic.AuthConfigFactoryImpl;
21  import org.apache.catalina.connector.Connector;
22  import org.apache.catalina.startup.Tomcat;
23  import org.openehealth.ipf.commons.ihe.core.ClientAuthType;
24  import org.slf4j.Logger;
25  import org.slf4j.LoggerFactory;
26  import org.springframework.web.context.ContextLoaderListener;
27  
28  import javax.security.auth.message.config.AuthConfigFactory;
29  import java.util.Map;
30  import java.util.concurrent.atomic.AtomicInteger;
31  
32  /**
33   * A servlet server based on the embedded Tomcat.
34   * <p>
35   * Note: any exceptions thrown are treated as assertion failures.
36   * @author Jens Riemschneider
37   */
38  public class TomcatServer extends ServletServer {
39      private static final Logger log = LoggerFactory.getLogger(TomcatServer.class);
40  
41      private static final AtomicInteger SERVLET_COUNTER = new AtomicInteger(0);
42      private Tomcat embedded;
43      private Wrapper wrapper;
44  
45      @Override
46      public void start() {
47          embedded = new Tomcat();
48          AuthConfigFactory.setFactory(new AuthConfigFactoryImpl());
49  
50          Context context = embedded.addContext(getContextPath(), "/");
51          context.addParameter("contextConfigLocation", getContextResource());
52          context.addApplicationListener(ContextLoaderListener.class.getName());
53  
54          embedded.getHost().setAppBase("");
55  
56          // Each servlet should get an unique name, otherwise all servers will reuse
57          // one and the same servlet instance.  Note that name clashes with servlets
58          // created somewhere else are still possible.
59          String servletName = getServletName() == null ?
60                  "ipf-servlet-" + SERVLET_COUNTER.getAndIncrement() :
61                  getServletName();
62  
63          wrapper = context.createWrapper();
64          wrapper.setName(servletName);
65          wrapper.setServletClass(getServlet().getClass().getName());
66  
67          for (Map.Entry<String, String> parameters : getInitParameters().entrySet()) {
68              wrapper.addInitParameter(parameters.getKey(), parameters.getValue());
69          }
70  
71          context.addChild(wrapper);
72          context.addServletMapping(getServletPath(), servletName);
73  
74          /*
75          VirtualWebappLoader loader = new VirtualWebappLoader(this.getClass().getClassLoader());
76          loader.setVirtualClasspath(System.getProperty("java.class.path"));
77          context.setLoader(loader);
78          */
79          Connector connector = embedded.getConnector();
80          connector.setPort(getPort());
81          if (isSecure()) {
82              connector.setSecure(true);
83              connector.setScheme("https");
84              connector.setProperty("SSLEnabled", "true");
85              connector.setProperty("sslProtocol", "TLS");
86              connector.setProperty("keystoreFile", getKeystoreFile());
87              connector.setProperty("keystorePass", getKeystorePass());
88              connector.setProperty("truststoreFile", getTruststoreFile());
89              connector.setProperty("truststorePass", getTruststorePass());
90              if (getClientAuthType() == ClientAuthType.MUST) {
91                  connector.setProperty("clientAuth", "true");
92              } else if (getClientAuthType() == ClientAuthType.WANT) {
93                  connector.setProperty("clientAuth", "want");
94              }
95          }
96  
97          try {
98              embedded.start();
99              wrapper.allocate();
100             log.info("Started embedded Tomcat server");
101         } catch (Exception e) {
102             throw new AssertionError(e);
103         }
104     }
105 
106     @Override
107     public void stop() {
108         if (embedded != null) {
109             try {
110                 wrapper.deallocate(getServlet());
111                 embedded.stop();
112                 log.info("Stopped embedded Tomcat server");
113             } catch (Exception e) {
114                 throw new AssertionError(e);
115             }
116         }
117     }
118 }