2 * ============LICENSE_START======================================================================
3 * Copyright (C) 2018 NOKIA Intellectual Property, 2018-2019 Nordix Foundation. All rights reserved.
4 * ===============================================================================================
5 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
6 * in compliance with the License. You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software distributed under the License
11 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
12 * or implied. See the License for the specific language governing permissions and limitations under
14 * ============LICENSE_END========================================================================
17 package org.onap.dcaegen2.collectors.datafile.configuration;
19 import static org.assertj.core.api.Assertions.assertThat;
20 import static org.assertj.core.api.Assertions.assertThatThrownBy;
21 import static org.junit.Assert.assertTrue;
22 import static org.mockito.ArgumentMatchers.any;
23 import static org.mockito.Mockito.doReturn;
24 import static org.mockito.Mockito.mock;
25 import static org.mockito.Mockito.spy;
26 import static org.mockito.Mockito.times;
27 import static org.mockito.Mockito.verify;
28 import static org.mockito.Mockito.when;
30 import ch.qos.logback.classic.spi.ILoggingEvent;
31 import ch.qos.logback.core.read.ListAppender;
32 import com.google.common.base.Charsets;
33 import com.google.common.io.Resources;
34 import com.google.gson.JsonElement;
35 import com.google.gson.JsonIOException;
36 import com.google.gson.JsonObject;
37 import com.google.gson.JsonParser;
38 import com.google.gson.JsonSyntaxException;
39 import java.io.ByteArrayInputStream;
40 import java.io.IOException;
41 import java.io.InputStream;
42 import java.io.InputStreamReader;
44 import java.nio.charset.StandardCharsets;
46 import java.util.Properties;
47 import org.junit.jupiter.api.Assertions;
48 import org.junit.jupiter.api.BeforeEach;
49 import org.junit.jupiter.api.Test;
50 import org.onap.dcaegen2.collectors.datafile.exceptions.DatafileTaskException;
51 import org.onap.dcaegen2.collectors.datafile.model.logging.MappedDiagnosticContext;
52 import org.onap.dcaegen2.collectors.datafile.utils.LoggingUtils;
53 import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.http.configuration.EnvProperties;
54 import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.http.configuration.ImmutableEnvProperties;
55 import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.providers.CloudConfigurationProvider;
56 import org.onap.dcaegen2.services.sdk.rest.services.dmaap.client.config.ImmutableDmaapConsumerConfiguration;
57 import org.onap.dcaegen2.services.sdk.rest.services.dmaap.client.config.ImmutableDmaapPublisherConfiguration;
58 import reactor.core.publisher.Flux;
59 import reactor.core.publisher.Mono;
60 import reactor.test.StepVerifier;
63 * Tests the AppConfig.
65 * @author <a href="mailto:przemyslaw.wasala@nokia.com">Przemysław Wąsala</a> on 4/9/18
66 * @author <a href="mailto:henrik.b.andersson@est.tech">Henrik Andersson</a>
70 private static final String CHANGE_IDENTIFIER = "PM_MEAS_FILES";
73 private static final ImmutableDmaapConsumerConfiguration CORRECT_DMAAP_CONSUMER_CONFIG = //
74 new ImmutableDmaapConsumerConfiguration.Builder() //
76 .dmaapHostName("message-router.onap.svc.cluster.local") //
77 .dmaapUserName("admin") //
78 .dmaapUserPassword("admin") //
79 .dmaapTopicName("events/unauthenticated.VES_NOTIFICATION_OUTPUT") //
80 .dmaapPortNumber(2222) //
81 .dmaapContentType("application/json") //
83 .dmaapProtocol("http") //
85 .consumerGroup("OpenDcae-c12") //
86 .trustStorePath("trustStorePath") //
87 .trustStorePasswordPath("trustStorePasswordPath") //
88 .keyStorePath("keyStorePath") //
89 .keyStorePasswordPath("keyStorePasswordPath") //
90 .enableDmaapCertAuth(true) //
93 private static final ConsumerConfiguration CORRECT_CONSUMER_CONFIG = ImmutableConsumerConfiguration.builder() //
95 "http://admin:admin@message-router.onap.svc.cluster.local:2222/events/unauthenticated.VES_NOTIFICATION_OUTPUT/OpenDcae-c12/C12")
96 .trustStorePath("trustStorePath") //
97 .trustStorePasswordPath("trustStorePasswordPath") //
98 .keyStorePath("keyStorePath") //
99 .keyStorePasswordPath("keyStorePasswordPath") //
100 .enableDmaapCertAuth(true) //
103 private static final PublisherConfiguration CORRECT_PUBLISHER_CONFIG = //
104 ImmutablePublisherConfiguration.builder() //
105 .publishUrl("https://message-router.onap.svc.cluster.local:3907/publish/1") //
106 .logUrl("https://dmaap.example.com/feedlog/972").trustStorePath("trustStorePath") //
107 .trustStorePasswordPath("trustStorePasswordPath") //
108 .keyStorePath("keyStorePath") //
109 .keyStorePasswordPath("keyStorePasswordPath") //
110 .enableDmaapCertAuth(true) //
111 .changeIdentifier("PM_MEAS_FILES") //
113 .passWord("password") //
116 private static final ImmutableFtpesConfig CORRECT_FTPES_CONFIGURATION = //
117 new ImmutableFtpesConfig.Builder() //
118 .keyCert("/config/dfc.jks") //
119 .keyPassword("secret") //
120 .trustedCa("config/ftp.jks") //
121 .trustedCaPassword("secret") //
124 private static final ImmutableDmaapPublisherConfiguration CORRECT_DMAAP_PUBLISHER_CONFIG = //
125 new ImmutableDmaapPublisherConfiguration.Builder() //
126 .dmaapTopicName("/publish/1") //
127 .dmaapUserPassword("password") //
128 .dmaapPortNumber(3907) //
129 .dmaapProtocol("https") //
130 .dmaapContentType("application/octet-stream") //
131 .dmaapHostName("message-router.onap.svc.cluster.local") //
132 .dmaapUserName("user") //
133 .trustStorePath("trustStorePath") //
134 .trustStorePasswordPath("trustStorePasswordPath") //
135 .keyStorePath("keyStorePath") //
136 .keyStorePasswordPath("keyStorePasswordPath") //
137 .enableDmaapCertAuth(true) //
140 private static EnvProperties properties() {
141 return ImmutableEnvProperties.builder() //
142 .consulHost("host") //
144 .cbsName("cbsName") //
145 .appName("appName") //
149 private AppConfig appConfigUnderTest;
150 private CloudConfigurationProvider cloudConfigurationProvider = mock(CloudConfigurationProvider.class);
151 private final Map<String, String> context = MappedDiagnosticContext.initializeTraceContext();
155 public void setUp() {
156 appConfigUnderTest = spy(AppConfig.class);
157 appConfigUnderTest.setCloudConfigurationProvider(cloudConfigurationProvider);
158 appConfigUnderTest.systemEnvironment = new Properties();
162 public void whenTheConfigurationFits() throws IOException, DatafileTaskException {
164 doReturn(getCorrectJson()).when(appConfigUnderTest).createInputStream(any());
165 appConfigUnderTest.initialize();
168 verify(appConfigUnderTest, times(1)).loadConfigurationFromFile();
170 ConsumerConfiguration consumerCfg = appConfigUnderTest.getDmaapConsumerConfiguration();
171 Assertions.assertNotNull(consumerCfg);
172 assertThat(consumerCfg.toDmaap()).isEqualToComparingFieldByField(CORRECT_DMAAP_CONSUMER_CONFIG);
173 assertThat(consumerCfg).isEqualToComparingFieldByField(CORRECT_CONSUMER_CONFIG);
175 PublisherConfiguration publisherCfg = appConfigUnderTest.getPublisherConfiguration(CHANGE_IDENTIFIER);
176 Assertions.assertNotNull(publisherCfg);
177 assertThat(publisherCfg).isEqualToComparingFieldByField(CORRECT_PUBLISHER_CONFIG);
178 assertThat(publisherCfg.toDmaap()).isEqualToComparingFieldByField(CORRECT_DMAAP_PUBLISHER_CONFIG);
180 FtpesConfig ftpesConfig = appConfigUnderTest.getFtpesConfiguration();
181 assertThat(ftpesConfig).isNotNull();
182 assertThat(ftpesConfig).isEqualToComparingFieldByField(CORRECT_FTPES_CONFIGURATION);
186 public void whenTheConfigurationFits_twoProducers() throws IOException, DatafileTaskException {
188 doReturn(getCorrectJsonTwoProducers()).when(appConfigUnderTest).createInputStream(any());
189 appConfigUnderTest.loadConfigurationFromFile();
192 verify(appConfigUnderTest, times(1)).loadConfigurationFromFile();
193 Assertions.assertNotNull(appConfigUnderTest.getDmaapConsumerConfiguration());
194 Assertions.assertNotNull(appConfigUnderTest.getPublisherConfiguration(CHANGE_IDENTIFIER));
195 Assertions.assertNotNull(appConfigUnderTest.getPublisherConfiguration("XX_FILES"));
196 Assertions.assertNotNull(appConfigUnderTest.getPublisherConfiguration("YY_FILES"));
198 assertThat(appConfigUnderTest.getPublisherConfiguration("XX_FILES").publishUrl())
199 .isEqualTo("feed01::publish_url");
200 assertThat(appConfigUnderTest.getPublisherConfiguration("YY_FILES").publishUrl())
201 .isEqualTo("feed01::publish_url");
205 public void whenFileIsNotExist_ThrowException() throws DatafileTaskException {
207 appConfigUnderTest.setFilepath("/temp.json");
209 ListAppender<ILoggingEvent> logAppender = LoggingUtils.getLogListAppender(AppConfig.class);
212 appConfigUnderTest.loadConfigurationFromFile();
215 assertTrue("Error message missing in log.",
216 logAppender.list.toString().contains("[WARN] Local configuration file not loaded: /temp.json"));
219 Assertions.assertNull(appConfigUnderTest.getDmaapConsumerConfiguration());
220 assertThatThrownBy(() -> appConfigUnderTest.getPublisherConfiguration(CHANGE_IDENTIFIER))
221 .hasMessageContaining("No PublishingConfiguration loaded, changeIdentifier: PM_MEAS_FILES");
222 Assertions.assertNull(appConfigUnderTest.getFtpesConfiguration());
226 public void whenFileIsExistsButJsonIsIncorrect() throws IOException, DatafileTaskException {
229 doReturn(getIncorrectJson()).when(appConfigUnderTest).createInputStream(any());
230 appConfigUnderTest.loadConfigurationFromFile();
233 verify(appConfigUnderTest, times(1)).loadConfigurationFromFile();
234 Assertions.assertNull(appConfigUnderTest.getDmaapConsumerConfiguration());
235 assertThatThrownBy(() -> appConfigUnderTest.getPublisherConfiguration(CHANGE_IDENTIFIER))
236 .hasMessageContaining(CHANGE_IDENTIFIER);
237 Assertions.assertNull(appConfigUnderTest.getFtpesConfiguration());
241 public void whenTheConfigurationFits_ButRootElementIsNotAJsonObject() throws IOException, DatafileTaskException {
244 doReturn(getCorrectJson()).when(appConfigUnderTest).createInputStream(any());
245 JsonElement jsonElement = mock(JsonElement.class);
246 when(jsonElement.isJsonObject()).thenReturn(false);
247 doReturn(jsonElement).when(appConfigUnderTest).getJsonElement(any(JsonParser.class), any(InputStream.class));
248 appConfigUnderTest.loadConfigurationFromFile();
251 verify(appConfigUnderTest, times(1)).loadConfigurationFromFile();
252 Assertions.assertNull(appConfigUnderTest.getDmaapConsumerConfiguration());
253 assertThatThrownBy(() -> appConfigUnderTest.getPublisherConfiguration(CHANGE_IDENTIFIER))
254 .hasMessageContaining(CHANGE_IDENTIFIER);
255 Assertions.assertNull(appConfigUnderTest.getFtpesConfiguration());
259 public void whenPeriodicConfigRefreshNoEnvironmentVariables() {
260 ListAppender<ILoggingEvent> logAppender = LoggingUtils.getLogListAppender(AppConfig.class);
262 Flux<AppConfig> task = appConfigUnderTest.createRefreshConfigurationTask(1L, context);
266 .expectSubscription() //
267 .expectNextCount(0) //
270 assertTrue(logAppender.list.toString().contains("$CONSUL_HOST environment has not been defined"));
274 public void whenPeriodicConfigRefreshNoConsul() {
276 doReturn(Mono.just(properties())).when(appConfigUnderTest).readEnvironmentVariables(any(), any());
277 Mono<JsonObject> err = Mono.error(new IOException());
278 doReturn(err).when(cloudConfigurationProvider).callForServiceConfigurationReactive(any());
280 ListAppender<ILoggingEvent> logAppender = LoggingUtils.getLogListAppender(AppConfig.class);
281 Flux<AppConfig> task = appConfigUnderTest.createRefreshConfigurationTask(1L, context);
285 .expectSubscription() //
286 .expectNextCount(0) //
289 assertTrue(logAppender.list.toString()
290 .contains("Could not refresh application configuration java.io.IOException"));
294 public void whenPeriodicConfigRefreshSuccess() throws JsonIOException, JsonSyntaxException, IOException {
295 doReturn(Mono.just(properties())).when(appConfigUnderTest).readEnvironmentVariables(any(), any());
297 Mono<JsonObject> json = Mono.just(getJsonRootObject());
299 doReturn(json, json).when(cloudConfigurationProvider).callForServiceConfigurationReactive(any());
301 Flux<AppConfig> task = appConfigUnderTest.createRefreshConfigurationTask(1L, context);
305 .expectSubscription() //
306 .expectNext(appConfigUnderTest) //
309 Assertions.assertNotNull(appConfigUnderTest.getDmaapConsumerConfiguration());
313 public void whenPeriodicConfigRefreshSuccess2() throws JsonIOException, JsonSyntaxException, IOException {
314 doReturn(Mono.just(properties())).when(appConfigUnderTest).readEnvironmentVariables(any(), any());
316 Mono<JsonObject> json = Mono.just(getJsonRootObject());
317 Mono<JsonObject> err = Mono.error(new IOException()); // no config entry created by the dmaap plugin
319 doReturn(json, err).when(cloudConfigurationProvider).callForServiceConfigurationReactive(any());
321 Flux<AppConfig> task = appConfigUnderTest.createRefreshConfigurationTask(1L, context);
325 .expectSubscription() //
326 .expectNext(appConfigUnderTest) //
329 Assertions.assertNotNull(appConfigUnderTest.getDmaapConsumerConfiguration());
332 private JsonObject getJsonRootObject() throws JsonIOException, JsonSyntaxException, IOException {
333 JsonObject rootObject = (new JsonParser()).parse(new InputStreamReader(getCorrectJson())).getAsJsonObject();
337 private static InputStream getCorrectJson() throws IOException {
338 URL url = CloudConfigParser.class.getClassLoader().getResource("datafile_endpoints_test.json");
339 String string = Resources.toString(url, Charsets.UTF_8);
340 return new ByteArrayInputStream((string.getBytes(StandardCharsets.UTF_8)));
343 private static InputStream getCorrectJsonTwoProducers() throws IOException {
344 URL url = CloudConfigParser.class.getClassLoader().getResource("datafile_endpoints_test_2producers.json");
345 String string = Resources.toString(url, Charsets.UTF_8);
346 return new ByteArrayInputStream((string.getBytes(StandardCharsets.UTF_8)));
349 private static InputStream getIncorrectJson() {
350 String string = "{" + //
351 " \"configs\": {" + //
353 return new ByteArrayInputStream((string.getBytes(StandardCharsets.UTF_8)));