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;
25 import org.onap.policy.apex.core.infrastructure.threading.ThreadUtilities;
26 import org.onap.policy.apex.service.engine.engdep.EngDepMessagingService;
27 import org.onap.policy.apex.service.engine.event.ApexEvent;
28 import org.onap.policy.apex.service.engine.runtime.ApexEventListener;
29 import org.onap.policy.apex.service.engine.runtime.EngineService;
30 import org.onap.policy.apex.service.engine.runtime.EngineServiceEventInterface;
31 import org.onap.policy.apex.service.engine.runtime.impl.EngineServiceImpl;
32 import org.onap.policy.apex.service.parameters.engineservice.EngineServiceParameters;
33 import org.slf4j.ext.XLogger;
34 import org.slf4j.ext.XLoggerFactory;
37 * The Class EngineTestServer is a test Apex service used to test the performance of Apex engines.
39 * @author Liam Fallon (liam.fallon@ericsson.com)
41 public class EngineTestServer implements Runnable, EngineServiceEventInterface {
42 private static final XLogger LOGGER = XLoggerFactory.getXLogger(EngineTestServer.class);
44 private static final int TEST_SERVER_WAIT_TIME = 200;
46 // The engine service for sending events to the Apex engines and the EngDEp service for engine
48 private EngineService engineService = null;
49 private EngDepMessagingService messageService = null;
51 // The inner class used to receive and process events
52 private TestApexListener testApexListener = null;
55 private boolean starting = true;
56 private boolean interrupted = false;
58 // Parameters for the test
59 private final EngineServiceParameters parameters;
61 // Apex performance statistics
62 private Date statsStartDate = null;
63 private long actionEventsReceivedCount = 0;
64 private long accumulatedExecutionTime = 0;
65 private long totalActionEventsReceivedCount = 0;
67 private ApexEvent lastEventReceived = null;
70 * Instantiates a new engine test server to test Apex performance.
72 * @param parameters the parameters
74 public EngineTestServer(final EngineServiceParameters parameters) {
75 this.parameters = parameters;
83 LOGGER.debug("engine<-->deployment test server starting . . .");
85 // Set the name of the test server thread
86 Thread.currentThread().setName(EngineTestServer.class.getName());
89 // Create the engine service and set the listener for events emitted by the Apex service
90 engineService = EngineServiceImpl.create(parameters);
91 testApexListener = new TestApexListener();
92 engineService.registerActionListener("testApexListener", testApexListener);
94 // Create the EngDep messaging service and start it
95 messageService = new EngDepMessagingService(engineService, parameters.getDeploymentPort());
96 messageService.start();
98 // Record the start date for statistics
99 statsStartDate = new Date();
100 } catch (final Exception e) {
101 LOGGER.error("engine<-->deployment test server exception", e);
105 LOGGER.debug("engine<-->deployment test server started");
109 while (!interrupted) {
110 if (!ThreadUtilities.sleep(TEST_SERVER_WAIT_TIME)) {
117 * Stop the test server.
119 public void stopServer() {
120 LOGGER.debug("engine<-->deployment test server stopping . . .");
123 messageService.stop();
125 LOGGER.debug("engine<-->deployment test server stopped");
129 * Checks if the test server is interrupted.
131 * @return true, if is interrupted
133 public boolean isInterrupted() {
138 * Gets the total action events received.
140 * @return the total action events received
142 public long getTotalActionEventsReceived() {
143 return totalActionEventsReceivedCount;
147 * Gets the last action events received.
149 * @return the last action event received
151 public ApexEvent getLastActionEvent() {
152 return lastEventReceived;
156 * Gets the Apex statistics and resets them.
158 * @return the statistics
160 public long[] getAndResetStats() {
161 // Check if we have statistics
162 if (statsStartDate == null || actionEventsReceivedCount == 0) {
166 // Calculate, save, and reset the statistics
167 final long[] stats = new long[2];
168 synchronized (statsStartDate) {
169 final long averageExecutionTime = accumulatedExecutionTime / actionEventsReceivedCount;
170 final long measuringTime = new Date().getTime() - statsStartDate.getTime();
171 final long transactionsPerMillisecond = actionEventsReceivedCount / measuringTime;
172 stats[0] = averageExecutionTime;
173 stats[1] = transactionsPerMillisecond;
174 statsStartDate = new Date();
176 actionEventsReceivedCount = 0;
177 accumulatedExecutionTime = 0;
180 // Return the statistics
185 * Checks if the test server is starting.
187 * @return true, if the server is starting
189 public boolean isStarting() {
197 public void sendEvent(final ApexEvent event) {
198 // Send the event onto the service being tested
199 engineService.getEngineServiceEventInterface().sendEvent(event);
203 * The listener interface for receiving testApex events. The class that is interested in processing a testApex event
204 * implements this interface, and the object created with that class is registered with a component using the
205 * component's {@code addTestApexListener} method. When the testApex event occurs, that object's appropriate method
208 * <p>This class listens for events from the Apex engine
212 private final class TestApexListener implements ApexEventListener {
218 public synchronized void onApexEvent(final ApexEvent apexEvent) {
219 LOGGER.debug("result is:" + apexEvent);
221 // Check the result event is correct
222 checkResult(apexEvent);
224 // Calculate the performance of the Apex engine service on this policy execution run and
225 // accumulate the total statistics
226 final Date testStartTime = new Date((Long) apexEvent.get("TestTimestamp"));
227 final Date testEndTime = new Date();
228 final long testTime = testEndTime.getTime() - testStartTime.getTime();
229 LOGGER.debug("policy execution time: " + testTime + "ms");
230 synchronized (statsStartDate) {
231 actionEventsReceivedCount++;
232 totalActionEventsReceivedCount++;
233 accumulatedExecutionTime += testTime;
235 lastEventReceived = apexEvent;
239 * Check that a reply event from the Apex engine is valid.
241 * @param result the result event from the Apex engine
243 private void checkResult(final ApexEvent result) {
244 assert result.getName().startsWith("Event0004") || result.getName().startsWith("Event0104");
246 // CHECKSTYLE:OFF: checkstyle:magicNumber
247 assert result.get("TestSlogan").equals("This is a test slogan");
248 assert result.get("TestMatchCase").equals((byte) 123);
249 assert result.get("TestTemperature").equals(34.5445667);
250 assert ((byte) result.get("TestMatchCaseSelected") >= 0 && (byte) result.get("TestMatchCaseSelected") <= 3);
251 assert ((byte) result.get("TestEstablishCaseSelected") >= 0
252 && (byte) result.get("TestEstablishCaseSelected") <= 3);
253 assert ((byte) result.get("TestDecideCaseSelected") >= 0
254 && (byte) result.get("TestDecideCaseSelected") <= 3);
255 assert ((byte) result.get("TestActCaseSelected") >= 0 && (byte) result.get("TestActCaseSelected") <= 3);
256 // CHECKSTYLE:ON: checkstyle:magicNumber