f5f728f1dd3f22a09662a9e8f0d7d24dd76b5775
[policy/drools-pdp.git] /
1 /*
2  * ============LICENSE_START=======================================================
3  * feature-active-standby-management
4  * ================================================================================
5  * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.policy.drools.activestandby;
22
23 import java.io.IOException;
24 import java.util.Date;
25 import java.util.HashMap;
26 import java.util.Map;
27 import java.util.Properties;
28
29 import javax.persistence.EntityManagerFactory;
30 import javax.persistence.Persistence;
31
32 import org.onap.policy.drools.core.PolicySessionFeatureAPI;
33 import org.onap.policy.drools.features.PolicyEngineFeatureApi;
34 import org.onap.policy.drools.statemanagement.StateManagementFeatureAPI;
35 import org.onap.policy.drools.system.PolicyEngine;
36 import org.onap.policy.drools.utils.PropertyUtil;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
39
40 /**
41  * If this feature is supported, there is a single instance of it.
42  * It adds persistence to Drools sessions, but it is also intertwined with
43  * active/standby state management and IntegrityMonitor. For now, they are
44  * all treated as a single feature, but it would be nice to separate them.
45  *
46  * <p>The bulk of the code here was once in other classes, such as
47  * 'PolicyContainer' and 'Main'. It was moved here as part of making this
48  * a separate optional feature.
49  */
50 public class ActiveStandbyFeature implements ActiveStandbyFeatureAPI, 
51     PolicySessionFeatureAPI, PolicyEngineFeatureApi {
52     // get an instance of logger
53     private static final Logger logger =
54             LoggerFactory.getLogger(ActiveStandbyFeature.class);
55
56     private static DroolsPdp myPdp;
57     private static Object myPdpSync = new Object();
58     private static DroolsPdpsElectionHandler electionHandler;
59
60     private StateManagementFeatureAPI stateManagementFeature;
61
62     public static final int SEQ_NUM = 1;
63
64
65     /*========================*/
66     /* 'FeatureAPI' interface */
67     /*========================*/
68
69     /**
70      * {@inheritDoc}.
71      */
72     @Override
73     public int getSequenceNumber() {
74         return SEQ_NUM;
75     }
76
77     /**
78      * {@inheritDoc}.
79      */
80     @Override
81     public void globalInit(String[] args, String configDir) {
82         // This must come first since it initializes myPdp
83         initializePersistence(configDir);
84
85         for (StateManagementFeatureAPI feature : StateManagementFeatureAPI.impl.getList()) {
86             if (feature.getResourceName().equals(myPdp.getPdpId())) {
87                 if (logger.isDebugEnabled()) {
88                     logger.debug("ActiveStandbyFeature.globalInit: Found StateManagementFeature"
89                             + " with resourceName: {}", myPdp.getPdpId());
90                 }
91                 stateManagementFeature = feature;
92                 break;
93             }
94         }
95         if (stateManagementFeature == null) {
96             if (logger.isDebugEnabled()) {
97                 logger.debug("ActiveStandbyFeature failed to initialize.  "
98                         + "Unable to get instance of StateManagementFeatureAPI "
99                         + "with resourceID: {}", myPdp.getPdpId());
100             }
101             logger.error("ActiveStandbyFeature failed to initialize.  "
102                     + "Unable to get instance of StateManagementFeatureAPI "
103                     + "with resourceID: {}", myPdp.getPdpId());
104             //
105             // Cannot add observer since stateManagementFeature is null
106             //
107             return;
108         }
109
110
111
112         //Create an instance of the Observer
113         PMStandbyStateChangeNotifier pmNotifier = new PMStandbyStateChangeNotifier();
114
115         //Register the PMStandbyStateChangeNotifier Observer
116         stateManagementFeature.addObserver(pmNotifier);
117         if (logger.isDebugEnabled()) {
118             logger.debug("ActiveStandbyFeature.globalInit() exit");
119         }
120     }
121
122
123     /**
124      * {@inheritDoc}.
125      */
126     @Override
127     public boolean afterStart(PolicyEngine engine) {
128         // ASSERTION: engine == PolicyEngine.manager
129         PolicyEngine.manager.lock();
130         return false;
131     }
132
133     /**
134      * Read in the persistence properties, determine whether persistence is
135      * enabled or disabled, and initialize persistence if enabled.
136      */
137     private static void initializePersistence(String configDir) {
138         //Get the Active Standby properties
139         try {
140             Properties activeStandbyProperties = 
141                     PropertyUtil.getProperties(configDir + "/feature-active-standby-management.properties");
142             ActiveStandbyProperties.initProperties(activeStandbyProperties);
143             logger.info("initializePersistence: ActiveStandbyProperties success");
144         } catch (IOException e) {
145             logger.error("ActiveStandbyFeature: initializePersistence ActiveStandbyProperties", e);
146         }
147
148         DroolsPdpsConnector conn = getDroolsPdpsConnector("activeStandbyPU");
149         String resourceName = ActiveStandbyProperties.getProperty(ActiveStandbyProperties.NODE_NAME);
150         if (resourceName == null) {
151             throw new NullPointerException();
152         }
153
154         /*
155          * In a JUnit test environment, one or more PDPs may already have been
156          * inserted in the DB, so we need to check for this.
157          */
158         DroolsPdp existingPdp = conn.getPdp(resourceName);
159         if (existingPdp != null) {
160             logger.info("Found existing PDP record, pdpId="
161                     + existingPdp.getPdpId() + ", isDesignated="
162                     + existingPdp.isDesignated() + ", updatedDate="
163                     + existingPdp.getUpdatedDate());
164             myPdp = existingPdp;
165         }
166
167         synchronized (myPdpSync) {
168             if (myPdp == null) {
169
170                 myPdp = new DroolsPdpImpl(resourceName,false,4,new Date());
171             }
172             String siteName = ActiveStandbyProperties.getProperty(ActiveStandbyProperties.SITE_NAME);
173             if (siteName == null) {
174                 siteName = "";
175             } else {
176                 siteName = siteName.trim();
177             }
178             myPdp.setSiteName(siteName);
179             if (electionHandler == null) {
180                 electionHandler = new DroolsPdpsElectionHandler(conn,myPdp);
181             }
182         }
183         logger.info("\n\nThis controller is a standby, waiting to be chosen as primary...\n\n");
184     }
185
186
187     /**
188      * Moved code to instantiate a JpaDroolsPdpsConnector object from main() to
189      * this method, so it can also be accessed from StandbyStateChangeNotifier
190      * class.
191      * 
192      * @param pu string
193      * @return connector object
194      */
195     public static DroolsPdpsConnector getDroolsPdpsConnector(String pu) {
196
197         Map<String, Object> propMap = new HashMap<>();
198         propMap.put("javax.persistence.jdbc.driver", ActiveStandbyProperties
199                 .getProperty(ActiveStandbyProperties.DB_DRIVER));
200         propMap.put("javax.persistence.jdbc.url",
201                 ActiveStandbyProperties.getProperty(ActiveStandbyProperties.DB_URL));
202         propMap.put("javax.persistence.jdbc.user", ActiveStandbyProperties
203                 .getProperty(ActiveStandbyProperties.DB_USER));
204         propMap.put("javax.persistence.jdbc.password",
205                 ActiveStandbyProperties.getProperty(ActiveStandbyProperties.DB_PWD));
206
207         EntityManagerFactory emf = Persistence.createEntityManagerFactory(
208                 pu, propMap);
209         return new JpaDroolsPdpsConnector(emf);
210     }
211
212     /**
213      * {@inheritDoc}.
214      */
215     @Override
216     public String getPdpdNowActive() {
217         return electionHandler.getPdpdNowActive();
218     }
219
220     /**
221      * {@inheritDoc}.
222      */
223     @Override
224     public String getPdpdLastActive() {
225         return electionHandler.getPdpdLastActive();
226     }
227
228     /**
229      * {@inheritDoc}.
230      */
231     @Override
232     public String getResourceName() {
233         return myPdp.getPdpId();
234     }
235 }