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 org.onap.policy.drools.statemanagement.StateManagementProperties;
25 import java.util.ArrayList;
26 import java.util.Properties;
28 import org.onap.policy.common.im.IntegrityMonitor;
29 import org.onap.policy.common.im.IntegrityMonitorException;
30 import org.onap.policy.drools.http.server.HttpServletServer;
31 import org.onap.policy.drools.properties.Startable;
32 import org.onap.policy.drools.utils.PropertyUtil;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
37 * This class extends 'IntegrityMonitor' for use in the 'Drools PDP'
38 * virtual machine. The included audits are 'Database' and 'Repository'.
40 public class DroolsPDPIntegrityMonitor extends IntegrityMonitor
43 // get an instance of logger
44 private static final Logger logger = LoggerFactory.getLogger(DroolsPDPIntegrityMonitor.class);
46 // static global instance
47 static private DroolsPDPIntegrityMonitor im = null;
49 // list of audits to run
50 static private AuditBase[] audits =
51 new AuditBase[]{DbAudit.getInstance(), RepositoryAudit.getInstance()};
53 static private Properties subsystemTestProperties = null;
55 static private final String PROPERTIES_NAME = "feature-state-management.properties";
57 static private void missingProperty(String prop) throws StateManagementPropertiesException{
58 String msg = "init: missing IntegrityMonitor property: ".concat(prop);
60 throw new StateManagementPropertiesException(msg);
63 static private void logPropertyValue(String prop, String val){
64 if(logger.isInfoEnabled()){
65 String msg = "\n\n init: property: " + prop + " = " + val + "\n";
70 * Static initialization -- create Drools Integrity Monitor, and
71 * an HTTP server to handle REST 'test' requests
73 static public DroolsPDPIntegrityMonitor init(String configDir) throws Exception
76 logger.info("init: Entering and invoking PropertyUtil.getProperties() on '{}'", configDir);
79 Properties stateManagementProperties =
80 PropertyUtil.getProperties(configDir + "/" + PROPERTIES_NAME);
81 // fetch and verify definitions of some properties
82 // (the 'IntegrityMonitor' constructor does some additional verification)
83 String testHost = stateManagementProperties.getProperty(StateManagementProperties.TEST_HOST);
84 String testPort = stateManagementProperties.getProperty(StateManagementProperties.TEST_PORT);
85 String testServices = stateManagementProperties.getProperty(StateManagementProperties.TEST_SERVICES,
86 StateManagementProperties.TEST_SERVICES_DEFAULT);
87 String testRestClasses = stateManagementProperties.getProperty(StateManagementProperties.TEST_REST_CLASSES,
88 StateManagementProperties.TEST_REST_CLASSES_DEFAULT);
89 String testManaged = stateManagementProperties.getProperty(StateManagementProperties.TEST_MANAGED,
90 StateManagementProperties.TEST_MANAGED_DEFAULT);
91 String testSwagger = stateManagementProperties.getProperty(StateManagementProperties.TEST_SWAGGER,
92 StateManagementProperties.TEST_SWAGGER_DEFAULT);
93 String resourceName = stateManagementProperties.getProperty(StateManagementProperties.RESOURCE_NAME);
94 String fpMonitorInterval = stateManagementProperties.getProperty(StateManagementProperties.FP_MONITOR_INTERVAL);
95 String failedCounterThreshold = stateManagementProperties.getProperty(StateManagementProperties.FAILED_COUNTER_THRESHOLD);
96 String testTransInterval = stateManagementProperties.getProperty(StateManagementProperties.TEST_TRANS_INTERVAL);
97 String writeFpcInterval = stateManagementProperties.getProperty(StateManagementProperties.WRITE_FPC_INTERVAL);
98 String siteName = stateManagementProperties.getProperty(StateManagementProperties.SITE_NAME);
99 String nodeType = stateManagementProperties.getProperty(StateManagementProperties.NODE_TYPE);
100 String dependencyGroups = stateManagementProperties.getProperty(StateManagementProperties.DEPENDENCY_GROUPS);
101 String javaxPersistenceJdbcDriver = stateManagementProperties.getProperty(StateManagementProperties.DB_DRIVER);
102 String javaxPersistenceJdbcUrl = stateManagementProperties.getProperty(StateManagementProperties.DB_URL);
103 String javaxPersistenceJdbcUser = stateManagementProperties.getProperty(StateManagementProperties.DB_USER);
104 String javaxPersistenceJdbcPassword = stateManagementProperties.getProperty(StateManagementProperties.DB_PWD);
106 if (testHost == null){
107 missingProperty(StateManagementProperties.TEST_HOST);
109 if (testPort == null){
110 missingProperty(StateManagementProperties.TEST_PORT);
112 if (!testServices.equals(StateManagementProperties.TEST_SERVICES_DEFAULT)){
113 logger.error("init: property {} does not have the expected value of {}",
114 StateManagementProperties.TEST_SERVICES,
115 StateManagementProperties.TEST_SERVICES_DEFAULT);
117 if (!testRestClasses.equals(StateManagementProperties.TEST_REST_CLASSES_DEFAULT)){
118 logger.error("init: property {} does not have the expected value of {}",
119 StateManagementProperties.TEST_REST_CLASSES,
120 StateManagementProperties.TEST_REST_CLASSES_DEFAULT);
122 if (!testManaged.equals(StateManagementProperties.TEST_MANAGED_DEFAULT)){
123 logger.warn("init: property {} does not have the expected value of {}",
124 StateManagementProperties.TEST_MANAGED,
125 StateManagementProperties.TEST_MANAGED_DEFAULT);
127 if (!testSwagger.equals(StateManagementProperties.TEST_SWAGGER_DEFAULT)){
128 logger.warn("init: property {} does not have the expected value of {}",
129 StateManagementProperties.TEST_SWAGGER,
130 StateManagementProperties.TEST_SWAGGER_DEFAULT);
132 if (resourceName == null){
133 missingProperty(StateManagementProperties.RESOURCE_NAME);
135 if (fpMonitorInterval == null){
136 missingProperty(StateManagementProperties.FP_MONITOR_INTERVAL);
138 if (failedCounterThreshold == null){
139 missingProperty(StateManagementProperties.FAILED_COUNTER_THRESHOLD);
141 if (testTransInterval == null){
142 missingProperty(StateManagementProperties.TEST_TRANS_INTERVAL);
144 if (writeFpcInterval == null){
145 missingProperty(StateManagementProperties.WRITE_FPC_INTERVAL);
147 if (siteName == null){
148 missingProperty(StateManagementProperties.SITE_NAME);
150 if (nodeType == null){
151 missingProperty(StateManagementProperties.NODE_TYPE);
153 if (dependencyGroups == null){
154 missingProperty(StateManagementProperties.DEPENDENCY_GROUPS);
156 if (javaxPersistenceJdbcDriver == null){
157 missingProperty(StateManagementProperties.DB_DRIVER);
159 if (javaxPersistenceJdbcUrl == null){
160 missingProperty(StateManagementProperties.DB_URL);
162 if (javaxPersistenceJdbcUser == null){
163 missingProperty(StateManagementProperties.DB_USER);
165 if (javaxPersistenceJdbcPassword == null){
166 missingProperty(StateManagementProperties.DB_PWD);
169 //Log the values so we can diagnose any issues
170 logPropertyValue(StateManagementProperties.TEST_HOST,testHost);
171 logPropertyValue(StateManagementProperties.TEST_PORT,testPort);
172 logPropertyValue(StateManagementProperties.TEST_SERVICES,testServices);
173 logPropertyValue(StateManagementProperties.TEST_REST_CLASSES,testRestClasses);
174 logPropertyValue(StateManagementProperties.TEST_MANAGED,testManaged);
175 logPropertyValue(StateManagementProperties.TEST_SWAGGER,testSwagger);
176 logPropertyValue(StateManagementProperties.RESOURCE_NAME,resourceName);
177 logPropertyValue(StateManagementProperties.FP_MONITOR_INTERVAL,fpMonitorInterval);
178 logPropertyValue(StateManagementProperties.FAILED_COUNTER_THRESHOLD,failedCounterThreshold);
179 logPropertyValue(StateManagementProperties.TEST_TRANS_INTERVAL,testTransInterval);
180 logPropertyValue(StateManagementProperties.WRITE_FPC_INTERVAL,writeFpcInterval);
181 logPropertyValue(StateManagementProperties.SITE_NAME,siteName);
182 logPropertyValue(StateManagementProperties.NODE_TYPE,nodeType);
183 logPropertyValue(StateManagementProperties.DEPENDENCY_GROUPS,dependencyGroups);
184 logPropertyValue(StateManagementProperties.DB_DRIVER,javaxPersistenceJdbcDriver);
185 logPropertyValue(StateManagementProperties.DB_URL,javaxPersistenceJdbcUrl);
186 logPropertyValue(StateManagementProperties.DB_USER,javaxPersistenceJdbcUser);
187 logPropertyValue(StateManagementProperties.DB_PWD,javaxPersistenceJdbcPassword);
189 subsystemTestProperties = stateManagementProperties;
191 // Now that we've validated the properties, create Drools Integrity Monitor
192 // with these properties.
193 im = new DroolsPDPIntegrityMonitor(resourceName,
194 stateManagementProperties);
195 logger.info("init: New DroolsPDPIntegrityMonitor instantiated, resourceName = ", resourceName);
197 // create http server
199 logger.info("init: Starting HTTP server, addr= {}", testHost+":"+testPort);
200 IntegrityMonitorRestServer server = new IntegrityMonitorRestServer();
202 server.init(stateManagementProperties);
203 } catch (Exception e) {
204 logger.error("init: Caught Exception attempting to start server on testPort= {} message:",
209 logger.info("init: Exiting and returning DroolsPDPIntegrityMonitor");
214 * Constructor - pass arguments to superclass, but remember properties
215 * @param resourceName unique name of this Integrity Monitor
216 * @param url the JMX URL of the MBean server
217 * @param properties properties used locally, as well as by
219 * @throws Exception (passed from superclass)
221 private DroolsPDPIntegrityMonitor(String resourceName,
222 Properties consolidatedProperties
224 super(resourceName, consolidatedProperties);
228 * Run tests (audits) unique to Drools PDP VM (Database + Repository)
231 public void subsystemTest() throws IntegrityMonitorException
233 logger.info("DroolsPDPIntegrityMonitor.subsystemTest called");
235 // clear all responses (non-null values indicate an error)
236 for (AuditBase audit : audits)
238 audit.setResponse(null);
241 // invoke all of the audits
242 for (AuditBase audit : audits)
246 // invoke the audit (responses are stored within the audit object)
247 audit.invoke(subsystemTestProperties);
251 logger.error("{} audit error", audit.getName(), e);
252 if (audit.getResponse() == null)
254 // if there is no current response, use the exception message
255 audit.setResponse(e.getMessage());
260 // will contain list of subsystems where the audit failed
261 String responseMsg = "";
263 // Loop through all of the audits, and see which ones have failed.
264 // NOTE: response information is stored within the audit objects
265 // themselves -- only one can run at a time.
266 for (AuditBase audit : audits)
268 String response = audit.getResponse();
269 if (response != null)
271 // the audit has failed -- add subsystem and
272 // and 'responseValue' with the new information
273 responseMsg = responseMsg.concat("\n" + audit.getName() + ": " + response);
277 if(!responseMsg.isEmpty()){
278 throw new IntegrityMonitorException(responseMsg);
282 /* ============================================================ */
285 * This is the base class for audits invoked in 'subsystemTest'
287 static public abstract class AuditBase
290 protected String name;
292 // non-null indicates the error response
293 protected String response;
296 * Constructor - initialize the name, and clear the initial response
297 * @param name name of the audit
299 public AuditBase(String name)
302 this.response = null;
306 * @return the name of this audit
308 public String getName()
314 * @return the response String (non-null indicates the error message)
316 public String getResponse()
322 * Set the response string to the specified value
323 * @param value the new value of the response string (null = no errors)
325 public void setResponse(String value)
331 * Abstract method to invoke the audit
332 * @param persistenceProperties Used for DB access
333 * @throws Exception passed in by the audit
335 abstract void invoke(Properties persistenceProperties) throws Exception;
338 public static class IntegrityMonitorRestServer implements Startable {
339 protected volatile HttpServletServer server = null;
340 protected volatile Properties integrityMonitorRestServerProperties = null;
342 public void init(Properties props) {
343 this.integrityMonitorRestServerProperties = props;
348 public boolean start() throws IllegalStateException {
350 ArrayList<HttpServletServer> servers = HttpServletServer.factory.build(integrityMonitorRestServerProperties);
352 if (!servers.isEmpty()) {
353 server = servers.get(0);
356 server.waitedStart(5);
357 } catch (Exception e) {
358 logger.error("Exception waiting for servers to start: ", e);
361 } catch (Exception e) {
362 logger.error("Exception building servers", e);
370 public boolean stop() throws IllegalStateException {
373 } catch (Exception e) {
374 logger.error("Exception during stop", e);
381 public void shutdown() throws IllegalStateException {
386 public synchronized boolean isAlive() {
387 return this.integrityMonitorRestServerProperties != null;
391 public static DroolsPDPIntegrityMonitor getInstance() throws Exception{
392 if(logger.isDebugEnabled()){
393 logger.debug("getInstance() called");
396 String msg = "No DroolsPDPIntegrityMonitor instance exists."
397 + " Please use the method DroolsPDPIntegrityMonitor init(String configDir)";
398 throw new Exception(msg);