org.sipfoundry.sipxconfig.commserver.imdb.ReplicationTrigger.java Source code

Java tutorial

Introduction

Here is the source code for org.sipfoundry.sipxconfig.commserver.imdb.ReplicationTrigger.java

Source

/*
 *
 *
 * Copyright (C) 2007 Pingtel Corp., certain elements licensed under a Contributor Agreement.
 * Contributors retain copyright to elements licensed under a Contributor Agreement.
 * Licensed to the User under the LGPL license.
 *
 *
 */
package org.sipfoundry.sipxconfig.commserver.imdb;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.sipfoundry.sipxconfig.branch.Branch;
import org.sipfoundry.sipxconfig.cfgmgt.ConfigManager;
import org.sipfoundry.sipxconfig.common.Replicable;
import org.sipfoundry.sipxconfig.common.SipxHibernateDaoSupport;
import org.sipfoundry.sipxconfig.common.event.DaoEventListener;
import org.sipfoundry.sipxconfig.feature.FeatureManager;
import org.sipfoundry.sipxconfig.im.ImManager;
import org.sipfoundry.sipxconfig.rls.Rls;
import org.sipfoundry.sipxconfig.setting.Group;

/**
 * This listener is responsible for triggering mongo replication of some entities.
 * Its most important job is to trigger replication of Replicable entities.
 * It also takes care of the replication of groups of Replicable entities such as Group or Branch.
 */
//PLEASE keep this class clean. Keep in mind this is not a multi-purpose listener and do not over-use.
//If specific packages need to do specific things based on save/delete to specific objects, that logic
//should exist with the project.
public class ReplicationTrigger extends SipxHibernateDaoSupport implements DaoEventListener {
    protected static final Log LOG = LogFactory.getLog(ReplicationTrigger.class);
    private static final String USER_GROUP_RESOURCE = "user";

    private ReplicationManager m_replicationManager;
    private ExecutorService m_executorService;
    private ConfigManager m_configManager;
    private FeatureManager m_featureManager;

    @Override
    public void onSave(Object entity) {
        if (entity instanceof Replicable) {
            if (entity instanceof Group) {
                //flush is necessary here in order to get consistent data
                getHibernateTemplate().flush();
                //It is important to replicate asynch since large groups might take a while to replicate
                //and we want to return control to the page immediately.
                replicateEntityGroup(new GroupWorker(entity));
            }
            m_replicationManager.replicateEntity((Replicable) entity);
        } else if (entity instanceof Branch) {
            getHibernateTemplate().flush();
            //there is no file replication needed so we can trigger the branch replication directly
            replicateEntityGroup(new BranchWorker(entity));
        }
    }

    @Override
    public void onDelete(Object entity) {
        if (entity instanceof Replicable) {
            if (entity instanceof Group) {
                //It is important to replicate asynch since large groups might take a while to replicate
                //and we want to return control to the page immadiately.
                replicateEntityGroup(new GroupDeleteWorker(entity));
            }
            m_replicationManager.removeEntity((Replicable) entity);
        } else if (entity instanceof Branch) {
            replicateEntityGroup(new BranchDeleteWorker(entity));
        }
    }

    /*
     * Runnables that call the actual replication to be submited to the ExecutorService
     */
    private class BranchWorker implements Runnable {
        private final Object m_entity;

        public BranchWorker(Object entity) {
            m_entity = entity;
        }

        @Override
        public void run() {
            m_replicationManager.replicateBranch((Branch) m_entity);
        }
    }

    //public for use in tests
    public class BranchDeleteWorker implements Runnable {
        private final Object m_entity;

        public BranchDeleteWorker(Object entity) {
            m_entity = entity;
        }

        @Override
        public void run() {
            m_replicationManager.deleteBranch((Branch) m_entity);
        }
    }

    private class GroupWorker implements Runnable {
        private final Object m_entity;

        public GroupWorker(Object entity) {
            m_entity = entity;
        }

        @Override
        public void run() {
            generateGroup((Group) m_entity);
        }
    }

    private class GroupDeleteWorker implements Runnable {
        private final Object m_entity;

        public GroupDeleteWorker(Object entity) {
            m_entity = entity;
        }

        @Override
        public void run() {
            deleteGroup((Group) m_entity);
        }
    }

    //ensure async replication of groups of entities
    //can be used for groups, as well as branches (don't let the name fool you)
    private void replicateEntityGroup(Runnable worker) {
        if (m_executorService == null) {
            m_executorService = Executors.newSingleThreadExecutor(Executors.defaultThreadFactory());
        }
        m_executorService.submit(worker);
        m_executorService.shutdown();
        m_executorService = null;
    }

    /**
     * Sequence of replication actions that need to be performed when a group is saved.
     * Order of the sequence is important - files must be replicated after group members.
     * @param group
     */
    private void generateGroup(Group group) {
        if (USER_GROUP_RESOURCE.equals(group.getResource())) {
            m_replicationManager.replicateGroup(group);
            activateGroup();
        }
    }

    /**
     * Sequence of replication actions that need to be performed when a group is deleted.
     * Order of the sequence is important - files must be replicated after group members.
     * @param group
     */
    private void deleteGroup(Group group) {
        if (USER_GROUP_RESOURCE.equals(group.getResource())) {
            m_replicationManager.deleteGroup(group);
            activateGroup();
        }
    }

    /**
     * Helper method to replicate files when group is saved/removed.
     */
    private void activateGroup() {
        if (m_featureManager.isFeatureEnabled(ImManager.FEATURE)) {
            m_configManager.configureEverywhere(ImManager.FEATURE);
        }
        if (m_featureManager.isFeatureEnabled(Rls.FEATURE)) {
            m_configManager.configureEverywhere(Rls.FEATURE);
        }
    }

    public void setReplicationManager(ReplicationManager replicationManager) {
        m_replicationManager = replicationManager;
    }

    /**
     * use only in tests
     * @param executorService
     */
    public void setExecutorService(ExecutorService executorService) {
        m_executorService = executorService;
    }

    public void setConfigManager(ConfigManager configManager) {
        m_configManager = configManager;
    }

    public void setFeatureManager(FeatureManager featureManager) {
        m_featureManager = featureManager;
    }
}