com.kurento.kmf.jsonrpcconnector.internal.server.config.JsonRpcConfiguration.java Source code

Java tutorial

Introduction

Here is the source code for com.kurento.kmf.jsonrpcconnector.internal.server.config.JsonRpcConfiguration.java

Source

/*
 * (C) Copyright 2013 Kurento (http://kurento.org/)
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser General Public License
 * (LGPL) version 2.1 which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/lgpl-2.1.html
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 */
package com.kurento.kmf.jsonrpcconnector.internal.server.config;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.Filter;

import org.apache.catalina.Context;
import org.apache.tomcat.websocket.server.WsSci;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.embedded.tomcat.TomcatContextCustomizer;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.util.CollectionUtils;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;

import com.kurento.kmf.jsonrpcconnector.JsonRpcHandler;
import com.kurento.kmf.jsonrpcconnector.internal.http.JsonRpcHttpRequestHandler;
import com.kurento.kmf.jsonrpcconnector.internal.server.PerSessionJsonRpcHandler;
import com.kurento.kmf.jsonrpcconnector.internal.server.ProtocolManager;
import com.kurento.kmf.jsonrpcconnector.internal.server.SessionsManager;
import com.kurento.kmf.jsonrpcconnector.internal.ws.JsonRpcWebSocketHandler;
import com.kurento.kmf.jsonrpcconnector.server.JsonRpcConfigurer;

@Configuration
@EnableWebSocket
public class JsonRpcConfiguration implements WebSocketConfigurer {

    public static final boolean INJECT_SESSION_ID = true;

    @Autowired
    protected ApplicationContext ctx;

    private final List<JsonRpcConfigurer> configurers = new ArrayList<>();
    private DefaultJsonRpcHandlerRegistry registry;

    private DefaultJsonRpcHandlerRegistry getJsonRpcHandlersRegistry() {
        if (registry == null) {
            registry = new DefaultJsonRpcHandlerRegistry();
            for (JsonRpcConfigurer configurer : this.configurers) {
                configurer.registerJsonRpcHandlers(registry);
            }
        }
        return registry;
    }

    @Autowired(required = false)
    public void setConfigurers(List<JsonRpcConfigurer> configurers) {
        if (!CollectionUtils.isEmpty(configurers)) {
            this.configurers.addAll(configurers);
        }
    }

    @Configuration
    protected static class ApplicationContextFilterConfiguration {

        @Bean
        public Filter applicationContextOAuthFilter(ApplicationContext context) {
            return new OAuthFiWareFilter();
        }
    }

    @Bean
    public JsonRpcProperties jsonRpcProperties() {
        return new JsonRpcProperties();
    }

    // ---------------- HttpRequestHandlers -------------

    @Bean
    public HandlerMapping jsonRpcHandlerMapping() {

        DefaultJsonRpcHandlerRegistry registry = getJsonRpcHandlersRegistry();

        Map<String, Object> urlMap = new LinkedHashMap<>();

        for (DefaultJsonRpcHandlerRegistration registration : registry.getRegistrations()) {

            for (Entry<JsonRpcHandler<?>, List<String>> e : registration.getHandlerMap().entrySet()) {

                JsonRpcHandler<?> handler = e.getKey();
                List<String> paths = e.getValue();
                putHandlersMappings(urlMap, handler, paths);
            }

            for (Entry<String, List<String>> e : registration.getPerSessionHandlerBeanNameMap().entrySet()) {

                String handlerBeanName = e.getKey();
                JsonRpcHandler<?> handler = (JsonRpcHandler<?>) ctx.getBean("perSessionJsonRpcHandler",
                        handlerBeanName, null);
                List<String> paths = e.getValue();
                putHandlersMappings(urlMap, handler, paths);
            }

            for (Entry<Class<? extends JsonRpcHandler<?>>, List<String>> e : registration
                    .getPerSessionHandlerClassMap().entrySet()) {

                Class<? extends JsonRpcHandler<?>> handlerClass = e.getKey();
                JsonRpcHandler<?> handler = (JsonRpcHandler<?>) ctx.getBean("perSessionJsonRpcHandler", null,
                        handlerClass);
                List<String> paths = e.getValue();
                putHandlersMappings(urlMap, handler, paths);
            }
        }

        SimpleUrlHandlerMapping hm = new SimpleUrlHandlerMapping();
        hm.setUrlMap(urlMap);
        hm.setOrder(1);
        return hm;
    }

    private void putHandlersMappings(Map<String, Object> urlMap, JsonRpcHandler<?> handler, List<String> paths) {

        JsonRpcHttpRequestHandler requestHandler = new JsonRpcHttpRequestHandler(
                (ProtocolManager) ctx.getBean("protocolManager", handler));

        for (String path : paths) {
            urlMap.put(path, requestHandler);
        }
    }

    // ---------------- Websockets -------------------

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry wsHandlerRegistry) {

        DefaultJsonRpcHandlerRegistry registry = getJsonRpcHandlersRegistry();

        for (DefaultJsonRpcHandlerRegistration registration : registry.getRegistrations()) {

            for (Entry<JsonRpcHandler<?>, List<String>> e : registration.getHandlerMap().entrySet()) {

                JsonRpcHandler<?> handler = e.getKey();
                List<String> paths = e.getValue();

                publishWebSocketEndpoint(wsHandlerRegistry, handler, paths);
            }

            for (Entry<String, List<String>> e : registration.getPerSessionHandlerBeanNameMap().entrySet()) {

                String handlerBeanName = e.getKey();
                JsonRpcHandler<?> handler = (JsonRpcHandler<?>) ctx.getBean("perSessionJsonRpcHandler",
                        handlerBeanName, null);
                List<String> paths = e.getValue();

                publishWebSocketEndpoint(wsHandlerRegistry, handler, paths);
            }

            for (Entry<Class<? extends JsonRpcHandler<?>>, List<String>> e : registration
                    .getPerSessionHandlerClassMap().entrySet()) {

                Class<? extends JsonRpcHandler<?>> handlerClass = e.getKey();
                JsonRpcHandler<?> handler = (JsonRpcHandler<?>) ctx.getBean("perSessionJsonRpcHandler", null,
                        handlerClass);
                List<String> paths = e.getValue();

                publishWebSocketEndpoint(wsHandlerRegistry, handler, paths);
            }

        }
    }

    private void publishWebSocketEndpoint(WebSocketHandlerRegistry wsHandlerRegistry, JsonRpcHandler<?> handler,
            List<String> paths) {

        JsonRpcWebSocketHandler wsHandler = new JsonRpcWebSocketHandler(
                (ProtocolManager) ctx.getBean("protocolManager", handler));

        for (String path : paths) {

            wsHandlerRegistry.addHandler(wsHandler, path + "/ws").withSockJS();
        }
    }

    // This methods workaround the bug
    // https://jira.springsource.org/browse/SPR-10841

    @Bean
    public TomcatEmbeddedServletContainerFactory tomcatContainerFactory() {
        TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();
        factory.setTomcatContextCustomizers(
                Arrays.asList(new TomcatContextCustomizer[] { tomcatContextCustomizer() }));
        return factory;
    }

    @Bean
    public TomcatContextCustomizer tomcatContextCustomizer() {
        return new TomcatContextCustomizer() {
            @Override
            public void customize(Context context) {
                context.addServletContainerInitializer(new WsSci(), null);
            }
        };
    }

    // ----------------------- Components ------------------------

    @Bean
    public SessionsManager sessionsManager() {
        return new SessionsManager();
    }

    @Bean
    @Scope("prototype")
    public ProtocolManager protocolManager(JsonRpcHandler<?> key) {
        return new ProtocolManager(key);
    }

    @Bean
    @Scope("prototype")
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public PerSessionJsonRpcHandler<?> perSessionJsonRpcHandler(String beanName,
            Class<? extends JsonRpcHandler<?>> beanClass) {
        return new PerSessionJsonRpcHandler(beanName, beanClass);
    }

    @Bean(destroyMethod = "shutdown")
    public TaskScheduler jsonrpcTaskScheduler() {
        return new ThreadPoolTaskScheduler();
    }

}