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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 * SPDX-License-Identifier: Apache-2.0
18 * ============LICENSE_END=========================================================
21 package org.onap.policy.apex.context.test.locking;
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;
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;
50 import com.google.gson.Gson;
53 * The Class ConcurrentContextJVM tests concurrent use of context in a single JVM.
55 * @author Liam Fallon (liam.fallon@ericsson.com)
57 public final class ConcurrentContextJVM {
58 // Logger for this class
59 private static final XLogger LOGGER = XLoggerFactory.getXLogger(ConcurrentContextJVM.class);
61 private static final int IPV4_ADDRESS_LENGTH = 4;
63 private final int jvmNo;
65 private final int threadCount;
67 private final int threadLoops;
69 private final ExecutorService executorService;
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
80 private ConcurrentContextJVM(final String testType, final int jvmNo, final int threadCount, final int threadLoops) {
82 this.threadCount = threadCount;
83 this.threadLoops = threadLoops;
84 final String name = testType + ":ConcurrentContextThread_" + jvmNo;
85 this.executorService = Executors.newFixedThreadPool(threadCount, new IntegrationThreadFactory(name));
88 public void execute() throws ApexException {
89 LOGGER.debug("starting JVMs and threads . . .");
91 final AxArtifactKey distributorKey = new AxArtifactKey("ApexDistributor" + jvmNo, "0.0.1");
92 final Distributor contextDistributor = new DistributorFactory().getDistributor(distributorKey);
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")
102 final AxContextModel albumsModel = TestContextAlbumFactory.createMultiAlbumsContextModel();
103 contextDistributor.registerModel(albumsModel);
105 final ContextAlbum lTypeAlbum =
106 contextDistributor.createContextAlbum(new AxArtifactKey("LTypeContextAlbum", "0.0.1"));
107 assert (lTypeAlbum != null);
108 lTypeAlbum.setUserArtifactStack(usedArtifactStackArray);
110 final List<Future<?>> tasks = new ArrayList<>(threadCount);
112 for (int t = 0; t < threadCount; t++) {
113 tasks.add(executorService.submit(new ConcurrentContextThread(jvmNo, t, threadLoops)));
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();
126 LOGGER.debug("threads finished, end value is {}", lTypeAlbum.get("testValue"));
127 contextDistributor.clear();
128 LOGGER.info("Shutting down now ... ");
129 executorService.shutdownNow();
137 * @param args the args
138 * @throws Exception Any exception thrown by the test code
140 @SuppressWarnings("unchecked")
141 public static void main(final String[] args) throws Exception {
144 System.out.println("JVM Arguments: " + Arrays.toString(args));
145 // CHECKSTYLE:OFF: checkstyle:magicNumber
147 // An even number of arguments greater than 3
148 if (args.length < 7) {
149 LOGGER.error("invalid arguments: " + Arrays.toString(args));
151 "usage: TestConcurrentContextJVM testType jvmNo threadCount threadLoops [parameterKey parameterJson].... ");
156 int threadCount = -1;
157 int threadLoops = -1;
158 String hazelCastfileLocation = null;
161 jvmNo = Integer.parseInt(args[1]);
162 } catch (final Exception e) {
163 LOGGER.error("invalid argument jvmNo", e);
168 threadCount = Integer.parseInt(args[2]);
169 } catch (final Exception e) {
170 LOGGER.error("invalid argument threadCount", e);
175 threadLoops = Integer.parseInt(args[3]);
176 } catch (final Exception e) {
177 LOGGER.error("invalid argument threadLoops", e);
182 hazelCastfileLocation = args[4].trim();
183 } catch (final Exception e) {
184 LOGGER.error("invalid argument hazelcast file location", e);
188 System.setProperty("hazelcast.config", hazelCastfileLocation);
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);
198 for (final Entry<Class<?>, AbstractParameters> parameterEntry : ParameterService.getAll()) {
199 LOGGER.info("Parameter class " + parameterEntry.getKey().getCanonicalName() + "="
200 + parameterEntry.getValue().toString());
204 final ConcurrentContextJVM concurrentContextJVM =
205 new ConcurrentContextJVM(args[0], jvmNo, threadCount, threadLoops);
206 concurrentContextJVM.execute();
208 } catch (final Exception e) {
209 LOGGER.error("error running test in JVM", e);
212 // CHECKSTYLE:ON: checkstyle:magicNumber
218 * This method setus up any static configuration required by the JVM.
220 * @throws Exception on configuration errors
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
227 // the JVMs in a test pick up the same IP address, this function sets te address to be the
228 // first non-loopback
231 final TreeSet<String> ipAddressSet = new TreeSet<String>();
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());
244 if (ipAddressSet.size() == 0) {
245 throw new Exception("cound not find real IP address for test");
247 System.out.println("Setting jgroups.tcp.address to: " + ipAddressSet.first());
248 System.setProperty("jgroups.tcp.address", ipAddressSet.first());