001//
002// $RCSfile: BexRuleServiceProvider.java,v $
003// $Revision: 1.4 $
004// $Date: 2014/04/11 21:58:14 $
005//
006//  Copyright 2014 Cloud Software Group, Inc. ALL RIGHTS RESERVED. 
007//  Cloud Software Group, Inc. Confidential Information
008//
009package com.tibco.xp.runtime;
010
011import java.util.Properties;
012
013import com.tibco.be.util.BEProperties;
014import com.tibco.be.util.BEPropertiesFactory;
015import com.tibco.cep.common.exception.LifecycleException;
016import com.tibco.cep.kernel.service.logging.Level;
017import com.tibco.cep.runtime.service.ServiceRegistry;
018import com.tibco.cep.runtime.service.cluster.MultiAgentCluster;
019import com.tibco.cep.runtime.service.cluster.util.DefaultCacheSequenceManager;
020import com.tibco.cep.runtime.service.management.process.EngineMBeansManager;
021import com.tibco.cep.runtime.session.RuleAdministrator;
022import com.tibco.cep.runtime.session.RuleServiceProviderManager;
023import com.tibco.cep.runtime.session.impl.RuleServiceProviderImpl;
024
025/**
026 * BE-X specific rule service provider
027 */
028public class BexRuleServiceProvider extends RuleServiceProviderImpl
029{
030    /**
031     * Create a rule service provider instance
032     * @param env Environment
033     * @return New instance
034     * @throws Exception Error creating instance
035     */
036    static BexRuleServiceProvider getInstance(final Properties env) throws Exception
037    {
038        BEProperties beProperties = BEPropertiesFactory.getInstance().makeBEProperties(env, null);
039        ServiceRegistry registry = ServiceRegistry.getSingletonServiceRegistry();
040        registry.initBasic();
041        registry.init(beProperties);
042        
043        BexRuleServiceProvider rsp = new BexRuleServiceProvider(null, env);
044        RuleServiceProviderManager.getInstance().setDefaultProvider(rsp);
045
046        return rsp;
047    }
048    
049    @Override
050    public byte getStatus()
051    {
052        //
053        //  Return parent's status if not running
054        //
055        if (m_status != STATE_RUNNING)
056        {
057            return super.getStatus();
058        }
059        
060        return m_status;
061    }
062    
063    /**
064     * Start the rule service provider
065     * @throws Exception Startup error
066     */
067    void start() throws Exception
068    {
069        initCluster();
070        
071        boolean complete = false;
072        
073        assert getCluster() != null;
074        assert getCluster() instanceof MultiAgentCluster : getCluster();
075        assert getCluster().getMetadataCache() != null : getCluster();
076        
077        MultiAgentCluster cluster = (MultiAgentCluster) getCluster();
078        
079        while (complete == false)
080        {
081            //
082            //  Reload the meta-data cache if the cluster fails
083            //  to start.  This allows new events to be added
084            //  without stopping the entire cluster.  See FLUENCY-6546.
085            //  This is a work-around for the rules engine not
086            //  supporting adding new events to a running cluster
087            //
088            try
089            {
090                startCluster();
091                complete = true;
092            }
093            catch (com.tibco.cep.common.exception.LifecycleException e)
094            {
095                // TODO - DJS: Can we remove this exception block now 
096                // that we provided our own startCluster()?
097                ServiceProvider.log(Level.WARN, "Reloading types: " + e.getMessage());
098                
099                cluster = (MultiAgentCluster)getCluster();
100                assert cluster != null;
101                assert cluster.getMetadataCache() != null : cluster;
102    
103                cluster.getMetadataCache().reloadTypes();
104            }
105        }
106        
107        cluster.getMetadataCache().reloadTypes();
108        m_deployedProject.startHotDeploy(this);
109        
110        //
111        //  Register MBeans in this JVM
112        //
113        new EngineMBeansManager(this).registerEngineMBeans();
114        
115        assert getRuleAdministrator() != null;
116        getRuleAdministrator().updateState(RuleAdministrator.STATE_RUNNING);
117        
118        m_status = STATE_RUNNING;
119        
120        ServiceProvider.log(Level.INFO, "Rules engine " + getName() + " initialization complete.");
121    }
122    
123    @Override
124    public void startCluster() throws LifecycleException
125    {
126        try
127        {
128            assert getCluster() != null;
129            assert getCluster() instanceof MultiAgentCluster : getCluster();
130            assert getCluster().getDaoProvider() != null : getCluster();
131            assert getCluster().getGroupMembershipService() != null : getCluster();
132            assert getCluster().getIdGenerator() != null : getCluster();           
133            assert getCluster().getMetadataCache() != null : getCluster();
134            assert getCluster().getObjectTableCache() != null : getCluster();
135            assert getCluster().getTopicRegistry() != null : getCluster();
136            assert getCluster().getSequenceManager() != null : getCluster();
137            assert getCluster().getSequenceManager() instanceof DefaultCacheSequenceManager : getCluster().getSequenceManager();
138            assert getCluster().getEventTableProvider() != null : getCluster();
139            assert getCluster().getRecoveryManager() != null : getCluster();
140            assert getCluster().getExternalClassesCache() != null : getCluster();
141            assert getCluster().getSchedulerCache() != null : getCluster();
142            assert getCluster().getAgentManager() != null : getCluster();
143            assert getCluster().getHotDeployer() != null : getCluster();
144            
145            MultiAgentCluster cluster = (MultiAgentCluster) getCluster();
146
147            //
148            //  N.B. copied from cluster.start() to support type reloading
149            //
150            cluster.getDaoProvider().start();
151            cluster.getGroupMembershipService().start();
152            cluster.getIdGenerator().start();
153            
154            //
155            //  Always reload types.  This works-around the lack of support
156            //  in the rules engine for loading new concepts.  See FLUENCY-6632
157            //  for more details
158            //
159            cluster.getMetadataCache().start();
160            cluster.getMetadataCache().reloadTypes();
161            
162            cluster.getObjectTableCache().start();
163            cluster.getTopicRegistry().start();
164            ((DefaultCacheSequenceManager)cluster.getSequenceManager()).start();
165            cluster.getEventTableProvider().start();
166            cluster.getRecoveryManager().start();
167            cluster.getExternalClassesCache().deployExternalClasses();
168            cluster.getSchedulerCache().start();
169            cluster.getAgentManager().start();
170            cluster.getHotDeployer().start();
171
172            assert changeListenerService != null : this;
173            assert moduleManager != null : this;
174            
175            changeListenerService.start();
176            moduleManager.startModules(0);
177        }
178        catch (Exception e)
179        {
180            throw new LifecycleException(e);
181        }
182    }
183    
184    private BexRuleServiceProvider(
185            final String instanceName, 
186            final Properties env)
187            throws Exception
188    {
189        super(instanceName, env);
190    }
191    
192    private byte m_status = STATE_UNINITIALIZED;
193}