e2a6b0da098e5b019dd2e86138097c73deb0990d
[policy/apex-pdp.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
4  * ================================================================================
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * SPDX-License-Identifier: Apache-2.0
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.policy.apex.context.test.locking;
22
23 import java.net.InetAddress;
24 import java.net.NetworkInterface;
25 import java.util.ArrayList;
26 import java.util.Arrays;
27 import java.util.Collections;
28 import java.util.Enumeration;
29 import java.util.List;
30 import java.util.Map.Entry;
31 import java.util.TreeSet;
32 import java.util.concurrent.ExecutorService;
33 import java.util.concurrent.Executors;
34 import java.util.concurrent.Future;
35 import java.util.concurrent.TimeUnit;
36
37 import org.onap.policy.apex.context.ContextAlbum;
38 import org.onap.policy.apex.context.Distributor;
39 import org.onap.policy.apex.context.impl.distribution.DistributorFactory;
40 import org.onap.policy.apex.context.test.factory.TestContextAlbumFactory;
41 import org.onap.policy.apex.context.test.utils.IntegrationThreadFactory;
42 import org.onap.policy.apex.model.basicmodel.concepts.ApexException;
43 import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
44 import org.onap.policy.apex.model.basicmodel.service.AbstractParameters;
45 import org.onap.policy.apex.model.basicmodel.service.ParameterService;
46 import org.onap.policy.apex.model.contextmodel.concepts.AxContextModel;
47 import org.slf4j.ext.XLogger;
48 import org.slf4j.ext.XLoggerFactory;
49
50 import com.google.gson.Gson;
51
52 /**
53  * The Class ConcurrentContextJVM tests concurrent use of context in a single JVM.
54  *
55  * @author Liam Fallon (liam.fallon@ericsson.com)
56  */
57 public final class ConcurrentContextJVM {
58     // Logger for this class
59     private static final XLogger LOGGER = XLoggerFactory.getXLogger(ConcurrentContextJVM.class);
60
61     private static final int IPV4_ADDRESS_LENGTH = 4;
62
63     private final int jvmNo;
64
65     private final int threadCount;
66
67     private final int threadLoops;
68
69     private final ExecutorService executorService;
70
71     /**
72      * The Constructor.
73      *
74      * @param testType the test type
75      * @param jvmNo the jvm no
76      * @param threadCount the thread count
77      * @param threadLoops the thread loops
78      * @throws ApexException the apex exception
79      */
80     private ConcurrentContextJVM(final String testType, final int jvmNo, final int threadCount, final int threadLoops) {
81         this.jvmNo = jvmNo;
82         this.threadCount = threadCount;
83         this.threadLoops = threadLoops;
84         final String name = testType + ":ConcurrentContextThread_" + jvmNo;
85         this.executorService = Executors.newFixedThreadPool(threadCount, new IntegrationThreadFactory(name));
86     }
87
88     public void execute() throws ApexException {
89         LOGGER.debug("starting JVMs and threads . . .");
90
91         final AxArtifactKey distributorKey = new AxArtifactKey("ApexDistributor" + jvmNo, "0.0.1");
92         final Distributor contextDistributor = new DistributorFactory().getDistributor(distributorKey);
93
94         // @formatter:off
95         final AxArtifactKey[] usedArtifactStackArray = {
96                 new AxArtifactKey("testC-top", "0.0.1"),
97                 new AxArtifactKey("testC-next", "0.0.1"),
98                 new AxArtifactKey("testC-bot", "0.0.1")
99                 };
100         // @formatter:on
101
102         final AxContextModel albumsModel = TestContextAlbumFactory.createMultiAlbumsContextModel();
103         contextDistributor.registerModel(albumsModel);
104
105         final ContextAlbum lTypeAlbum =
106                 contextDistributor.createContextAlbum(new AxArtifactKey("LTypeContextAlbum", "0.0.1"));
107         assert (lTypeAlbum != null);
108         lTypeAlbum.setUserArtifactStack(usedArtifactStackArray);
109
110         final List<Future<?>> tasks = new ArrayList<>(threadCount);
111
112         for (int t = 0; t < threadCount; t++) {
113             tasks.add(executorService.submit(new ConcurrentContextThread(jvmNo, t, threadLoops)));
114         }
115
116         try {
117             executorService.shutdown();
118             // wait for threads to finish, if not Timeout
119             executorService.awaitTermination(10, TimeUnit.MINUTES);
120         } catch (final InterruptedException interruptedException) {
121             LOGGER.error("Exception while waiting for threads to finish", interruptedException);
122             // restore the interrupt status
123             Thread.currentThread().interrupt();
124         }
125
126         LOGGER.debug("threads finished, end value is {}", lTypeAlbum.get("testValue"));
127         contextDistributor.clear();
128         LOGGER.info("Shutting down now ... ");
129         executorService.shutdownNow();
130     }
131
132
133
134     /**
135      * The main method.
136      *
137      * @param args the args
138      * @throws Exception Any exception thrown by the test code
139      */
140     @SuppressWarnings("unchecked")
141     public static void main(final String[] args) throws Exception {
142         configure();
143
144         System.out.println("JVM Arguments: " + Arrays.toString(args));
145         // CHECKSTYLE:OFF: checkstyle:magicNumber
146
147         // An even number of arguments greater than 3
148         if (args.length < 7) {
149             LOGGER.error("invalid arguments: " + Arrays.toString(args));
150             LOGGER.error(
151                     "usage: TestConcurrentContextJVM testType jvmNo threadCount threadLoops [parameterKey parameterJson].... ");
152             return;
153         }
154
155         int jvmNo = -1;
156         int threadCount = -1;
157         int threadLoops = -1;
158         String hazelCastfileLocation = null;
159
160         try {
161             jvmNo = Integer.parseInt(args[1]);
162         } catch (final Exception e) {
163             LOGGER.error("invalid argument jvmNo", e);
164             return;
165         }
166
167         try {
168             threadCount = Integer.parseInt(args[2]);
169         } catch (final Exception e) {
170             LOGGER.error("invalid argument threadCount", e);
171             return;
172         }
173
174         try {
175             threadLoops = Integer.parseInt(args[3]);
176         } catch (final Exception e) {
177             LOGGER.error("invalid argument threadLoops", e);
178             return;
179         }
180
181         try {
182             hazelCastfileLocation = args[4].trim();
183         } catch (final Exception e) {
184             LOGGER.error("invalid argument hazelcast file location", e);
185             return;
186         }
187
188         System.setProperty("hazelcast.config", hazelCastfileLocation);
189
190         for (int p = 5; p < args.length - 1; p += 2) {
191             @SuppressWarnings("rawtypes")
192             final Class parametersClass = Class.forName(args[p]);
193             final AbstractParameters parameters =
194                     (AbstractParameters) new Gson().fromJson(args[p + 1], parametersClass);
195             ParameterService.registerParameters(parametersClass, parameters);
196         }
197
198         for (final Entry<Class<?>, AbstractParameters> parameterEntry : ParameterService.getAll()) {
199             LOGGER.info("Parameter class " + parameterEntry.getKey().getCanonicalName() + "="
200                     + parameterEntry.getValue().toString());
201         }
202
203         try {
204             final ConcurrentContextJVM concurrentContextJVM =
205                     new ConcurrentContextJVM(args[0], jvmNo, threadCount, threadLoops);
206             concurrentContextJVM.execute();
207
208         } catch (final Exception e) {
209             LOGGER.error("error running test in JVM", e);
210             return;
211         }
212         // CHECKSTYLE:ON: checkstyle:magicNumber
213
214
215     }
216
217     /**
218      * This method setus up any static configuration required by the JVM.
219      *
220      * @throws Exception on configuration errors
221      */
222     public static void configure() throws Exception {
223         System.setProperty("java.net.preferIPv4Stack", "true");
224         // The JGroups IP address must be set to a real (not loopback) IP address for Infinispan to
225         // work. IN order to
226         // ensure that all
227         // the JVMs in a test pick up the same IP address, this function sets te address to be the
228         // first non-loopback
229         // IPv4 address
230         // on a host
231         final TreeSet<String> ipAddressSet = new TreeSet<String>();
232
233         final Enumeration<NetworkInterface> nets = NetworkInterface.getNetworkInterfaces();
234         for (final NetworkInterface netint : Collections.list(nets)) {
235             final Enumeration<InetAddress> inetAddresses = netint.getInetAddresses();
236             for (final InetAddress inetAddress : Collections.list(inetAddresses)) {
237                 // Look for real IPv4 Internet addresses
238                 if (!inetAddress.isLoopbackAddress() && inetAddress.getAddress().length == IPV4_ADDRESS_LENGTH) {
239                     ipAddressSet.add(inetAddress.getHostAddress());
240                 }
241             }
242         }
243
244         if (ipAddressSet.size() == 0) {
245             throw new Exception("cound not find real IP address for test");
246         }
247         System.out.println("Setting jgroups.tcp.address to: " + ipAddressSet.first());
248         System.setProperty("jgroups.tcp.address", ipAddressSet.first());
249     }
250 }