VESCollector Test optimization
[dcaegen2/collectors/ves.git] / src / main / java / org / onap / dcae / ApplicationSettings.java
1 /*
2  * ============LICENSE_START=======================================================
3  * VES Collector
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
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
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=========================================================
20  */
21
22 package org.onap.dcae;
23
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;
38
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;
46
47 import static java.lang.String.format;
48
49 /**
50  * Abstraction over application configuration.
51  * Its job is to provide easily discoverable (by method names lookup) and type safe access to configuration properties.
52  */
53 public class ApplicationSettings {
54
55     public static String responseCompatibility;
56
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;
59
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();
70
71     public ApplicationSettings(String[] args, Function1<String[], Map<String, String>> argsParser) {
72         this(args, argsParser, System.getProperty("user.dir"));
73     }
74
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         
85         loadedJsonSchemas = new JSonSchemasSupplier().loadJsonSchemas(collectorSchemaFile);
86         eventTransformations = loadEventTransformations();
87         responseCompatibility = getResponseCompatibilityFlag();
88     }
89
90     /**
91      * Reload application settings.
92      */
93     public void reload() {
94         try {
95             properties.load(configurationFileLocation);
96             properties.refresh();
97         } catch (ConfigurationException ex) {
98             log.error("Cannot load properties cause:", ex);
99             throw new ApplicationException(ex);
100         }
101     }
102
103     public Map<String, String> validAuthorizationCredentials() {
104         return prepareUsersMap(properties.getString("header.authlist", null));
105     }
106     public Path configurationFileLocation() {
107         return Paths.get(configurationFileLocation);
108     }
109
110     public boolean eventSchemaValidationEnabled() {
111         return properties.getInt("collector.schema.checkflag", DISABLED) > 0;
112     }
113
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."));
118     }
119
120     public boolean isVersionSupported(String version){
121        return loadedJsonSchemas.containsKey(version);
122     }
123
124     public int httpPort() {
125         return properties.getInt("collector.service.port", 8080);
126     }
127
128     public int httpsPort() {
129         return properties.getInt("collector.service.secure.port", 8443);
130     }
131
132     public int configurationUpdateFrequency() {
133         return properties.getInt("collector.dynamic.config.update.frequency", 5);
134     }
135
136     public boolean httpsEnabled() {
137         return httpsPort() > 0;
138     }
139
140     public boolean eventTransformingEnabled() {
141         return properties.getInt("event.transform.flag", ENABLED) > 0;
142     }
143
144     public String keystorePasswordFileLocation() {
145         return prependWithUserDirOnRelative(properties.getString("collector.keystore.passwordfile", "etc/passwordfile"));
146     }
147
148     public String keystoreFileLocation() {
149         return prependWithUserDirOnRelative(properties.getString("collector.keystore.file.location", "etc/keystore"));
150     }
151
152     public String truststorePasswordFileLocation() {
153         return prependWithUserDirOnRelative(properties.getString("collector.truststore.passwordfile", "etc/trustpasswordfile"));
154     }
155
156     public String truststoreFileLocation() {
157         return prependWithUserDirOnRelative(properties.getString("collector.truststore.file.location", "etc/truststore"));
158     }
159
160     public String exceptionConfigFileLocation() {
161         return properties.getString("exceptionConfig", null);
162     }
163
164     public String dMaaPConfigurationFileLocation() {
165         return prependWithUserDirOnRelative(properties.getString("collector.dmaapfile", "etc/ves-dmaap-config.json"));
166     }
167
168     public String certSubjectMatcher(){
169         return prependWithUserDirOnRelative(properties.getString("collector.cert.subject.matcher", "etc/certSubjectMatcher.properties"));
170     }
171
172     public String authMethod(){
173         return properties.getString("auth.method", AuthMethodType.NO_AUTH.value());
174     }
175
176     public Map<String, String> getDmaapStreamIds() {
177         String streamIdsProperty = properties.getString("collector.dmaap.streamid", null);
178         return streamIdsProperty == null ? HashMap.empty() : reduceStream(streamIdsProperty);
179     }
180
181     public boolean getExternalSchemaValidationCheckflag() {
182         return properties.getInt("collector.externalSchema.checkflag", DISABLED) > 0;
183     }
184
185     public String getExternalSchemaSchemasLocation() {
186         return properties.getString("collector.externalSchema.schemasLocation", "./etc/externalRepo");
187     }
188
189     public String getExternalSchemaMappingFileLocation() {
190         return properties.getString("collector.externalSchema.mappingFileLocation", "./etc/externalRepo/schema-map.json");
191     }
192
193     public String getExternalSchemaSchemaRefPath() {
194         return properties.getString("event.externalSchema.schemaRefPath", "/event/stndDefinedFields/schemaReference");
195     }
196
197     public String getExternalSchemaStndDefinedDataPath() {
198         return properties.getString("event.externalSchema.stndDefinedDataPath", "/event/stndDefinedFields/data");
199     }
200
201     public List<EventTransformation> getEventTransformations() {
202         return eventTransformations;
203     }
204
205     public String getApiVersionDescriptionFilepath() {
206         return properties.getString("collector.description.api.version.location", "etc/api_version_description.json");
207     }
208
209     private String getResponseCompatibilityFlag() {
210         return properties.getString("collector.response.compatibility", "v7.2");
211     }
212
213     private void loadPropertiesFromFile() {
214         try {
215             properties.load(configurationFileLocation);
216         } catch (ConfigurationException ex) {
217             log.error("Cannot load properties cause:", ex);
218             throw new ApplicationException(ex);
219         }
220     }
221
222     private void addOrUpdate(String key, String value) {
223         if (properties.containsKey(key)) {
224             properties.setProperty(key, value);
225         } else {
226             properties.addProperty(key, value);
227         }
228     }
229
230     private String findOutConfigurationFileLocation(Map<String, String> parsedArgs) {
231         return prependWithUserDirOnRelative(parsedArgs.get("c").getOrElse("etc/collector.properties"));
232     }
233
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());
239     }
240
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);
248         }
249         return HashMap.ofAll(domainToStreamIdsMapping);
250     }
251
252     private String prependWithUserDirOnRelative(String filePath) {
253         if (!Paths.get(filePath).isAbsolute()) {
254             filePath = Paths.get(appInvocationDir, filePath).toString();
255         }
256         return filePath;
257     }
258
259     private List<EventTransformation> loadEventTransformations() {
260         Type EVENT_TRANSFORM_LIST_TYPE = new TypeToken<List<EventTransformation>>() {}.getType();
261
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);
268         }
269     }
270
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;
276     }
277
278     @VisibleForTesting
279     String getStringDirectly(String key) {
280         return properties.getString(key);
281     }
282 }
283