2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017,2023 AT&T Intellectual Property. All rights reserved.
6 * Copyright (C) 2018 - 2021 Nokia. All rights reserved.
7 * ================================================================================
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 * ============LICENSE_END=========================================================
22 package org.onap.dcae;
24 import com.google.common.annotations.VisibleForTesting;
25 import com.google.common.reflect.TypeToken;
26 import com.google.gson.Gson;
27 import com.networknt.schema.JsonSchema;
28 import io.vavr.Function1;
29 import io.vavr.collection.HashMap;
30 import io.vavr.collection.Map;
31 import org.apache.commons.configuration.ConfigurationException;
32 import org.apache.commons.configuration.PropertiesConfiguration;
33 import org.onap.dcae.common.EventTransformation;
34 import org.onap.dcae.common.configuration.AuthMethodType;
35 import org.onap.dcae.multiplestreamreducer.MultipleStreamReducer;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
39 import javax.annotation.Nullable;
40 import java.io.FileReader;
41 import java.io.IOException;
42 import java.lang.reflect.Type;
43 import java.nio.file.Path;
44 import java.nio.file.Paths;
45 import java.util.List;
47 import static java.lang.String.format;
50 * Abstraction over application configuration.
51 * Its job is to provide easily discoverable (by method names lookup) and type safe access to configuration properties.
53 public class ApplicationSettings {
55 public static String responseCompatibility;
57 private static final String EVENT_TRANSFORM_FILE_PATH = "./etc/eventTransform.json";
58 private static final String COULD_NOT_FIND_FILE = "Couldn't find file " + EVENT_TRANSFORM_FILE_PATH;
60 private static final Logger log = LoggerFactory.getLogger(ApplicationSettings.class);
61 private static final String FALLBACK_VES_VERSION = "v5";
62 private static final int DISABLED = -1;
63 private static final int ENABLED = 1;
64 private final String appInvocationDir;
65 private final String configurationFileLocation;
66 private final PropertiesConfiguration properties = new PropertiesConfiguration();
67 private final Map<String, JsonSchema> loadedJsonSchemas;
68 private final List<EventTransformation> eventTransformations;
69 private final MultipleStreamReducer multipleStreamReducer = new MultipleStreamReducer();
71 public ApplicationSettings(String[] args, Function1<String[], Map<String, String>> argsParser) {
72 this(args, argsParser, System.getProperty("user.dir"));
75 public ApplicationSettings(String[] args, Function1<String[], Map<String, String>> argsParser, String appInvocationDir) {
76 this.appInvocationDir = appInvocationDir;
77 properties.setDelimiterParsingDisabled(true);
78 Map<String, String> parsedArgs = argsParser.apply(args);
79 configurationFileLocation = findOutConfigurationFileLocation(parsedArgs);
80 loadPropertiesFromFile();
81 parsedArgs.filterKeys(k -> !"c".equals(k)).forEach(this::addOrUpdate);
82 String collectorSchemaFile = properties.getString("collector.schema.file",
83 format("{\"%s\":\"./etc/CommonEventFormat_28.4.1.json\"}", FALLBACK_VES_VERSION));
85 loadedJsonSchemas = new JSonSchemasSupplier().loadJsonSchemas(collectorSchemaFile);
86 eventTransformations = loadEventTransformations();
87 responseCompatibility = getResponseCompatibilityFlag();
91 * Reload application settings.
93 public void reload() {
95 properties.load(configurationFileLocation);
97 } catch (ConfigurationException ex) {
98 log.error("Cannot load properties cause:", ex);
99 throw new ApplicationException(ex);
103 public Map<String, String> validAuthorizationCredentials() {
104 return prepareUsersMap(properties.getString("header.authlist", null));
106 public Path configurationFileLocation() {
107 return Paths.get(configurationFileLocation);
110 public boolean eventSchemaValidationEnabled() {
111 return properties.getInt("collector.schema.checkflag", DISABLED) > 0;
114 public JsonSchema jsonSchema(String version) {
115 return loadedJsonSchemas.get(version)
116 .orElse(loadedJsonSchemas.get(FALLBACK_VES_VERSION))
117 .getOrElseThrow(() -> new IllegalStateException("No fallback schema present in application."));
120 public boolean isVersionSupported(String version){
121 return loadedJsonSchemas.containsKey(version);
124 public int httpPort() {
125 return properties.getInt("collector.service.port", 8080);
128 public int httpsPort() {
129 return properties.getInt("collector.service.secure.port", 8443);
132 public int configurationUpdateFrequency() {
133 return properties.getInt("collector.dynamic.config.update.frequency", 5);
136 public boolean httpsEnabled() {
137 return httpsPort() > 0;
140 public boolean eventTransformingEnabled() {
141 return properties.getInt("event.transform.flag", ENABLED) > 0;
144 public String keystorePasswordFileLocation() {
145 return prependWithUserDirOnRelative(properties.getString("collector.keystore.passwordfile", "etc/passwordfile"));
148 public String keystoreFileLocation() {
149 return prependWithUserDirOnRelative(properties.getString("collector.keystore.file.location", "etc/keystore"));
152 public String truststorePasswordFileLocation() {
153 return prependWithUserDirOnRelative(properties.getString("collector.truststore.passwordfile", "etc/trustpasswordfile"));
156 public String truststoreFileLocation() {
157 return prependWithUserDirOnRelative(properties.getString("collector.truststore.file.location", "etc/truststore"));
160 public String exceptionConfigFileLocation() {
161 return properties.getString("exceptionConfig", null);
164 public String dMaaPConfigurationFileLocation() {
165 return prependWithUserDirOnRelative(properties.getString("collector.dmaapfile", "etc/ves-dmaap-config.json"));
168 public String certSubjectMatcher(){
169 return prependWithUserDirOnRelative(properties.getString("collector.cert.subject.matcher", "etc/certSubjectMatcher.properties"));
172 public String authMethod(){
173 return properties.getString("auth.method", AuthMethodType.NO_AUTH.value());
176 public Map<String, String> getDmaapStreamIds() {
177 String streamIdsProperty = properties.getString("collector.dmaap.streamid", null);
178 return streamIdsProperty == null ? HashMap.empty() : reduceStream(streamIdsProperty);
181 public boolean getExternalSchemaValidationCheckflag() {
182 return properties.getInt("collector.externalSchema.checkflag", DISABLED) > 0;
185 public String getExternalSchemaSchemasLocation() {
186 return properties.getString("collector.externalSchema.schemasLocation", "./etc/externalRepo");
189 public String getExternalSchemaMappingFileLocation() {
190 return properties.getString("collector.externalSchema.mappingFileLocation", "./etc/externalRepo/schema-map.json");
193 public String getExternalSchemaSchemaRefPath() {
194 return properties.getString("event.externalSchema.schemaRefPath", "/event/stndDefinedFields/schemaReference");
197 public String getExternalSchemaStndDefinedDataPath() {
198 return properties.getString("event.externalSchema.stndDefinedDataPath", "/event/stndDefinedFields/data");
201 public List<EventTransformation> getEventTransformations() {
202 return eventTransformations;
205 public String getApiVersionDescriptionFilepath() {
206 return properties.getString("collector.description.api.version.location", "etc/api_version_description.json");
209 private String getResponseCompatibilityFlag() {
210 return properties.getString("collector.response.compatibility", "v7.2");
213 private void loadPropertiesFromFile() {
215 properties.load(configurationFileLocation);
216 } catch (ConfigurationException ex) {
217 log.error("Cannot load properties cause:", ex);
218 throw new ApplicationException(ex);
222 private void addOrUpdate(String key, String value) {
223 if (properties.containsKey(key)) {
224 properties.setProperty(key, value);
226 properties.addProperty(key, value);
230 private String findOutConfigurationFileLocation(Map<String, String> parsedArgs) {
231 return prependWithUserDirOnRelative(parsedArgs.get("c").getOrElse("etc/collector.properties"));
234 private Map<String, String> prepareUsersMap(@Nullable String allowedUsers) {
235 return allowedUsers == null ? HashMap.empty()
236 : io.vavr.collection.List.of(allowedUsers.split("\\|"))
237 .map(t->t.split(","))
238 .toMap(t-> t[0].trim(), t -> t[1].trim());
241 private Map<String, String[]> convertDMaaPStreamsPropertyToMap(String streamIdsProperty) {
242 java.util.HashMap<String, String[]> domainToStreamIdsMapping = new java.util.HashMap<>();
243 String[] topics = streamIdsProperty.split("\\|");
244 for (String t : topics) {
245 String domain = t.split("=")[0];
246 String[] streamIds = t.split("=")[1].split(",");
247 domainToStreamIdsMapping.put(domain, streamIds);
249 return HashMap.ofAll(domainToStreamIdsMapping);
252 private String prependWithUserDirOnRelative(String filePath) {
253 if (!Paths.get(filePath).isAbsolute()) {
254 filePath = Paths.get(appInvocationDir, filePath).toString();
259 private List<EventTransformation> loadEventTransformations() {
260 Type EVENT_TRANSFORM_LIST_TYPE = new TypeToken<List<EventTransformation>>() {}.getType();
262 try (FileReader fr = new FileReader(EVENT_TRANSFORM_FILE_PATH)) {
263 log.info("parse " + EVENT_TRANSFORM_FILE_PATH + " file");
264 return new Gson().fromJson(fr, EVENT_TRANSFORM_LIST_TYPE);
265 } catch (IOException e) {
266 log.error(COULD_NOT_FIND_FILE, e);
267 throw new ApplicationException(COULD_NOT_FIND_FILE, e);
271 private Map<String, String> reduceStream(String streamIdsProperty) {
272 Map<String, String[]> dMaaPStreamsProperty = convertDMaaPStreamsPropertyToMap(streamIdsProperty);
273 final Map<String, String> domainToStreamConfig = multipleStreamReducer.reduce(dMaaPStreamsProperty);
274 log.warn(multipleStreamReducer.getDomainToStreamsInfo(domainToStreamConfig));
275 return domainToStreamConfig;
279 String getStringDirectly(String key) {
280 return properties.getString(key);