2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2016-2018 Ericsson. All rights reserved.
4 * Modifications Copyright (C) 2020 Nordix Foundation.
5 * ================================================================================
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 * SPDX-License-Identifier: Apache-2.0
19 * ============LICENSE_END=========================================================
22 package org.onap.policy.apex.testsuites.integration.uservice.engdep;
24 import java.util.Date;
26 import org.onap.policy.apex.core.infrastructure.threading.ThreadUtilities;
27 import org.onap.policy.apex.service.engine.engdep.EngDepMessagingService;
28 import org.onap.policy.apex.service.engine.event.ApexEvent;
29 import org.onap.policy.apex.service.engine.runtime.ApexEventListener;
30 import org.onap.policy.apex.service.engine.runtime.EngineService;
31 import org.onap.policy.apex.service.engine.runtime.EngineServiceEventInterface;
32 import org.onap.policy.apex.service.engine.runtime.impl.EngineServiceImpl;
33 import org.onap.policy.apex.service.parameters.engineservice.EngineServiceParameters;
34 import org.slf4j.ext.XLogger;
35 import org.slf4j.ext.XLoggerFactory;
38 * The Class EngineTestServer is a test Apex service used to test the performance of Apex engines.
40 * @author Liam Fallon (liam.fallon@ericsson.com)
42 public class EngineTestServer implements Runnable, EngineServiceEventInterface {
43 private static final XLogger LOGGER = XLoggerFactory.getXLogger(EngineTestServer.class);
45 private static final int TEST_SERVER_WAIT_TIME = 200;
47 // The engine service for sending events to the Apex engines and the EngDEp service for engine
49 private EngineService engineService = null;
50 private EngDepMessagingService messageService = null;
52 // The inner class used to receive and process events
53 private TestApexListener testApexListener = null;
56 private boolean starting = true;
57 private boolean interrupted = false;
59 // Parameters for the test
60 private final EngineServiceParameters parameters;
62 // Apex performance statistics
63 private Date statsStartDate = null;
64 private long actionEventsReceivedCount = 0;
65 private long accumulatedExecutionTime = 0;
66 private long totalActionEventsReceivedCount = 0;
68 private ApexEvent lastEventReceived = null;
71 * Instantiates a new engine test server to test Apex performance.
73 * @param parameters the parameters
75 public EngineTestServer(final EngineServiceParameters parameters) {
76 this.parameters = parameters;
84 LOGGER.debug("engine<-->deployment test server starting . . .");
86 // Set the name of the test server thread
87 Thread.currentThread().setName(EngineTestServer.class.getName());
90 // Create the engine service and set the listener for events emitted by the Apex service
91 engineService = EngineServiceImpl.create(parameters);
92 testApexListener = new TestApexListener();
93 engineService.registerActionListener("testApexListener", testApexListener);
95 // Create the EngDep messaging service and start it
96 messageService = new EngDepMessagingService(engineService, parameters.getDeploymentPort());
97 messageService.start();
99 // Record the start date for statistics
100 statsStartDate = new Date();
101 } catch (final Exception e) {
102 LOGGER.error("engine<-->deployment test server exception", e);
106 LOGGER.debug("engine<-->deployment test server started");
110 while (!interrupted) {
111 if (!ThreadUtilities.sleep(TEST_SERVER_WAIT_TIME)) {
118 * Stop the test server.
120 public void stopServer() {
121 LOGGER.debug("engine<-->deployment test server stopping . . .");
124 messageService.stop();
126 LOGGER.debug("engine<-->deployment test server stopped");
130 * Checks if the test server is interrupted.
132 * @return true, if is interrupted
134 public boolean isInterrupted() {
139 * Gets the total action events received.
141 * @return the total action events received
143 public long getTotalActionEventsReceived() {
144 return totalActionEventsReceivedCount;
148 * Gets the last action events received.
150 * @return the last action event received
152 public ApexEvent getLastActionEvent() {
153 return lastEventReceived;
157 * Gets the Apex statistics and resets them.
159 * @return the statistics
161 public long[] getAndResetStats() {
162 // Check if we have statistics
163 if (statsStartDate == null || actionEventsReceivedCount == 0) {
167 // Calculate, save, and reset the statistics
168 final long[] stats = new long[2];
169 synchronized (statsStartDate) {
170 final long averageExecutionTime = accumulatedExecutionTime / actionEventsReceivedCount;
171 final long measuringTime = new Date().getTime() - statsStartDate.getTime();
172 final long transactionsPerMillisecond = actionEventsReceivedCount / measuringTime;
173 stats[0] = averageExecutionTime;
174 stats[1] = transactionsPerMillisecond;
175 statsStartDate = new Date();
177 actionEventsReceivedCount = 0;
178 accumulatedExecutionTime = 0;
181 // Return the statistics
186 * Checks if the test server is starting.
188 * @return true, if the server is starting
190 public boolean isStarting() {
198 public void sendEvent(final ApexEvent event) {
199 // Send the event onto the service being tested
200 engineService.getEngineServiceEventInterface().sendEvent(event);
204 * The listener interface for receiving testApex events. The class that is interested in processing a testApex event
205 * implements this interface, and the object created with that class is registered with a component using the
206 * component's {@code addTestApexListener} method. When the testApex event occurs, that object's appropriate method
209 * <p>This class listens for events from the Apex engine
213 private final class TestApexListener implements ApexEventListener {
219 public synchronized void onApexEvent(final ApexEvent apexEvent) {
220 LOGGER.debug("result is:" + apexEvent);
222 // Check the result event is correct
223 checkResult(apexEvent);
225 // Calculate the performance of the Apex engine service on this policy execution run and
226 // accumulate the total statistics
227 final Date testStartTime = new Date((Long) apexEvent.get("TestTimestamp"));
228 final Date testEndTime = new Date();
229 final long testTime = testEndTime.getTime() - testStartTime.getTime();
230 LOGGER.debug("policy execution time: " + testTime + "ms");
231 synchronized (statsStartDate) {
232 actionEventsReceivedCount++;
233 totalActionEventsReceivedCount++;
234 accumulatedExecutionTime += testTime;
236 lastEventReceived = apexEvent;
240 * Check that a reply event from the Apex engine is valid.
242 * @param result the result event from the Apex engine
244 private void checkResult(final ApexEvent result) {
245 assert result.getName().startsWith("Event0004") || result.getName().startsWith("Event0104");
247 // CHECKSTYLE:OFF: checkstyle:magicNumber
248 assert result.get("TestSlogan").equals("This is a test slogan");
249 assert result.get("TestMatchCase").equals((byte) 123);
250 assert result.get("TestTemperature").equals(34.5445667);
251 assert ((byte) result.get("TestMatchCaseSelected") >= 0 && (byte) result.get("TestMatchCaseSelected") <= 3);
252 assert ((byte) result.get("TestEstablishCaseSelected") >= 0
253 && (byte) result.get("TestEstablishCaseSelected") <= 3);
254 assert ((byte) result.get("TestDecideCaseSelected") >= 0
255 && (byte) result.get("TestDecideCaseSelected") <= 3);
256 assert ((byte) result.get("TestActCaseSelected") >= 0 && (byte) result.get("TestActCaseSelected") <= 3);
257 // CHECKSTYLE:ON: checkstyle:magicNumber