e3125a5f0747abf1d70374956ebe5a5ade2457ac
[policy/drools-pdp.git] /
1 /*
2  * ============LICENSE_START=======================================================
3  * feature-active-standby-management
4  * ================================================================================
5  * Copyright (C) 2017-2021 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.HashMap;
25 import java.util.Map;
26 import javax.persistence.Persistence;
27 import org.eclipse.persistence.config.PersistenceUnitProperties;
28 import org.onap.policy.common.im.MonitorTime;
29 import org.onap.policy.drools.core.PolicySessionFeatureApi;
30 import org.onap.policy.drools.features.PolicyEngineFeatureApi;
31 import org.onap.policy.drools.statemanagement.StateManagementFeatureApi;
32 import org.onap.policy.drools.statemanagement.StateManagementFeatureApiConstants;
33 import org.onap.policy.drools.system.PolicyEngine;
34 import org.onap.policy.drools.system.PolicyEngineConstants;
35 import org.onap.policy.drools.utils.PropertyUtil;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
38
39 /**
40  * If this feature is supported, there is a single instance of it.
41  * It adds persistence to Drools sessions, but it is also intertwined with
42  * active/standby state management and IntegrityMonitor. For now, they are
43  * all treated as a single feature, but it would be nice to separate them.
44  *
45  * <p>The bulk of the code here was once in other classes, such as
46  * 'PolicyContainer' and 'Main'. It was moved here as part of making this
47  * a separate optional feature.
48  */
49 public class ActiveStandbyFeature implements ActiveStandbyFeatureApi,
50     PolicySessionFeatureApi, PolicyEngineFeatureApi {
51     // get an instance of logger
52     private static final Logger logger =
53             LoggerFactory.getLogger(ActiveStandbyFeature.class);
54
55     private static DroolsPdp myPdp;
56     private static Object myPdpSync = new Object();
57     private static DroolsPdpsElectionHandler electionHandler;
58
59     private StateManagementFeatureApi stateManagementFeature;
60
61     public static final int SEQ_NUM = 1;
62
63
64     /*========================*/
65     /* 'FeatureAPI' interface */
66     /*========================*/
67
68     /**
69      * {@inheritDoc}.
70      */
71     @Override
72     public int getSequenceNumber() {
73         return SEQ_NUM;
74     }
75
76     /**
77      * {@inheritDoc}.
78      */
79     @Override
80     public void globalInit(String[] args, String configDir) {
81         // This must come first since it initializes myPdp
82         initializePersistence(configDir);
83
84         for (StateManagementFeatureApi feature : StateManagementFeatureApiConstants.getImpl().getList()) {
85             if (feature.getResourceName().equals(myPdp.getPdpId())) {
86                 logger.debug("ActiveStandbyFeature.globalInit: Found StateManagementFeature"
87                                 + " with resourceName: {}", myPdp.getPdpId());
88                 stateManagementFeature = feature;
89                 break;
90             }
91         }
92         if (stateManagementFeature == null) {
93             logger.debug("ActiveStandbyFeature failed to initialize.  "
94                             + "Unable to get instance of StateManagementFeatureApi "
95                             + "with resourceID: {}", myPdp.getPdpId());
96             logger.error("ActiveStandbyFeature failed to initialize.  "
97                     + "Unable to get instance of StateManagementFeatureApi "
98                     + "with resourceID: {}", myPdp.getPdpId());
99             //
100             // Cannot add observer since stateManagementFeature is null
101             //
102             return;
103         }
104
105
106
107         //Create an instance of the Observer
108         var pmNotifier = new PmStandbyStateChangeNotifier();
109
110         //Register the PMStandbyStateChangeNotifier Observer
111         stateManagementFeature.addObserver(pmNotifier);
112         logger.debug("ActiveStandbyFeature.globalInit() exit");
113     }
114
115
116     /**
117      * {@inheritDoc}.
118      */
119     @Override
120     public boolean afterStart(PolicyEngine engine) {
121         // ASSERTION: engine == PolicyEngine.manager
122         PolicyEngineConstants.getManager().lock();
123         return false;
124     }
125
126     /**
127      * Read in the persistence properties, determine whether persistence is
128      * enabled or disabled, and initialize persistence if enabled.
129      */
130     private static void initializePersistence(String configDir) {
131         //Get the Active Standby properties
132         try {
133             var activeStandbyProperties =
134                     PropertyUtil.getProperties(configDir + "/feature-active-standby-management.properties");
135             ActiveStandbyProperties.initProperties(activeStandbyProperties);
136             logger.info("initializePersistence: ActiveStandbyProperties success");
137         } catch (IOException e) {
138             logger.error("ActiveStandbyFeature: initializePersistence ActiveStandbyProperties", e);
139         }
140
141         var conn = getDroolsPdpsConnector("activeStandbyPU");
142         String resourceName = ActiveStandbyProperties.getProperty(ActiveStandbyProperties.NODE_NAME);
143         if (resourceName == null) {
144             throw new NullPointerException();
145         }
146
147         /*
148          * In a JUnit test environment, one or more PDPs may already have been
149          * inserted in the DB, so we need to check for this.
150          */
151         DroolsPdp existingPdp = conn.getPdp(resourceName);
152         if (existingPdp != null) {
153             logger.info("Found existing PDP record, pdpId={} isDesignated={}, updatedDate={}",
154                      existingPdp.getPdpId(), existingPdp.isDesignated(), existingPdp.getUpdatedDate());
155             myPdp = existingPdp;
156         }
157
158         synchronized (myPdpSync) {
159             if (myPdp == null) {
160
161                 myPdp = new DroolsPdpImpl(resourceName, false, 4, MonitorTime.getInstance().getDate());
162             }
163             String siteName = ActiveStandbyProperties.getProperty(ActiveStandbyProperties.SITE_NAME);
164             if (siteName == null) {
165                 siteName = "";
166             } else {
167                 siteName = siteName.trim();
168             }
169             myPdp.setSite(siteName);
170             if (electionHandler == null) {
171                 electionHandler = new DroolsPdpsElectionHandler(conn, myPdp);
172             }
173         }
174         logger.info("\n\nThis controller is a standby, waiting to be chosen as primary...\n\n");
175     }
176
177
178     /**
179      * Moved code to instantiate a JpaDroolsPdpsConnector object from main() to
180      * this method, so it can also be accessed from StandbyStateChangeNotifier
181      * class.
182      *
183      * @param pu string
184      * @return connector object
185      */
186     public static DroolsPdpsConnector getDroolsPdpsConnector(String pu) {
187
188         Map<String, Object> propMap = new HashMap<>();
189         propMap.put(PersistenceUnitProperties.JDBC_DRIVER,
190                         ActiveStandbyProperties.getProperty(ActiveStandbyProperties.DB_DRIVER));
191         propMap.put(PersistenceUnitProperties.JDBC_URL,
192                         ActiveStandbyProperties.getProperty(ActiveStandbyProperties.DB_URL));
193         propMap.put(PersistenceUnitProperties.JDBC_USER,
194                         ActiveStandbyProperties.getProperty(ActiveStandbyProperties.DB_USER));
195         propMap.put(PersistenceUnitProperties.JDBC_PASSWORD,
196                         ActiveStandbyProperties.getProperty(ActiveStandbyProperties.DB_PWD));
197         propMap.put(PersistenceUnitProperties.TARGET_DATABASE,
198                         ActiveStandbyProperties.getProperty(ActiveStandbyProperties.DB_TYPE));
199
200         var emf = Persistence.createEntityManagerFactory(pu, propMap);
201         return new JpaDroolsPdpsConnector(emf);
202     }
203
204     /**
205      * {@inheritDoc}.
206      */
207     @Override
208     public String getPdpdNowActive() {
209         return electionHandler.getPdpdNowActive();
210     }
211
212     /**
213      * {@inheritDoc}.
214      */
215     @Override
216     public String getPdpdLastActive() {
217         return electionHandler.getPdpdLastActive();
218     }
219
220     /**
221      * {@inheritDoc}.
222      */
223     @Override
224     public String getResourceName() {
225         return myPdp.getPdpId();
226     }
227 }