14e836bebe24ffdeed6d09b294e219a87d02813a
[nonrtric.git] / policy-agent / src / main / java / org / oransc / policyagent / configuration / ApplicationConfigParser.java
1 /*-
2  * ========================LICENSE_START=================================
3  * O-RAN-SC
4  * %%
5  * Copyright (C) 2019 Nordix Foundation
6  * %%
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ========================LICENSE_END===================================
19  */
20
21 package org.oransc.policyagent.configuration;
22
23 import com.google.gson.JsonArray;
24 import com.google.gson.JsonElement;
25 import com.google.gson.JsonObject;
26
27 import java.util.ArrayList;
28 import java.util.HashMap;
29 import java.util.HashSet;
30 import java.util.Iterator;
31 import java.util.List;
32 import java.util.Map;
33 import java.util.Map.Entry;
34 import java.util.Set;
35
36 import javax.validation.constraints.NotNull;
37
38 import org.immutables.gson.Gson;
39 import org.immutables.value.Value;
40 import org.oransc.policyagent.exceptions.ServiceException;
41
42 /**
43  * Parser for the Json representing of the component configuration.
44  */
45 public class ApplicationConfigParser {
46
47     private static final String CONFIG = "config";
48     private static final String CONTROLLER = "controller";
49
50     @Value.Immutable
51     @Gson.TypeAdapters
52     public interface ConfigParserResult {
53         List<RicConfig> ricConfigs();
54
55         Map<String, ControllerConfig> controllerConfigs();
56
57         String dmaapConsumerTopicUrl();
58
59         String dmaapProducerTopicUrl();
60
61     }
62
63     public ConfigParserResult parse(JsonObject root) throws ServiceException {
64
65         String dmaapProducerTopicUrl = "";
66         String dmaapConsumerTopicUrl = "";
67
68         JsonObject agentConfigJson = root.getAsJsonObject(CONFIG);
69
70         if (agentConfigJson == null) {
71             throw new ServiceException("Missing root configuration \"" + CONFIG + "\" in JSON: " + root);
72         }
73
74         JsonObject json = agentConfigJson.getAsJsonObject("streams_publishes");
75         if (json != null) {
76             dmaapProducerTopicUrl = parseDmaapConfig(json);
77         }
78
79         json = agentConfigJson.getAsJsonObject("streams_subscribes");
80         if (json != null) {
81             dmaapConsumerTopicUrl = parseDmaapConfig(json);
82         }
83
84         List<RicConfig> ricConfigs = parseRics(agentConfigJson);
85         Map<String, ControllerConfig> controllerConfigs = parseControllerConfigs(agentConfigJson);
86         checkConfigurationConsistency(ricConfigs, controllerConfigs);
87
88         return ImmutableConfigParserResult.builder() //
89             .dmaapConsumerTopicUrl(dmaapConsumerTopicUrl) //
90             .dmaapProducerTopicUrl(dmaapProducerTopicUrl) //
91             .ricConfigs(ricConfigs) //
92             .controllerConfigs(controllerConfigs) //
93             .build();
94     }
95
96     private void checkConfigurationConsistency(List<RicConfig> ricConfigs,
97         Map<String, ControllerConfig> controllerConfigs) throws ServiceException {
98         Set<String> ricUrls = new HashSet<>();
99         Set<String> ricNames = new HashSet<>();
100         for (RicConfig ric : ricConfigs) {
101             if (!ricUrls.add(ric.baseUrl())) {
102                 throw new ServiceException("Configuration error, more than one RIC URL: " + ric.baseUrl());
103             }
104             if (!ricNames.add(ric.name())) {
105                 throw new ServiceException("Configuration error, more than one RIC with name: " + ric.name());
106             }
107             if (!ric.controllerName().isEmpty() && controllerConfigs.get(ric.controllerName()) == null) {
108                 throw new ServiceException(
109                     "Configuration error, controller configuration not found: " + ric.controllerName());
110             }
111
112         }
113     }
114
115     private List<RicConfig> parseRics(JsonObject config) throws ServiceException {
116         List<RicConfig> result = new ArrayList<>();
117         for (JsonElement ricElem : getAsJsonArray(config, "ric")) {
118             JsonObject ricAsJson = ricElem.getAsJsonObject();
119             JsonElement controllerNameElement = ricAsJson.get(CONTROLLER);
120             ImmutableRicConfig ricConfig = ImmutableRicConfig.builder() //
121                 .name(get(ricAsJson, "name").getAsString()) //
122                 .baseUrl(get(ricAsJson, "baseUrl").getAsString()) //
123                 .managedElementIds(parseManagedElementIds(get(ricAsJson, "managedElementIds").getAsJsonArray())) //
124                 .controllerName(controllerNameElement != null ? controllerNameElement.getAsString() : "") //
125                 .build();
126             result.add(ricConfig);
127         }
128         return result;
129     }
130
131     Map<String, ControllerConfig> parseControllerConfigs(JsonObject config) throws ServiceException {
132         if (config.get(CONTROLLER) == null) {
133             return new HashMap<>();
134         }
135         Map<String, ControllerConfig> result = new HashMap<>();
136         for (JsonElement element : getAsJsonArray(config, CONTROLLER)) {
137             JsonObject controllerAsJson = element.getAsJsonObject();
138             ImmutableControllerConfig controllerConfig = ImmutableControllerConfig.builder() //
139                 .name(get(controllerAsJson, "name").getAsString()) //
140                 .baseUrl(get(controllerAsJson, "baseUrl").getAsString()) //
141                 .password(get(controllerAsJson, "password").getAsString()) //
142                 .userName(get(controllerAsJson, "userName").getAsString()) // )
143                 .build();
144
145             if (result.put(controllerConfig.name(), controllerConfig) != null) {
146                 throw new ServiceException(
147                     "Configuration error, more than one controller with name: " + controllerConfig.name());
148             }
149         }
150         return result;
151     }
152
153     private List<String> parseManagedElementIds(JsonArray asJsonObject) {
154         Iterator<JsonElement> iterator = asJsonObject.iterator();
155         List<String> managedElementIds = new ArrayList<>();
156         while (iterator.hasNext()) {
157             managedElementIds.add(iterator.next().getAsString());
158
159         }
160         return managedElementIds;
161     }
162
163     private static JsonElement get(JsonObject obj, String memberName) throws ServiceException {
164         JsonElement elem = obj.get(memberName);
165         if (elem == null) {
166             throw new ServiceException("Could not find member: '" + memberName + "' in: " + obj);
167         }
168         return elem;
169     }
170
171     private JsonArray getAsJsonArray(JsonObject obj, String memberName) throws ServiceException {
172         return get(obj, memberName).getAsJsonArray();
173     }
174
175     private String parseDmaapConfig(JsonObject streamCfg) throws ServiceException {
176         Set<Entry<String, JsonElement>> streamConfigEntries = streamCfg.entrySet();
177         if (streamConfigEntries.size() != 1) {
178             throw new ServiceException(
179                 "Invalid configuration. Number of streams must be one, config: " + streamConfigEntries);
180         }
181         JsonObject streamConfigEntry = streamConfigEntries.iterator().next().getValue().getAsJsonObject();
182         JsonObject dmaapInfo = get(streamConfigEntry, "dmaap_info").getAsJsonObject();
183         return getAsString(dmaapInfo, "topic_url");
184     }
185
186     private static @NotNull String getAsString(JsonObject obj, String memberName) throws ServiceException {
187         return get(obj, memberName).getAsString();
188     }
189 }