2 * ============LICENSE_START=======================================================
3 * feature-state-management
4 * ================================================================================
5 * Copyright (C) 2017 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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
21 package org.onap.policy.drools.statemanagement;
23 import java.io.IOException;
24 import java.util.ArrayList;
25 import java.util.Properties;
26 import org.onap.policy.common.im.IntegrityMonitor;
27 import org.onap.policy.common.im.IntegrityMonitorException;
28 import org.onap.policy.drools.http.server.HttpServletServer;
29 import org.onap.policy.drools.properties.Startable;
30 import org.onap.policy.drools.utils.PropertyUtil;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
35 * This class extends 'IntegrityMonitor' for use in the 'Drools PDP'
36 * virtual machine. The included audits are 'Database' and 'Repository'.
38 public class DroolsPDPIntegrityMonitor extends IntegrityMonitor
41 private static final String INVALID_PROPERTY_VALUE = "init: property {} does not have the expected value of {}";
43 // get an instance of logger
44 private static final Logger logger = LoggerFactory.getLogger(DroolsPDPIntegrityMonitor.class);
46 // static global instance
47 private static DroolsPDPIntegrityMonitor im = null;
49 // list of audits to run
50 private static AuditBase[] audits =
51 new AuditBase[]{DbAudit.getInstance(), RepositoryAudit.getInstance()};
53 private static Properties subsystemTestProperties = null;
55 private static final String PROPERTIES_NAME = "feature-state-management.properties";
58 * Constructor - pass arguments to superclass, but remember properties
59 * @param resourceName unique name of this Integrity Monitor
60 * @param url the JMX URL of the MBean server
61 * @param properties properties used locally, as well as by
63 * @throws Exception (passed from superclass)
65 private DroolsPDPIntegrityMonitor(String resourceName,
66 Properties consolidatedProperties
68 super(resourceName, consolidatedProperties);
71 private static void missingProperty(String prop) throws IntegrityMonitorException{
72 String msg = "init: missing IntegrityMonitor property: ".concat(prop);
74 throw new IntegrityMonitorException(msg);
77 private static void logPropertyValue(String prop, String val){
78 if(logger.isInfoEnabled()){
79 String msg = "\n\n init: property: " + prop + " = " + val + "\n";
85 * Static initialization -- create Drools Integrity Monitor, and
86 * an HTTP server to handle REST 'test' requests
87 * @throws StateManagementPropertiesException
88 * @throws IntegrityMonitorException
90 public static DroolsPDPIntegrityMonitor init(String configDir) throws IntegrityMonitorException
93 logger.info("init: Entering and invoking PropertyUtil.getProperties() on '{}'", configDir);
96 Properties stateManagementProperties = getProperties(configDir);
98 // fetch and verify definitions of some properties, adding defaults where
100 // (the 'IntegrityMonitor' constructor does some additional verification)
102 checkPropError(stateManagementProperties, StateManagementProperties.TEST_HOST);
103 checkPropError(stateManagementProperties, StateManagementProperties.TEST_PORT);
105 addDefaultPropError(stateManagementProperties,
106 StateManagementProperties.TEST_SERVICES,
107 StateManagementProperties.TEST_SERVICES_DEFAULT);
109 addDefaultPropError(stateManagementProperties,
110 StateManagementProperties.TEST_REST_CLASSES,
111 StateManagementProperties.TEST_REST_CLASSES_DEFAULT);
113 addDefaultPropWarn(stateManagementProperties,
114 StateManagementProperties.TEST_MANAGED,
115 StateManagementProperties.TEST_MANAGED_DEFAULT);
117 addDefaultPropWarn(stateManagementProperties,
118 StateManagementProperties.TEST_SWAGGER,
119 StateManagementProperties.TEST_SWAGGER_DEFAULT);
121 checkPropError(stateManagementProperties, StateManagementProperties.RESOURCE_NAME);
122 checkPropError(stateManagementProperties, StateManagementProperties.FP_MONITOR_INTERVAL);
123 checkPropError(stateManagementProperties, StateManagementProperties.FAILED_COUNTER_THRESHOLD);
124 checkPropError(stateManagementProperties, StateManagementProperties.TEST_TRANS_INTERVAL);
125 checkPropError(stateManagementProperties, StateManagementProperties.WRITE_FPC_INTERVAL);
126 checkPropError(stateManagementProperties, StateManagementProperties.SITE_NAME);
127 checkPropError(stateManagementProperties, StateManagementProperties.NODE_TYPE);
128 checkPropError(stateManagementProperties, StateManagementProperties.DEPENDENCY_GROUPS);
129 checkPropError(stateManagementProperties, StateManagementProperties.DB_DRIVER);
130 checkPropError(stateManagementProperties, StateManagementProperties.DB_URL);
131 checkPropError(stateManagementProperties, StateManagementProperties.DB_USER);
132 checkPropError(stateManagementProperties, StateManagementProperties.DB_PWD);
134 String testHost = stateManagementProperties.getProperty(StateManagementProperties.TEST_HOST);
135 String testPort = stateManagementProperties.getProperty(StateManagementProperties.TEST_PORT);
136 String resourceName = stateManagementProperties.getProperty(StateManagementProperties.RESOURCE_NAME);
138 subsystemTestProperties = stateManagementProperties;
140 // Now that we've validated the properties, create Drools Integrity Monitor
141 // with these properties.
142 im = makeMonitor(resourceName, stateManagementProperties);
143 logger.info("init: New DroolsPDPIntegrityMonitor instantiated, resourceName = ", resourceName);
145 // create http server
146 makeRestServer(testHost, testPort, stateManagementProperties);
147 logger.info("init: Exiting and returning DroolsPDPIntegrityMonitor");
153 * Makes an Integrity Monitor.
154 * @param resourceName unique name of this Integrity Monitor
155 * @param properties properties used to configure the Integrity Monitor
157 * @throws IntegrityMonitorException
159 private static DroolsPDPIntegrityMonitor makeMonitor(String resourceName, Properties properties)
160 throws IntegrityMonitorException {
163 return new DroolsPDPIntegrityMonitor(resourceName, properties);
165 } catch (Exception e) {
166 throw new IntegrityMonitorException(e);
171 * Makes a rest server for the Integrity Monitor.
172 * @param testHost host name
173 * @param testPort port
174 * @param properties properties used to configure the rest server
175 * @throws IntegrityMonitorException
177 private static void makeRestServer(String testHost, String testPort, Properties properties)
178 throws IntegrityMonitorException {
181 logger.info("init: Starting HTTP server, addr= {}", testHost+":"+testPort);
183 IntegrityMonitorRestServer server = new IntegrityMonitorRestServer();
184 server.init(properties);
186 } catch (Exception e) {
187 logger.error("init: Caught Exception attempting to start server on testPort= {} message:",
189 throw new IntegrityMonitorException(e);
194 * Gets the properties from the property file.
195 * @param configDir directory containing the property file
196 * @return the properties
197 * @throws IntegrityMonitorException
199 private static Properties getProperties(String configDir) throws IntegrityMonitorException {
201 return PropertyUtil.getProperties(configDir + "/" + PROPERTIES_NAME);
203 } catch (IOException e) {
204 throw new IntegrityMonitorException(e);
209 * Checks that a property is defined.
210 * @param props set of properties
211 * @param name name of the property to check
212 * @throws IntegrityMonitorException
214 private static void checkPropError(Properties props, String name) throws IntegrityMonitorException {
215 String val = props.getProperty(name);
217 missingProperty(name);
220 logPropertyValue(name, val);
224 * Checks a property's value to verify that it matches the expected value.
225 * If the property is not defined, then it is added to the property set,
226 * with the expected value. Logs an error if the property is defined,
227 * but does not have the expected value.
228 * @param props set of properties
229 * @param name name of the property to check
230 * @param expected expected/default value
232 private static void addDefaultPropError(Properties props, String name, String expected) {
233 String val = props.getProperty(name);
235 props.setProperty(name, expected);
237 } else if( ! val.equals(expected)) {
238 logger.error(INVALID_PROPERTY_VALUE, name, expected);
241 logPropertyValue(name, val);
245 * Checks a property's value to verify that it matches the expected value.
246 * If the property is not defined, then it is added to the property set,
247 * with the expected value. Logs a warning if the property is defined,
248 * but does not have the expected value.
249 * @param props set of properties
250 * @param name name of the property to check
251 * @param expected expected/default value
253 private static void addDefaultPropWarn(Properties props, String name, String dflt) {
254 String val = props.getProperty(name);
256 props.setProperty(name, dflt);
258 } else if( ! val.equals(dflt)) {
259 logger.warn(INVALID_PROPERTY_VALUE, name, dflt);
262 logPropertyValue(name, val);
266 * Run tests (audits) unique to Drools PDP VM (Database + Repository)
269 public void subsystemTest() throws IntegrityMonitorException
271 logger.info("DroolsPDPIntegrityMonitor.subsystemTest called");
273 // clear all responses (non-null values indicate an error)
274 for (AuditBase audit : audits)
276 audit.setResponse(null);
279 // invoke all of the audits
280 for (AuditBase audit : audits)
284 // invoke the audit (responses are stored within the audit object)
285 audit.invoke(subsystemTestProperties);
289 logger.error("{} audit error", audit.getName(), e);
290 if (audit.getResponse() == null)
292 // if there is no current response, use the exception message
293 audit.setResponse(e.getMessage());
298 // will contain list of subsystems where the audit failed
299 String responseMsg = "";
301 // Loop through all of the audits, and see which ones have failed.
302 // NOTE: response information is stored within the audit objects
303 // themselves -- only one can run at a time.
304 for (AuditBase audit : audits)
306 String response = audit.getResponse();
307 if (response != null)
309 // the audit has failed -- add subsystem and
310 // and 'responseValue' with the new information
311 responseMsg = responseMsg.concat("\n" + audit.getName() + ": " + response);
315 if(!responseMsg.isEmpty()){
316 throw new IntegrityMonitorException(responseMsg);
320 /* ============================================================ */
323 * This is the base class for audits invoked in 'subsystemTest'
325 public abstract static class AuditBase
328 protected String name;
330 // non-null indicates the error response
331 protected String response;
334 * Constructor - initialize the name, and clear the initial response
335 * @param name name of the audit
337 public AuditBase(String name)
340 this.response = null;
344 * @return the name of this audit
346 public String getName()
352 * @return the response String (non-null indicates the error message)
354 public String getResponse()
360 * Set the response string to the specified value
361 * @param value the new value of the response string (null = no errors)
363 public void setResponse(String value)
369 * Abstract method to invoke the audit
370 * @param persistenceProperties Used for DB access
371 * @throws Exception passed in by the audit
373 abstract void invoke(Properties persistenceProperties) throws Exception;
376 public static class IntegrityMonitorRestServer implements Startable {
377 protected volatile HttpServletServer server = null;
378 protected volatile Properties integrityMonitorRestServerProperties = null;
380 public void init(Properties props) {
381 this.integrityMonitorRestServerProperties = props;
386 public boolean start() {
388 ArrayList<HttpServletServer> servers = HttpServletServer.factory.build(integrityMonitorRestServerProperties);
390 if (!servers.isEmpty()) {
391 server = servers.get(0);
395 } catch (Exception e) {
396 logger.error("Exception building servers", e);
403 private void waitServerStart() {
405 server.waitedStart(5);
406 } catch (Exception e) {
407 logger.error("Exception waiting for servers to start: ", e);
412 public boolean stop() {
415 } catch (Exception e) {
416 logger.error("Exception during stop", e);
423 public void shutdown() {
428 public synchronized boolean isAlive() {
429 return this.integrityMonitorRestServerProperties != null;
433 public static DroolsPDPIntegrityMonitor getInstance() throws IntegrityMonitorException{
434 if(logger.isDebugEnabled()){
435 logger.debug("getInstance() called");
438 String msg = "No DroolsPDPIntegrityMonitor instance exists."
439 + " Please use the method DroolsPDPIntegrityMonitor init(String configDir)";
440 throw new IntegrityMonitorException(msg);