2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 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));
84 loadedJsonSchemas = new JSonSchemasSupplier().loadJsonSchemas(collectorSchemaFile);
85 eventTransformations = loadEventTransformations();
86 responseCompatibility = getResponseCompatibilityFlag();
90 * Reload application settings.
92 public void reload() {
94 properties.load(configurationFileLocation);
96 } catch (ConfigurationException ex) {
97 log.error("Cannot load properties cause:", ex);
98 throw new ApplicationException(ex);
102 public Map<String, String> validAuthorizationCredentials() {
103 return prepareUsersMap(properties.getString("header.authlist", null));
105 public Path configurationFileLocation() {
106 return Paths.get(configurationFileLocation);
109 public boolean eventSchemaValidationEnabled() {
110 return properties.getInt("collector.schema.checkflag", DISABLED) > 0;
113 public JsonSchema jsonSchema(String version) {
114 return loadedJsonSchemas.get(version)
115 .orElse(loadedJsonSchemas.get(FALLBACK_VES_VERSION))
116 .getOrElseThrow(() -> new IllegalStateException("No fallback schema present in application."));
119 public boolean isVersionSupported(String version){
120 return loadedJsonSchemas.containsKey(version);
123 public int httpPort() {
124 return properties.getInt("collector.service.port", 8080);
127 public int httpsPort() {
128 return properties.getInt("collector.service.secure.port", 8443);
131 public int configurationUpdateFrequency() {
132 return properties.getInt("collector.dynamic.config.update.frequency", 5);
135 public boolean httpsEnabled() {
136 return httpsPort() > 0;
139 public boolean eventTransformingEnabled() {
140 return properties.getInt("event.transform.flag", ENABLED) > 0;
143 public String keystorePasswordFileLocation() {
144 return prependWithUserDirOnRelative(properties.getString("collector.keystore.passwordfile", "etc/passwordfile"));
147 public String keystoreFileLocation() {
148 return prependWithUserDirOnRelative(properties.getString("collector.keystore.file.location", "etc/keystore"));
151 public String truststorePasswordFileLocation() {
152 return prependWithUserDirOnRelative(properties.getString("collector.truststore.passwordfile", "etc/trustpasswordfile"));
155 public String truststoreFileLocation() {
156 return prependWithUserDirOnRelative(properties.getString("collector.truststore.file.location", "etc/truststore"));
159 public String exceptionConfigFileLocation() {
160 return properties.getString("exceptionConfig", null);
163 public String dMaaPConfigurationFileLocation() {
164 return prependWithUserDirOnRelative(properties.getString("collector.dmaapfile", "etc/ves-dmaap-config.json"));
167 public String certSubjectMatcher(){
168 return prependWithUserDirOnRelative(properties.getString("collector.cert.subject.matcher", "etc/certSubjectMatcher.properties"));
171 public String authMethod(){
172 return properties.getString("auth.method", AuthMethodType.NO_AUTH.value());
175 public Map<String, String> getDmaapStreamIds() {
176 String streamIdsProperty = properties.getString("collector.dmaap.streamid", null);
177 return streamIdsProperty == null ? HashMap.empty() : reduceStream(streamIdsProperty);
180 public boolean getExternalSchemaValidationCheckflag() {
181 return properties.getInt("collector.externalSchema.checkflag", DISABLED) > 0;
184 public String getExternalSchemaSchemasLocation() {
185 return properties.getString("collector.externalSchema.schemasLocation", "./etc/externalRepo");
188 public String getExternalSchemaMappingFileLocation() {
189 return properties.getString("collector.externalSchema.mappingFileLocation", "./etc/externalRepo/schema-map.json");
192 public String getExternalSchemaSchemaRefPath() {
193 return properties.getString("event.externalSchema.schemaRefPath", "/event/stndDefinedFields/schemaReference");
196 public String getExternalSchemaStndDefinedDataPath() {
197 return properties.getString("event.externalSchema.stndDefinedDataPath", "/event/stndDefinedFields/data");
200 public List<EventTransformation> getEventTransformations() {
201 return eventTransformations;
204 public String getApiVersionDescriptionFilepath() {
205 return properties.getString("collector.description.api.version.location", "etc/api_version_description.json");
208 private String getResponseCompatibilityFlag() {
209 return properties.getString("collector.response.compatibility", "v7.2");
212 private void loadPropertiesFromFile() {
214 properties.load(configurationFileLocation);
215 } catch (ConfigurationException ex) {
216 log.error("Cannot load properties cause:", ex);
217 throw new ApplicationException(ex);
221 private void addOrUpdate(String key, String value) {
222 if (properties.containsKey(key)) {
223 properties.setProperty(key, value);
225 properties.addProperty(key, value);
229 private String findOutConfigurationFileLocation(Map<String, String> parsedArgs) {
230 return prependWithUserDirOnRelative(parsedArgs.get("c").getOrElse("etc/collector.properties"));
233 private Map<String, String> prepareUsersMap(@Nullable String allowedUsers) {
234 return allowedUsers == null ? HashMap.empty()
235 : io.vavr.collection.List.of(allowedUsers.split("\\|"))
236 .map(t->t.split(","))
237 .toMap(t-> t[0].trim(), t -> t[1].trim());
240 private Map<String, String[]> convertDMaaPStreamsPropertyToMap(String streamIdsProperty) {
241 java.util.HashMap<String, String[]> domainToStreamIdsMapping = new java.util.HashMap<>();
242 String[] topics = streamIdsProperty.split("\\|");
243 for (String t : topics) {
244 String domain = t.split("=")[0];
245 String[] streamIds = t.split("=")[1].split(",");
246 domainToStreamIdsMapping.put(domain, streamIds);
248 return HashMap.ofAll(domainToStreamIdsMapping);
251 private String prependWithUserDirOnRelative(String filePath) {
252 if (!Paths.get(filePath).isAbsolute()) {
253 filePath = Paths.get(appInvocationDir, filePath).toString();
258 private List<EventTransformation> loadEventTransformations() {
259 Type EVENT_TRANSFORM_LIST_TYPE = new TypeToken<List<EventTransformation>>() {}.getType();
261 try (FileReader fr = new FileReader(EVENT_TRANSFORM_FILE_PATH)) {
262 log.info("parse " + EVENT_TRANSFORM_FILE_PATH + " file");
263 return new Gson().fromJson(fr, EVENT_TRANSFORM_LIST_TYPE);
264 } catch (IOException e) {
265 log.error(COULD_NOT_FIND_FILE, e);
266 throw new ApplicationException(COULD_NOT_FIND_FILE, e);
270 private Map<String, String> reduceStream(String streamIdsProperty) {
271 Map<String, String[]> dMaaPStreamsProperty = convertDMaaPStreamsPropertyToMap(streamIdsProperty);
272 final Map<String, String> domainToStreamConfig = multipleStreamReducer.reduce(dMaaPStreamsProperty);
273 log.warn(multipleStreamReducer.getDomainToStreamsInfo(domainToStreamConfig));
274 return domainToStreamConfig;
278 String getStringDirectly(String key) {
279 return properties.getString(key);