103704df21b119da0e25f3be6e2e976d5c0e9142
[policy/apex-pdp.git] / testsuites / integration / integration-uservice-test / src / test / java / org / onap / policy / apex / testsuites / integration / uservice / engdep / EngineTestServer.java
1 /*-
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
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
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.
17  *
18  * SPDX-License-Identifier: Apache-2.0
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.onap.policy.apex.testsuites.integration.uservice.engdep;
23
24 import java.util.Date;
25
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;
36
37 /**
38  * The Class EngineTestServer is a test Apex service used to test the performance of Apex engines.
39  *
40  * @author Liam Fallon (liam.fallon@ericsson.com)
41  */
42 public class EngineTestServer implements Runnable, EngineServiceEventInterface {
43     private static final XLogger LOGGER = XLoggerFactory.getXLogger(EngineTestServer.class);
44
45     private static final int TEST_SERVER_WAIT_TIME = 200;
46
47     // The engine service for sending events to the Apex engines and the EngDEp service for engine
48     // administration
49     private EngineService engineService = null;
50     private EngDepMessagingService messageService = null;
51
52     // The inner class used to receive and process events
53     private TestApexListener testApexListener = null;
54
55     // Status flags
56     private boolean starting = true;
57     private boolean interrupted = false;
58
59     // Parameters for the test
60     private final EngineServiceParameters parameters;
61
62     // Apex performance statistics
63     private Date statsStartDate = null;
64     private long actionEventsReceivedCount = 0;
65     private long accumulatedExecutionTime = 0;
66     private long totalActionEventsReceivedCount = 0;
67
68     private ApexEvent lastEventReceived = null;
69
70     /**
71      * Instantiates a new engine test server to test Apex performance.
72      *
73      * @param parameters the parameters
74      */
75     public EngineTestServer(final EngineServiceParameters parameters) {
76         this.parameters = parameters;
77     }
78
79     /**
80      * {@inheritDoc}.
81      */
82     @Override
83     public void run() {
84         LOGGER.debug("engine<-->deployment  test server starting . . .");
85
86         // Set the name of the test server thread
87         Thread.currentThread().setName(EngineTestServer.class.getName());
88
89         try {
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);
94
95             // Create the EngDep messaging service and start it
96             messageService = new EngDepMessagingService(engineService, parameters.getDeploymentPort());
97             messageService.start();
98
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);
103             e.printStackTrace();
104             return;
105         }
106         LOGGER.debug("engine<-->deployment test server started");
107
108         starting = false;
109
110         while (!interrupted) {
111             if (!ThreadUtilities.sleep(TEST_SERVER_WAIT_TIME)) {
112                 interrupted = true;
113             }
114         }
115     }
116
117     /**
118      * Stop the test server.
119      */
120     public void stopServer() {
121         LOGGER.debug("engine<-->deployment test server stopping . . .");
122
123         interrupted = true;
124         messageService.stop();
125
126         LOGGER.debug("engine<-->deployment test server stopped");
127     }
128
129     /**
130      * Checks if the test server is interrupted.
131      *
132      * @return true, if is interrupted
133      */
134     public boolean isInterrupted() {
135         return interrupted;
136     }
137
138     /**
139      * Gets the total action events received.
140      *
141      * @return the total action events received
142      */
143     public long getTotalActionEventsReceived() {
144         return totalActionEventsReceivedCount;
145     }
146
147     /**
148      * Gets the last action events received.
149      *
150      * @return the last action event received
151      */
152     public ApexEvent getLastActionEvent() {
153         return lastEventReceived;
154     }
155
156     /**
157      * Gets the Apex statistics and resets them.
158      *
159      * @return the statistics
160      */
161     public long[] getAndResetStats() {
162         // Check if we have statistics
163         if (statsStartDate == null || actionEventsReceivedCount == 0) {
164             return null;
165         }
166
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();
176
177             actionEventsReceivedCount = 0;
178             accumulatedExecutionTime = 0;
179         }
180
181         // Return the statistics
182         return stats;
183     }
184
185     /**
186      * Checks if the test server is starting.
187      *
188      * @return true, if the server is starting
189      */
190     public boolean isStarting() {
191         return starting;
192     }
193
194     /**
195      * {@inheritDoc}.
196      */
197     @Override
198     public void sendEvent(final ApexEvent event) {
199         // Send the event onto the service being tested
200         engineService.getEngineServiceEventInterface().sendEvent(event);
201     }
202
203     /**
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
207      * is invoked.
208      *
209      * <p>This class listens for events from the Apex engine
210      *
211      * @see TestApexEvent
212      */
213     private final class TestApexListener implements ApexEventListener {
214
215         /**
216          * {@inheritDoc}.
217          */
218         @Override
219         public synchronized void onApexEvent(final ApexEvent apexEvent) {
220             LOGGER.debug("result is:" + apexEvent);
221
222             // Check the result event is correct
223             checkResult(apexEvent);
224
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;
235             }
236             lastEventReceived = apexEvent;
237         }
238
239         /**
240          * Check that a reply event from the Apex engine is valid.
241          *
242          * @param result the result event from the Apex engine
243          */
244         private void checkResult(final ApexEvent result) {
245             assert result.getName().startsWith("Event0004") || result.getName().startsWith("Event0104");
246
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
258         }
259     }
260 }