2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2016-2018 Ericsson. All rights reserved.
4 * Modifications Copyright (C) 2019 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.context.locking;
24 import com.google.gson.Gson;
25 import java.net.InetAddress;
26 import java.net.NetworkInterface;
27 import java.net.SocketException;
28 import java.util.ArrayList;
29 import java.util.Arrays;
30 import java.util.Collections;
31 import java.util.Enumeration;
32 import java.util.List;
33 import java.util.Map.Entry;
34 import java.util.TreeSet;
35 import java.util.concurrent.ExecutorService;
36 import java.util.concurrent.Future;
37 import java.util.concurrent.TimeUnit;
38 import org.onap.policy.apex.context.ContextAlbum;
39 import org.onap.policy.apex.context.Distributor;
40 import org.onap.policy.apex.model.basicmodel.concepts.ApexException;
41 import org.onap.policy.apex.model.basicmodel.concepts.ApexRuntimeException;
42 import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
43 import org.onap.policy.apex.testsuites.integration.context.utils.ConfigrationProvider;
44 import org.onap.policy.apex.testsuites.integration.context.utils.ConfigrationProviderImpl;
45 import org.onap.policy.apex.testsuites.integration.context.utils.Constants;
46 import org.onap.policy.common.parameters.ParameterGroup;
47 import org.onap.policy.common.parameters.ParameterService;
48 import org.slf4j.ext.XLogger;
49 import org.slf4j.ext.XLoggerFactory;
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 ExecutorService executorService;
67 private final ConfigrationProvider configrationProvider;
69 private ConcurrentContextJvm(final int jvmNo, final ConfigrationProvider configrationProvider) {
71 this.configrationProvider = configrationProvider;
72 final String name = configrationProvider.getTestName() + ":ConcurrentContextThread_" + jvmNo;
73 this.executorService = configrationProvider.getExecutorService(name, configrationProvider.getThreadCount());
77 * This method executes the test of concurrent use of context in a single JVM.
79 * @throws ApexException the Apex exception occurs while running the test
81 public void execute() throws ApexException {
82 LOGGER.debug("starting JVMs and threads . . .");
84 final AxArtifactKey distributorKey = new AxArtifactKey("ApexDistributor" + jvmNo, "0.0.1");
85 final Distributor distributor = configrationProvider.getDistributor(distributorKey);
86 final ContextAlbum contextAlbum = configrationProvider.getContextAlbum(distributor);
87 assert (contextAlbum != null);
89 final List<Future<?>> tasks = new ArrayList<>(configrationProvider.getThreadCount());
91 for (int t = 0; t < configrationProvider.getThreadCount(); t++) {
92 tasks.add(executorService.submit(new ConcurrentContextThread(jvmNo, t, configrationProvider)));
96 executorService.shutdown();
97 // wait for threads to finish, if not Timeout
98 executorService.awaitTermination(10, TimeUnit.MINUTES);
99 } catch (final InterruptedException interruptedException) {
100 LOGGER.error("Exception while waiting for threads to finish", interruptedException);
101 // restore the interrupt status
102 Thread.currentThread().interrupt();
105 LOGGER.debug("threads finished, end value is {}", contextAlbum.get(Constants.TEST_VALUE));
109 LOGGER.info("Shutting down now ... ");
110 executorService.shutdownNow();
118 * @param args the args
119 * @throws Exception Any exception thrown by the test code
121 @SuppressWarnings("unchecked")
122 public static void main(final String[] args) throws Exception {
125 LOGGER.info("JVM Arguments: " + Arrays.toString(args));
126 // CHECKSTYLE:OFF: checkstyle:magicNumber
128 // An even number of arguments greater than 3
129 if (args.length < 9) {
130 LOGGER.error("invalid arguments: " + Arrays.toString(args));
131 LOGGER.error("usage: TestConcurrentContextJVM testType jvmNo threadCount threadLoops albumSize "
132 + "lockType [parameterKey parameterJson].... ");
137 final String testName = getStringValue("testType", args, 0);
138 final int jvmNo = getIntValue("jvmNo", args, 1);
139 final int threadCount = getIntValue("threadCount", args, 2);
140 final int threadLoops = getIntValue("threadLoops", args, 3);
141 final int albumSize = getIntValue("albumSize", args, 4);
142 final int lockType = getIntValue("lockType", args, 5);
143 final String hazelCastfileLocation = getStringValue("hazelcast file location", args, 6);
145 System.setProperty("hazelcast.config", hazelCastfileLocation);
147 for (int p = 7; p < args.length - 1; p += 2) {
148 @SuppressWarnings("rawtypes")
149 final Class parametersClass = Class.forName(args[p]);
150 final ParameterGroup parameters = (ParameterGroup) new Gson().fromJson(args[p + 1], parametersClass);
151 ParameterService.register(parameters);
154 for (final Entry<String, ParameterGroup> parameterEntry : ParameterService.getAll()) {
155 LOGGER.info("Parameter class " + parameterEntry.getKey() + "=" + parameterEntry.getValue().toString());
159 final ConfigrationProvider configrationProvider =
160 new ConfigrationProviderImpl(testName, 1, threadCount, threadLoops, albumSize, lockType);
161 final ConcurrentContextJvm concurrentContextJvm = new ConcurrentContextJvm(jvmNo, configrationProvider);
162 concurrentContextJvm.execute();
164 } catch (final Exception e) {
165 LOGGER.error("error running test in JVM", e);
167 // CHECKSTYLE:ON: checkstyle:magicNumber
170 private static String getStringValue(final String key, final String[] args, final int position) {
172 return args[position];
173 } catch (final Exception e) {
174 final String msg = "invalid argument " + key;
175 LOGGER.error(msg, e);
176 throw new ApexRuntimeException(msg, e);
180 private static int getIntValue(final String key, final String[] args, final int position) {
181 final String value = getStringValue(key, args, position);
183 return Integer.parseInt(value);
184 } catch (final Exception e) {
185 final String msg = "Expects number found " + value;
186 LOGGER.error(msg, e);
187 throw new ApexRuntimeException(msg, e);
193 * This method sets up any static configuration required by the JVM.
195 * @throws ApexException on configuration errors
197 public static void configure() throws ApexException {
198 System.setProperty("java.net.preferIPv4Stack", "true");
199 // The JGroups IP address must be set to a real (not loopback) IP address for Infinispan to
202 // the JVMs in a test pick up the same IP address, this function sets te address to be the
203 // first non-loopback
206 final TreeSet<String> ipAddressSet = new TreeSet<>();
208 Enumeration<NetworkInterface> nets;
210 nets = NetworkInterface.getNetworkInterfaces();
211 } catch (final SocketException e) {
212 throw new ApexException("cound not get network interfaces for test", e);
215 for (final NetworkInterface netint : Collections.list(nets)) {
216 final Enumeration<InetAddress> inetAddresses = netint.getInetAddresses();
217 for (final InetAddress inetAddress : Collections.list(inetAddresses)) {
218 // Look for real IPv4 Internet addresses
219 if (!inetAddress.isLoopbackAddress() && inetAddress.getAddress().length == IPV4_ADDRESS_LENGTH) {
220 ipAddressSet.add(inetAddress.getHostAddress());
225 if (ipAddressSet.isEmpty()) {
226 throw new ApexException("cound not find real IP address for test");
228 LOGGER.info("Setting jgroups.tcp.address to: " + ipAddressSet.first());
229 System.setProperty("jgroups.tcp.address", ipAddressSet.first());