Standalone TCA with EELF Logger
[dcaegen2/analytics/tca-gen2.git] / dcae-analytics / dcae-analytics-tca-web / src / main / java / org / onap / dcae / analytics / tca / web / validation / TcaAppPropertiesValidator.java
1 /*
2  * ================================================================================
3  * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
4  * ================================================================================
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  * ============LICENSE_END=========================================================
17  *
18  */
19
20 package org.onap.dcae.analytics.tca.web.validation;
21
22
23 import java.net.MalformedURLException;
24 import java.net.URL;
25 import java.util.LinkedList;
26 import java.util.List;
27 import java.util.Map;
28 import java.util.stream.Collectors;
29
30 import org.onap.dcae.analytics.model.configbindingservice.BaseConfigBindingServiceProperties.PubSubCommonDetails;
31 import org.onap.dcae.analytics.model.configbindingservice.BaseConfigBindingServiceProperties.PublisherDetails;
32 import org.onap.dcae.analytics.model.configbindingservice.BaseConfigBindingServiceProperties.SubscriberDetails;
33 import org.onap.dcae.analytics.model.configbindingservice.ConfigBindingServiceConstants;
34 import org.onap.dcae.analytics.tca.web.TcaAppProperties;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
37 import org.springframework.lang.Nullable;
38 import org.springframework.validation.Errors;
39 import org.springframework.validation.Validator;
40
41 /**
42  * Validator for {@link TcaAppProperties}. This validator is used by spring at start up time to validate
43  * TCA Application properties
44  *
45  * @author Rajiv Singla
46  */
47 public class TcaAppPropertiesValidator implements Validator {
48
49     private static final Logger logger = LoggerFactory.getLogger(TcaAppPropertiesValidator.class);
50
51     @Override
52     public boolean supports(final Class<?> type) {
53         return type == TcaAppProperties.class;
54     }
55
56     @Override
57     public void validate(@Nullable final Object props, final Errors errors) {
58
59         if (props == null) {
60             errors.rejectValue(ConfigBindingServiceConstants.CONFIG_BINDING_SERVICE_PROPERTIES_KEY,
61                     "TCA App Properties are not present");
62             return;
63         }
64
65         final TcaAppProperties tcaAppProperties = (TcaAppProperties) props;
66
67         logger.info("Validating TCA App Properties: {}", tcaAppProperties);
68
69         final Map<String, PublisherDetails> streamsPublishes = tcaAppProperties.getStreamsPublishes();
70         final Map<String, SubscriberDetails> streamsSubscribes = tcaAppProperties.getStreamsSubscribes();
71
72         // Validate that stream publishes has at least 1 publisher and subscriber
73         if (!validatePubSubArePresent(errors, streamsPublishes, streamsSubscribes)) {
74             return;
75         }
76
77         // Validate that streams publishes and subscribes has at least one message router
78         List<? super PubSubCommonDetails> pubSubMRCommonDetails =
79                 validatePubSubHasMRDetails(errors, streamsPublishes, streamsSubscribes);
80         if (pubSubMRCommonDetails.isEmpty()) {
81             return;
82         }
83
84         //Confirm each message router has dmaap info and their url is present and valid
85         validateMRProperties(errors, pubSubMRCommonDetails);
86
87         // validated aai properties
88         validateAAIProperties(errors, tcaAppProperties.getTca().getAai());
89
90         logger.info("Validation of TCA App Properties completed successfully");
91
92     }
93
94
95     private void validateAAIProperties(final Errors errors, final TcaAppProperties.Aai aai) {
96         new ConfigPropertiesAaiValidator().validate(aai, errors);
97     }
98
99     private void validateMRProperties(final Errors errors,
100                                       final List<? super PubSubCommonDetails> pubSubMRCommonDetails) {
101
102         for (Object pubSubMRCommonDetail : pubSubMRCommonDetails) {
103             final PubSubCommonDetails mrDetails = (PubSubCommonDetails) pubSubMRCommonDetail;
104
105             if (mrDetails.getDmaapInfo() == null || mrDetails.getDmaapInfo().getTopicUrl() == null) {
106                 errors.rejectValue("dmaap_info",
107                         "dmaap_info url not present for MR configuration properties: " + mrDetails);
108             }
109
110             if (mrDetails.getDmaapInfo() != null && mrDetails.getDmaapInfo().getTopicUrl() != null
111                     && !isURLValid(mrDetails.getDmaapInfo().getTopicUrl())) {
112                 errors.rejectValue("topic_url",
113                         "Invalid MR Topic URL in configuration properties:" + mrDetails);
114
115             }
116
117             if (mrDetails.getProxyUrl() != null && !mrDetails.getProxyUrl().trim().isEmpty()
118                     && !isURLValid(mrDetails.getProxyUrl())) {
119                 errors.rejectValue("proxy_url",
120                         "Invalid Proxy url in configuration properties:" + mrDetails);
121             }
122         }
123
124     }
125
126     private List<? super PubSubCommonDetails> validatePubSubHasMRDetails(
127             final Errors errors,
128             final Map<String, PublisherDetails> streamsPublishes,
129             final Map<String, SubscriberDetails> streamsSubscribes) {
130
131         final List<Map.Entry<String, PublisherDetails>> messageRouterPublishers =
132                 streamsPublishes.entrySet().stream()
133                         .filter(ConfigBindingServiceConstants.MESSAGE_ROUTER_PREDICATE)
134                         .collect(Collectors.toList());
135         if (messageRouterPublishers.isEmpty()) {
136             errors.rejectValue("stream_publishes",
137                     "Stream publishes must contain at least 1 message router publisher");
138         }
139
140         final List<Map.Entry<String, SubscriberDetails>> messageRouterSubscribers =
141                 streamsSubscribes.entrySet().stream()
142                         .filter(ConfigBindingServiceConstants.MESSAGE_ROUTER_PREDICATE)
143                         .collect(Collectors.toList());
144         if (messageRouterSubscribers.isEmpty()) {
145             errors.rejectValue("stream_subscribes",
146                     "Stream subscriber must contain at least 1 message router subscriber");
147         }
148
149         // create common pub sub MR list
150         final List<? super PubSubCommonDetails> pubSubMRCommonDetails = new LinkedList<>();
151         pubSubMRCommonDetails.addAll(messageRouterPublishers.stream()
152                 .map(Map.Entry::getValue).collect(Collectors.toList()));
153         pubSubMRCommonDetails.addAll(messageRouterSubscribers.stream()
154                 .map(Map.Entry::getValue).collect(Collectors.toList())
155         );
156
157         return pubSubMRCommonDetails;
158     }
159
160     private boolean validatePubSubArePresent(final Errors errors,
161                                              final Map<String, PublisherDetails> streamsPublishes,
162                                              final Map<String, SubscriberDetails>
163                                                      streamsSubscribes) {
164         if (streamsPublishes.isEmpty()) {
165             errors.rejectValue("streams_publishes", "Streams publishes must define at least 1 publisher");
166             return false;
167         }
168         if (streamsSubscribes.isEmpty()) {
169             errors.rejectValue("streams_subscribes", "Streams subscribes must define at least 1 subscriber");
170             return false;
171         }
172
173         return true;
174     }
175
176     private static boolean isURLValid(final String urlString) {
177         try {
178             new URL(urlString);
179             return true;
180         } catch (MalformedURLException ex) {
181             return false;
182         }
183     }
184
185
186 }