diff options
11 files changed, 543 insertions, 518 deletions
diff --git a/feature-healthcheck/checkstyle-suppressions.xml b/feature-healthcheck/checkstyle-suppressions.xml deleted file mode 100644 index ed04d894..00000000 --- a/feature-healthcheck/checkstyle-suppressions.xml +++ /dev/null @@ -1,30 +0,0 @@ -<?xml version="1.0"?> -<!-- - ============LICENSE_START======================================================= - Copyright (C) 2018 AT&T Technologies. All rights reserved. - ================================================================================ - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - SPDX-License-Identifier: Apache-2.0 - ============LICENSE_END========================================================= ---> - -<!DOCTYPE suppressions PUBLIC - "-//Puppy Crawl//DTD Suppressions 1.0//EN" - "http://www.puppycrawl.com/dtds/suppressions_1_0.dtd"> - -<suppressions> - <suppress checks="OneTopLevelClass" - files="HealthCheck.java" - lines="1-9999"/> -</suppressions> diff --git a/feature-healthcheck/pom.xml b/feature-healthcheck/pom.xml index eec0b622..a4385f77 100644 --- a/feature-healthcheck/pom.xml +++ b/feature-healthcheck/pom.xml @@ -2,7 +2,7 @@ ============LICENSE_START======================================================= ONAP Policy Engine - Drools PDP ================================================================================ - Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved. + Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved. ================================================================================ Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -105,7 +105,6 @@ <includeTestResources>true</includeTestResources> <excludes> </excludes> - <suppressionsLocation>${project.baseUri}checkstyle-suppressions.xml</suppressionsLocation> <consoleOutput>true</consoleOutput> <failsOnViolation>true</failsOnViolation> <violationSeverity>warning</violationSeverity> diff --git a/feature-healthcheck/src/main/java/org/onap/policy/drools/healthcheck/HealthCheck.java b/feature-healthcheck/src/main/java/org/onap/policy/drools/healthcheck/HealthCheck.java index d7009be9..1a4dab6b 100644 --- a/feature-healthcheck/src/main/java/org/onap/policy/drools/healthcheck/HealthCheck.java +++ b/feature-healthcheck/src/main/java/org/onap/policy/drools/healthcheck/HealthCheck.java @@ -22,19 +22,7 @@ package org.onap.policy.drools.healthcheck; import java.util.ArrayList; import java.util.List; -import java.util.Properties; -import javax.ws.rs.core.Response; import org.onap.policy.common.capabilities.Startable; -import org.onap.policy.common.endpoints.http.client.HttpClient; -import org.onap.policy.common.endpoints.http.client.HttpClientFactory; -import org.onap.policy.common.endpoints.http.client.HttpClientFactoryInstance; -import org.onap.policy.common.endpoints.http.server.HttpServletServer; -import org.onap.policy.common.endpoints.http.server.HttpServletServerFactory; -import org.onap.policy.common.endpoints.http.server.HttpServletServerFactoryInstance; -import org.onap.policy.drools.persistence.SystemPersistence; -import org.onap.policy.drools.system.PolicyEngine; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * Healthcheck. @@ -175,205 +163,3 @@ public interface HealthCheck extends Startable { */ public Reports healthCheck(); } - - -/** - * Healthcheck Monitor. - */ -class HealthCheckMonitor implements HealthCheck { - - /** - * Logger. - */ - private static Logger logger = LoggerFactory.getLogger(HealthCheckMonitor.class); - - /** - * Attached http servers. - */ - protected volatile List<HttpServletServer> servers = new ArrayList<>(); - - /** - * Attached http clients. - */ - protected volatile List<HttpClient> clients = new ArrayList<>(); - - /** - * Healthcheck configuration. - */ - protected volatile Properties healthCheckProperties = null; - - /** - * {@inheritDoc}. - */ - @Override - public Reports healthCheck() { - Reports reports = new Reports(); - boolean thisEngineIsAlive = getEngineManager().isAlive(); - reports.setHealthy(thisEngineIsAlive); - - HealthCheck.Report engineReport = new Report(); - engineReport.setHealthy(thisEngineIsAlive); - engineReport.setName("PDP-D"); - engineReport.setUrl("self"); - engineReport.setCode(thisEngineIsAlive ? 200 : 500); - engineReport.setMessage(thisEngineIsAlive ? "alive" : "not alive"); - reports.getDetails().add(engineReport); - - for (HttpClient client : clients) { - HealthCheck.Report report = new Report(); - report.setName(client.getName()); - report.setUrl(client.getBaseUrl()); - report.setHealthy(true); - try { - Response response = client.get(); - report.setCode(response.getStatus()); - if (report.getCode() != 200) { - report.setHealthy(false); - reports.setHealthy(false); - } - - report.setMessage(getHttpBody(response, client)); - } catch (Exception e) { - logger.warn("{}: cannot contact http-client {}", this, client, e); - - report.setHealthy(false); - reports.setHealthy(false); - } - reports.getDetails().add(report); - } - return reports; - } - - /** - * {@inheritDoc}. - */ - @Override - public boolean start() { - - try { - this.healthCheckProperties = getPersistentProperties(HealthCheckFeature.CONFIGURATION_PROPERTIES_NAME); - this.servers = getServerFactory().build(healthCheckProperties); - this.clients = getClientFactory().build(healthCheckProperties); - - for (HttpServletServer server : servers) { - if (server.isAaf()) { - server.addFilterClass(null, AafHealthCheckFilter.class.getName()); - } - startServer(server); - } - } catch (Exception e) { - logger.warn("{}: cannot start {}", this, e); - return false; - } - - return true; - } - - /** - * {@inheritDoc}. - */ - @Override - public boolean stop() { - - for (HttpServletServer server : servers) { - try { - server.stop(); - } catch (Exception e) { - logger.warn("{}: cannot stop http-server {}", this, server, e); - } - } - - for (HttpClient client : clients) { - try { - client.stop(); - } catch (Exception e) { - logger.warn("{}: cannot stop http-client {}", this, client, e); - } - } - - return true; - } - - /** - * {@inheritDoc}. - */ - @Override - public void shutdown() { - this.stop(); - } - - /** - * {@inheritDoc}. - */ - @Override - public synchronized boolean isAlive() { - return this.healthCheckProperties != null; - } - - /** - * Get servers. - * - * @return list of attached Http Servers - */ - public List<HttpServletServer> getServers() { - return this.servers; - } - - /** - * Get clients. - * - * @return list of attached Http Clients - */ - public List<HttpClient> getClients() { - return this.clients; - } - - public String getHttpBody(Response response, HttpClient client) { - - String body = null; - try { - body = HttpClient.getBody(response, String.class); - } catch (Exception e) { - logger.info("{}: cannot get body from http-client {}", this, client, e); - } - - return body; - } - - public void startServer(HttpServletServer server) { - try { - server.start(); - } catch (Exception e) { - logger.warn("{}: cannot start http-server {}", this, server, e); - } - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("HealthCheckMonitor [servers="); - builder.append(servers); - builder.append(", clients="); - builder.append(clients); - builder.append("]"); - return builder.toString(); - } - - // the following methods may be overridden by junit tests - - protected PolicyEngine getEngineManager() { - return PolicyEngine.manager; - } - - protected HttpServletServerFactory getServerFactory() { - return HttpServletServerFactoryInstance.getServerFactory(); - } - - protected HttpClientFactory getClientFactory() { - return HttpClientFactoryInstance.getClientFactory(); - } - - protected Properties getPersistentProperties(String propertyName) { - return SystemPersistence.manager.getProperties(propertyName); - } -} diff --git a/feature-healthcheck/src/main/java/org/onap/policy/drools/healthcheck/HealthCheckMonitor.java b/feature-healthcheck/src/main/java/org/onap/policy/drools/healthcheck/HealthCheckMonitor.java new file mode 100644 index 00000000..cca56e01 --- /dev/null +++ b/feature-healthcheck/src/main/java/org/onap/policy/drools/healthcheck/HealthCheckMonitor.java @@ -0,0 +1,250 @@ +/* + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.drools.healthcheck; + +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; +import javax.ws.rs.core.Response; +import org.onap.policy.common.endpoints.http.client.HttpClient; +import org.onap.policy.common.endpoints.http.client.HttpClientFactory; +import org.onap.policy.common.endpoints.http.client.HttpClientFactoryInstance; +import org.onap.policy.common.endpoints.http.server.HttpServletServer; +import org.onap.policy.common.endpoints.http.server.HttpServletServerFactory; +import org.onap.policy.common.endpoints.http.server.HttpServletServerFactoryInstance; +import org.onap.policy.drools.persistence.SystemPersistence; +import org.onap.policy.drools.system.PolicyEngine; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +/** + * Healthcheck Monitor. + */ +public class HealthCheckMonitor implements HealthCheck { + + /** + * Logger. + */ + private static Logger logger = LoggerFactory.getLogger(HealthCheckMonitor.class); + + /** + * Attached http servers. + */ + protected List<HttpServletServer> servers = new ArrayList<>(); + + /** + * Attached http clients. + */ + protected List<HttpClient> clients = new ArrayList<>(); + + /** + * Healthcheck configuration. + */ + protected Properties healthCheckProperties = null; + + /** + * {@inheritDoc}. + */ + @Override + public Reports healthCheck() { + Reports reports = new Reports(); + boolean thisEngineIsAlive = getEngineManager().isAlive(); + reports.setHealthy(thisEngineIsAlive); + + HealthCheck.Report engineReport = new Report(); + engineReport.setHealthy(thisEngineIsAlive); + engineReport.setName("PDP-D"); + engineReport.setUrl("self"); + engineReport.setCode(thisEngineIsAlive ? 200 : 500); + engineReport.setMessage(thisEngineIsAlive ? "alive" : "not alive"); + reports.getDetails().add(engineReport); + + for (HttpClient client : clients) { + HealthCheck.Report report = new Report(); + report.setName(client.getName()); + report.setUrl(client.getBaseUrl()); + report.setHealthy(true); + try { + Response response = client.get(); + report.setCode(response.getStatus()); + if (report.getCode() != 200) { + report.setHealthy(false); + reports.setHealthy(false); + } + + report.setMessage(getHttpBody(response, client)); + } catch (Exception e) { + logger.warn("{}: cannot contact http-client {}", this, client, e); + + report.setHealthy(false); + reports.setHealthy(false); + } + reports.getDetails().add(report); + } + return reports; + } + + /** + * {@inheritDoc}. + */ + @Override + public boolean start() { + + try { + this.healthCheckProperties = getPersistentProperties(HealthCheckFeature.CONFIGURATION_PROPERTIES_NAME); + this.servers = getServerFactory().build(healthCheckProperties); + this.clients = getClientFactory().build(healthCheckProperties); + + for (HttpServletServer server : servers) { + if (server.isAaf()) { + server.addFilterClass(null, AafHealthCheckFilter.class.getName()); + } + startServer(server); + } + } catch (Exception e) { + logger.warn("{}: cannot start {}", this, e); + return false; + } + + return true; + } + + /** + * {@inheritDoc}. + */ + @Override + public boolean stop() { + + for (HttpServletServer server : servers) { + try { + server.stop(); + } catch (Exception e) { + logger.warn("{}: cannot stop http-server {}", this, server, e); + } + } + + for (HttpClient client : clients) { + try { + client.stop(); + } catch (Exception e) { + logger.warn("{}: cannot stop http-client {}", this, client, e); + } + } + + return true; + } + + /** + * {@inheritDoc}. + */ + @Override + public void shutdown() { + this.stop(); + } + + /** + * {@inheritDoc}. + */ + @Override + public synchronized boolean isAlive() { + return this.healthCheckProperties != null; + } + + /** + * Get servers. + * + * @return list of attached Http Servers + */ + public List<HttpServletServer> getServers() { + return this.servers; + } + + /** + * Get clients. + * + * @return list of attached Http Clients + */ + public List<HttpClient> getClients() { + return this.clients; + } + + /** + * Gets the body from the response. + * + * @param response response from which to get the body + * @param client HTTP client from which the response was received + * @return the response body + */ + public String getHttpBody(Response response, HttpClient client) { + + String body = null; + try { + body = HttpClient.getBody(response, String.class); + } catch (Exception e) { + logger.info("{}: cannot get body from http-client {}", this, client, e); + } + + return body; + } + + /** + * Starts an HTTP server. + * + * @param server server to be started + */ + public void startServer(HttpServletServer server) { + try { + server.start(); + } catch (Exception e) { + logger.warn("{}: cannot start http-server {}", this, server, e); + } + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("HealthCheckMonitor [servers="); + builder.append(servers); + builder.append(", clients="); + builder.append(clients); + builder.append("]"); + return builder.toString(); + } + + // the following methods may be overridden by junit tests + + protected PolicyEngine getEngineManager() { + return PolicyEngine.manager; + } + + protected HttpServletServerFactory getServerFactory() { + return HttpServletServerFactoryInstance.getServerFactory(); + } + + protected HttpClientFactory getClientFactory() { + return HttpClientFactoryInstance.getClientFactory(); + } + + protected Properties getPersistentProperties(String propertyName) { + return SystemPersistence.manager.getProperties(propertyName); + } +} diff --git a/feature-test-transaction/checkstyle-suppressions.xml b/feature-test-transaction/checkstyle-suppressions.xml deleted file mode 100644 index 7112bbe4..00000000 --- a/feature-test-transaction/checkstyle-suppressions.xml +++ /dev/null @@ -1,33 +0,0 @@ -<?xml version="1.0"?> -<!-- - ============LICENSE_START======================================================= - Copyright (C) 2018 AT&T Technologies. All rights reserved. - ================================================================================ - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - SPDX-License-Identifier: Apache-2.0 - ============LICENSE_END========================================================= ---> - -<!DOCTYPE suppressions PUBLIC - "-//Puppy Crawl//DTD Suppressions 1.0//EN" - "http://www.puppycrawl.com/dtds/suppressions_1_0.dtd"> - -<suppressions> - <suppress checks="AbbreviationAsWordInName" - files="TestTransaction.java" - lines="1-9999"/> - <suppress checks="OneTopLevelClass" - files="TestTransaction.java" - lines="1-9999"/> -</suppressions> diff --git a/feature-test-transaction/pom.xml b/feature-test-transaction/pom.xml index 6e028615..da12e4b0 100644 --- a/feature-test-transaction/pom.xml +++ b/feature-test-transaction/pom.xml @@ -2,7 +2,7 @@ ============LICENSE_START======================================================= feature-test-transaction ================================================================================ - Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved. + Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved. ================================================================================ Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -102,7 +102,6 @@ <includeTestResources>true</includeTestResources> <excludes> </excludes> - <suppressionsLocation>${project.baseUri}checkstyle-suppressions.xml</suppressionsLocation> <consoleOutput>true</consoleOutput> <failsOnViolation>true</failsOnViolation> <violationSeverity>warning</violationSeverity> diff --git a/feature-test-transaction/src/main/java/org/onap/policy/drools/testtransaction/TestTransaction.java b/feature-test-transaction/src/main/java/org/onap/policy/drools/testtransaction/TestTransaction.java index 452825c0..03a0e4b7 100644 --- a/feature-test-transaction/src/main/java/org/onap/policy/drools/testtransaction/TestTransaction.java +++ b/feature-test-transaction/src/main/java/org/onap/policy/drools/testtransaction/TestTransaction.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * feature-test-transaction * ================================================================================ - * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,15 +20,7 @@ package org.onap.policy.drools.testtransaction; -import java.util.EventObject; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.onap.policy.drools.controller.DroolsController; import org.onap.policy.drools.system.PolicyController; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** TestTransaction interface. */ public interface TestTransaction { @@ -38,7 +30,7 @@ public interface TestTransaction { public static final String TT_UUID = "43868e59-d1f3-43c2-bd6f-86f89a61eea5"; public static long DEFAULT_TT_TASK_SLEEP = 20000; - public static final TestTransaction manager = new TTImpl(); + public static final TestTransaction manager = new TtImpl(); /** * register a controller for monitoring test transactions. @@ -54,213 +46,3 @@ public interface TestTransaction { */ public void unregister(PolicyController controller); } - -/** - * Implementation of TestTransaction interface. Controls the registering/unregistering of - * PolicyController objects and the management of their related TTControllerTask threads. - */ -class TTImpl implements TestTransaction { - - protected final Map<String, TTControllerTask> controllers = new HashMap<>(); - - @Override - public synchronized void register(PolicyController controller) { - TTControllerTask controllerTask = this.controllers.get(controller.getName()); - if (controllerTask != null && controllerTask.isAlive()) { - return; - } - - // continue : unregister, register operation - - controllerTask = makeControllerTask(controller); - this.controllers.put(controller.getName(), controllerTask); - } - - @Override - public synchronized void unregister(PolicyController controller) { - final TTControllerTask controllerTask = this.controllers.remove(controller.getName()); - if (controllerTask != null) { - controllerTask.stop(); - } - } - - // these may be overridden by junit tests - - protected TTControllerTask makeControllerTask(PolicyController controller) { - return new TTControllerTask(controller); - } -} - -/** - * TTControllerTask implements the Runnabale interface Carries out the injection of an event into a - * drools session and subsequent query of a counter to ensure that forward progress is occuring. - */ -class TTControllerTask implements Runnable { - - // get an instance of logger - private static final Logger logger = LoggerFactory.getLogger(TTControllerTask.class); - - protected final PolicyController controller; - - protected volatile boolean alive = true; - protected final Thread thread = makeThread(this); - - public TTControllerTask(PolicyController controller) { - this.controller = controller; - this.thread.setName("tt-controller-task-" + controller.getName()); - this.thread.start(); - } - - public PolicyController getController() { - return this.controller; - } - - public synchronized boolean isAlive() { - return this.alive; - } - - public synchronized void stop() { - this.alive = false; - this.thread.interrupt(); - try { - joinThread(1000); - } catch (final InterruptedException e) { - logger.error("TestTransaction thread threw", e); - this.thread.interrupt(); - } - } - - public Thread getThread() { - return this.thread; - } - - @Override - public void run() { - try { - final List<String> sessions = this.controller.getDrools().getSessionNames(); - - if (!(this.controller.getDrools().isBrained())) { - this.alive = false; - logger.error("{}: unknown drools controller", this); - return; - } - - final DroolsController drools = this.controller.getDrools(); - - final HashMap<String, Long> fpcs = new HashMap<>(); - for (final String session : sessions) { - fpcs.put(session, -1L); - } - - while (this.controller.isAlive() - && !this.controller.isLocked() - && drools.isBrained() - && this.alive) { - - injectTxIntoSessions(sessions, fpcs, drools); - - if (!this.alive) { - return; - } - - if (!getCurrentThread().isInterrupted()) { - doSleep(TestTransaction.DEFAULT_TT_TASK_SLEEP); - } - } - } catch (final InterruptedException e) { - logger.info("{}: stopping ...", this, e); - getCurrentThread().interrupt(); - } catch (final IllegalArgumentException e) { - logger.error( - "{}: controller {} has not been enabled for testing: ", - this, - this.controller.getName(), - e.getMessage(), - e); - } catch (final Exception e) { - logger.error( - "Controller: {} is not testable - TestTransaction caught exception: {} ", - this.controller.getName(), - e.getMessage()); - logger.error("TestTransaction thread threw", e); - } finally { - logger.info("Exiting: {}", this); - this.alive = false; - } - } - - private void injectTxIntoSessions( - List<String> sessions, HashMap<String, Long> fpcs, DroolsController drools) { - - for (final String session : sessions) { - final List<Object> facts = - this.controller - .getDrools() - .factQuery(session, TestTransaction.TT_FPC, TestTransaction.TT_COUNTER, false); - if (facts == null || facts.size() != 1) { - /* - * unexpected something wrong here, can't expect to recover note this exception is - * caught right below at the exit of run() - */ - logger.error( - "Controller: {}, with rules artifact: (group) {}, (artifact) {}, (version) {} " - + "- FPC query failed after EventObject insertion! ", - this.controller.getName(), - this.controller.getDrools().getGroupId(), - this.controller.getDrools().getArtifactId(), - this.controller.getDrools().getVersion()); - break; - } - logger.debug("Facts: {}", facts); - - final long fpc = (Long) facts.get(0); - if (fpc != fpcs.get(session)) { - logger.info( - "Controller: {} , session {} - Forward progress successful: {} -> {}", - this.controller.getName(), - session, - fpcs.get(session), - fpc); - } else { - logger.error( - "Controller: {}, session {} - Forward progress failure: {}", - this.controller.getName(), - session, - fpc); - } - fpcs.put(session, fpc); - drools.getContainer().insert(session, new EventObject(TestTransaction.TT_UUID)); - } - } - - @Override - public String toString() { - final StringBuilder builder = new StringBuilder(); - builder.append("TTControllerTask [controller="); - builder.append(this.controller); - builder.append(", alive="); - builder.append(this.alive); - builder.append(", thread="); - builder.append(this.thread.getName()); - builder.append("]"); - return builder.toString(); - } - - // these may be overridden by junit tests - - protected Thread makeThread(Runnable action) { - return new Thread(action); - } - - protected void joinThread(long waitTimeMs) throws InterruptedException { - this.thread.join(waitTimeMs); - } - - protected void doSleep(long sleepMs) throws InterruptedException { - Thread.sleep(sleepMs); - } - - protected Thread getCurrentThread() { - return Thread.currentThread(); - } -} diff --git a/feature-test-transaction/src/main/java/org/onap/policy/drools/testtransaction/TtControllerTask.java b/feature-test-transaction/src/main/java/org/onap/policy/drools/testtransaction/TtControllerTask.java new file mode 100644 index 00000000..cd54eb07 --- /dev/null +++ b/feature-test-transaction/src/main/java/org/onap/policy/drools/testtransaction/TtControllerTask.java @@ -0,0 +1,211 @@ +/* + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.drools.testtransaction; + +import java.util.EventObject; +import java.util.HashMap; +import java.util.List; +import org.onap.policy.drools.controller.DroolsController; +import org.onap.policy.drools.system.PolicyController; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * TtControllerTask implements the Runnabale interface Carries out the injection of an event into a + * drools session and subsequent query of a counter to ensure that forward progress is occuring. + */ +public class TtControllerTask implements Runnable { + + // get an instance of logger + private static final Logger logger = LoggerFactory.getLogger(TtControllerTask.class); + + protected final PolicyController controller; + + protected volatile boolean alive = true; + protected final Thread thread = makeThread(this); + + /** + * Constructs the object. + * + * @param controller controller with which the task is associated + */ + public TtControllerTask(PolicyController controller) { + this.controller = controller; + this.thread.setName("tt-controller-task-" + controller.getName()); + this.thread.start(); + } + + public PolicyController getController() { + return this.controller; + } + + public synchronized boolean isAlive() { + return this.alive; + } + + /** + * Stops the task. + */ + public synchronized void stop() { + this.alive = false; + this.thread.interrupt(); + try { + joinThread(1000); + } catch (final InterruptedException e) { + logger.error("TestTransaction thread threw", e); + this.thread.interrupt(); + } + } + + public Thread getThread() { + return this.thread; + } + + @Override + public void run() { + try { + final List<String> sessions = this.controller.getDrools().getSessionNames(); + + if (!(this.controller.getDrools().isBrained())) { + this.alive = false; + logger.error("{}: unknown drools controller", this); + return; + } + + final DroolsController drools = this.controller.getDrools(); + + final HashMap<String, Long> fpcs = new HashMap<>(); + for (final String session : sessions) { + fpcs.put(session, -1L); + } + + while (this.controller.isAlive() + && !this.controller.isLocked() + && drools.isBrained() + && this.alive) { + + injectTxIntoSessions(sessions, fpcs, drools); + + if (!this.alive) { + return; + } + + if (!getCurrentThread().isInterrupted()) { + doSleep(TestTransaction.DEFAULT_TT_TASK_SLEEP); + } + } + } catch (final InterruptedException e) { + logger.info("{}: stopping ...", this, e); + getCurrentThread().interrupt(); + } catch (final IllegalArgumentException e) { + logger.error( + "{}: controller {} has not been enabled for testing: ", + this, + this.controller.getName(), + e.getMessage(), + e); + } catch (final Exception e) { + logger.error( + "Controller: {} is not testable - TestTransaction caught exception: {} ", + this.controller.getName(), + e.getMessage()); + logger.error("TestTransaction thread threw", e); + } finally { + logger.info("Exiting: {}", this); + this.alive = false; + } + } + + private void injectTxIntoSessions( + List<String> sessions, HashMap<String, Long> fpcs, DroolsController drools) { + + for (final String session : sessions) { + final List<Object> facts = + this.controller + .getDrools() + .factQuery(session, TestTransaction.TT_FPC, TestTransaction.TT_COUNTER, false); + if (facts == null || facts.size() != 1) { + /* + * unexpected something wrong here, can't expect to recover note this exception is + * caught right below at the exit of run() + */ + logger.error( + "Controller: {}, with rules artifact: (group) {}, (artifact) {}, (version) {} " + + "- FPC query failed after EventObject insertion! ", + this.controller.getName(), + this.controller.getDrools().getGroupId(), + this.controller.getDrools().getArtifactId(), + this.controller.getDrools().getVersion()); + break; + } + logger.debug("Facts: {}", facts); + + final long fpc = (Long) facts.get(0); + if (fpc != fpcs.get(session)) { + logger.info( + "Controller: {} , session {} - Forward progress successful: {} -> {}", + this.controller.getName(), + session, + fpcs.get(session), + fpc); + } else { + logger.error( + "Controller: {}, session {} - Forward progress failure: {}", + this.controller.getName(), + session, + fpc); + } + fpcs.put(session, fpc); + drools.getContainer().insert(session, new EventObject(TestTransaction.TT_UUID)); + } + } + + @Override + public String toString() { + final StringBuilder builder = new StringBuilder(); + builder.append("TTControllerTask [controller="); + builder.append(this.controller); + builder.append(", alive="); + builder.append(this.alive); + builder.append(", thread="); + builder.append(this.thread.getName()); + builder.append("]"); + return builder.toString(); + } + + // these may be overridden by junit tests + + protected Thread makeThread(Runnable action) { + return new Thread(action); + } + + protected void joinThread(long waitTimeMs) throws InterruptedException { + this.thread.join(waitTimeMs); + } + + protected void doSleep(long sleepMs) throws InterruptedException { + Thread.sleep(sleepMs); + } + + protected Thread getCurrentThread() { + return Thread.currentThread(); + } +} diff --git a/feature-test-transaction/src/main/java/org/onap/policy/drools/testtransaction/TtImpl.java b/feature-test-transaction/src/main/java/org/onap/policy/drools/testtransaction/TtImpl.java new file mode 100644 index 00000000..cc207d7b --- /dev/null +++ b/feature-test-transaction/src/main/java/org/onap/policy/drools/testtransaction/TtImpl.java @@ -0,0 +1,61 @@ +/* + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.drools.testtransaction; + +import java.util.HashMap; +import java.util.Map; +import org.onap.policy.drools.system.PolicyController; + +/** + * Implementation of TestTransaction interface. Controls the registering/unregistering of + * PolicyController objects and the management of their related TTControllerTask threads. + */ +public class TtImpl implements TestTransaction { + + protected final Map<String, TtControllerTask> controllers = new HashMap<>(); + + @Override + public synchronized void register(PolicyController controller) { + TtControllerTask controllerTask = this.controllers.get(controller.getName()); + if (controllerTask != null && controllerTask.isAlive()) { + return; + } + + // continue : unregister, register operation + + controllerTask = makeControllerTask(controller); + this.controllers.put(controller.getName(), controllerTask); + } + + @Override + public synchronized void unregister(PolicyController controller) { + final TtControllerTask controllerTask = this.controllers.remove(controller.getName()); + if (controllerTask != null) { + controllerTask.stop(); + } + } + + // these may be overridden by junit tests + + protected TtControllerTask makeControllerTask(PolicyController controller) { + return new TtControllerTask(controller); + } +} diff --git a/feature-test-transaction/src/test/java/org/onap/policy/drools/testtransaction/TestTransactionAdditionalTest.java b/feature-test-transaction/src/test/java/org/onap/policy/drools/testtransaction/TestTransactionAdditionalTest.java index 465b7aa0..23fdc215 100644 --- a/feature-test-transaction/src/test/java/org/onap/policy/drools/testtransaction/TestTransactionAdditionalTest.java +++ b/feature-test-transaction/src/test/java/org/onap/policy/drools/testtransaction/TestTransactionAdditionalTest.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * feature-test-transaction * ================================================================================ - * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -67,10 +67,10 @@ public class TestTransactionAdditionalTest { private long doSleepMs; private DroolsController drools; private PolicyContainer container; - private Map<String, TTControllerTask> name2task; - private TTControllerTask task; - private TTControllerTask task2; - private TTControllerTask task3; + private Map<String, TtControllerTask> name2task; + private TtControllerTask task; + private TtControllerTask task2; + private TtControllerTask task3; private TestTransTImplTester impl; /** @@ -87,8 +87,8 @@ public class TestTransactionAdditionalTest { doSleepMs = -1; drools = mock(DroolsController.class); container = mock(PolicyContainer.class); - task2 = mock(TTControllerTask.class); - task3 = mock(TTControllerTask.class); + task2 = mock(TtControllerTask.class); + task3 = mock(TtControllerTask.class); name2task = new TreeMap<>(); when(drools.getSessionNames()).thenReturn(sessions); @@ -119,12 +119,12 @@ public class TestTransactionAdditionalTest { @Test public void testTestTransactionImpl() { - assertNotNull(TTImpl.manager); + assertNotNull(TtImpl.manager); } @Test public void testTestTransactionImplRegister_testTestTransactionImplUnregister() { - task = mock(TTControllerTask.class); + task = mock(TtControllerTask.class); when(task.isAlive()).thenReturn(true); name2task.put(CONTROLLER1, task); @@ -163,7 +163,7 @@ public class TestTransactionAdditionalTest { @Test public void testTestTransactionControllerTaskFactory() throws Exception { - task = new TTControllerTask(controller) { + task = new TtControllerTask(controller) { @Override protected Thread makeThread(Runnable action) { return theThread; @@ -363,10 +363,10 @@ public class TestTransactionAdditionalTest { /** * TestTransaction with overridden methods. */ - private class TestTransTImplTester extends TTImpl { + private class TestTransTImplTester extends TtImpl { @Override - protected TTControllerTask makeControllerTask(PolicyController controller) { + protected TtControllerTask makeControllerTask(PolicyController controller) { return name2task.get(controller.getName()); } } @@ -374,7 +374,7 @@ public class TestTransactionAdditionalTest { /** * Controller task with overridden methods. */ - private class TestTransControllerTaskTester extends TTControllerTask { + private class TestTransControllerTaskTester extends TtControllerTask { private int sleepCount = MAX_SLEEP_COUNT; public TestTransControllerTaskTester(PolicyController controller) { diff --git a/feature-test-transaction/src/test/java/org/onap/policy/drools/testtransaction/TestTransactionTest.java b/feature-test-transaction/src/test/java/org/onap/policy/drools/testtransaction/TestTransactionTest.java index 40b1ff9d..e0779ba0 100644 --- a/feature-test-transaction/src/test/java/org/onap/policy/drools/testtransaction/TestTransactionTest.java +++ b/feature-test-transaction/src/test/java/org/onap/policy/drools/testtransaction/TestTransactionTest.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * feature-test-transaction * ================================================================================ - * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -80,10 +80,10 @@ public class TestTransactionTest { CountDownLatch latch = new CountDownLatch(1); // use our own impl so we can decrement the latch when run() completes - TTImpl impl = new TTImpl() { + TtImpl impl = new TtImpl() { @Override - protected TTControllerTask makeControllerTask(PolicyController controller) { - return new TTControllerTask(controller) { + protected TtControllerTask makeControllerTask(PolicyController controller) { + return new TtControllerTask(controller) { @Override public void run() { super.run(); |