All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.red5.server.war.WarLoaderServlet Maven / Gradle / Ivy

Go to download

Ant Media Server supports RTMP, RTSP, MP4, HLS, WebRTC, Adaptive Streaming, etc.

There is a newer version: 2.10.0
Show newest version
/*
 * RED5 Open Source Media Server - https://github.com/Red5/
 * 
 * Copyright 2006-2016 by respective authors (see below). All rights reserved.
 * 
 * Licensed 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.red5.server.war;

import java.beans.Introspector;
import java.io.File;
import java.sql.Driver;
import java.sql.DriverManager;
import java.util.ArrayList;
import java.util.Enumeration;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;

import org.red5.io.amf.Output;
import org.red5.logging.Red5LoggerFactory;
import org.red5.server.ClientRegistry;
import org.red5.server.Context;
import org.red5.server.MappingStrategy;
import org.red5.server.Server;
import org.red5.server.api.Red5;
import org.red5.server.scope.GlobalScope;
import org.red5.server.scope.ScopeResolver;
import org.red5.server.scope.WebScope;
import org.red5.server.service.ServiceInvoker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.web.context.ConfigurableWebApplicationContext;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.WebApplicationContext;

import ch.qos.logback.classic.LoggerContext;

/**
 * Entry point from which the server config file is loaded while running within a J2EE application container.
 * 
 * This listener should be registered after Log4jConfigListener in web.xml, if the latter is used.
 * 
 * @author The Red5 Project
 * @author Paul Gregoire ([email protected])
 */
public class WarLoaderServlet extends ContextLoaderListener {

    // Initialize Logging
    public static final Logger logger = Red5LoggerFactory.getLogger(WarLoaderServlet.class);

    private static ArrayList registeredContexts = new ArrayList(3);

    private ConfigurableWebApplicationContext applicationContext;

    private DefaultListableBeanFactory parentFactory;

    private static ServletContext servletContext;

    private ClientRegistry clientRegistry;

    private ServiceInvoker globalInvoker;

    private MappingStrategy globalStrategy;

    private ScopeResolver globalResolver;

    private GlobalScope global;

    private Server server;

    /**
     * Main entry point for the Red5 Server as a war
     */
    // Notification that the web application is ready to process requests
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        if (null != servletContext) {
            return;
        }
        System.setProperty("red5.deployment.type", "war");

        servletContext = sce.getServletContext();
        String prefix = servletContext.getRealPath("/");

        if (System.getProperty("red5.webapp.root") == null) {
            File webapps = new File(prefix);
            System.setProperty("red5.webapp.root", webapps.getParent());
            webapps = null;
        }

        long time = System.currentTimeMillis();

        logger.info("{} WAR loader", Red5.VERSION);
        logger.debug("Path: {}", prefix);

        try {
            //use super to initialize
            super.contextInitialized(sce);
            //get the web context
            applicationContext = (ConfigurableWebApplicationContext) servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
            logger.debug("Root context path: {}", applicationContext.getServletContext().getContextPath());

            ConfigurableBeanFactory factory = applicationContext.getBeanFactory();

            // register default
            factory.registerSingleton("default.context", applicationContext);

            // get the main factory
            parentFactory = (DefaultListableBeanFactory) factory.getParentBeanFactory();

        } catch (Throwable t) {
            logger.error("", t);
        }

        long startupIn = System.currentTimeMillis() - time;
        logger.info("Startup done in: {} ms", startupIn);

    }

    /*
     * Registers a subcontext with red5
     */
    public void registerSubContext(String webAppKey) {
        // get the sub contexts - servlet context
        ServletContext ctx = servletContext.getContext(webAppKey);
        if (ctx == null) {
            ctx = servletContext;
        }
        ContextLoader loader = new ContextLoader();
        ConfigurableWebApplicationContext appCtx = (ConfigurableWebApplicationContext) loader.initWebApplicationContext(ctx);
        appCtx.setParent(applicationContext);
        appCtx.refresh();

        ctx.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, appCtx);

        ConfigurableBeanFactory appFactory = appCtx.getBeanFactory();

        logger.debug("About to grab Webcontext bean for {}", webAppKey);
        Context webContext = (Context) appCtx.getBean("web.context");
        webContext.setCoreBeanFactory(parentFactory);
        webContext.setClientRegistry(clientRegistry);
        webContext.setServiceInvoker(globalInvoker);
        webContext.setScopeResolver(globalResolver);
        webContext.setMappingStrategy(globalStrategy);

        WebScope scope = (WebScope) appFactory.getBean("web.scope");
        scope.setServer(server);
        scope.setParent(global);
        scope.register();
        scope.start();

        // register the context so we dont try to reinitialize it
        registeredContexts.add(ctx);

    }

    /**
     * Clearing the in-memory configuration parameters, we will receive notification that the servlet context is about to be shut down
     */
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        synchronized (servletContext) {
            logger.info("Webapp shutdown");
            // XXX Paul: grabbed this from
            // http://opensource.atlassian.com/confluence/spring/display/DISC/Memory+leak+-+classloader+won%27t+let+go
            // in hopes that we can clear all the issues with J2EE containers
            // during shutdown
            ServletContext ctx = null;
            try {
                ctx = sce.getServletContext();
                // prepare spring for shutdown
                Introspector.flushCaches();
                // dereg any drivers
                for (Enumeration e = DriverManager.getDrivers(); e.hasMoreElements();) {
                    Driver driver = (Driver) e.nextElement();
                    if (driver.getClass().getClassLoader() == getClass().getClassLoader()) {
                        DriverManager.deregisterDriver(driver);
                    }
                }
                // clear the AMF output cache
                Output.destroyCache();
                // stop the logger
                try {
                    ((LoggerContext) LoggerFactory.getILoggerFactory()).stop();
                } catch (Exception e) {
                }
                // shutdown spring
                Object attr = ctx.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
                if (attr != null) {
                    // get web application context from the servlet context
                    ConfigurableWebApplicationContext applicationContext = (ConfigurableWebApplicationContext) attr;
                    ConfigurableBeanFactory factory = applicationContext.getBeanFactory();
                    // for (String scope : factory.getRegisteredScopeNames()) {
                    // logger.debug("Registered scope: " + scope);
                    // }
                    try {
                        for (String singleton : factory.getSingletonNames()) {
                            logger.debug("Registered singleton: {}", singleton);
                            factory.destroyScopedBean(singleton);
                        }
                    } catch (RuntimeException e) {
                    }
                    factory.destroySingletons();
                    applicationContext.close();
                }
            } catch (Throwable e) {
                logger.warn("Exception {}", e);
            } finally {
                super.contextDestroyed(sce);
                if (ctx != null) {
                    ctx.removeAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
                }
            }
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy