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
9 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
20 package org.onap.dcae.analytics.tca.web.validation;
23 import java.net.MalformedURLException;
25 import java.util.LinkedList;
26 import java.util.List;
28 import java.util.stream.Collectors;
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;
42 * Validator for {@link TcaAppProperties}. This validator is used by spring at start up time to validate
43 * TCA Application properties
45 * @author Rajiv Singla
47 public class TcaAppPropertiesValidator implements Validator {
49 private static final Logger logger = LoggerFactory.getLogger(TcaAppPropertiesValidator.class);
52 public boolean supports(final Class<?> type) {
53 return type == TcaAppProperties.class;
57 public void validate(@Nullable final Object props, final Errors errors) {
60 errors.rejectValue(ConfigBindingServiceConstants.CONFIG_BINDING_SERVICE_PROPERTIES_KEY,
61 "TCA App Properties are not present");
65 final TcaAppProperties tcaAppProperties = (TcaAppProperties) props;
67 logger.info("Validating TCA App Properties: {}", tcaAppProperties);
69 final Map<String, PublisherDetails> streamsPublishes = tcaAppProperties.getStreamsPublishes();
70 final Map<String, SubscriberDetails> streamsSubscribes = tcaAppProperties.getStreamsSubscribes();
72 // Validate that stream publishes has at least 1 publisher and subscriber
73 if (!validatePubSubArePresent(errors, streamsPublishes, streamsSubscribes)) {
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()) {
84 //Confirm each message router has dmaap info and their url is present and valid
85 validateMRProperties(errors, pubSubMRCommonDetails);
87 // validated aai properties
88 validateAAIProperties(errors, tcaAppProperties.getTca().getAai());
90 logger.info("Validation of TCA App Properties completed successfully");
95 private void validateAAIProperties(final Errors errors, final TcaAppProperties.Aai aai) {
96 new ConfigPropertiesAaiValidator().validate(aai, errors);
99 private void validateMRProperties(final Errors errors,
100 final List<? super PubSubCommonDetails> pubSubMRCommonDetails) {
102 for (Object pubSubMRCommonDetail : pubSubMRCommonDetails) {
103 final PubSubCommonDetails mrDetails = (PubSubCommonDetails) pubSubMRCommonDetail;
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);
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);
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);
126 private List<? super PubSubCommonDetails> validatePubSubHasMRDetails(
128 final Map<String, PublisherDetails> streamsPublishes,
129 final Map<String, SubscriberDetails> streamsSubscribes) {
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");
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");
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())
157 return pubSubMRCommonDetails;
160 private boolean validatePubSubArePresent(final Errors errors,
161 final Map<String, PublisherDetails> streamsPublishes,
162 final Map<String, SubscriberDetails>
164 if (streamsPublishes.isEmpty()) {
165 errors.rejectValue("streams_publishes", "Streams publishes must define at least 1 publisher");
168 if (streamsSubscribes.isEmpty()) {
169 errors.rejectValue("streams_subscribes", "Streams subscribes must define at least 1 subscriber");
176 private static boolean isURLValid(final String urlString) {
180 } catch (MalformedURLException ex) {