0145bd161054195167ac35334b457895ec5903d8
[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.util.Arrays;
28 import java.util.Collections;
29 import java.util.Enumeration;
30 import java.util.Map.Entry;
31 import java.util.TreeSet;
32
33 import org.onap.policy.apex.context.ContextAlbum;
34 import org.onap.policy.apex.context.Distributor;
35 import org.onap.policy.apex.context.impl.distribution.DistributorFactory;
36 import org.onap.policy.apex.context.test.factory.TestContextAlbumFactory;
37 import org.onap.policy.apex.model.basicmodel.concepts.ApexException;
38 import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
39 import org.onap.policy.apex.model.basicmodel.service.AbstractParameters;
40 import org.onap.policy.apex.model.basicmodel.service.ParameterService;
41 import org.onap.policy.apex.model.contextmodel.concepts.AxContextModel;
42 import org.slf4j.ext.XLogger;
43 import org.slf4j.ext.XLoggerFactory;
44
45 /**
46  * The Class ConcurrentContextJVM tests concurrent use of context in a single JVM.
47  *
48  * @author Liam Fallon (liam.fallon@ericsson.com)
49  */
50 public final class ConcurrentContextJVM {
51     // Logger for this class
52     private static final XLogger LOGGER = XLoggerFactory.getXLogger(ConcurrentContextJVM.class);
53
54     private static final int TEN_MILLISECONDS = 10;
55     private static final int IPV4_ADDRESS_LENGTH = 4;
56
57     /**
58      * The Constructor.
59      *
60      * @param testType the test type
61      * @param jvmNo the jvm no
62      * @param threadCount the thread count
63      * @param threadLoops the thread loops
64      * @throws ApexException the apex exception
65      */
66     private ConcurrentContextJVM(final String testType, final int jvmNo, final int threadCount, final int threadLoops)
67             throws ApexException {
68         super();
69         LOGGER.debug("starting JVMs and threads . . .");
70
71         final AxArtifactKey distributorKey = new AxArtifactKey("ApexDistributor" + jvmNo, "0.0.1");
72         final Distributor contextDistributor = new DistributorFactory().getDistributor(distributorKey);
73
74         // @formatter:off
75         final AxArtifactKey[] usedArtifactStackArray = {
76                 new AxArtifactKey("testC-top", "0.0.1"),
77                 new AxArtifactKey("testC-next", "0.0.1"),
78                 new AxArtifactKey("testC-bot", "0.0.1")
79                 };
80         // @formatter:on
81
82         final AxContextModel albumsModel = TestContextAlbumFactory.createMultiAlbumsContextModel();
83         contextDistributor.registerModel(albumsModel);
84
85         final ContextAlbum lTypeAlbum =
86                 contextDistributor.createContextAlbum(new AxArtifactKey("LTypeContextAlbum", "0.0.1"));
87         assert (lTypeAlbum != null);
88         lTypeAlbum.setUserArtifactStack(usedArtifactStackArray);
89
90         final Thread[] threadArray = new Thread[threadCount];
91
92         for (int t = 0; t < threadCount; t++) {
93             threadArray[t] = new Thread(new ConcurrentContextThread(jvmNo, t, threadLoops));
94             threadArray[t].setName(testType + ":ConcurrentContextThread_" + jvmNo + "_" + t);
95             threadArray[t].start();
96             LOGGER.debug("started thread " + threadArray[t].getName());
97         }
98
99         boolean allFinished;
100         do {
101             allFinished = true;
102             for (int t = 0; t < threadCount; t++) {
103                 if (threadArray[t].isAlive()) {
104                     allFinished = false;
105                     try {
106                         Thread.sleep(TEN_MILLISECONDS);
107                     } catch (final Exception e) {
108                     }
109                     break;
110                 }
111             }
112         } while (!allFinished);
113
114         LOGGER.debug("threads finished, end value is {}", lTypeAlbum.get("testValue"));
115         contextDistributor.clear();
116     }
117
118     /**
119      * The main method.
120      *
121      * @param args the args
122      * @throws Exception Any exception thrown by the test code
123      */
124     @SuppressWarnings("unchecked")
125     public static void main(final String[] args) throws Exception {
126         configure();
127
128         System.out.println("JVM Arguments: " + Arrays.toString(args));
129         // CHECKSTYLE:OFF: checkstyle:magicNumber
130
131         // An even number of arguments greater than 3
132         if (args.length < 4 || (args.length % 2 != 0)) {
133             LOGGER.error("invalid arguments: " + Arrays.toString(args));
134             LOGGER.error(
135                     "usage: TestConcurrentContextJVM testType jvmNo threadCount threadLoops [parameterKey parameterJson].... ");
136             return;
137         }
138
139         int jvmNo = -1;
140         int threadCount = -1;
141         int threadLoops = -1;
142
143         try {
144             jvmNo = Integer.parseInt(args[1]);
145         } catch (final Exception e) {
146             LOGGER.error("invalid argument jvmNo", e);
147             return;
148         }
149
150         try {
151             threadCount = Integer.parseInt(args[2]);
152         } catch (final Exception e) {
153             LOGGER.error("invalid argument threadCount", e);
154             return;
155         }
156
157         try {
158             threadLoops = Integer.parseInt(args[3]);
159         } catch (final Exception e) {
160             LOGGER.error("invalid argument threadLoops", e);
161             return;
162         }
163
164         for (int p = 4; p < args.length - 1; p += 2) {
165             @SuppressWarnings("rawtypes")
166             final Class parametersClass = Class.forName(args[p]);
167             final AbstractParameters parameters =
168                     (AbstractParameters) new Gson().fromJson(args[p + 1], parametersClass);
169             ParameterService.registerParameters(parametersClass, parameters);
170         }
171
172         for (final Entry<Class<?>, AbstractParameters> parameterEntry : ParameterService.getAll()) {
173             LOGGER.info("Parameter class " + parameterEntry.getKey().getCanonicalName() + "="
174                     + parameterEntry.getValue().toString());
175         }
176
177         try {
178             new ConcurrentContextJVM(args[0], jvmNo, threadCount, threadLoops);
179         } catch (final Exception e) {
180             LOGGER.error("error running test in JVM", e);
181             return;
182         }
183         // CHECKSTYLE:ON: checkstyle:magicNumber
184     }
185
186     /**
187      * This method setus up any static configuration required by the JVM.
188      *
189      * @throws Exception on configuration errors
190      */
191     public static void configure() throws Exception {
192         System.setProperty("java.net.preferIPv4Stack", "true");
193         System.setProperty("hazelcast.config", "src/test/resources/hazelcast/hazelcast.xml");
194
195         // The JGroups IP address must be set to a real (not loopback) IP address for Infinispan to work. IN order to
196         // ensure that all
197         // the JVMs in a test pick up the same IP address, this function sets te address to be the first non-loopback
198         // IPv4 address
199         // on a host
200         final TreeSet<String> ipAddressSet = new TreeSet<String>();
201
202         final Enumeration<NetworkInterface> nets = NetworkInterface.getNetworkInterfaces();
203         for (final NetworkInterface netint : Collections.list(nets)) {
204             final Enumeration<InetAddress> inetAddresses = netint.getInetAddresses();
205             for (final InetAddress inetAddress : Collections.list(inetAddresses)) {
206                 // Look for real IPv4 Internet addresses
207                 if (!inetAddress.isLoopbackAddress() && inetAddress.getAddress().length == IPV4_ADDRESS_LENGTH) {
208                     ipAddressSet.add(inetAddress.getHostAddress());
209                 }
210             }
211         }
212
213         if (ipAddressSet.size() == 0) {
214             throw new Exception("cound not find real IP address for test");
215         }
216         System.out.println("Setting jgroups.tcp.address to: " + ipAddressSet.first());
217         System.setProperty("jgroups.tcp.address", ipAddressSet.first());
218     }
219 }