Sonar Fixes: Variable name changes
[aaf/authz.git] / auth / auth-core / src / main / java / org / onap / aaf / auth / server / JettyServiceStarter.java
1 /**
2  * ============LICENSE_START====================================================
3  * org.onap.aaf
4  * ===========================================================================
5  * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
6  * ===========================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END====================================================
19  *
20  */
21 package org.onap.aaf.auth.server;
22
23 import java.io.IOException;
24 import java.net.InetAddress;
25 import java.util.Properties;
26
27 import javax.servlet.Filter;
28 import javax.servlet.FilterChain;
29 import javax.servlet.ServletException;
30 import javax.servlet.ServletRequest;
31 import javax.servlet.ServletResponse;
32 import javax.servlet.http.HttpServletRequest;
33 import javax.servlet.http.HttpServletResponse;
34
35 import org.eclipse.jetty.http.HttpVersion;
36 import org.eclipse.jetty.server.HttpConfiguration;
37 import org.eclipse.jetty.server.HttpConnectionFactory;
38 import org.eclipse.jetty.server.Request;
39 import org.eclipse.jetty.server.SecureRequestCustomizer;
40 import org.eclipse.jetty.server.Server;
41 import org.eclipse.jetty.server.ServerConnector;
42 import org.eclipse.jetty.server.SslConnectionFactory;
43 import org.eclipse.jetty.server.handler.AbstractHandler;
44 import org.eclipse.jetty.util.ssl.SslContextFactory;
45 import org.onap.aaf.auth.org.OrganizationException;
46 import org.onap.aaf.auth.rserv.RServlet;
47 import org.onap.aaf.cadi.Access.Level;
48 import org.onap.aaf.cadi.CadiException;
49 import org.onap.aaf.cadi.LocatorException;
50 import org.onap.aaf.cadi.config.Config;
51 import org.onap.aaf.misc.env.Trans;
52 import org.onap.aaf.misc.env.util.Split;
53 import org.onap.aaf.misc.rosetta.env.RosettaEnv;
54
55
56 public class JettyServiceStarter<ENV extends RosettaEnv, TRANS extends Trans> extends AbsServiceStarter<ENV,TRANS> {
57
58     public JettyServiceStarter(final AbsService<ENV,TRANS> service, boolean secure) throws OrganizationException {
59         super(service, secure);
60     }
61
62     @Override
63     public void _propertyAdjustment() {
64         Properties props = access().getProperties();
65         Object httpproto = null;
66         // Critical - if no Security Protocols set, then set it.  We'll just get messed up if not
67         if ((httpproto=props.get(Config.CADI_PROTOCOLS))==null) {
68             if ((httpproto=props.get(Config.HTTPS_PROTOCOLS))==null) {
69                 props.put(Config.CADI_PROTOCOLS, (httpproto=Config.HTTPS_PROTOCOLS_DEFAULT));
70             } else {
71                 props.put(Config.CADI_PROTOCOLS, httpproto);
72             }
73         }
74
75         if ("1.7".equals(System.getProperty("java.specification.version")) && (httpproto==null || (httpproto instanceof String && ((String)httpproto).contains("TLSv1.2")))) {
76             System.setProperty(Config.HTTPS_CIPHER_SUITES, Config.HTTPS_CIPHER_SUITES_DEFAULT);
77         }
78     }
79
80     @Override
81     public void _start(RServlet<TRANS> rserv) throws Exception {
82         final int port = Integer.parseInt(access().getProperty("port","0"));
83         final String keystore = access().getProperty(Config.CADI_KEYSTORE, null);
84         final int IDLE_TIMEOUT = Integer.parseInt(access().getProperty(Config.AAF_CONN_IDLE_TIMEOUT, Config.AAF_CONN_IDLE_TIMEOUT_DEF));
85         Server server = new Server();
86
87         ServerConnector conn;
88         String protocol;
89         if (!secure || keystore==null) {
90             conn = new ServerConnector(server);
91             protocol = "http";
92         } else {
93             protocol = "https";
94
95
96             String keystorePassword = access().getProperty(Config.CADI_KEYSTORE_PASSWORD, null);
97             if (keystorePassword==null) {
98                 throw new CadiException("No Keystore Password configured for " + keystore);
99             }
100             SslContextFactory sslContextFactory = new SslContextFactory();
101             sslContextFactory.setKeyStorePath(keystore);
102             String temp;
103             sslContextFactory.setKeyStorePassword(temp=access().decrypt(keystorePassword, true)); // don't allow unencrypted
104             sslContextFactory.setKeyManagerPassword(temp);
105             temp=null; // don't leave lying around
106
107             String truststore = access().getProperty(Config.CADI_TRUSTSTORE, null);
108             if (truststore!=null) {
109                 String truststorePassword = access().getProperty(Config.CADI_TRUSTSTORE_PASSWORD, null);
110                 if (truststorePassword==null) {
111                     throw new CadiException("No Truststore Password configured for " + truststore);
112                 }
113                 sslContextFactory.setTrustStorePath(truststore);
114                 sslContextFactory.setTrustStorePassword(access().decrypt(truststorePassword, false));
115             }
116             // Be able to accept only certain protocols, i.e. TLSv1.1+
117             String subprotocols = access().getProperty(Config.CADI_PROTOCOLS, Config.HTTPS_PROTOCOLS_DEFAULT);
118             service.setSubprotocol(subprotocols);
119             final String[] protocols = Split.splitTrim(',', subprotocols);
120             sslContextFactory.setIncludeProtocols(protocols);
121
122             // Want to use Client Certificates, if they exist.
123             sslContextFactory.setWantClientAuth(true);
124
125             String certAlias = access().getProperty(Config.CADI_ALIAS, null);
126             if (certAlias!=null) {
127                 sslContextFactory.setCertAlias(certAlias);
128             }
129
130             HttpConfiguration httpConfig = new HttpConfiguration();
131             httpConfig.setSecureScheme(protocol);
132             httpConfig.setSecurePort(port);
133             httpConfig.addCustomizer(new SecureRequestCustomizer());
134             //  httpConfig.setOutputBufferSize(32768);  Not sure why take this setting
135
136             conn = new ServerConnector(server,
137                 new SslConnectionFactory(sslContextFactory,HttpVersion.HTTP_1_1.asString()),
138                     new HttpConnectionFactory(httpConfig)
139                 );
140         }
141         service.setProtocol(protocol);
142
143         conn.setHost(hostname);
144         conn.setPort(port);
145         conn.setIdleTimeout(IDLE_TIMEOUT);
146         server.addConnector(conn);
147
148         server.setHandler(new AbstractHandler() {
149                 private FilterChain fc = buildFilterChain(service,new FilterChain() {
150                     @Override
151                     public void doFilter(ServletRequest req, ServletResponse resp) throws IOException, ServletException {
152                         rserv.service(req, resp);
153                     }
154                 });
155
156                 @Override
157                 public void handle(String target, Request baseRequest, HttpServletRequest hreq, HttpServletResponse hresp) throws IOException, ServletException {
158                     try {
159                         fc.doFilter(hreq,hresp);
160                     } catch (Exception e) {
161                         service.access.log(e, "Error Processing " + target);
162                         hresp.setStatus(500 /* Service Error */);
163                     }
164                     baseRequest.setHandled(true);
165                 }
166             }
167         );
168
169         try {
170             access().printf(Level.INIT, "Starting service on %s:%d (%s)",hostname,port,InetAddress.getByName(hostname).getHostAddress());
171             server.start();
172             access().log(Level.INIT,server.dump());
173         } catch (Exception e) {
174             access().log(e,"Error starting " + hostname + ':' + port + ' ' + InetAddress.getLocalHost().getHostAddress());
175             String doExit = access().getProperty("cadi_exitOnFailure", "true");
176             if (doExit == "true") {
177                 System.exit(1);
178             } else {
179                 throw e;
180             }
181         }
182         try {
183             String noRegister = env().getProperty("aaf_no_register",null);
184             if(noRegister==null) {
185                 register(service.registrants(port));
186             } else {
187                 access().printf(Level.INIT,"'aaf_no_register' is set.  %s will not be registered with Locator", service.appName);
188             }
189             access().printf(Level.INIT, "Starting Jetty Service for %s, version %s, on %s://%s:%d", service.appName,service.appVersion,protocol,hostname,port);
190
191             rserv.postStartup(hostname, port);
192         } catch (Exception e) {
193             access().log(e,"Error registering " + service.appName);
194             String doExit = access().getProperty("cadi_exitOnFailure", "true");
195             if (doExit == "true") {
196                 System.exit(1);
197             } else {
198                 throw e;
199             }
200         }
201     }
202
203     private FilterChain buildFilterChain(final AbsService<?,?> as, final FilterChain doLast) throws CadiException, LocatorException {
204         Filter[] filters = as.filters();
205         FilterChain fc = doLast;
206         for (int i=filters.length-1;i>=0;--i) {
207             fc = new FCImpl(filters[i],fc);
208         }
209         return fc;
210     }
211
212     private class FCImpl implements FilterChain {
213         private Filter f;
214         private FilterChain next;
215
216         public FCImpl(final Filter f, final FilterChain fc) {
217             this.f=f;
218             next = fc;
219
220         }
221         @Override
222         public void doFilter(ServletRequest req, ServletResponse resp) throws IOException, ServletException {
223             f.doFilter(req,resp, next);
224         }
225     }
226 }