org.wso2.carbon.inbound.endpoint.common.InboundRequestProcessorImpl.java Source code

Java tutorial

Introduction

Here is the source code for org.wso2.carbon.inbound.endpoint.common.InboundRequestProcessorImpl.java

Source

/*
 *  Copyright (c) 2005-2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
 *
 *  WSO2 Inc. licenses this file to you 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.wso2.carbon.inbound.endpoint.common;

import org.apache.axis2.description.Parameter;
import org.apache.axis2.engine.AxisConfiguration;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.synapse.SynapseConstants;
import org.apache.synapse.core.SynapseEnvironment;
import org.apache.synapse.inbound.InboundRequestProcessor;
import org.apache.synapse.startup.quartz.StartUpController;
import org.apache.synapse.task.Task;
import org.apache.synapse.task.TaskDescription;
import org.wso2.carbon.CarbonConstants;
import org.wso2.carbon.base.MultitenantConstants;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.inbound.endpoint.osgi.service.ServiceReferenceHolder;
import org.wso2.carbon.inbound.endpoint.persistence.InboundEndpointsDataStore;
import org.wso2.carbon.inbound.endpoint.protocol.PollingConstants;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.*;

/**
 * 
 * This class provides the common implementation for polling protocol processors
 * 
 */
public abstract class InboundRequestProcessorImpl implements InboundRequestProcessor {

    protected SynapseEnvironment synapseEnvironment;
    protected long interval;
    protected String name;
    protected boolean coordination;

    private List<StartUpController> startUpControllersList = new ArrayList<>();
    private HashMap<Thread, InboundRunner> inboundRunnersThreadsMap = new HashMap<>();
    private static final Log log = LogFactory.getLog(InboundRequestProcessorImpl.class);
    private InboundEndpointsDataStore dataStore;

    protected final static String COMMON_ENDPOINT_POSTFIX = "--SYNAPSE_INBOUND_ENDPOINT";

    public InboundRequestProcessorImpl() {
        dataStore = InboundEndpointsDataStore.getInstance();
    }

    /**
     * 
     * Based on the coordination option schedule the task with NTASK or run as a
     * background thread
     * 
     * @param task
     * @param endpointPostfix
     */
    protected void start(InboundTask task, String endpointPostfix) {
        log.info("Starting the inbound endpoint " + name + ", with coordination " + coordination + ". Interval : "
                + interval + ". Type : " + endpointPostfix);
        if (coordination) {
            try {
                TaskDescription taskDescription = new TaskDescription();
                taskDescription.setName(name + "-" + endpointPostfix);
                taskDescription.setTaskGroup(endpointPostfix);
                if (interval < InboundTask.TASK_THRESHOLD_INTERVAL) {
                    taskDescription.setInterval(InboundTask.TASK_THRESHOLD_INTERVAL);
                } else {
                    taskDescription.setInterval(interval);
                }
                taskDescription.setIntervalInMs(true);
                taskDescription.addResource(TaskDescription.INSTANCE, task);
                taskDescription.addResource(TaskDescription.CLASSNAME, task.getClass().getName());
                StartUpController startUpController = new StartUpController();
                startUpController.setTaskDescription(taskDescription);
                startUpController.init(synapseEnvironment);
                startUpControllersList.add(startUpController);
            } catch (Exception e) {
                log.error("Error starting the inbound endpoint " + name + ". Unable to schedule the task. "
                        + e.getLocalizedMessage(), e);
            }
        } else {
            PrivilegedCarbonContext carbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext();
            int tenantId = carbonContext.getTenantId();
            String tenantDomain = null;
            if (tenantId != MultitenantConstants.SUPER_TENANT_ID) {
                tenantDomain = carbonContext.getTenantDomain();
                if (!dataStore.isPollingEndpointRegistered(tenantDomain, name)) {
                    dataStore.registerPollingingEndpoint(tenantDomain, name);
                }
            }

            // When coordination is false, we sometimes require pinned server concept ex: when clustering
            // is not available.
            if (isPinnedServerEnabled(task.getInboundProperties())) {
                if (isPinnedServer(task.getInboundProperties())) {
                    startInboundRunnerThread(task, tenantDomain, true);
                } else {
                    log.info("Inbound Endpoint " + name + " not started as it is not pinned to this server");
                }
            } else {
                startInboundRunnerThread(task, tenantDomain, false);
            }
        }
    }

    private void startInboundRunnerThread(InboundTask task, String tenantDomain, boolean mgrOverride) {
        InboundRunner inboundRunner = new InboundRunner(task, interval, tenantDomain, mgrOverride);
        Thread runningThread = new Thread(inboundRunner);
        inboundRunnersThreadsMap.put(runningThread, inboundRunner);
        runningThread.start();
    }

    /**
     * Stop the inbound polling processor This will be called when inbound is
     * undeployed/redeployed or when server stop
     */
    public void destroy() {
        log.info("Inbound endpoint " + name + " stopping.");
        PrivilegedCarbonContext carbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext();
        int tenantId = carbonContext.getTenantId();
        if (tenantId != MultitenantConstants.SUPER_TENANT_ID) {
            dataStore.unregisterPollingEndpoint(carbonContext.getTenantDomain(), name);
        }
        if (!startUpControllersList.isEmpty()) {
            for (StartUpController sc : startUpControllersList) {
                sc.destroy();
            }
            startUpControllersList.clear();
        } else if (!inboundRunnersThreadsMap.isEmpty()) {

            Iterator itr = inboundRunnersThreadsMap.entrySet().iterator();
            while (itr.hasNext()) {
                Map.Entry entry = (Map.Entry) itr.next();
                Thread thread = (Thread) entry.getKey();
                InboundRunner inboundRunner = (InboundRunner) entry.getValue();

                inboundRunner.terminate();
                try {
                    thread.join();
                } catch (InterruptedException e) {
                    log.error("Error while stopping the inbound thread.");
                }
            }
            inboundRunnersThreadsMap.clear();
        }
    }

    protected static boolean isPinnedServerEnabled(Properties inboundProperties) {
        if (inboundProperties != null
                && inboundProperties.getProperty(PollingConstants.INBOUND_PINNED_SERVER) != null) {
            return true;
        }

        return false;
    }

    protected boolean isPinnedServer(Properties inboundProperties) {
        String thisServerName = System.getProperty("pinServerName", null);
        if (thisServerName == null || "".equals(thisServerName)) {
            thisServerName = getAxis2ParameterValue(ServiceReferenceHolder.getInstance()
                    .getConfigurationContextService().getServerConfigContext().getAxisConfiguration(),
                    SynapseConstants.Axis2Param.SYNAPSE_SERVER_NAME);
            if (thisServerName == null || "".equals(thisServerName)) {
                thisServerName = System.getProperty("SynapseServerName", null);
                if (thisServerName == null || "".equals(thisServerName)) {
                    thisServerName = getServerHost();
                    if (thisServerName == null || "".equals(thisServerName)) {
                        thisServerName = "localhost";
                    }
                }
            }
        }

        String pinnedServersValue = inboundProperties.getProperty(PollingConstants.INBOUND_PINNED_SERVER, null);

        List<String> pinnedServers = getPinnedServers(pinnedServersValue);
        if (pinnedServers != null && !pinnedServers.isEmpty()) {
            if (pinnedServers.contains(thisServerName)) {
                return true;
            }
        }

        return false;
    }

    /**
     * Helper method to get a value of a parameters in the AxisConfiguration
     *
     * @param axisConfiguration AxisConfiguration instance
     * @param paramKey The name / key of the parameter
     * @return The value of the parameter
     */
    private static String getAxis2ParameterValue(AxisConfiguration axisConfiguration, String paramKey) {
        Parameter parameter = axisConfiguration.getParameter(paramKey);
        if (parameter == null) {
            return null;
        }
        Object value = parameter.getValue();
        if (value != null && value instanceof String) {
            return (String) parameter.getValue();
        } else {
            return null;
        }
    }

    private List<String> getPinnedServers(String pinnedServersValue) {
        StringTokenizer st = new StringTokenizer(pinnedServersValue, " ,");
        List<String> pinnedServersList = new ArrayList<String>();
        while (st.hasMoreTokens()) {
            String token = st.nextToken();
            if (token.length() != 0) {
                pinnedServersList.add(token);
            }
        }
        return pinnedServersList;
    }

    private String getServerHost() {
        try {
            InetAddress addr = InetAddress.getLocalHost();
            if (addr != null) {
                return addr.getHostName();
            }
        } catch (UnknownHostException e) {
            log.warn("Unable to get the hostName or IP address of the server", e);
        }

        return null;
    }
}