cd2c2ed1f1ddad8bbb52c8da3b1680d7b54c4428
[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 com.google.gson.Gson;
24
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
39 import org.onap.policy.apex.context.ContextAlbum;
40 import org.onap.policy.apex.context.Distributor;
41 import org.onap.policy.apex.context.test.utils.ConfigrationProvider;
42 import org.onap.policy.apex.context.test.utils.ConfigrationProviderImpl;
43 import org.onap.policy.apex.context.test.utils.Constants;
44 import org.onap.policy.apex.model.basicmodel.concepts.ApexException;
45 import org.onap.policy.apex.model.basicmodel.concepts.ApexRuntimeException;
46 import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
47 import org.onap.policy.common.parameters.ParameterGroup;
48 import org.onap.policy.common.parameters.ParameterService;
49 import org.slf4j.ext.XLogger;
50 import org.slf4j.ext.XLoggerFactory;
51
52
53 /**
54  * The Class ConcurrentContextJVM tests concurrent use of context in a single JVM.
55  *
56  * @author Liam Fallon (liam.fallon@ericsson.com)
57  */
58 public final class ConcurrentContextJvm {
59     // Logger for this class
60     private static final XLogger LOGGER = XLoggerFactory.getXLogger(ConcurrentContextJvm.class);
61
62     private static final int IPV4_ADDRESS_LENGTH = 4;
63
64     private final int jvmNo;
65
66     private final ExecutorService executorService;
67
68     private final ConfigrationProvider configrationProvider;
69
70     private ConcurrentContextJvm(final int jvmNo, final ConfigrationProvider configrationProvider) {
71         this.jvmNo = jvmNo;
72         this.configrationProvider = configrationProvider;
73         final String name = configrationProvider.getTestName() + ":ConcurrentContextThread_" + jvmNo;
74         this.executorService = configrationProvider.getExecutorService(name, configrationProvider.getThreadCount());
75     }
76
77     /**
78      * 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
80      */
81     public void execute() throws ApexException {
82         LOGGER.debug("starting JVMs and threads . . .");
83
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);
88
89         final List<Future<?>> tasks = new ArrayList<>(configrationProvider.getThreadCount());
90
91         for (int t = 0; t < configrationProvider.getThreadCount(); t++) {
92             tasks.add(executorService.submit(new ConcurrentContextThread(jvmNo, t, configrationProvider)));
93         }
94
95         try {
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();
103         }
104
105         LOGGER.debug("threads finished, end value is {}", contextAlbum.get(Constants.TEST_VALUE));
106         distributor.clear();
107         LOGGER.info("Shutting down now ... ");
108         executorService.shutdownNow();
109     }
110
111
112
113     /**
114      * The main method.
115      *
116      * @param args the args
117      * @throws Exception Any exception thrown by the test code
118      */
119     @SuppressWarnings("unchecked")
120     public static void main(final String[] args) throws Exception {
121         configure();
122
123         LOGGER.info("JVM Arguments: " + Arrays.toString(args));
124         // CHECKSTYLE:OFF: checkstyle:magicNumber
125
126         // An even number of arguments greater than 3
127         if (args.length < 9) {
128             LOGGER.error("invalid arguments: " + Arrays.toString(args));
129             LOGGER.error("usage: TestConcurrentContextJVM testType jvmNo threadCount threadLoops albumSize "
130                     + "lockType [parameterKey parameterJson].... ");
131             return;
132         }
133
134
135         final String testName = getStringValue("testType", args, 0);
136         final int jvmNo = getIntValue("jvmNo", args, 1);
137         final int threadCount = getIntValue("threadCount", args, 2);
138         final int threadLoops = getIntValue("threadLoops", args, 3);
139         final int albumSize = getIntValue("albumSize", args, 4);
140         final int lockType = getIntValue("lockType", args, 5);
141         final String hazelCastfileLocation = getStringValue("hazelcast file location", args, 6);
142
143         System.setProperty("hazelcast.config", hazelCastfileLocation);
144
145         for (int p = 7; p < args.length - 1; p += 2) {
146             @SuppressWarnings("rawtypes")
147             final Class parametersClass = Class.forName(args[p]);
148             final ParameterGroup parameters =
149                     (ParameterGroup) new Gson().fromJson(args[p + 1], parametersClass);
150             ParameterService.register(parameters);
151         }
152
153         for (final Entry<String, ParameterGroup> parameterEntry : ParameterService.getAll()) {
154             LOGGER.info("Parameter class " + parameterEntry.getKey() + "="
155                     + parameterEntry.getValue().toString());
156         }
157
158         try {
159             final ConfigrationProvider configrationProvider =
160                     new ConfigrationProviderImpl(testName, 1, threadCount, threadLoops, albumSize, lockType);
161             final ConcurrentContextJvm concurrentContextJvm = new ConcurrentContextJvm(jvmNo, configrationProvider);
162             concurrentContextJvm.execute();
163
164         } catch (final Exception e) {
165             LOGGER.error("error running test in JVM", e);
166         }
167         // CHECKSTYLE:ON: checkstyle:magicNumber
168     }
169
170     private static String getStringValue(final String key, final String[] args, final int position) {
171         try {
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);
177         }
178     }
179
180     private static int getIntValue(final String key, final String[] args, final int position) {
181         final String value = getStringValue(key, args, position);
182         try {
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);
188         }
189     }
190
191
192     /**
193      * This method sets up any static configuration required by the JVM.
194      *
195      * @throws Exception on configuration errors
196      */
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
200         // work. IN order to
201         // ensure that all
202         // the JVMs in a test pick up the same IP address, this function sets te address to be the
203         // first non-loopback
204         // IPv4 address
205         // on a host
206         final TreeSet<String> ipAddressSet = new TreeSet<>();
207
208         Enumeration<NetworkInterface> nets;
209         try {
210             nets = NetworkInterface.getNetworkInterfaces();
211         } catch (SocketException e) {
212             throw new ApexException("cound not get network interfaces for test", e);
213         }
214         
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());
221                 }
222             }
223         }
224
225         if (ipAddressSet.isEmpty()) {
226             throw new ApexException("cound not find real IP address for test");
227         }
228         LOGGER.info("Setting jgroups.tcp.address to: " + ipAddressSet.first());
229         System.setProperty("jgroups.tcp.address", ipAddressSet.first());
230     }
231 }