932ebb2d72a6d7e6ec22fbaeb522ec1d9b066a3c
[policy/drools-pdp.git] /
1 /*
2  * ============LICENSE_START=======================================================
3  * feature-active-standby-management
4  * ================================================================================
5  * Copyright (C) 2017-2018 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.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
34 import org.onap.policy.drools.core.PolicySessionFeatureAPI;
35 import org.onap.policy.drools.features.PolicyEngineFeatureAPI;
36 import org.onap.policy.drools.statemanagement.StateManagementFeatureAPI;
37 import org.onap.policy.drools.system.PolicyEngine;
38 import org.onap.policy.drools.utils.PropertyUtil;
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  * 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 {
53         // get an instance of logger
54         private static final Logger logger =
55                         LoggerFactory.getLogger(ActiveStandbyFeature.class);
56         
57         private static DroolsPdp myPdp;
58         private static Object myPdpSync = new Object();
59         private static DroolsPdpsElectionHandler electionHandler;
60         
61         private StateManagementFeatureAPI stateManagementFeature;
62         
63         public static final int SEQ_NUM = 1;
64         
65
66         /**************************/
67         /* 'FeatureAPI' interface */
68         /**************************/
69
70         /**
71          * {@inheritDoc}
72          */
73         @Override
74         public int getSequenceNumber()
75         {
76                 return(SEQ_NUM);
77         }
78
79         /**
80          * {@inheritDoc}
81          */
82         @Override
83         public void globalInit(String[] args, String configDir)
84         {
85                 // This must come first since it initializes myPdp
86                 initializePersistence(configDir);
87                 
88                 for (StateManagementFeatureAPI feature : StateManagementFeatureAPI.impl.getList())
89                 {
90                         if (feature.getResourceName().equals(myPdp.getPdpId()))
91                         {
92                                 if(logger.isDebugEnabled()){
93                                         logger.debug("ActiveStandbyFeature.globalInit: Found StateManagementFeature"
94                                                 + " with resourceName: {}", myPdp.getPdpId());
95                                 }
96                                 stateManagementFeature = feature;
97                                 break;
98                         }
99                 }
100                 if(stateManagementFeature == null){
101                         if(logger.isDebugEnabled()){
102                                 logger.debug("ActiveStandbyFeature failed to initialize.  "
103                                         + "Unable to get instance of StateManagementFeatureAPI "
104                                         + "with resourceID: {}", myPdp.getPdpId());
105                         }
106                         logger.error("ActiveStandbyFeature failed to initialize.  "
107                                         + "Unable to get instance of StateManagementFeatureAPI "
108                                         + "with resourceID: {}", myPdp.getPdpId());
109                         //
110                         // Cannot add observer since stateManagementFeature is null
111                         //
112                         return;
113                 }
114
115
116
117                 //Create an instance of the Observer
118                 PMStandbyStateChangeNotifier pmNotifier = new PMStandbyStateChangeNotifier();
119
120                 //Register the PMStandbyStateChangeNotifier Observer
121                 stateManagementFeature.addObserver(pmNotifier);
122                 if(logger.isDebugEnabled()){
123                         logger.debug("ActiveStandbyFeature.globalInit() exit");
124                 }
125         }
126
127
128         /**
129          * {@inheritDoc}
130          */
131         @Override
132         public boolean afterStart(PolicyEngine engine) 
133         {
134                 // ASSERTION: engine == PolicyEngine.manager
135                 PolicyEngine.manager.lock();
136                 return false;
137         }
138
139         /**
140          * Read in the persistence properties, determine whether persistence is
141          * enabled or disabled, and initialize persistence if enabled.
142          */
143         private static void initializePersistence(String configDir)
144         {
145                 //Get the Active Standby properties
146                 try {
147                                 Properties activeStandbyProperties = 
148                                                 PropertyUtil.getProperties(configDir + "/feature-active-standby-management.properties");
149                                 ActiveStandbyProperties.initProperties(activeStandbyProperties);
150                                 logger.info("initializePersistence: ActiveStandbyProperties success");
151                 } catch (IOException e) {
152                         logger.error("ActiveStandbyFeature: initializePersistence ActiveStandbyProperties", e);
153                 }
154                 
155                 DroolsPdpsConnector conn = getDroolsPdpsConnector("activeStandbyPU");
156                 String resourceName = ActiveStandbyProperties.getProperty(ActiveStandbyProperties.NODE_NAME);
157                 if(resourceName == null){
158                         throw new NullPointerException();
159                 }
160
161                 /*
162                  * In a JUnit test environment, one or more PDPs may already have been
163                  * inserted in the DB, so we need to check for this.
164                  */
165                 DroolsPdp existingPdp = conn.getPdp(resourceName);
166                 if (existingPdp != null) {
167                         logger.info("Found existing PDP record, pdpId="
168                                         + existingPdp.getPdpId() + ", isDesignated="
169                                         + existingPdp.isDesignated() + ", updatedDate="
170                                         + existingPdp.getUpdatedDate());
171                         myPdp = existingPdp;
172                 }
173
174                 synchronized(myPdpSync){
175                         if(myPdp == null){
176
177                                 myPdp = new DroolsPdpImpl(resourceName,false,4,new Date());     
178                         }
179                         String siteName = ActiveStandbyProperties.getProperty(ActiveStandbyProperties.SITE_NAME);
180                         if (siteName == null) {
181                                 siteName = "";
182                         }else{
183                                 siteName = siteName.trim();
184                         }
185                         myPdp.setSiteName(siteName);
186                         if(electionHandler == null){
187                                 electionHandler = new DroolsPdpsElectionHandler(conn,myPdp);
188                         }
189                 }
190                 logger.info("\n\nThis controller is a standby, waiting to be chosen as primary...\n\n");
191         }
192
193
194         /*
195          * Moved code to instantiate a JpaDroolsPdpsConnector object from main() to
196          * this method, so it can also be accessed from StandbyStateChangeNotifier
197          * class.
198          */
199         public static DroolsPdpsConnector getDroolsPdpsConnector(String pu) {
200
201                 Map<String, Object> propMap = new HashMap<>();
202                 propMap.put("javax.persistence.jdbc.driver", ActiveStandbyProperties
203                                 .getProperty(ActiveStandbyProperties.DB_DRIVER));
204                 propMap.put("javax.persistence.jdbc.url",
205                                 ActiveStandbyProperties.getProperty(ActiveStandbyProperties.DB_URL));
206                 propMap.put("javax.persistence.jdbc.user", ActiveStandbyProperties
207                                 .getProperty(ActiveStandbyProperties.DB_USER));
208                 propMap.put("javax.persistence.jdbc.password",
209                                 ActiveStandbyProperties.getProperty(ActiveStandbyProperties.DB_PWD));
210
211                 EntityManagerFactory emf = Persistence.createEntityManagerFactory(
212                                 pu, propMap);
213                 return new JpaDroolsPdpsConnector(emf);
214         }
215
216         /**
217          * {@inheritDoc}
218          */
219         @Override
220         public String getPdpdNowActive(){
221                 return electionHandler.getPdpdNowActive();
222         }
223
224         /**
225          * {@inheritDoc}
226          */
227         @Override
228         public String getPdpdLastActive(){
229                 return electionHandler.getPdpdLastActive();
230         }
231
232         /**
233          * {@inheritDoc}
234          */
235         @Override
236         public String getResourceName() {
237                 return myPdp.getPdpId();
238         }
239 }