| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.slider.server.appmaster.web.rest.agent; |
| |
| import com.google.common.base.Preconditions; |
| import com.sun.jersey.api.core.ResourceConfig; |
| import com.sun.jersey.spi.container.WebApplication; |
| import com.sun.jersey.spi.container.servlet.ServletContainer; |
| import com.sun.jersey.spi.container.servlet.WebConfig; |
| import com.sun.jersey.spi.inject.SingletonTypeInjectableProvider; |
| import org.apache.slider.core.conf.MapOperations; |
| import org.apache.slider.providers.agent.AgentKeys; |
| import org.apache.slider.server.appmaster.web.WebAppApi; |
| import org.apache.slider.server.appmaster.web.rest.RestPaths; |
| import org.apache.slider.server.services.security.SecurityUtils; |
| import org.mortbay.jetty.Connector; |
| import org.mortbay.jetty.Server; |
| import org.mortbay.jetty.security.SslSelectChannelConnector; |
| import org.mortbay.jetty.servlet.Context; |
| import org.mortbay.jetty.servlet.ServletHolder; |
| import org.mortbay.thread.QueuedThreadPool; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| import javax.ws.rs.ext.Provider; |
| import java.io.Closeable; |
| import java.io.File; |
| import java.io.IOException; |
| import java.util.Set; |
| |
| /** |
| * |
| */ |
| public class AgentWebApp implements Closeable { |
| protected static final Logger LOG = LoggerFactory.getLogger(AgentWebApp.class); |
| private int port; |
| private int securedPort; |
| private static Server agentServer; |
| public static final String BASE_PATH = "slideragent"; |
| |
| public static class Builder { |
| final String name; |
| final String wsName; |
| final WebAppApi application; |
| MapOperations configsMap; |
| |
| public Builder(String name, String wsName, WebAppApi application) { |
| this.name = name; |
| this.wsName = wsName; |
| this.application = application; |
| } |
| |
| public Builder withComponentConfig(MapOperations appMasterConfig) { |
| this.configsMap = appMasterConfig; |
| return this; |
| } |
| |
| public AgentWebApp start() throws IOException { |
| if (configsMap == null) { |
| throw new IllegalStateException("No SSL Configuration Available"); |
| } |
| |
| agentServer = new Server(); |
| agentServer.setThreadPool( |
| new QueuedThreadPool( |
| configsMap.getOptionInt("agent.threadpool.size.max", 25))); |
| agentServer.setStopAtShutdown(true); |
| |
| SslSelectChannelConnector ssl1WayConnector = createSSLConnector(false); |
| SslSelectChannelConnector ssl2WayConnector = |
| createSSLConnector(Boolean.valueOf( |
| configsMap.getOption(AgentKeys.KEY_AGENT_TWO_WAY_SSL_ENABLED, |
| "false"))); |
| agentServer.setConnectors(new Connector[]{ssl1WayConnector, |
| ssl2WayConnector}); |
| |
| ServletHolder agent = new ServletHolder(new AgentServletContainer()); |
| Context agentRoot = new Context(agentServer, "/", Context.SESSIONS); |
| |
| agent.setInitParameter("com.sun.jersey.config.property.resourceConfigClass", |
| "com.sun.jersey.api.core.PackagesResourceConfig"); |
| agent.setInitParameter("com.sun.jersey.config.property.packages", |
| "org.apache.slider.server.appmaster.web.rest.agent"); |
| agent.setInitParameter("com.sun.jersey.api.json.POJOMappingFeature", |
| "true"); |
| // agent.setInitParameter("com.sun.jersey.spi.container.ContainerRequestFilters", "com.sun.jersey.api.container.filter.LoggingFilter"); |
| // agent.setInitParameter("com.sun.jersey.spi.container.ContainerResponseFilters", "com.sun.jersey.api.container.filter.LoggingFilter"); |
| // agent.setInitParameter("com.sun.jersey.config.feature.Trace", "true"); |
| agentRoot.addServlet(agent, "/*"); |
| |
| try { |
| agentServer.start(); |
| } catch (IOException e) { |
| LOG.error("Unable to start agent server", e); |
| throw e; |
| } catch (Exception e) { |
| LOG.error("Unable to start agent server", e); |
| throw new IOException("Unable to start agent server: " + e, e); |
| } |
| |
| AgentWebApp webApp = new AgentWebApp(); |
| webApp.setPort(getConnectorPort(agentServer, 0)); |
| webApp.setSecuredPort(getConnectorPort(agentServer, 1)); |
| return webApp; |
| |
| } |
| |
| private SslSelectChannelConnector createSSLConnector(boolean needClientAuth) { |
| SslSelectChannelConnector sslConnector = new |
| SslSelectChannelConnector(); |
| |
| String keystore = SecurityUtils.getSecurityDir() + |
| File.separator + "keystore.p12"; |
| String srvrCrtPass = SecurityUtils.getKeystorePass(); |
| sslConnector.setKeystore(keystore); |
| sslConnector.setTruststore(keystore); |
| sslConnector.setPassword(srvrCrtPass); |
| sslConnector.setKeyPassword(srvrCrtPass); |
| sslConnector.setTrustPassword(srvrCrtPass); |
| sslConnector.setKeystoreType("PKCS12"); |
| sslConnector.setTruststoreType("PKCS12"); |
| sslConnector.setNeedClientAuth(needClientAuth); |
| |
| sslConnector.setAcceptors(2); |
| return sslConnector; |
| } |
| |
| @Provider |
| public class WebAppApiProvider extends |
| SingletonTypeInjectableProvider<javax.ws.rs.core.Context, WebAppApi> { |
| |
| public WebAppApiProvider () { |
| super(WebAppApi.class, application); |
| } |
| } |
| |
| public class AgentServletContainer extends ServletContainer { |
| public AgentServletContainer() { |
| super(); |
| } |
| |
| @Override |
| protected void configure(WebConfig wc, |
| ResourceConfig rc, |
| WebApplication wa) { |
| super.configure(wc, rc, wa); |
| Set<Object> singletons = rc.getSingletons(); |
| singletons.add(new WebAppApiProvider()); |
| } |
| } |
| |
| private int getConnectorPort(Server webServer, int index) { |
| Preconditions.checkArgument(index >= 0); |
| if (index > webServer.getConnectors().length) |
| throw new IllegalStateException("Illegal connect index requested"); |
| |
| Connector c = webServer.getConnectors()[index]; |
| if (c.getLocalPort() == -1) { |
| // The connector is not bounded |
| throw new IllegalStateException("The connector is not bound to a port"); |
| } |
| |
| return c.getLocalPort(); |
| } |
| } |
| |
| public static Builder $for(String name, WebAppApi app, String wsPrefix) { |
| return new Builder(name, wsPrefix, app); |
| } |
| |
| public int getPort() { |
| return port; |
| } |
| |
| public void setPort(int port) { |
| this.port = port; |
| } |
| |
| public void setSecuredPort(int securedPort) { |
| this.securedPort = securedPort; |
| } |
| |
| public int getSecuredPort() { |
| return securedPort; |
| } |
| |
| public void close() throws IOException{ |
| //need to stop server and reset injector |
| try { |
| agentServer.stop(); |
| } catch (IOException e) { |
| throw e; |
| } catch (Exception e) { |
| throw new IOException(e.toString(), e); |
| } |
| } |
| |
| } |