Merge "Fix checkstyle warnings in context-test-utils"
[policy/apex-pdp.git] / context / context-test-utils / src / main / java / org / onap / policy / apex / context / test / locking / ConcurrentContextJVM.java
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.Future;
34 import java.util.concurrent.TimeUnit;
35
36 import org.onap.policy.apex.context.ContextAlbum;
37 import org.onap.policy.apex.context.Distributor;
38 import org.onap.policy.apex.context.test.utils.ConfigrationProvider;
39 import org.onap.policy.apex.context.test.utils.ConfigrationProviderImpl;
40 import org.onap.policy.apex.context.test.utils.Constants;
41 import org.onap.policy.apex.model.basicmodel.concepts.ApexException;
42 import org.onap.policy.apex.model.basicmodel.concepts.ApexRuntimeException;
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.slf4j.ext.XLogger;
47 import org.slf4j.ext.XLoggerFactory;
48
49 import com.google.gson.Gson;
50
51 /**
52  * The Class ConcurrentContextJVM tests concurrent use of context in a single JVM.
53  *
54  * @author Liam Fallon (liam.fallon@ericsson.com)
55  */
56 public final class ConcurrentContextJVM {
57     // Logger for this class
58     private static final XLogger LOGGER = XLoggerFactory.getXLogger(ConcurrentContextJVM.class);
59
60     private static final int IPV4_ADDRESS_LENGTH = 4;
61
62     private final int jvmNo;
63
64     private final ExecutorService executorService;
65
66     private final ConfigrationProvider configrationProvider;
67
68     private ConcurrentContextJVM(final int jvmNo, final ConfigrationProvider configrationProvider) {
69         this.jvmNo = jvmNo;
70         this.configrationProvider = configrationProvider;
71         final String name = configrationProvider.getTestName() + ":ConcurrentContextThread_" + jvmNo;
72         this.executorService = configrationProvider.getExecutorService(name, configrationProvider.getThreadCount());
73     }
74
75     public void execute() throws ApexException {
76         LOGGER.debug("starting JVMs and threads . . .");
77
78         final AxArtifactKey distributorKey = new AxArtifactKey("ApexDistributor" + jvmNo, "0.0.1");
79         final Distributor distributor = configrationProvider.getDistributor(distributorKey);
80         final ContextAlbum contextAlbum = configrationProvider.getContextAlbum(distributor);
81         assert (contextAlbum != null);
82
83         final List<Future<?>> tasks = new ArrayList<>(configrationProvider.getThreadCount());
84
85         for (int t = 0; t < configrationProvider.getThreadCount(); t++) {
86             tasks.add(executorService.submit(new ConcurrentContextThread(jvmNo, t, configrationProvider)));
87         }
88
89         try {
90             executorService.shutdown();
91             // wait for threads to finish, if not Timeout
92             executorService.awaitTermination(10, TimeUnit.MINUTES);
93         } catch (final InterruptedException interruptedException) {
94             LOGGER.error("Exception while waiting for threads to finish", interruptedException);
95             // restore the interrupt status
96             Thread.currentThread().interrupt();
97         }
98
99         LOGGER.debug("threads finished, end value is {}", contextAlbum.get(Constants.TEST_VALUE));
100         distributor.clear();
101         LOGGER.info("Shutting down now ... ");
102         executorService.shutdownNow();
103     }
104
105
106
107     /**
108      * The main method.
109      *
110      * @param args the args
111      * @throws Exception Any exception thrown by the test code
112      */
113     @SuppressWarnings("unchecked")
114     public static void main(final String[] args) throws Exception {
115         configure();
116
117         System.out.println("JVM Arguments: " + Arrays.toString(args));
118         // CHECKSTYLE:OFF: checkstyle:magicNumber
119
120         // An even number of arguments greater than 3
121         if (args.length < 9) {
122             LOGGER.error("invalid arguments: " + Arrays.toString(args));
123             LOGGER.error("usage: TestConcurrentContextJVM testType jvmNo threadCount threadLoops albumSize "
124                     + "lockType [parameterKey parameterJson].... ");
125             return;
126         }
127
128
129         final String testName = getStringValue("testType", args, 0);
130         final int jvmNo = getIntValue("jvmNo", args, 1);
131         final int threadCount = getIntValue("threadCount", args, 2);
132         final int threadLoops = getIntValue("threadLoops", args, 3);
133         final int albumSize = getIntValue("albumSize", args, 4);
134         final int lockType = getIntValue("lockType", args, 5);
135         final String hazelCastfileLocation = getStringValue("hazelcast file location", args, 6);;
136
137         System.setProperty("hazelcast.config", hazelCastfileLocation);
138
139         for (int p = 7; p < args.length - 1; p += 2) {
140             @SuppressWarnings("rawtypes")
141             final Class parametersClass = Class.forName(args[p]);
142             final AbstractParameters parameters =
143                     (AbstractParameters) new Gson().fromJson(args[p + 1], parametersClass);
144             ParameterService.registerParameters(parametersClass, parameters);
145         }
146
147         for (final Entry<Class<?>, AbstractParameters> parameterEntry : ParameterService.getAll()) {
148             LOGGER.info("Parameter class " + parameterEntry.getKey().getCanonicalName() + "="
149                     + parameterEntry.getValue().toString());
150         }
151
152         try {
153             final ConfigrationProvider configrationProvider =
154                     new ConfigrationProviderImpl(testName, 1, threadCount, threadLoops, albumSize, lockType);
155             final ConcurrentContextJVM concurrentContextJVM = new ConcurrentContextJVM(jvmNo, configrationProvider);
156             concurrentContextJVM.execute();
157
158         } catch (final Exception e) {
159             LOGGER.error("error running test in JVM", e);
160             return;
161         }
162         // CHECKSTYLE:ON: checkstyle:magicNumber
163
164     }
165
166     private static String getStringValue(final String key, final String[] args, final int position) {
167         try {
168             return args[position];
169         } catch (final Exception e) {
170             final String msg = "invalid argument " + key;
171             LOGGER.error(msg, e);
172             throw new ApexRuntimeException(msg, e);
173         }
174     }
175
176     private static int getIntValue(final String key, final String[] args, final int position) {
177         final String value = getStringValue(key, args, position);
178         try {
179             return Integer.parseInt(value);
180         } catch (final Exception e) {
181             final String msg = "Expects number found " + value;
182             LOGGER.error(msg, e);
183             throw new ApexRuntimeException(msg, e);
184         }
185     }
186
187
188     /**
189      * This method setus up any static configuration required by the JVM.
190      *
191      * @throws Exception on configuration errors
192      */
193     public static void configure() throws Exception {
194         System.setProperty("java.net.preferIPv4Stack", "true");
195         // The JGroups IP address must be set to a real (not loopback) IP address for Infinispan to
196         // work. IN order to
197         // ensure that all
198         // the JVMs in a test pick up the same IP address, this function sets te address to be the
199         // first non-loopback
200         // IPv4 address
201         // on a host
202         final TreeSet<String> ipAddressSet = new TreeSet<String>();
203
204         final Enumeration<NetworkInterface> nets = NetworkInterface.getNetworkInterfaces();
205         for (final NetworkInterface netint : Collections.list(nets)) {
206             final Enumeration<InetAddress> inetAddresses = netint.getInetAddresses();
207             for (final InetAddress inetAddress : Collections.list(inetAddresses)) {
208                 // Look for real IPv4 Internet addresses
209                 if (!inetAddress.isLoopbackAddress() && inetAddress.getAddress().length == IPV4_ADDRESS_LENGTH) {
210                     ipAddressSet.add(inetAddress.getHostAddress());
211                 }
212             }
213         }
214
215         if (ipAddressSet.size() == 0) {
216             throw new Exception("cound not find real IP address for test");
217         }
218         System.out.println("Setting jgroups.tcp.address to: " + ipAddressSet.first());
219         System.setProperty("jgroups.tcp.address", ipAddressSet.first());
220     }
221 }