001/*
002 * Licensed under the Apache License, Version 2.0 (the "License");
003 * you may not use this file except in compliance with the License.
004 * You may obtain a copy of the License at
005 *
006 * http://www.apache.org/licenses/LICENSE-2.0
007 *
008 * Unless required by applicable law or agreed to in writing, software
009 * distributed under the License is distributed on an "AS IS" BASIS,
010 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
011 * See the License for the specific language governing permissions and
012 * limitations under the License.
013 */
014package org.atteo.moonshine.jetty;
015
016import java.util.ArrayList;
017import java.util.Arrays;
018import java.util.List;
019
020import javax.management.MBeanServer;
021import javax.xml.bind.annotation.XmlElementRef;
022import javax.xml.bind.annotation.XmlElementWrapper;
023import javax.xml.bind.annotation.XmlRootElement;
024
025import org.atteo.moonshine.jetty.connectors.ConnectorConfig;
026import org.atteo.moonshine.jetty.connectors.ServerConnectorConfig;
027import org.atteo.moonshine.jetty.connectors.SslContextFactoryConfig;
028import org.atteo.moonshine.jetty.handlers.HandlerCollectionConfig;
029import org.atteo.moonshine.jetty.handlers.HandlerConfig;
030import org.atteo.moonshine.jetty.handlers.HandlerListConfig;
031import org.atteo.moonshine.jetty.handlers.ServletContextHandlerConfig;
032import org.atteo.moonshine.services.Service;
033import org.atteo.moonshine.webserver.WebServerService;
034import org.eclipse.jetty.jmx.MBeanContainer;
035import org.eclipse.jetty.server.Server;
036import org.eclipse.jetty.util.log.Log;
037
038import com.google.common.collect.Iterables;
039import com.google.inject.Inject;
040
041/**
042 * Starts Jetty web server instance.
043 */
044@XmlRootElement(name = "jetty")
045public class Jetty extends WebServerService {
046    @XmlElementWrapper(name = "sslcontextfactories")
047    @XmlElementRef
048    private SslContextFactoryConfig[] sslContextFactories;
049
050
051    /**
052     * List of connectors.
053     */
054    @XmlElementWrapper(name = "connectors")
055    @XmlElementRef
056    private ConnectorConfig[] connectors = new ConnectorConfig[] {
057        new ServerConnectorConfig()
058    };
059
060    /**
061     * Main handler. Usually a {@link HandlerCollectionConfig collection} or {@link HandlerListConfig list}
062     * of handlers. By default set to {@link ServletContextHandlerConfig}.
063     */
064    @XmlElementRef
065    private HandlerConfig handler = new ServletContextHandlerConfig();
066
067    private static void addRecursively(List<Service> handlerServices, HandlerConfig handler) {
068        if (handler instanceof Service) {
069            handlerServices.add((Service) handler);
070        }
071        for (HandlerConfig subHandler : handler.getSubHandlers()) {
072            addRecursively(handlerServices, subHandler);
073        }
074    }
075
076    @Override
077    public Iterable<? extends Service> getSubServices() {
078        List<Service> handlerServices = new ArrayList<>();
079        addRecursively(handlerServices, handler);
080
081        return Iterables.concat(Arrays.asList(connectors), handlerServices);
082    }
083
084    @Inject(optional = true)
085    private MBeanServer mbeanServer;
086
087    private Server server;
088
089    @Override
090    public void start() {
091        server = new Server();
092
093        server.setHandler(handler.getHandler());
094
095        for (ConnectorConfig config : connectors) {
096            server.addConnector(config.getConnector(server));
097        }
098
099        if (mbeanServer != null) {
100            MBeanContainer mbContainer = new MBeanContainer(mbeanServer);
101            server.addBean(mbContainer);
102            server.addBean(Log.getLog());
103        }
104
105        try {
106            server.start();
107        } catch (RuntimeException e) {
108            throw e;
109        } catch (Exception e) {
110            throw new RuntimeException(e);
111        }
112    }
113
114    @Override
115    public void stop() {
116        if (server == null) {
117            return;
118        }
119        try {
120            server.stop();
121        } catch (Exception e) {
122            throw new RuntimeException(e);
123        }
124    }
125}