blob: ab6128db3fa8c13b615fd8e403ad2176d90bdb66 [file] [log] [blame]
David K. Bainbridgeeda2b052017-07-12 09:41:04 -07001/*
2 * Copyright 2017-present Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.opencord.sadis;
17
18import java.io.IOException;
19import java.net.MalformedURLException;
20import java.net.URL;
21import java.time.Duration;
22import java.util.ArrayList;
23import java.util.List;
24
25import org.onlab.packet.VlanId;
26import org.onosproject.core.ApplicationId;
27import org.onosproject.net.config.Config;
28import org.slf4j.Logger;
29import org.slf4j.LoggerFactory;
30
31import com.fasterxml.jackson.core.JsonParser;
32import com.fasterxml.jackson.core.JsonProcessingException;
33import com.fasterxml.jackson.core.ObjectCodec;
34import com.fasterxml.jackson.databind.DeserializationContext;
35import com.fasterxml.jackson.databind.JsonDeserializer;
36import com.fasterxml.jackson.databind.JsonNode;
37import com.fasterxml.jackson.databind.ObjectMapper;
38import com.fasterxml.jackson.databind.module.SimpleModule;
39
40/**
41 * Configuration options for the Subscriber And Device Information Service.
42 *
43 * <pre>
44 * "sadis" : {
45 * "integration" : {
46 * "url" : "http://{hostname}{:port}",
47 * "cache" : {
48 * "enable" : true or false,
49 * "maxsize" : number of entries,
50 * "entryttl" : duration, i.e. 10s or 1m
51 * }
52 * },
53 * "entries" : [
54 * {
55 * "id" : "uniqueid",
56 * "ctag" : int,
57 * "stag" : int,
58 * "nasportid" : string,
59 * "port" : int,
60 * "slot" : int,
61 * "hardwareidentifier" : string
62 * }, ...
63 * ]
64 * }
65 * </pre>
66 */
67public class SadisConfig extends Config<ApplicationId> {
68
69 private final Logger log = LoggerFactory.getLogger(this.getClass());
70
71 private static final String SADIS_INTEGRATION = "integration";
72 private static final String SADIS_CACHE = "cache";
73 private static final String SADIS_CACHE_ENABLED = "enabled";
74 private static final String SADIS_CACHE_SIZE = "maxsize";
75 private static final String SADIS_CACHE_TTL = "ttl";
76 private static final String SADIS_URL = "url";
77 private static final String SADIS_ENTRIES = "entries";
78 private static final String DEFAULT_CACHE_TTL = "PT0S";
79
80 /**
81 * Returns SADIS integration URL.
82 *
83 * @return configured URL or null
84 * @throws MalformedURLException
85 * specified URL not valid
86 */
87 public URL getUrl() throws MalformedURLException {
88 final JsonNode integration = this.object.path(SADIS_INTEGRATION);
89 if (integration.isMissingNode()) {
90 return null;
91 }
92
93 final JsonNode url = integration.path(SADIS_URL);
94 if (url.isMissingNode()) {
95 return null;
96 }
97
98 return new URL(url.asText());
99 }
100
101 /**
102 * Returns configuration if cache should be used or not. Only used if
103 * integration URL is set.
104 *
105 * @return if cache should be used
106 */
107 public Boolean getCacheEnabled() {
108 final JsonNode integration = this.object.path(SADIS_INTEGRATION);
109 if (integration.isMissingNode()) {
110 return false;
111 }
112
113 final JsonNode cache = integration.path(SADIS_CACHE);
114 if (cache.isMissingNode()) {
115 return false;
116 }
117
118 return cache.path(SADIS_CACHE_ENABLED).asBoolean(false);
119 }
120
121 public int getCacheMaxSize() {
122 final JsonNode integration = this.object.path(SADIS_INTEGRATION);
123 if (integration.isMissingNode()) {
124 return -1;
125 }
126
127 final JsonNode cache = integration.path(SADIS_CACHE);
128 if (cache.isMissingNode()) {
129 return -1;
130 }
131
132 return cache.path(SADIS_CACHE_SIZE).asInt(-1);
133 }
134
135 public Duration getCacheTtl() {
136 final JsonNode integration = this.object.path(SADIS_INTEGRATION);
137 if (integration.isMissingNode()) {
138 return Duration.parse(DEFAULT_CACHE_TTL);
139 }
140
141 final JsonNode cache = integration.path(SADIS_CACHE);
142 if (cache.isMissingNode()) {
143 return Duration.parse(DEFAULT_CACHE_TTL);
144 }
145
146 return Duration.parse(cache.path(SADIS_CACHE_TTL).asText(DEFAULT_CACHE_TTL));
147 }
148
149 public List<SubscriberAndDeviceInformation> getEntries() {
150 List<SubscriberAndDeviceInformation> result = new ArrayList<SubscriberAndDeviceInformation>();
151 ObjectMapper mapper = new ObjectMapper();
152 SimpleModule module = new SimpleModule();
153 module.addDeserializer(VlanId.class, new VlanIdDeserializer());
154 mapper.registerModule(module);
155 final JsonNode entries = this.object.path(SADIS_ENTRIES);
156 entries.forEach(entry -> {
157 try {
158 result.add(mapper.readValue(entry.toString(), SubscriberAndDeviceInformation.class));
159 } catch (IOException e) {
160 log.warn("Unable to parse configuration entry, '{}', error: {}", entry.toString(), e.getMessage());
161 }
162 });
163
164 return result;
165 }
166
167 public class VlanIdDeserializer extends JsonDeserializer<VlanId> {
168 @Override
169 public VlanId deserialize(JsonParser jp, DeserializationContext ctxt)
170 throws IOException, JsonProcessingException {
171 ObjectCodec oc = jp.getCodec();
172 JsonNode node = oc.readTree(jp);
173 return VlanId.vlanId((short) node.asInt());
174 }
175 }
176}