b76b008401d744025b77e1a34b6f68a46eda9919
[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 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;
36
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;
49
50 import com.google.gson.Gson;
51
52 /**
53  * The Class ConcurrentContextJVM tests concurrent use of context in a single JVM.
54  *
55  * @author Liam Fallon (liam.fallon@ericsson.com)
56  */
57 public final class ConcurrentContextJVM {
58     // Logger for this class
59     private static final XLogger LOGGER = XLoggerFactory.getXLogger(ConcurrentContextJVM.class);
60
61     private static final int IPV4_ADDRESS_LENGTH = 4;
62
63     private final int jvmNo;
64
65     private final int threadCount;
66
67     private final int threadLoops;
68
69     private final ExecutorService executorService;
70
71     /**
72      * The Constructor.
73      *
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
79      */
80     private ConcurrentContextJVM(final String testType, final int jvmNo, final int threadCount, final int threadLoops) {
81         this.jvmNo = jvmNo;
82         this.threadCount = threadCount;
83         this.threadLoops = threadLoops;
84         final String name = testType + ":ConcurrentContextThread_" + jvmNo;
85         this.executorService = Executors.newFixedThreadPool(threadCount, new IntegrationThreadFactory(name));
86     }
87
88     public void execute() throws ApexException {
89         LOGGER.debug("starting JVMs and threads . . .");
90
91         final AxArtifactKey distributorKey = new AxArtifactKey("ApexDistributor" + jvmNo, "0.0.1");
92         final Distributor contextDistributor = new DistributorFactory().getDistributor(distributorKey);
93
94         // @formatter:off
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")
99                 };
100         // @formatter:on
101
102         final AxContextModel albumsModel = TestContextAlbumFactory.createMultiAlbumsContextModel();
103         contextDistributor.registerModel(albumsModel);
104
105         final ContextAlbum lTypeAlbum =
106                 contextDistributor.createContextAlbum(new AxArtifactKey("LTypeContextAlbum", "0.0.1"));
107         assert (lTypeAlbum != null);
108         lTypeAlbum.setUserArtifactStack(usedArtifactStackArray);
109
110         final List<Future<?>> tasks = new ArrayList<>(threadCount);
111
112         for (int t = 0; t < threadCount; t++) {
113             tasks.add(executorService.submit(new ConcurrentContextThread(jvmNo, t, threadLoops)));
114         }
115
116         try {
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         }
123
124         LOGGER.debug("threads finished, end value is {}", lTypeAlbum.get("testValue"));
125         contextDistributor.clear();
126         LOGGER.info("Shutting down now ... ");
127         executorService.shutdownNow();
128     }
129
130
131
132     /**
133      * The main method.
134      *
135      * @param args the args
136      * @throws Exception Any exception thrown by the test code
137      */
138     @SuppressWarnings("unchecked")
139     public static void main(final String[] args) throws Exception {
140         configure();
141
142         System.out.println("JVM Arguments: " + Arrays.toString(args));
143         // CHECKSTYLE:OFF: checkstyle:magicNumber
144
145         // An even number of arguments greater than 3
146         if (args.length < 7) {
147             LOGGER.error("invalid arguments: " + Arrays.toString(args));
148             LOGGER.error(
149                     "usage: TestConcurrentContextJVM testType jvmNo threadCount threadLoops [parameterKey parameterJson].... ");
150             return;
151         }
152
153         int jvmNo = -1;
154         int threadCount = -1;
155         int threadLoops = -1;
156         String hazelCastfileLocation = null;
157
158         try {
159             jvmNo = Integer.parseInt(args[1]);
160         } catch (final Exception e) {
161             LOGGER.error("invalid argument jvmNo", e);
162             return;
163         }
164
165         try {
166             threadCount = Integer.parseInt(args[2]);
167         } catch (final Exception e) {
168             LOGGER.error("invalid argument threadCount", e);
169             return;
170         }
171
172         try {
173             threadLoops = Integer.parseInt(args[3]);
174         } catch (final Exception e) {
175             LOGGER.error("invalid argument threadLoops", e);
176             return;
177         }
178
179         try {
180             hazelCastfileLocation = args[4].trim();
181         } catch (final Exception e) {
182             LOGGER.error("invalid argument hazelcast file location", e);
183             return;
184         }
185
186         System.setProperty("hazelcast.config", hazelCastfileLocation);
187
188         for (int p = 5; p < args.length - 1; p += 2) {
189             @SuppressWarnings("rawtypes")
190             final Class parametersClass = Class.forName(args[p]);
191             final AbstractParameters parameters =
192                     (AbstractParameters) new Gson().fromJson(args[p + 1], parametersClass);
193             ParameterService.registerParameters(parametersClass, parameters);
194         }
195
196         for (final Entry<Class<?>, AbstractParameters> parameterEntry : ParameterService.getAll()) {
197             LOGGER.info("Parameter class " + parameterEntry.getKey().getCanonicalName() + "="
198                     + parameterEntry.getValue().toString());
199         }
200
201         try {
202             final ConcurrentContextJVM concurrentContextJVM =
203                     new ConcurrentContextJVM(args[0], jvmNo, threadCount, threadLoops);
204             concurrentContextJVM.execute();
205
206         } catch (final Exception e) {
207             LOGGER.error("error running test in JVM", e);
208             return;
209         }
210         // CHECKSTYLE:ON: checkstyle:magicNumber
211
212
213     }
214
215     /**
216      * This method setus up any static configuration required by the JVM.
217      *
218      * @throws Exception on configuration errors
219      */
220     public static void configure() throws Exception {
221         System.setProperty("java.net.preferIPv4Stack", "true");
222         // The JGroups IP address must be set to a real (not loopback) IP address for Infinispan to
223         // work. IN order to
224         // ensure that all
225         // the JVMs in a test pick up the same IP address, this function sets te address to be the
226         // first non-loopback
227         // IPv4 address
228         // on a host
229         final TreeSet<String> ipAddressSet = new TreeSet<String>();
230
231         final Enumeration<NetworkInterface> nets = NetworkInterface.getNetworkInterfaces();
232         for (final NetworkInterface netint : Collections.list(nets)) {
233             final Enumeration<InetAddress> inetAddresses = netint.getInetAddresses();
234             for (final InetAddress inetAddress : Collections.list(inetAddresses)) {
235                 // Look for real IPv4 Internet addresses
236                 if (!inetAddress.isLoopbackAddress() && inetAddress.getAddress().length == IPV4_ADDRESS_LENGTH) {
237                     ipAddressSet.add(inetAddress.getHostAddress());
238                 }
239             }
240         }
241
242         if (ipAddressSet.size() == 0) {
243             throw new Exception("cound not find real IP address for test");
244         }
245         System.out.println("Setting jgroups.tcp.address to: " + ipAddressSet.first());
246         System.setProperty("jgroups.tcp.address", ipAddressSet.first());
247     }
248 }