| /* |
| * Copyright (c) 2007, 2018 Oracle and/or its affiliates. All rights reserved. |
| * |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v. 2.0, which is available at |
| * http://www.eclipse.org/legal/epl-2.0. |
| * |
| * This Source Code may also be made available under the following Secondary |
| * Licenses when the conditions for such availability set forth in the |
| * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, |
| * version 2 with the GNU Classpath Exception, which is available at |
| * https://www.gnu.org/software/classpath/license.html. |
| * |
| * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 |
| */ |
| |
| package com.sun.enterprise.v3.services.impl; |
| |
| import org.glassfish.grizzly.config.dom.NetworkListener; |
| import org.glassfish.api.container.EndpointRegistrationException; |
| import org.glassfish.api.deployment.ApplicationContainer; |
| |
| import java.io.IOException; |
| import java.net.InetAddress; |
| import java.net.UnknownHostException; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collection; |
| import java.util.concurrent.Future; |
| import java.util.logging.Level; |
| import java.util.logging.Logger; |
| import com.sun.enterprise.util.Result; |
| import java.util.concurrent.Callable; |
| import org.glassfish.api.logging.LogHelper; |
| import org.glassfish.grizzly.Grizzly; |
| import org.glassfish.grizzly.config.GenericGrizzlyListener; |
| import org.glassfish.grizzly.config.GrizzlyListener; |
| import org.glassfish.grizzly.http.server.HttpHandler; |
| import org.glassfish.grizzly.impl.FutureImpl; |
| import org.glassfish.grizzly.utils.Futures; |
| import org.glassfish.kernel.KernelLoggerInfo; |
| |
| /** |
| * This class is responsible for configuring Grizzly. |
| * |
| * @author Jerome Dochez |
| * @author Jeanfrancois Arcand |
| */ |
| public class GrizzlyProxy implements NetworkProxy { |
| final Logger logger; |
| final NetworkListener networkListener; |
| |
| protected GrizzlyListener grizzlyListener; |
| private int portNumber; |
| |
| public final static String LEADER_FOLLOWER |
| = "org.glassfish.grizzly.useLeaderFollower"; |
| |
| public final static String AUTO_CONFIGURE |
| = "org.glassfish.grizzly.autoConfigure"; |
| |
| // <http-listener> 'address' attribute |
| private InetAddress address; |
| |
| private GrizzlyService grizzlyService; |
| |
| //private VirtualServer vs; |
| |
| |
| public GrizzlyProxy(GrizzlyService service, NetworkListener listener) { |
| grizzlyService = service; |
| logger = service.getLogger(); |
| networkListener = listener; |
| } |
| |
| /** |
| * Create a <code>GrizzlyServiceListener</code> based on a NetworkListener |
| * configuration object. |
| */ |
| public void initialize() throws IOException { |
| portNumber = initPort(networkListener); |
| address = initAddress(networkListener); |
| grizzlyListener = createGrizzlyListener(networkListener); |
| |
| grizzlyListener.configure(grizzlyService.getHabitat(), networkListener); |
| } |
| |
| int initPort(final NetworkListener networkListener) { |
| String port = networkListener.getPort(); |
| if (port == null) { |
| logger.severe(KernelLoggerInfo.noPort); |
| throw new RuntimeException("Cannot find port information from domain configuration"); |
| } |
| try { |
| return Integer.parseInt(port); |
| } catch (final NumberFormatException e) { |
| logger.log(Level.SEVERE, KernelLoggerInfo.badPort, port); |
| return 8080; |
| } |
| } |
| |
| InetAddress initAddress(final NetworkListener networkListener) { |
| String addressAsString = networkListener.getAddress(); |
| try { |
| return InetAddress.getByName(addressAsString); |
| } catch (final UnknownHostException e) { |
| LogHelper.log(logger, Level.SEVERE, KernelLoggerInfo.badAddress, e, addressAsString); |
| return null; |
| } |
| } |
| |
| protected GrizzlyListener createGrizzlyListener( |
| final NetworkListener networkListener) { |
| if (GrizzlyService.isLightWeightListener(networkListener)) { |
| return createServiceInitializerListener(networkListener); |
| } else { |
| return createGlassfishListener(networkListener); |
| } |
| } |
| |
| protected GrizzlyListener createGlassfishListener( |
| final NetworkListener networkListener) { |
| return new GlassfishNetworkListener(grizzlyService, |
| networkListener, logger); |
| } |
| |
| protected GrizzlyListener createServiceInitializerListener( |
| final NetworkListener networkListener) { |
| return new ServiceInitializerListener(grizzlyService, |
| networkListener, logger); |
| } |
| |
| static ArrayList<String> toArray(String list, String token){ |
| return new ArrayList<String>(Arrays.asList(list.split(token))); |
| } |
| |
| /** |
| * Stops the Grizzly service. |
| */ |
| @Override |
| public void stop() throws IOException { |
| grizzlyListener.stop(); |
| } |
| |
| @Override |
| public void destroy() { |
| grizzlyListener.destroy(); |
| } |
| |
| @Override |
| public String toString() { |
| return "GrizzlyProxy{" + |
| //"virtual server=" + vs + |
| "address=" + address + |
| ", portNumber=" + portNumber + |
| '}'; |
| } |
| |
| |
| /* |
| * Registers a new endpoint (adapter implementation) for a particular |
| * context-root. All request coming with the context root will be dispatched |
| * to the adapter instance passed in. |
| * @param contextRoot for the adapter |
| * @param endpointAdapter servicing requests. |
| */ |
| @Override |
| public void registerEndpoint(String contextRoot, Collection<String> vsServers, |
| HttpHandler endpointService, |
| ApplicationContainer container) throws EndpointRegistrationException { |
| |
| // e.g., there is no admin service in an instance |
| if (contextRoot == null) { |
| return; |
| } |
| |
| if (endpointService == null) { |
| throw new EndpointRegistrationException( |
| "The endpoint adapter is null"); |
| } |
| |
| final HttpAdapter httpAdapter = grizzlyListener.getAdapter(HttpAdapter.class); |
| if (httpAdapter != null) { |
| httpAdapter.getMapper().register(contextRoot, vsServers, endpointService, container); |
| } |
| } |
| |
| /** |
| * Removes the context-root from our list of endpoints. |
| */ |
| @Override |
| public void unregisterEndpoint(String contextRoot, ApplicationContainer app) throws EndpointRegistrationException { |
| final HttpAdapter httpAdapter = grizzlyListener.getAdapter(HttpAdapter.class); |
| if (httpAdapter != null) { |
| httpAdapter.getMapper().unregister(contextRoot); |
| } |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public void registerEndpoint(final Endpoint endpoint) { |
| final HttpAdapter httpAdapter = grizzlyListener.getAdapter(HttpAdapter.class); |
| if (httpAdapter != null) { |
| httpAdapter.getMapper().register(endpoint); |
| } |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public void unregisterEndpoint(final Endpoint endpoint) throws EndpointRegistrationException { |
| unregisterEndpoint(endpoint.getContextRoot(), endpoint.getContainer()); |
| } |
| |
| |
| @Override |
| public Future<Result<Thread>> start() throws IOException { |
| final FutureImpl<Result<Thread>> future = |
| Futures.<Result<Thread>>createUnsafeFuture(); |
| |
| if (!isAjpEnabled(grizzlyListener)) { |
| // If this is not AJP listener - initiate startup right now |
| start0(); |
| } else { |
| // For AJP listener we have to wait until server is up and ready |
| // to process incoming requests |
| // Related to the GLASSFISH-18267 |
| grizzlyService.addServerReadyListener(new Callable<Void>() { |
| |
| @Override |
| public Void call() throws Exception { |
| start0(); |
| return null; |
| } |
| }); |
| } |
| |
| future.result(new Result<Thread>(Thread.currentThread())); |
| return future; |
| } |
| |
| /** |
| * Start internal Grizzly listener. |
| * @throws IOException |
| */ |
| protected void start0() throws IOException { |
| final long t1 = System.currentTimeMillis(); |
| |
| grizzlyListener.start(); |
| |
| if (logger.isLoggable(Level.INFO)) { |
| logger.log(Level.INFO, KernelLoggerInfo.grizzlyStarted, |
| new Object[]{Grizzly.getDotedVersion(), |
| System.currentTimeMillis() - t1, |
| grizzlyListener.getAddress() + ":" + grizzlyListener.getPort()}); |
| } |
| } |
| |
| @Override |
| public int getPort() { |
| return portNumber; |
| } |
| |
| @Override |
| public InetAddress getAddress() { |
| return address; |
| } |
| |
| public GrizzlyListener getUnderlyingListener() { |
| return grizzlyListener; |
| } |
| |
| private static boolean isAjpEnabled(final GrizzlyListener grizzlyListener) { |
| return (grizzlyListener instanceof GenericGrizzlyListener) && |
| ((GenericGrizzlyListener) grizzlyListener).isAjpEnabled(); |
| } |
| } |