2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2020-2021 AT&T Intellectual Property. All rights reserved.
4 * Modifications Copyright (C) 2020-2021 Bell Canada. All rights reserved.
5 * Modifications Copyright 2023-2024 Nordix Foundation.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 * SPDX-License-Identifier: Apache-2.0
20 * ============LICENSE_END=========================================================
23 package org.onap.policy.models.simulators;
25 import java.io.FileNotFoundException;
26 import java.io.IOException;
27 import java.util.Properties;
28 import java.util.concurrent.atomic.AtomicReference;
29 import lombok.AccessLevel;
31 import org.apache.commons.lang3.StringUtils;
32 import org.onap.policy.common.endpoints.http.server.HttpServletServer;
33 import org.onap.policy.common.endpoints.http.server.HttpServletServerFactoryInstance;
34 import org.onap.policy.common.endpoints.properties.PolicyEndPointProperties;
35 import org.onap.policy.common.gson.GsonMessageBodyHandler;
36 import org.onap.policy.common.parameters.BeanValidationResult;
37 import org.onap.policy.common.utils.coder.Coder;
38 import org.onap.policy.common.utils.coder.CoderException;
39 import org.onap.policy.common.utils.coder.StandardCoder;
40 import org.onap.policy.common.utils.network.NetworkUtil;
41 import org.onap.policy.common.utils.resources.ResourceUtils;
42 import org.onap.policy.common.utils.services.Registry;
43 import org.onap.policy.common.utils.services.ServiceManagerContainer;
44 import org.onap.policy.simulators.CdsSimulator;
45 import org.slf4j.Logger;
46 import org.slf4j.LoggerFactory;
49 * This class runs all simulators specified in the parameter file.
51 public class Main extends ServiceManagerContainer {
52 private static final Logger logger = LoggerFactory.getLogger(Main.class);
54 private static final String CANNOT_CONNECT = "cannot connect to port ";
56 @Getter(AccessLevel.PROTECTED)
57 private static Main instance;
61 * Runs the simulators.
63 * @param paramFile parameter file name
65 public Main(String paramFile) {
66 super(Main.class.getPackage().getName());
68 SimulatorParameters params = readParameters(paramFile);
70 CdsServerParameters cdsServer = params.getGrpcServer();
73 if (cdsServer != null) {
74 AtomicReference<CdsSimulator> cdsSim = new AtomicReference<>();
75 addAction(cdsServer.getName(), () -> cdsSim.set(buildCdsSimulator(cdsServer)), () -> cdsSim.get().stop());
78 // REST server simulators
80 for (ClassRestServerParameters restsim : params.getRestServers()) {
81 AtomicReference<HttpServletServer> ref = new AtomicReference<>();
82 if (StringUtils.isNotBlank(restsim.getResourceLocation())) {
83 String resourceLocationId = restsim.getProviderClass() + "_RESOURCE_LOCATION";
84 addAction(resourceLocationId,
85 () -> Registry.register(resourceLocationId, restsim.getResourceLocation()),
86 () -> Registry.unregister(resourceLocationId));
88 addAction(restsim.getName(),
89 () -> ref.set(buildRestServer(restsim)),
90 () -> ref.get().shutdown());
96 * The main method. The arguments are validated, thus adding the NOSONAR.
98 * @param args the arguments, the first of which is the name of the parameter file
100 public static void main(final String[] args) { // NOSONAR
102 * Only one argument is used and is validated implicitly by the constructor (i.e.,
103 * file-not-found), thus sonar is disabled.
107 if (args.length != 1) {
108 throw new IllegalArgumentException("arg(s): parameter-file-name");
111 instance = new Main(args[0]);
114 } catch (RuntimeException e) {
115 logger.error("failed to start simulators", e);
119 private SimulatorParameters readParameters(String paramFile) {
121 var paramsJson = getResourceAsString(paramFile);
122 if (paramsJson == null) {
123 throw new IllegalArgumentException(new FileNotFoundException(paramFile));
126 String hostName = NetworkUtil.getHostname();
127 logger.info("replacing 'HOST_NAME' with {} in {}", hostName, paramFile);
129 paramsJson = paramsJson.replace("${HOST_NAME}", hostName);
131 return makeCoder().decode(paramsJson, SimulatorParameters.class);
133 } catch (CoderException e) {
134 throw new IllegalArgumentException("cannot decode " + paramFile, e);
138 private CdsSimulator buildCdsSimulator(CdsServerParameters params) throws IOException {
139 var cdsSimulator = new CdsSimulator(params.getHost(), params.getPort(), params.getResourceLocation(),
140 params.getSuccessRepeatCount(), params.getRequestedResponseDelayMs());
141 cdsSimulator.start();
146 private HttpServletServer buildRestServer(ClassRestServerParameters params) {
148 var props = getServerProperties(params);
149 HttpServletServer testServer = makeServer(props);
150 testServer.waitedStart(5000);
152 String svcpfx = PolicyEndPointProperties.PROPERTY_HTTP_SERVER_SERVICES + "." + params.getName();
153 String hostName = props.getProperty(svcpfx + PolicyEndPointProperties.PROPERTY_HTTP_HOST_SUFFIX);
155 if (!isTcpPortOpen(hostName, testServer.getPort())) {
156 throw new IllegalStateException(CANNOT_CONNECT + testServer.getPort());
161 } catch (InterruptedException e) {
162 Thread.currentThread().interrupt();
163 throw new IllegalStateException("interrupted while building " + params.getName(), e);
169 * Creates a set of properties, suitable for building a REST server, from the
172 * @param params parameters from which to build the properties
173 * @return a Map of properties representing the given parameters
175 private static Properties getServerProperties(ClassRestServerParameters params) {
176 final var props = new Properties();
177 props.setProperty(PolicyEndPointProperties.PROPERTY_HTTP_SERVER_SERVICES, params.getName());
179 final String svcpfx = PolicyEndPointProperties.PROPERTY_HTTP_SERVER_SERVICES + "." + params.getName();
181 props.setProperty(PolicyEndPointProperties.PROPERTY_HTTP_SERVER_SERVICES, params.getName());
182 props.setProperty(svcpfx + PolicyEndPointProperties.PROPERTY_HTTP_HOST_SUFFIX, params.getHost());
183 props.setProperty(svcpfx + PolicyEndPointProperties.PROPERTY_HTTP_PORT_SUFFIX,
184 Integer.toString(params.getPort()));
185 props.setProperty(svcpfx + PolicyEndPointProperties.PROPERTY_HTTP_HTTPS_SUFFIX,
186 Boolean.toString(params.isHttps()));
187 props.setProperty(svcpfx + PolicyEndPointProperties.PROPERTY_HTTP_REST_CLASSES_SUFFIX,
188 params.getProviderClass());
189 props.setProperty(svcpfx + PolicyEndPointProperties.PROPERTY_MANAGED_SUFFIX, "false");
190 props.setProperty(svcpfx + PolicyEndPointProperties.PROPERTY_HTTP_SWAGGER_SUFFIX, "false");
191 props.setProperty(svcpfx + PolicyEndPointProperties.PROPERTY_HTTP_SNI_HOST_CHECK_SUFFIX, "false");
192 props.setProperty(svcpfx + PolicyEndPointProperties.PROPERTY_MANAGED_SUFFIX, "true");
194 props.setProperty(svcpfx + PolicyEndPointProperties.PROPERTY_HTTP_SERIALIZATION_PROVIDER, String.join(",",
195 GsonMessageBodyHandler.class.getName(), TextMessageBodyHandler.class.getName()));
201 // the following methods may be overridden by junit tests
203 protected String getResourceAsString(String resourceName) {
204 return ResourceUtils.getResourceAsString(resourceName);
207 protected Coder makeCoder() {
208 return new StandardCoder();
211 protected HttpServletServer makeServer(Properties props) {
212 return HttpServletServerFactoryInstance.getServerFactory().build(props).get(0);
215 protected boolean isTcpPortOpen(String hostName, int port) throws InterruptedException {
216 return NetworkUtil.isTcpPortOpen(hostName, port, 100, 200L);