| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF 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.apache.axis2.clustering.state; |
| |
| import org.apache.axis2.clustering.ClusteringAgent; |
| import org.apache.axis2.clustering.ClusteringFault; |
| import org.apache.axis2.context.AbstractContext; |
| import org.apache.axis2.context.ConfigurationContext; |
| import org.apache.axis2.context.MessageContext; |
| import org.apache.axis2.context.ServiceContext; |
| import org.apache.axis2.context.ServiceGroupContext; |
| import org.apache.axis2.engine.AxisConfiguration; |
| import org.apache.commons.logging.Log; |
| import org.apache.commons.logging.LogFactory; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| /** |
| * Replicates serializable properties |
| */ |
| @SuppressWarnings("unused") |
| public final class Replicator { |
| |
| private static final Log log = LogFactory.getLog(Replicator.class); |
| |
| |
| /** |
| * Replicate state using a custom StateClusteringCommand |
| * |
| * @param command The StateClusteringCommand which is used for replicating state |
| * @param axisConfig The AxisConfiguration |
| * @throws ClusteringFault If replication fails |
| */ |
| public static void replicateState(StateClusteringCommand command, |
| AxisConfiguration axisConfig) throws ClusteringFault { |
| |
| StateManager stateManager = getStateManager(axisConfig); |
| if (stateManager != null) { |
| stateManager.replicateState(command); |
| } |
| } |
| |
| /** |
| * Replicates all serializable properties in the ConfigurationContext, ServiceGroupContext & |
| * ServiceContext |
| * |
| * @param msgContext The MessageContext associated with the ServiceContext, |
| * ServiceGroupContext and ConfigurationContext to be replicated |
| * @throws ClusteringFault If replication fails |
| */ |
| public static void replicate(MessageContext msgContext) throws ClusteringFault { |
| if (!canReplicate(msgContext)) { |
| return; |
| } |
| log.debug("Going to replicate state stored in ConfigurationContext," + |
| " ServiceGroupContext, ServiceContext associated with " + msgContext + "..."); |
| ConfigurationContext configurationContext = msgContext.getConfigurationContext(); |
| StateManager stateManager = getStateManager(msgContext); |
| if (stateManager == null) { |
| return; |
| } |
| List<AbstractContext> contexts = new ArrayList<AbstractContext>(); |
| |
| // Do we need to replicate state stored in ConfigurationContext? |
| if (!configurationContext.getPropertyDifferences().isEmpty()) { |
| contexts.add(configurationContext); |
| } |
| |
| // Do we need to replicate state stored in ServiceGroupContext? |
| ServiceGroupContext sgContext = msgContext.getServiceGroupContext(); |
| if (sgContext != null && !sgContext.getPropertyDifferences().isEmpty()) { |
| contexts.add(sgContext); |
| } |
| |
| // Do we need to replicate state stored in ServiceContext? |
| ServiceContext serviceContext = msgContext.getServiceContext(); |
| if (serviceContext != null && !serviceContext.getPropertyDifferences().isEmpty()) { |
| contexts.add(serviceContext); |
| } |
| |
| // Do the actual replication here |
| if (!contexts.isEmpty()) { |
| AbstractContext[] contextArray = contexts.toArray(new AbstractContext[contexts.size()]); |
| stateManager.updateContexts(contextArray); |
| } |
| } |
| |
| /** |
| * Replicate all serializable properties stored in the given <code>abstractContext</code>. |
| * |
| * @param abstractContext The AbstractContext which holds the properties to be replicated |
| * @throws ClusteringFault If replication fails |
| */ |
| public static void replicate(AbstractContext abstractContext) throws ClusteringFault { |
| if (!canReplicate(abstractContext)) { |
| return; |
| } |
| log.debug("Going to replicate state in " + abstractContext + "..."); |
| StateManager stateManager = getStateManager(abstractContext); |
| if (stateManager != null && !abstractContext.getPropertyDifferences().isEmpty()) { |
| synchronized (abstractContext) { // This IDEA/FindBugs warning can be ignored |
| stateManager.updateContext(abstractContext); |
| } |
| } |
| } |
| |
| /** |
| * Replicate all the properties given in <code>propertyNames</code> |
| * in the specified <code>abstractContext</code> |
| * |
| * @param abstractContext The context to be replicated |
| * @param propertyNames The names of the properties to be replicated |
| * @throws ClusteringFault IF replication fails |
| */ |
| public static void replicate(AbstractContext abstractContext, |
| String[] propertyNames) throws ClusteringFault { |
| if (!canReplicate(abstractContext)) { |
| return; |
| } |
| log.debug("Going to replicate selected properties in " + abstractContext + "..."); |
| StateManager stateManager = getStateManager(abstractContext); |
| if (stateManager != null) { |
| stateManager.updateContext(abstractContext, propertyNames); |
| } |
| } |
| |
| private static ClusteringAgent getClusterManager(AbstractContext abstractContext) { |
| return abstractContext.getRootContext().getAxisConfiguration().getClusteringAgent(); |
| } |
| |
| private static StateManager getStateManager(AbstractContext abstractContext) { |
| return getClusterManager(abstractContext).getStateManager(); |
| } |
| |
| private static StateManager getStateManager(AxisConfiguration axisConfiguration) { |
| ClusteringAgent clusteringAgent = axisConfiguration.getClusteringAgent(); |
| if (clusteringAgent != null) { |
| return clusteringAgent.getStateManager(); |
| } |
| return null; |
| } |
| |
| /** |
| * Check whether the state store in the specified <code>abstractContext</code> can be replicated. |
| * Also note that if there are no members, we need not do any replication |
| * |
| * @param abstractContext The context to be subjected to this test |
| * @return true - State needs to be replicated |
| * false - otherwise |
| */ |
| private static boolean canReplicate(AbstractContext abstractContext) { |
| ClusteringAgent clusteringAgent = |
| abstractContext.getRootContext().getAxisConfiguration().getClusteringAgent(); |
| boolean canReplicate = false; |
| if (clusteringAgent != null && clusteringAgent.getStateManager() != null) { |
| canReplicate = |
| clusteringAgent.getStateManager().isContextClusterable(abstractContext); |
| } |
| return canReplicate; |
| } |
| |
| /** |
| * Check whether the state store in the specified <code>messageContext</code> can be replicated. |
| * Also note that if there are no members, we need not do any replication |
| * |
| * @param messageContext The MessageContext to be subjected to this test |
| * @return true - State needs to be replicated |
| * false - otherwise |
| */ |
| private static boolean canReplicate(MessageContext messageContext) { |
| ClusteringAgent clusteringAgent = |
| messageContext.getRootContext().getAxisConfiguration().getClusteringAgent(); |
| return clusteringAgent != null && clusteringAgent.getStateManager() != null; |
| } |
| } |