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