com.haulmont.cuba.core.sys.remoting.CubaRemoteInvocationExecutor.java Source code

Java tutorial

Introduction

Here is the source code for com.haulmont.cuba.core.sys.remoting.CubaRemoteInvocationExecutor.java

Source

/*
 * Copyright (c) 2008-2016 Haulmont.
 *
 * 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 com.haulmont.cuba.core.sys.remoting;

import com.haulmont.cuba.core.app.ServerConfig;
import com.haulmont.cuba.core.global.AppBeans;
import com.haulmont.cuba.core.global.Configuration;
import com.haulmont.cuba.core.global.GlobalConfig;
import com.haulmont.cuba.core.sys.AppContext;
import com.haulmont.cuba.core.sys.SecurityContext;
import com.haulmont.cuba.core.sys.UserInvocationContext;
import com.haulmont.cuba.core.sys.remoting.discovery.ServerSelector;
import com.haulmont.cuba.core.sys.remoting.discovery.StaticServerSelector;
import com.haulmont.cuba.security.app.TrustedClientService;
import com.haulmont.cuba.security.app.UserSessionsAPI;
import com.haulmont.cuba.security.global.UserSession;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.remoting.support.RemoteInvocation;
import org.springframework.remoting.support.RemoteInvocationExecutor;

import java.lang.reflect.InvocationTargetException;
import java.util.Locale;
import java.util.UUID;

/**
 * Executes {@link CubaRemoteInvocation} on middleware, setting and clearing a {@link SecurityContext} in the request
 * handling thread.
 */
public class CubaRemoteInvocationExecutor implements RemoteInvocationExecutor {

    private static final Logger log = LoggerFactory.getLogger(CubaRemoteInvocationExecutor.class);

    protected volatile ServerSelector serverSelector;

    protected UserSessionsAPI userSessions;
    protected Configuration configuration;
    protected GlobalConfig globalConfig;

    public CubaRemoteInvocationExecutor() {
        userSessions = AppBeans.get(UserSessionsAPI.NAME);
        configuration = AppBeans.get(Configuration.NAME);
        globalConfig = configuration.getConfig(GlobalConfig.class);
    }

    @Override
    public Object invoke(RemoteInvocation invocation, Object targetObject)
            throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
        if (invocation instanceof CubaRemoteInvocation) {
            CubaRemoteInvocation cubaInvocation = (CubaRemoteInvocation) invocation;

            UUID sessionId = cubaInvocation.getSessionId();
            if (sessionId != null) {
                UserSession session = userSessions.getAndRefresh(sessionId);
                if (session == null) {
                    ServerConfig serverConfig = configuration.getConfig(ServerConfig.class);
                    String sessionProviderUrl = serverConfig.getUserSessionProviderUrl();
                    if (StringUtils.isNotBlank(sessionProviderUrl)) {
                        log.debug("User session {} not found, trying to get it from {}", sessionId,
                                sessionProviderUrl);
                        try {
                            HttpServiceProxy proxyFactory = new HttpServiceProxy(
                                    getServerSelector(sessionProviderUrl));
                            proxyFactory.setServiceUrl("cuba_TrustedClientService");
                            proxyFactory.setServiceInterface(TrustedClientService.class);
                            proxyFactory.afterPropertiesSet();
                            TrustedClientService trustedClientService = (TrustedClientService) proxyFactory
                                    .getObject();
                            if (trustedClientService != null) {
                                UserSession userSession = trustedClientService
                                        .findSession(serverConfig.getTrustedClientPassword(), sessionId);
                                if (userSession != null) {
                                    userSessions.add(userSession);
                                } else {
                                    log.debug("User session {} not found on {}", sessionId, sessionProviderUrl);
                                }
                            }
                        } catch (Exception e) {
                            log.error("Error getting user session from {}", sessionProviderUrl, e);
                        }
                    }
                }
                AppContext.setSecurityContext(new SecurityContext(sessionId));
            }

            if (cubaInvocation.getLocale() != null) {
                Locale requestLocale = Locale.forLanguageTag(cubaInvocation.getLocale());
                if (!globalConfig.getAvailableLocales().containsValue(requestLocale)) {
                    requestLocale = null;
                }

                UserInvocationContext.setRequestScopeInfo(sessionId, requestLocale, cubaInvocation.getTimeZone(),
                        cubaInvocation.getAddress(), cubaInvocation.getClientInfo());
            }
        }

        Object result;
        try {
            result = invocation.invoke(targetObject);
        } finally {
            AppContext.setSecurityContext(null);
            UserInvocationContext.clearRequestScopeInfo();
        }

        return result;
    }

    protected ServerSelector getServerSelector(String sessionProviderUrl) {
        if (serverSelector == null) {
            synchronized (this) {
                if (serverSelector == null) {
                    StaticServerSelector result = new StaticServerSelector();
                    result.setBaseUrl(sessionProviderUrl);
                    result.init();
                    serverSelector = result;
                }
            }
        }
        return serverSelector;
    }
}