Implementing net config subsystem and revising its interfaces.
Added a few basic configs for device, host and links. Added initial REST API. Added CLI. Tests remain to be added. Change-Id: Ic7bba4b5ad7d553c51d69f6459b3bff146970323
Showing
28 changed files
with
2243 additions
and
64 deletions
1 | +/* | ||
2 | + * Copyright 2015 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 | + */ | ||
16 | +package org.onosproject.cli.cfg; | ||
17 | + | ||
18 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
19 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
20 | +import org.apache.karaf.shell.commands.Argument; | ||
21 | +import org.apache.karaf.shell.commands.Command; | ||
22 | +import org.onosproject.cli.AbstractShellCommand; | ||
23 | +import org.onosproject.incubator.net.config.Config; | ||
24 | +import org.onosproject.incubator.net.config.NetworkConfigService; | ||
25 | +import org.onosproject.incubator.net.config.SubjectFactory; | ||
26 | + | ||
27 | +import static com.google.common.base.Strings.isNullOrEmpty; | ||
28 | + | ||
29 | +/** | ||
30 | + * Manages network configuration. | ||
31 | + */ | ||
32 | +@Command(scope = "onos", name = "netcfg", | ||
33 | + description = "Manages network configuration") | ||
34 | +public class NetworkConfigCommand extends AbstractShellCommand { | ||
35 | + | ||
36 | + @Argument(index = 0, name = "subjectKey", description = "Subject key", | ||
37 | + required = false, multiValued = false) | ||
38 | + String subjectKey = null; | ||
39 | + | ||
40 | + @Argument(index = 1, name = "subject", description = "Subject", | ||
41 | + required = false, multiValued = false) | ||
42 | + String subject = null; | ||
43 | + | ||
44 | + @Argument(index = 2, name = "configKey", description = "Config key", | ||
45 | + required = false, multiValued = false) | ||
46 | + String configKey = null; | ||
47 | + | ||
48 | + private final ObjectMapper mapper = new ObjectMapper(); | ||
49 | + private NetworkConfigService service; | ||
50 | + | ||
51 | + @Override | ||
52 | + protected void execute() { | ||
53 | + service = get(NetworkConfigService.class); | ||
54 | + ObjectNode root = new ObjectMapper().createObjectNode(); | ||
55 | + if (isNullOrEmpty(subjectKey)) { | ||
56 | + addAll(root); | ||
57 | + } else { | ||
58 | + SubjectFactory subjectFactory = service.getSubjectFactory(subjectKey); | ||
59 | + if (isNullOrEmpty(subject)) { | ||
60 | + addSubjectClass(root, subjectFactory); | ||
61 | + } else { | ||
62 | + Object s = subjectFactory.createSubject(subject); | ||
63 | + if (isNullOrEmpty(configKey)) { | ||
64 | + addSubject(root, s); | ||
65 | + } else { | ||
66 | + addSubjectConfig(root, getConfig(s, configKey)); | ||
67 | + } | ||
68 | + } | ||
69 | + } | ||
70 | + print("%s", root.toString()); | ||
71 | + } | ||
72 | + | ||
73 | + @SuppressWarnings("unchecked") | ||
74 | + private void addAll(ObjectNode root) { | ||
75 | + service.getSubjectClasses() | ||
76 | + .forEach(sc -> { | ||
77 | + SubjectFactory sf = service.getSubjectFactory((Class) sc); | ||
78 | + addSubjectClass(newObject(root, sf.subjectKey()), sf); | ||
79 | + }); | ||
80 | + } | ||
81 | + | ||
82 | + @SuppressWarnings("unchecked") | ||
83 | + private void addSubjectClass(ObjectNode root, SubjectFactory sf) { | ||
84 | + service.getSubjects(sf.subjectClass()) | ||
85 | + .forEach(s -> addSubject(newObject(root, s.toString()), s)); | ||
86 | + } | ||
87 | + | ||
88 | + private void addSubject(ObjectNode root, Object s) { | ||
89 | + service.getConfigs(s) | ||
90 | + .forEach(c -> addSubjectConfig(newObject(root, c.key()), getConfig(s, c.key()))); | ||
91 | + } | ||
92 | + | ||
93 | + private void addSubjectConfig(ObjectNode root, Config config) { | ||
94 | + if (config != null) { | ||
95 | + root.set(config.key(), config.node()); | ||
96 | + } | ||
97 | + } | ||
98 | + | ||
99 | + private Config getConfig(Object s, String ck) { | ||
100 | + Class<? extends Config> configClass = service.getConfigClass(ck); | ||
101 | + return configClass != null ? service.getConfig(s, configClass) : null; | ||
102 | + } | ||
103 | + | ||
104 | + private ObjectNode newObject(ObjectNode parent, String key) { | ||
105 | + ObjectNode node = mapper.createObjectNode(); | ||
106 | + parent.set(key, node); | ||
107 | + return node; | ||
108 | + } | ||
109 | +} |
1 | +/* | ||
2 | + * Copyright 2015 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 | + */ | ||
16 | +package org.onosproject.cli.cfg; | ||
17 | + | ||
18 | +import org.apache.karaf.shell.commands.Command; | ||
19 | +import org.apache.karaf.shell.commands.Option; | ||
20 | +import org.onosproject.cli.AbstractShellCommand; | ||
21 | +import org.onosproject.incubator.net.config.ConfigFactory; | ||
22 | +import org.onosproject.incubator.net.config.NetworkConfigRegistry; | ||
23 | + | ||
24 | +/** | ||
25 | + * Displays network configuration registry contents. | ||
26 | + */ | ||
27 | +@Command(scope = "onos", name = "netcfg-registry", | ||
28 | + description = "Displays network configuration registry contents") | ||
29 | +public class NetworkConfigRegistryCommand extends AbstractShellCommand { | ||
30 | + | ||
31 | + private static final String FMT = "subjectKey=%s, configKey=%s, subjectClass=%s, configClass=%s"; | ||
32 | + private static final String SHORT_FMT = "%-12s %-12s %-40s %s"; | ||
33 | + | ||
34 | + @Option(name = "-s", aliases = "--short", description = "Show short output only", | ||
35 | + required = false, multiValued = false) | ||
36 | + private boolean shortOnly = false; | ||
37 | + | ||
38 | + @Override | ||
39 | + protected void execute() { | ||
40 | + get(NetworkConfigRegistry.class).getConfigFactories().forEach(this::print); | ||
41 | + } | ||
42 | + | ||
43 | + private void print(ConfigFactory configFactory) { | ||
44 | + print(shortOnly ? SHORT_FMT : FMT, | ||
45 | + configFactory.subjectFactory().subjectKey(), | ||
46 | + configFactory.configKey(), | ||
47 | + configFactory.subjectFactory().subjectClass().getName(), | ||
48 | + configFactory.configClass().getName()); | ||
49 | + } | ||
50 | + | ||
51 | +} |
... | @@ -15,6 +15,6 @@ | ... | @@ -15,6 +15,6 @@ |
15 | */ | 15 | */ |
16 | 16 | ||
17 | /** | 17 | /** |
18 | - * CLI commands for managing centralized component configuration. | 18 | + * CLI commands for managing centralized component and network configurations. |
19 | */ | 19 | */ |
20 | package org.onosproject.cli.cfg; | 20 | package org.onosproject.cli.cfg; |
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
... | @@ -51,6 +51,14 @@ | ... | @@ -51,6 +51,14 @@ |
51 | </command> | 51 | </command> |
52 | 52 | ||
53 | <command> | 53 | <command> |
54 | + <action class="org.onosproject.cli.cfg.NetworkConfigRegistryCommand"/> | ||
55 | + </command> | ||
56 | + | ||
57 | + <command> | ||
58 | + <action class="org.onosproject.cli.cfg.NetworkConfigCommand"/> | ||
59 | + </command> | ||
60 | + | ||
61 | + <command> | ||
54 | <action class="org.onosproject.cli.MetricsListCommand"/> | 62 | <action class="org.onosproject.cli.MetricsListCommand"/> |
55 | </command> | 63 | </command> |
56 | 64 | ... | ... |
... | @@ -17,7 +17,11 @@ package org.onosproject.net; | ... | @@ -17,7 +17,11 @@ package org.onosproject.net; |
17 | 17 | ||
18 | /** | 18 | /** |
19 | * Collection of keys for annotation. | 19 | * Collection of keys for annotation. |
20 | - * Definitions of annotation keys needs to be here to avoid scattering. | 20 | + * <p> |
21 | + * Number of the annotation keys have been deprecated as the use of annotations | ||
22 | + * is being phased out and instead network configuration subsystem is being | ||
23 | + * phased-in for majority of model meta-data. | ||
24 | + * </p> | ||
21 | */ | 25 | */ |
22 | public final class AnnotationKeys { | 26 | public final class AnnotationKeys { |
23 | 27 | ||
... | @@ -26,22 +30,34 @@ public final class AnnotationKeys { | ... | @@ -26,22 +30,34 @@ public final class AnnotationKeys { |
26 | 30 | ||
27 | /** | 31 | /** |
28 | * Annotation key for instance name. | 32 | * Annotation key for instance name. |
33 | + * | ||
34 | + * @deprecated since Cardinal | ||
29 | */ | 35 | */ |
36 | + @Deprecated | ||
30 | public static final String NAME = "name"; | 37 | public static final String NAME = "name"; |
31 | 38 | ||
32 | /** | 39 | /** |
33 | * Annotation key for instance type (e.g. host type). | 40 | * Annotation key for instance type (e.g. host type). |
41 | + * | ||
42 | + * @deprecated since Cardinal | ||
34 | */ | 43 | */ |
44 | + @Deprecated | ||
35 | public static final String TYPE = "type"; | 45 | public static final String TYPE = "type"; |
36 | 46 | ||
37 | /** | 47 | /** |
38 | * Annotation key for latitude (e.g. latitude of device). | 48 | * Annotation key for latitude (e.g. latitude of device). |
49 | + * | ||
50 | + * @deprecated since Cardinal | ||
39 | */ | 51 | */ |
52 | + @Deprecated | ||
40 | public static final String LATITUDE = "latitude"; | 53 | public static final String LATITUDE = "latitude"; |
41 | 54 | ||
42 | /** | 55 | /** |
43 | * Annotation key for longitute (e.g. longitude of device). | 56 | * Annotation key for longitute (e.g. longitude of device). |
57 | + * | ||
58 | + * @deprecated since Cardinal | ||
44 | */ | 59 | */ |
60 | + @Deprecated | ||
45 | public static final String LONGITUDE = "longitude"; | 61 | public static final String LONGITUDE = "longitude"; |
46 | 62 | ||
47 | /** | 63 | /** |
... | @@ -51,7 +67,10 @@ public final class AnnotationKeys { | ... | @@ -51,7 +67,10 @@ public final class AnnotationKeys { |
51 | 67 | ||
52 | /** | 68 | /** |
53 | * Annotation key for the device driver name. | 69 | * Annotation key for the device driver name. |
70 | + * | ||
71 | + * @deprecated since Cardinal | ||
54 | */ | 72 | */ |
73 | + @Deprecated | ||
55 | public static final String DRIVER = "driver"; | 74 | public static final String DRIVER = "driver"; |
56 | 75 | ||
57 | /** | 76 | /** |
... | @@ -61,13 +80,19 @@ public final class AnnotationKeys { | ... | @@ -61,13 +80,19 @@ public final class AnnotationKeys { |
61 | 80 | ||
62 | /** | 81 | /** |
63 | * Annotation key for latency. | 82 | * Annotation key for latency. |
83 | + * | ||
84 | + * @deprecated since Cardinal | ||
64 | */ | 85 | */ |
86 | + @Deprecated | ||
65 | public static final String LATENCY = "latency"; | 87 | public static final String LATENCY = "latency"; |
66 | 88 | ||
67 | /** | 89 | /** |
68 | * Annotation key for bandwidth. | 90 | * Annotation key for bandwidth. |
69 | * The value for this key is interpreted as Mbps. | 91 | * The value for this key is interpreted as Mbps. |
92 | + * | ||
93 | + * @deprecated since Cardinal | ||
70 | */ | 94 | */ |
95 | + @Deprecated | ||
71 | public static final String BANDWIDTH = "bandwidth"; | 96 | public static final String BANDWIDTH = "bandwidth"; |
72 | 97 | ||
73 | /** | 98 | /** | ... | ... |
... | @@ -16,6 +16,7 @@ | ... | @@ -16,6 +16,7 @@ |
16 | package org.onosproject.rest; | 16 | package org.onosproject.rest; |
17 | 17 | ||
18 | import com.fasterxml.jackson.databind.ObjectMapper; | 18 | import com.fasterxml.jackson.databind.ObjectMapper; |
19 | +import com.fasterxml.jackson.databind.node.ArrayNode; | ||
19 | import com.fasterxml.jackson.databind.node.ObjectNode; | 20 | import com.fasterxml.jackson.databind.node.ObjectNode; |
20 | import org.onlab.rest.BaseResource; | 21 | import org.onlab.rest.BaseResource; |
21 | import org.onosproject.codec.CodecContext; | 22 | import org.onosproject.codec.CodecContext; |
... | @@ -27,9 +28,11 @@ import org.onosproject.codec.JsonCodec; | ... | @@ -27,9 +28,11 @@ import org.onosproject.codec.JsonCodec; |
27 | */ | 28 | */ |
28 | public class AbstractWebResource extends BaseResource implements CodecContext { | 29 | public class AbstractWebResource extends BaseResource implements CodecContext { |
29 | 30 | ||
31 | + private final ObjectMapper mapper = new ObjectMapper(); | ||
32 | + | ||
30 | @Override | 33 | @Override |
31 | public ObjectMapper mapper() { | 34 | public ObjectMapper mapper() { |
32 | - return new ObjectMapper(); | 35 | + return mapper; |
33 | } | 36 | } |
34 | 37 | ||
35 | /** | 38 | /** |
... | @@ -65,4 +68,31 @@ public class AbstractWebResource extends BaseResource implements CodecContext { | ... | @@ -65,4 +68,31 @@ public class AbstractWebResource extends BaseResource implements CodecContext { |
65 | return get(serviceClass); | 68 | return get(serviceClass); |
66 | } | 69 | } |
67 | 70 | ||
71 | + /** | ||
72 | + * Creates and returns a new child object within the specified parent and | ||
73 | + * bound to the given key. | ||
74 | + * | ||
75 | + * @param parent parent object | ||
76 | + * @param key key for the new child object | ||
77 | + * @return child object | ||
78 | + */ | ||
79 | + public ObjectNode newObject(ObjectNode parent, String key) { | ||
80 | + ObjectNode node = mapper.createObjectNode(); | ||
81 | + parent.set(key, node); | ||
82 | + return node; | ||
83 | + } | ||
84 | + | ||
85 | + /** | ||
86 | + * Creates and returns a new child array within the specified parent and | ||
87 | + * bound to the given key. | ||
88 | + * | ||
89 | + * @param parent parent object | ||
90 | + * @param key key for the new child array | ||
91 | + * @return child array | ||
92 | + */ | ||
93 | + public ArrayNode newArray(ObjectNode parent, String key) { | ||
94 | + ArrayNode node = mapper.createArrayNode(); | ||
95 | + parent.set(key, node); | ||
96 | + return node; | ||
97 | + } | ||
68 | } | 98 | } | ... | ... |
... | @@ -23,48 +23,212 @@ import static com.google.common.base.Preconditions.checkNotNull; | ... | @@ -23,48 +23,212 @@ import static com.google.common.base.Preconditions.checkNotNull; |
23 | 23 | ||
24 | /** | 24 | /** |
25 | * Base abstraction of a configuration facade for a specific subject. Derived | 25 | * Base abstraction of a configuration facade for a specific subject. Derived |
26 | - * classes should keep all state in the specified JSON tree. | 26 | + * classes should keep all state in the specified JSON tree as that is the |
27 | + * only state that will be distributed or persisted; this class is merely | ||
28 | + * a facade for interacting with a particular facet of configuration on a | ||
29 | + * given subject. | ||
27 | * | 30 | * |
28 | * @param <S> type of subject | 31 | * @param <S> type of subject |
29 | */ | 32 | */ |
30 | @Beta | 33 | @Beta |
31 | public abstract class Config<S> { | 34 | public abstract class Config<S> { |
32 | 35 | ||
33 | - protected ObjectMapper mapper; | 36 | + protected S subject; |
37 | + protected String key; | ||
34 | protected ObjectNode node; | 38 | protected ObjectNode node; |
35 | - private S subject; | 39 | + protected ObjectMapper mapper; |
36 | - private ConfigApplyDelegate<S> delegate; | 40 | + protected ConfigApplyDelegate delegate; |
37 | - | ||
38 | - /** | ||
39 | - * Returns the specific subject to which this configuration pertains. | ||
40 | - * | ||
41 | - * @return configuration subject | ||
42 | - */ | ||
43 | - S subject() { | ||
44 | - return subject; | ||
45 | - } | ||
46 | 41 | ||
47 | /** | 42 | /** |
48 | * Initializes the configuration behaviour with necessary context. | 43 | * Initializes the configuration behaviour with necessary context. |
49 | * | 44 | * |
50 | * @param subject configuration subject | 45 | * @param subject configuration subject |
46 | + * @param key configuration key | ||
51 | * @param node JSON object node where configuration data is stored | 47 | * @param node JSON object node where configuration data is stored |
52 | * @param mapper JSON object mapper | 48 | * @param mapper JSON object mapper |
53 | * @param delegate delegate context | 49 | * @param delegate delegate context |
54 | */ | 50 | */ |
55 | - public void init(S subject, ObjectNode node, ObjectMapper mapper, | 51 | + public void init(S subject, String key, ObjectNode node, ObjectMapper mapper, |
56 | - ConfigApplyDelegate<S> delegate) { | 52 | + ConfigApplyDelegate delegate) { |
57 | this.subject = checkNotNull(subject); | 53 | this.subject = checkNotNull(subject); |
54 | + this.key = key; | ||
58 | this.node = checkNotNull(node); | 55 | this.node = checkNotNull(node); |
59 | this.mapper = checkNotNull(mapper); | 56 | this.mapper = checkNotNull(mapper); |
60 | this.delegate = checkNotNull(delegate); | 57 | this.delegate = checkNotNull(delegate); |
61 | } | 58 | } |
62 | 59 | ||
63 | /** | 60 | /** |
61 | + * Returns the specific subject to which this configuration pertains. | ||
62 | + * | ||
63 | + * @return configuration subject | ||
64 | + */ | ||
65 | + public S subject() { | ||
66 | + return subject; | ||
67 | + } | ||
68 | + | ||
69 | + /** | ||
70 | + * Returns the configuration key. This is primarily aimed for use in | ||
71 | + * composite JSON trees in external representations and has no bearing on | ||
72 | + * the internal behaviours. | ||
73 | + * | ||
74 | + * @return configuration key | ||
75 | + */ | ||
76 | + public String key() { | ||
77 | + return key; | ||
78 | + } | ||
79 | + | ||
80 | + /** | ||
81 | + * Returns the JSON node that contains the configuration data. | ||
82 | + * | ||
83 | + * @return JSON node backing the configuration | ||
84 | + */ | ||
85 | + public ObjectNode node() { | ||
86 | + return node; | ||
87 | + } | ||
88 | + | ||
89 | + /** | ||
64 | * Applies any configuration changes made via this configuration. | 90 | * Applies any configuration changes made via this configuration. |
65 | */ | 91 | */ |
66 | public void apply() { | 92 | public void apply() { |
67 | delegate.onApply(this); | 93 | delegate.onApply(this); |
68 | } | 94 | } |
69 | 95 | ||
96 | + | ||
97 | + // Miscellaneous helpers for interacting with JSON | ||
98 | + | ||
99 | + /** | ||
100 | + * Gets the specified property as a string. | ||
101 | + * | ||
102 | + * @param name property name | ||
103 | + * @param defaultValue default value if property not set | ||
104 | + * @return property value or default value | ||
105 | + */ | ||
106 | + protected String get(String name, String defaultValue) { | ||
107 | + return node.path(name).asText(defaultValue); | ||
108 | + } | ||
109 | + | ||
110 | + /** | ||
111 | + * Sets the specified property as a string or clears it if null value given. | ||
112 | + * | ||
113 | + * @param name property name | ||
114 | + * @param value new value or null to clear the property | ||
115 | + * @return self | ||
116 | + */ | ||
117 | + protected Config<S> setOrClear(String name, String value) { | ||
118 | + if (value != null) { | ||
119 | + node.put(name, value); | ||
120 | + } else { | ||
121 | + node.remove(name); | ||
122 | + } | ||
123 | + return this; | ||
124 | + } | ||
125 | + | ||
126 | + /** | ||
127 | + * Gets the specified property as a boolean. | ||
128 | + * | ||
129 | + * @param name property name | ||
130 | + * @param defaultValue default value if property not set | ||
131 | + * @return property value or default value | ||
132 | + */ | ||
133 | + protected boolean get(String name, boolean defaultValue) { | ||
134 | + return node.path(name).asBoolean(defaultValue); | ||
135 | + } | ||
136 | + | ||
137 | + /** | ||
138 | + * Sets the specified property as a boolean or clears it if null value given. | ||
139 | + * | ||
140 | + * @param name property name | ||
141 | + * @param value new value or null to clear the property | ||
142 | + * @return self | ||
143 | + */ | ||
144 | + protected Config<S> setOrClear(String name, Boolean value) { | ||
145 | + if (value != null) { | ||
146 | + node.put(name, value.booleanValue()); | ||
147 | + } else { | ||
148 | + node.remove(name); | ||
149 | + } | ||
150 | + return this; | ||
151 | + } | ||
152 | + | ||
153 | + /** | ||
154 | + * Gets the specified property as a long. | ||
155 | + * | ||
156 | + * @param name property name | ||
157 | + * @param defaultValue default value if property not set | ||
158 | + * @return property value or default value | ||
159 | + */ | ||
160 | + protected long get(String name, long defaultValue) { | ||
161 | + return node.path(name).asLong(defaultValue); | ||
162 | + } | ||
163 | + | ||
164 | + /** | ||
165 | + * Sets the specified property as a long or clears it if null value given. | ||
166 | + * | ||
167 | + * @param name property name | ||
168 | + * @param value new value or null to clear the property | ||
169 | + * @return self | ||
170 | + */ | ||
171 | + protected Config<S> setOrClear(String name, Long value) { | ||
172 | + if (value != null) { | ||
173 | + node.put(name, value.longValue()); | ||
174 | + } else { | ||
175 | + node.remove(name); | ||
176 | + } | ||
177 | + return this; | ||
178 | + } | ||
179 | + | ||
180 | + /** | ||
181 | + * Gets the specified property as a double. | ||
182 | + * | ||
183 | + * @param name property name | ||
184 | + * @param defaultValue default value if property not set | ||
185 | + * @return property value or default value | ||
186 | + */ | ||
187 | + protected double get(String name, double defaultValue) { | ||
188 | + return node.path(name).asDouble(defaultValue); | ||
189 | + } | ||
190 | + | ||
191 | + /** | ||
192 | + * Sets the specified property as a double or clears it if null value given. | ||
193 | + * | ||
194 | + * @param name property name | ||
195 | + * @param value new value or null to clear the property | ||
196 | + * @return self | ||
197 | + */ | ||
198 | + protected Config<S> setOrClear(String name, Double value) { | ||
199 | + if (value != null) { | ||
200 | + node.put(name, value.doubleValue()); | ||
201 | + } else { | ||
202 | + node.remove(name); | ||
203 | + } | ||
204 | + return this; | ||
205 | + } | ||
206 | + | ||
207 | + /** | ||
208 | + * Gets the specified property as an enum. | ||
209 | + * | ||
210 | + * @param name property name | ||
211 | + * @param defaultValue default value if property not set | ||
212 | + * @param enumClass the enum class | ||
213 | + * @return property value or default value | ||
214 | + */ | ||
215 | + protected <E extends Enum<E>> E get(String name, E defaultValue, Class<E> enumClass) { | ||
216 | + return Enum.valueOf(enumClass, node.path(name).asText(defaultValue.toString())); | ||
217 | + } | ||
218 | + | ||
219 | + /** | ||
220 | + * Sets the specified property as a double or clears it if null value given. | ||
221 | + * | ||
222 | + * @param name property name | ||
223 | + * @param value new value or null to clear the property | ||
224 | + * @return self | ||
225 | + */ | ||
226 | + protected <E extends Enum> Config<S> setOrClear(String name, E value) { | ||
227 | + if (value != null) { | ||
228 | + node.put(name, value.toString()); | ||
229 | + } else { | ||
230 | + node.remove(name); | ||
231 | + } | ||
232 | + return this; | ||
233 | + } | ||
70 | } | 234 | } | ... | ... |
... | @@ -21,13 +21,13 @@ import com.google.common.annotations.Beta; | ... | @@ -21,13 +21,13 @@ import com.google.common.annotations.Beta; |
21 | * Delegate for notification when configuration changes have been applied. | 21 | * Delegate for notification when configuration changes have been applied. |
22 | */ | 22 | */ |
23 | @Beta | 23 | @Beta |
24 | -public interface ConfigApplyDelegate<S> { | 24 | +public interface ConfigApplyDelegate { |
25 | 25 | ||
26 | /** | 26 | /** |
27 | * Processes changes applied to the specified configuration. | 27 | * Processes changes applied to the specified configuration. |
28 | * | 28 | * |
29 | * @param config changed configuration | 29 | * @param config changed configuration |
30 | */ | 30 | */ |
31 | - void onApply(Config<S> config); | 31 | + void onApply(Config config); |
32 | 32 | ||
33 | } | 33 | } | ... | ... |
... | @@ -21,24 +21,31 @@ import com.google.common.annotations.Beta; | ... | @@ -21,24 +21,31 @@ import com.google.common.annotations.Beta; |
21 | /** | 21 | /** |
22 | * Base abstract factory for creating configurations for the specified subject type. | 22 | * Base abstract factory for creating configurations for the specified subject type. |
23 | * | 23 | * |
24 | - * @param <S> subject class | 24 | + * @param <S> type of subject |
25 | + * @param <C> type of configuration | ||
25 | */ | 26 | */ |
26 | @Beta | 27 | @Beta |
27 | -public abstract class ConfigFactory<S> { | 28 | +public abstract class ConfigFactory<S, C extends Config<S>> { |
28 | 29 | ||
29 | - private final Class<S> subjectClass; | 30 | + private final SubjectFactory<S> subjectFactory; |
30 | - private final String key; | 31 | + private final Class<C> configClass; |
32 | + private final String configKey; | ||
31 | 33 | ||
32 | /** | 34 | /** |
33 | * Creates a new configuration factory for the specified class of subjects | 35 | * Creates a new configuration factory for the specified class of subjects |
34 | - * and bound to the given subject configuration key. | 36 | + * capable of generating the configurations of the specified class. The |
37 | + * subject and configuration class keys are used merely as keys for use in | ||
38 | + * composite JSON trees. | ||
35 | * | 39 | * |
36 | - * @param subjectClass subject class | 40 | + * @param subjectFactory subject factory |
37 | - * @param key subject configuration key | 41 | + * @param configClass configuration class |
42 | + * @param configKey configuration class key | ||
38 | */ | 43 | */ |
39 | - protected ConfigFactory(Class<S> subjectClass, String key) { | 44 | + protected ConfigFactory(SubjectFactory<S> subjectFactory, |
40 | - this.subjectClass = subjectClass; | 45 | + Class<C> configClass, String configKey) { |
41 | - this.key = key; | 46 | + this.subjectFactory = subjectFactory; |
47 | + this.configClass = configClass; | ||
48 | + this.configKey = configKey; | ||
42 | } | 49 | } |
43 | 50 | ||
44 | /** | 51 | /** |
... | @@ -46,17 +53,28 @@ public abstract class ConfigFactory<S> { | ... | @@ -46,17 +53,28 @@ public abstract class ConfigFactory<S> { |
46 | * | 53 | * |
47 | * @return subject type | 54 | * @return subject type |
48 | */ | 55 | */ |
49 | - public Class<S> subjectClass() { | 56 | + public SubjectFactory<S> subjectFactory() { |
50 | - return subjectClass; | 57 | + return subjectFactory; |
51 | } | 58 | } |
52 | 59 | ||
53 | /** | 60 | /** |
54 | - * Returns the key to which produced configurations should be bound. | 61 | + * Returns the class of the configuration which this factory generates. |
55 | * | 62 | * |
56 | - * @return subject configuration key | 63 | + * @return configuration type |
57 | */ | 64 | */ |
58 | - public String key() { | 65 | + public Class<C> configClass() { |
59 | - return key; | 66 | + return configClass; |
67 | + } | ||
68 | + | ||
69 | + /** | ||
70 | + * Returns the unique key (within subject class) of this configuration. | ||
71 | + * This is primarily aimed for use in composite JSON trees in external | ||
72 | + * representations and has no bearing on the internal behaviours. | ||
73 | + * | ||
74 | + * @return configuration key | ||
75 | + */ | ||
76 | + public String configKey() { | ||
77 | + return configKey; | ||
60 | } | 78 | } |
61 | 79 | ||
62 | /** | 80 | /** |
... | @@ -65,6 +83,6 @@ public abstract class ConfigFactory<S> { | ... | @@ -65,6 +83,6 @@ public abstract class ConfigFactory<S> { |
65 | * | 83 | * |
66 | * @return new uninitialized configuration | 84 | * @return new uninitialized configuration |
67 | */ | 85 | */ |
68 | - public abstract Config<S> createConfig(); | 86 | + public abstract C createConfig(); |
69 | 87 | ||
70 | } | 88 | } | ... | ... |
1 | +/* | ||
2 | + * Copyright 2015 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 | + */ | ||
16 | +package org.onosproject.incubator.net.config; | ||
17 | + | ||
18 | +import org.onosproject.event.AbstractEvent; | ||
19 | + | ||
20 | +/** | ||
21 | + * Describes network configuration event. | ||
22 | + */ | ||
23 | +public class NetworkConfigEvent extends AbstractEvent<NetworkConfigEvent.Type, Object> { | ||
24 | + | ||
25 | + private final Class configClass; | ||
26 | + | ||
27 | + /** | ||
28 | + * Type of network configuration events. | ||
29 | + */ | ||
30 | + public enum Type { | ||
31 | + /** | ||
32 | + * Signifies that network configuration was added. | ||
33 | + */ | ||
34 | + | ||
35 | + CONFIG_ADDED, | ||
36 | + /** | ||
37 | + * Signifies that network configuration was updated. | ||
38 | + */ | ||
39 | + CONFIG_UPDATED, | ||
40 | + | ||
41 | + /** | ||
42 | + * Signifies that network configuration was removed. | ||
43 | + */ | ||
44 | + CONFIG_REMOVED | ||
45 | + } | ||
46 | + | ||
47 | + /** | ||
48 | + * Creates an event of a given type and for the specified subject and the | ||
49 | + * current time. | ||
50 | + * | ||
51 | + * @param type event type | ||
52 | + * @param subject event subject | ||
53 | + * @param configClass configuration class | ||
54 | + */ | ||
55 | + public NetworkConfigEvent(Type type, Object subject, Class configClass) { | ||
56 | + super(type, subject); | ||
57 | + this.configClass = configClass; | ||
58 | + } | ||
59 | + | ||
60 | + /** | ||
61 | + * Creates an event of a given type and for the specified subject and time. | ||
62 | + * | ||
63 | + * @param type device event type | ||
64 | + * @param subject event subject | ||
65 | + * @param configClass configuration class | ||
66 | + * @param time occurrence time | ||
67 | + */ | ||
68 | + public NetworkConfigEvent(Type type, Object subject, Class configClass, long time) { | ||
69 | + super(type, subject, time); | ||
70 | + this.configClass = configClass; | ||
71 | + } | ||
72 | + | ||
73 | + /** | ||
74 | + * Returns the class of configuration that has been changed. | ||
75 | + * | ||
76 | + * @return configuration class | ||
77 | + */ | ||
78 | + public Class configClass() { | ||
79 | + return configClass; | ||
80 | + } | ||
81 | + | ||
82 | +} |
incubator/api/src/main/java/org/onosproject/incubator/net/config/NetworkConfigListener.java
0 → 100644
1 | +/* | ||
2 | + * Copyright 2015 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 | + */ | ||
16 | +package org.onosproject.incubator.net.config; | ||
17 | + | ||
18 | +import org.onosproject.event.EventListener; | ||
19 | + | ||
20 | +/** | ||
21 | + * Entity capable of receiving network configuration related events. | ||
22 | + */ | ||
23 | +public interface NetworkConfigListener extends EventListener<NetworkConfigEvent> { | ||
24 | +} |
... | @@ -20,7 +20,11 @@ import com.google.common.annotations.Beta; | ... | @@ -20,7 +20,11 @@ import com.google.common.annotations.Beta; |
20 | import java.util.Set; | 20 | import java.util.Set; |
21 | 21 | ||
22 | /** | 22 | /** |
23 | - * Service for tracking network configuration factories. | 23 | + * Service for tracking network configuration factories. It is the basis for |
24 | + * extensibility to allow various core subsystems or apps to register their | ||
25 | + * own configuration factories that permit use to inject additional meta | ||
26 | + * information about how various parts of the network should be viewed and | ||
27 | + * treated. | ||
24 | */ | 28 | */ |
25 | @Beta | 29 | @Beta |
26 | public interface NetworkConfigRegistry { | 30 | public interface NetworkConfigRegistry { |
... | @@ -40,34 +44,32 @@ public interface NetworkConfigRegistry { | ... | @@ -40,34 +44,32 @@ public interface NetworkConfigRegistry { |
40 | void unregisterConfigFactory(ConfigFactory configFactory); | 44 | void unregisterConfigFactory(ConfigFactory configFactory); |
41 | 45 | ||
42 | /** | 46 | /** |
43 | - * Returns set of configuration factories available for the specified | 47 | + * Returns set of all registered configuration factories. |
44 | - * class of subject. | ||
45 | * | 48 | * |
46 | - * @param subjectClass subject class | ||
47 | - * @param <T> type of subject | ||
48 | * @return set of config factories | 49 | * @return set of config factories |
49 | */ | 50 | */ |
50 | - <T> Set<ConfigFactory<T>> getConfigFactories(Class<T> subjectClass); | 51 | + Set<ConfigFactory> getConfigFactories(); |
51 | 52 | ||
52 | /** | 53 | /** |
53 | - * Returns the configuration type registered for the specified | 54 | + * Returns set of all configuration factories registered for the specified |
54 | - * subject type and key. | 55 | + * class of subject. |
55 | * | 56 | * |
56 | * @param subjectClass subject class | 57 | * @param subjectClass subject class |
57 | - * @param configKey configuration key | 58 | + * @param <S> type of subject |
58 | - * @param <T> type of subject | 59 | + * @param <C> type of configuration |
59 | - * @return config factory | 60 | + * @return set of config factories |
60 | */ | 61 | */ |
61 | - <T> ConfigFactory<T> getConfigFactory(Class<T> subjectClass, String configKey); | 62 | + <S, C extends Config<S>> Set<ConfigFactory<S, C>> getConfigFactories(Class<S> subjectClass); |
62 | 63 | ||
63 | /** | 64 | /** |
64 | - * Returns the configuration type registered for the specified | 65 | + * Returns the configuration factory that produces the specified class of |
65 | - * configuration class. | 66 | + * configurations. |
66 | * | 67 | * |
67 | * @param configClass configuration class | 68 | * @param configClass configuration class |
68 | - * @param <T> type of subject | 69 | + * @param <S> type of subject |
70 | + * @param <C> type of configuration | ||
69 | * @return config factory | 71 | * @return config factory |
70 | */ | 72 | */ |
71 | - <T> ConfigFactory<T> getConfigFactory(Class<Config<T>> configClass); | 73 | + <S, C extends Config<S>> ConfigFactory<S, C> getConfigFactory(Class<C> configClass); |
72 | 74 | ||
73 | } | 75 | } | ... | ... |
... | @@ -15,26 +15,59 @@ | ... | @@ -15,26 +15,59 @@ |
15 | */ | 15 | */ |
16 | package org.onosproject.incubator.net.config; | 16 | package org.onosproject.incubator.net.config; |
17 | 17 | ||
18 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
18 | import com.google.common.annotations.Beta; | 19 | import com.google.common.annotations.Beta; |
19 | 20 | ||
20 | import java.util.Set; | 21 | import java.util.Set; |
21 | 22 | ||
22 | /** | 23 | /** |
23 | * Service for tracking network configurations which specify how the discovered | 24 | * Service for tracking network configurations which specify how the discovered |
24 | - * network information should be interpreted and how the network should be | 25 | + * network information should be interpreted and how the core or applications |
25 | - * configured. | 26 | + * should act on or configure the network. |
26 | */ | 27 | */ |
27 | @Beta | 28 | @Beta |
28 | public interface NetworkConfigService { | 29 | public interface NetworkConfigService { |
29 | 30 | ||
30 | /** | 31 | /** |
32 | + * Returns the set of subject classes for which configuration may be | ||
33 | + * available. | ||
34 | + * | ||
35 | + * @return set of subject classes | ||
36 | + */ | ||
37 | + Set<Class> getSubjectClasses(); | ||
38 | + | ||
39 | + /** | ||
40 | + * Returns the subject factory with the specified key. | ||
41 | + * | ||
42 | + * @param subjectKey subject class key | ||
43 | + * @return subject class | ||
44 | + */ | ||
45 | + SubjectFactory getSubjectFactory(String subjectKey); | ||
46 | + | ||
47 | + /** | ||
48 | + * Returns the subject factory for the specified class. | ||
49 | + * | ||
50 | + * @param subjectClass subject class | ||
51 | + * @return subject class key | ||
52 | + */ | ||
53 | + SubjectFactory getSubjectFactory(Class subjectClass); | ||
54 | + | ||
55 | + /** | ||
56 | + * Returns the configuration class with the specified key. | ||
57 | + * | ||
58 | + * @param configKey subject class name | ||
59 | + * @return subject class | ||
60 | + */ | ||
61 | + Class<? extends Config> getConfigClass(String configKey); | ||
62 | + | ||
63 | + /** | ||
31 | * Returns the set of subjects for which some configuration is available. | 64 | * Returns the set of subjects for which some configuration is available. |
32 | * | 65 | * |
33 | * @param subjectClass subject class | 66 | * @param subjectClass subject class |
34 | - * @param <T> type of subject | 67 | + * @param <S> type of subject |
35 | * @return set of configured subjects | 68 | * @return set of configured subjects |
36 | */ | 69 | */ |
37 | - <T> Set<T> getSubjects(Class<T> subjectClass); | 70 | + <S> Set<S> getSubjects(Class<S> subjectClass); |
38 | 71 | ||
39 | /** | 72 | /** |
40 | * Returns the set of subjects for which the specified configuration is | 73 | * Returns the set of subjects for which the specified configuration is |
... | @@ -42,20 +75,20 @@ public interface NetworkConfigService { | ... | @@ -42,20 +75,20 @@ public interface NetworkConfigService { |
42 | * | 75 | * |
43 | * @param subjectClass subject class | 76 | * @param subjectClass subject class |
44 | * @param configClass configuration class | 77 | * @param configClass configuration class |
45 | - * @param <T> type of subject | 78 | + * @param <S> type of subject |
79 | + * @param <C> type of configuration | ||
46 | * @return set of configured subjects | 80 | * @return set of configured subjects |
47 | */ | 81 | */ |
48 | - <T> Set<T> getSubjects(Class<T> subjectClass, Class<Config<T>> configClass); | 82 | + <S, C extends Config<S>> Set<S> getSubjects(Class<S> subjectClass, Class<C> configClass); |
49 | - | ||
50 | 83 | ||
51 | /** | 84 | /** |
52 | * Returns all configurations for the specified subject. | 85 | * Returns all configurations for the specified subject. |
53 | * | 86 | * |
54 | * @param subject configuration subject | 87 | * @param subject configuration subject |
55 | - * @param <T> type of subject | 88 | + * @param <S> type of subject |
56 | * @return set of configurations | 89 | * @return set of configurations |
57 | */ | 90 | */ |
58 | - <T> Set<Config<T>> getConfigs(T subject); | 91 | + <S> Set<? extends Config<S>> getConfigs(S subject); |
59 | 92 | ||
60 | /** | 93 | /** |
61 | * Returns the configuration for the specified subject and configuration | 94 | * Returns the configuration for the specified subject and configuration |
... | @@ -63,9 +96,61 @@ public interface NetworkConfigService { | ... | @@ -63,9 +96,61 @@ public interface NetworkConfigService { |
63 | * | 96 | * |
64 | * @param subject configuration subject | 97 | * @param subject configuration subject |
65 | * @param configClass configuration class | 98 | * @param configClass configuration class |
66 | - * @param <T> type of subject | 99 | + * @param <S> type of subject |
100 | + * @param <C> type of configuration | ||
101 | + * @return configuration or null if one is not available | ||
102 | + */ | ||
103 | + <S, C extends Config<S>> C getConfig(S subject, Class<C> configClass); | ||
104 | + | ||
105 | + /** | ||
106 | + * Creates a new configuration for the specified subject and configuration | ||
107 | + * class. If one already exists, it is simply returned. | ||
108 | + * | ||
109 | + * @param subject configuration subject | ||
110 | + * @param configClass configuration class | ||
111 | + * @param <S> type of subject | ||
112 | + * @param <C> type of configuration | ||
113 | + * @return configuration or null if one is not available | ||
114 | + */ | ||
115 | + <S, C extends Config<S>> C addConfig(S subject, Class<C> configClass); | ||
116 | + | ||
117 | + /** | ||
118 | + * Applies configuration for the specified subject and configuration | ||
119 | + * class using the raw JSON object. If configuration already exists, it | ||
120 | + * will be updated. | ||
121 | + * | ||
122 | + * @param subject configuration subject | ||
123 | + * @param configClass configuration class | ||
124 | + * @param json raw JSON node containing the configuration data | ||
125 | + * @param <S> type of subject | ||
126 | + * @param <C> type of configuration | ||
67 | * @return configuration or null if one is not available | 127 | * @return configuration or null if one is not available |
68 | */ | 128 | */ |
69 | - <T> Config<T> getConfig(T subject, Class<Config<T>> configClass); | 129 | + <S, C extends Config<S>> C applyConfig(S subject, Class<C> configClass, |
130 | + ObjectNode json); | ||
70 | 131 | ||
132 | + /** | ||
133 | + * Clears any configuration for the specified subject and configuration | ||
134 | + * class. If one does not exist, this call has no effect. | ||
135 | + * | ||
136 | + * @param subject configuration subject | ||
137 | + * @param configClass configuration class | ||
138 | + * @param <S> type of subject | ||
139 | + * @param <C> type of configuration | ||
140 | + */ | ||
141 | + <S, C extends Config<S>> void removeConfig(S subject, Class<C> configClass); | ||
142 | + | ||
143 | + /** | ||
144 | + * Adds the specified network config listener. | ||
145 | + * | ||
146 | + * @param listener network config listener | ||
147 | + */ | ||
148 | + void addListener(NetworkConfigListener listener); | ||
149 | + | ||
150 | + /** | ||
151 | + * Removes the specified network config listener. | ||
152 | + * | ||
153 | + * @param listener network config listener | ||
154 | + */ | ||
155 | + void removeListener(NetworkConfigListener listener); | ||
71 | } | 156 | } | ... | ... |
1 | +/* | ||
2 | + * Copyright 2015 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 | + */ | ||
16 | +package org.onosproject.incubator.net.config; | ||
17 | + | ||
18 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
19 | +import org.onosproject.store.Store; | ||
20 | + | ||
21 | +import java.util.Set; | ||
22 | + | ||
23 | +/** | ||
24 | + * Mechanism for distributing and storing network configuration information. | ||
25 | + */ | ||
26 | +public interface NetworkConfigStore extends Store<NetworkConfigEvent, NetworkConfigStoreDelegate> { | ||
27 | + | ||
28 | + /** | ||
29 | + * Adds a new configuration factory. | ||
30 | + * | ||
31 | + * @param configFactory configuration factory to add | ||
32 | + */ | ||
33 | + void addConfigFactory(ConfigFactory configFactory); | ||
34 | + | ||
35 | + /** | ||
36 | + * Removes a configuration factory. | ||
37 | + * | ||
38 | + * @param configFactory configuration factory to remove | ||
39 | + */ | ||
40 | + void removeConfigFactory(ConfigFactory configFactory); | ||
41 | + | ||
42 | + /** | ||
43 | + * Returns the configuration factory for the specified configuration class. | ||
44 | + * | ||
45 | + * @param configClass configuration class | ||
46 | + * @param <S> type of subject | ||
47 | + * @param <C> type of configuration | ||
48 | + * @return configuration factory or null | ||
49 | + */ | ||
50 | + <S, C extends Config<S>> ConfigFactory<S, C> getConfigFactory(Class<C> configClass); | ||
51 | + | ||
52 | + /** | ||
53 | + * Returns set of subjects of the specified class, which have some | ||
54 | + * network configuration associated with them. | ||
55 | + * | ||
56 | + * @param subjectClass subject class | ||
57 | + * @param <S> type of subject | ||
58 | + * @return set of subject | ||
59 | + */ | ||
60 | + <S> Set<S> getSubjects(Class<S> subjectClass); | ||
61 | + | ||
62 | + /** | ||
63 | + * Returns set of subjects of the specified class, which have the | ||
64 | + * specified class of network configuration associated with them. | ||
65 | + * | ||
66 | + * @param subjectClass subject class | ||
67 | + * @param configClass configuration class | ||
68 | + * @param <S> type of subject | ||
69 | + * @param <C> type of configuration | ||
70 | + * @return set of subject | ||
71 | + */ | ||
72 | + <S, C extends Config<S>> Set<S> getSubjects(Class<S> subjectClass, Class<C> configClass); | ||
73 | + | ||
74 | + /** | ||
75 | + * Returns set of configuration classes available for the specified subject. | ||
76 | + * | ||
77 | + * @param subject configuration subject | ||
78 | + * @param <S> type of subject | ||
79 | + * @return set of configuration classes | ||
80 | + */ | ||
81 | + <S> Set<Class<? extends Config<S>>> getConfigClasses(S subject); | ||
82 | + | ||
83 | + /** | ||
84 | + * Get the configuration of the given class and for the specified subject. | ||
85 | + * | ||
86 | + * @param subject configuration subject | ||
87 | + * @param configClass configuration class | ||
88 | + * @param <S> type of subject | ||
89 | + * @param <C> type of configuration | ||
90 | + * @return configuration object | ||
91 | + */ | ||
92 | + <S, C extends Config<S>> C getConfig(S subject, Class<C> configClass); | ||
93 | + | ||
94 | + /** | ||
95 | + * Creates a new configuration of the given class for the specified subject. | ||
96 | + * | ||
97 | + * @param subject configuration subject | ||
98 | + * @param configClass configuration class | ||
99 | + * @param <S> type of subject | ||
100 | + * @param <C> type of configuration | ||
101 | + * @return configuration object | ||
102 | + */ | ||
103 | + <S, C extends Config<S>> C createConfig(S subject, Class<C> configClass); | ||
104 | + | ||
105 | + /** | ||
106 | + * Applies configuration for the specified subject and configuration | ||
107 | + * class using the raw JSON object. If configuration already exists, it | ||
108 | + * will be updated. | ||
109 | + * | ||
110 | + * @param subject configuration subject | ||
111 | + * @param configClass configuration class | ||
112 | + * @param json raw JSON node containing the configuration data | ||
113 | + * @param <S> type of subject | ||
114 | + * @param <C> type of configuration | ||
115 | + */ | ||
116 | + <S, C extends Config<S>> C applyConfig(S subject, Class<C> configClass, | ||
117 | + ObjectNode json); | ||
118 | + | ||
119 | + /** | ||
120 | + * Clears the configuration of the given class for the specified subject. | ||
121 | + * | ||
122 | + * @param subject configuration subject | ||
123 | + * @param configClass configuration class | ||
124 | + * @param <S> type of subject | ||
125 | + * @param <C> type of configuration | ||
126 | + */ | ||
127 | + <S, C extends Config<S>> void clearConfig(S subject, Class<C> configClass); | ||
128 | + | ||
129 | +} |
incubator/api/src/main/java/org/onosproject/incubator/net/config/NetworkConfigStoreDelegate.java
0 → 100644
1 | +/* | ||
2 | + * Copyright 2015 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 | + */ | ||
16 | +package org.onosproject.incubator.net.config; | ||
17 | + | ||
18 | +import org.onosproject.store.StoreDelegate; | ||
19 | + | ||
20 | +/** | ||
21 | + * Network configuration store delegate abstraction. | ||
22 | + */ | ||
23 | +public interface NetworkConfigStoreDelegate extends StoreDelegate<NetworkConfigEvent> { | ||
24 | +} |
1 | +/* | ||
2 | + * Copyright 2015 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 | + */ | ||
16 | +package org.onosproject.incubator.net.config; | ||
17 | + | ||
18 | + | ||
19 | +import com.google.common.annotations.Beta; | ||
20 | + | ||
21 | +/** | ||
22 | + * Base abstract factory for creating configuration subjects from their | ||
23 | + * string key image. | ||
24 | + * | ||
25 | + * @param <S> subject class | ||
26 | + */ | ||
27 | +@Beta | ||
28 | +public abstract class SubjectFactory<S> { | ||
29 | + | ||
30 | + private final Class<S> subjectClass; | ||
31 | + private final String subjectKey; | ||
32 | + | ||
33 | + /** | ||
34 | + * Creates a new configuration factory for the specified class of subjects | ||
35 | + * capable of generating the configurations of the specified class. The | ||
36 | + * subject and configuration class keys are used merely as keys for use in | ||
37 | + * composite JSON trees. | ||
38 | + * | ||
39 | + * @param subjectClass subject class | ||
40 | + * @param subjectKey subject class key | ||
41 | + */ | ||
42 | + protected SubjectFactory(Class<S> subjectClass, String subjectKey) { | ||
43 | + this.subjectClass = subjectClass; | ||
44 | + this.subjectKey = subjectKey; | ||
45 | + } | ||
46 | + | ||
47 | + /** | ||
48 | + * Returns the class of the subject to which this factory applies. | ||
49 | + * | ||
50 | + * @return subject type | ||
51 | + */ | ||
52 | + public Class<S> subjectClass() { | ||
53 | + return subjectClass; | ||
54 | + } | ||
55 | + | ||
56 | + /** | ||
57 | + * Returns the unique key of this configuration subject class. | ||
58 | + * This is primarily aimed for use in composite JSON trees in external | ||
59 | + * representations and has no bearing on the internal behaviours. | ||
60 | + * | ||
61 | + * @return configuration key | ||
62 | + */ | ||
63 | + public String subjectKey() { | ||
64 | + return subjectKey; | ||
65 | + } | ||
66 | + | ||
67 | + /** | ||
68 | + * Creates a configuration subject from its key image. | ||
69 | + * | ||
70 | + * @return configuration subject | ||
71 | + */ | ||
72 | + public abstract S createSubject(String key); | ||
73 | + | ||
74 | +} |
incubator/api/src/main/java/org/onosproject/incubator/net/config/basics/AllowedEntityConfig.java
0 → 100644
1 | +/* | ||
2 | + * Copyright 2015 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 | + */ | ||
16 | +package org.onosproject.incubator.net.config.basics; | ||
17 | + | ||
18 | +import org.onosproject.incubator.net.config.Config; | ||
19 | + | ||
20 | +/** | ||
21 | + * Base abstraction for network entities for which admission into control | ||
22 | + * domain can be selectively configured, e.g. devices, end-stations, links | ||
23 | + */ | ||
24 | +public abstract class AllowedEntityConfig<S> extends Config<S> { | ||
25 | + | ||
26 | + private static final String ALLOWED = "allowed"; | ||
27 | + | ||
28 | + /** | ||
29 | + * Indicates whether the element is allowed for admission into the control | ||
30 | + * domain. | ||
31 | + * | ||
32 | + * @return true if element is allowed | ||
33 | + */ | ||
34 | + public boolean isAllowed() { | ||
35 | + return get(ALLOWED, true); | ||
36 | + } | ||
37 | + | ||
38 | + /** | ||
39 | + * Specifies whether the element is to be allowed for admission into the | ||
40 | + * control domain. | ||
41 | + * | ||
42 | + * @param isAllowed true to allow; false to forbid; null to clear | ||
43 | + * @return self | ||
44 | + */ | ||
45 | + public AllowedEntityConfig isAllowed(Boolean isAllowed) { | ||
46 | + return (AllowedEntityConfig) setOrClear(ALLOWED, isAllowed); | ||
47 | + } | ||
48 | + | ||
49 | +} |
incubator/api/src/main/java/org/onosproject/incubator/net/config/basics/BasicDeviceConfig.java
0 → 100644
1 | +/* | ||
2 | + * Copyright 2015 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 | + */ | ||
16 | +package org.onosproject.incubator.net.config.basics; | ||
17 | + | ||
18 | +import org.onosproject.net.Device; | ||
19 | +import org.onosproject.net.DeviceId; | ||
20 | + | ||
21 | +/** | ||
22 | + * Basic configuration for network infrastructure devices. | ||
23 | + */ | ||
24 | +public class BasicDeviceConfig extends BasicElementConfig<DeviceId> { | ||
25 | + | ||
26 | + public static final String TYPE = "type"; | ||
27 | + public static final String DRIVER = "driver"; | ||
28 | + | ||
29 | + /** | ||
30 | + * Returns the device type. | ||
31 | + * | ||
32 | + * @return device type override | ||
33 | + */ | ||
34 | + public Device.Type type() { | ||
35 | + return get(TYPE, Device.Type.SWITCH, Device.Type.class); | ||
36 | + } | ||
37 | + | ||
38 | + /** | ||
39 | + * Sets the device type. | ||
40 | + * | ||
41 | + * @param type device type override | ||
42 | + * @return self | ||
43 | + */ | ||
44 | + public BasicDeviceConfig type(Device.Type type) { | ||
45 | + return (BasicDeviceConfig) setOrClear(TYPE, type); | ||
46 | + } | ||
47 | + | ||
48 | + /** | ||
49 | + * Returns the device driver name. | ||
50 | + * | ||
51 | + * @return driver name of null if not set | ||
52 | + */ | ||
53 | + public String driver() { | ||
54 | + return get(DRIVER, subject.toString()); | ||
55 | + } | ||
56 | + | ||
57 | + /** | ||
58 | + * Sets the driver name. | ||
59 | + * | ||
60 | + * @param driverName new driver name; null to clear | ||
61 | + * @return self | ||
62 | + */ | ||
63 | + public BasicElementConfig driver(String driverName) { | ||
64 | + return (BasicElementConfig) setOrClear(DRIVER, driverName); | ||
65 | + } | ||
66 | + | ||
67 | + // TODO: device port meta-data to be configured via BasicPortsConfig | ||
68 | + // TODO: device credentials/keys | ||
69 | + | ||
70 | +} |
incubator/api/src/main/java/org/onosproject/incubator/net/config/basics/BasicElementConfig.java
0 → 100644
1 | +/* | ||
2 | + * Copyright 2015 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 | + */ | ||
16 | +package org.onosproject.incubator.net.config.basics; | ||
17 | + | ||
18 | +/** | ||
19 | + * Basic configuration for network elements, e.g. devices, hosts. Such elements | ||
20 | + * can have a friendly name, geo-coordinates, logical rack coordinates and | ||
21 | + * an owner entity. | ||
22 | + */ | ||
23 | +public abstract class BasicElementConfig<S> extends AllowedEntityConfig<S> { | ||
24 | + | ||
25 | + public static final String NAME = "name"; | ||
26 | + | ||
27 | + public static final String LATITUDE = "latitude"; | ||
28 | + public static final String LONGITUDE = "longitude"; | ||
29 | + | ||
30 | + public static final String RACK_ADDRESS = "rackAddress"; | ||
31 | + public static final String OWNER = "owner"; | ||
32 | + | ||
33 | + /** | ||
34 | + * Returns friendly label for the element. | ||
35 | + * | ||
36 | + * @return friendly label or element id itself if not set | ||
37 | + */ | ||
38 | + public String name() { | ||
39 | + return get(NAME, subject.toString()); | ||
40 | + } | ||
41 | + | ||
42 | + /** | ||
43 | + * Sets friendly label for the element. | ||
44 | + * | ||
45 | + * @param name new friendly label; null to clear | ||
46 | + * @return self | ||
47 | + */ | ||
48 | + public BasicElementConfig name(String name) { | ||
49 | + return (BasicElementConfig) setOrClear(NAME, name); | ||
50 | + } | ||
51 | + | ||
52 | + /** | ||
53 | + * Returns element latitude. | ||
54 | + * | ||
55 | + * @return element latitude; -1 if not set | ||
56 | + */ | ||
57 | + public double latitude() { | ||
58 | + return get(LATITUDE, -1.0); | ||
59 | + } | ||
60 | + | ||
61 | + /** | ||
62 | + * Sets the element latitude. | ||
63 | + * | ||
64 | + * @param latitude new latitude; null to clear | ||
65 | + * @return self | ||
66 | + */ | ||
67 | + public BasicElementConfig latitude(Double latitude) { | ||
68 | + return (BasicElementConfig) setOrClear(LATITUDE, latitude); | ||
69 | + } | ||
70 | + | ||
71 | + /** | ||
72 | + * Returns element latitude. | ||
73 | + * | ||
74 | + * @return element latitude; -1 if not set | ||
75 | + */ | ||
76 | + public double longitude() { | ||
77 | + return get(LONGITUDE, -1.0); | ||
78 | + } | ||
79 | + | ||
80 | + /** | ||
81 | + * Sets the element longitude. | ||
82 | + * | ||
83 | + * @param longitude new longitude; null to clear | ||
84 | + * @return self | ||
85 | + */ | ||
86 | + public BasicElementConfig longitude(Double longitude) { | ||
87 | + return (BasicElementConfig) setOrClear(LONGITUDE, longitude); | ||
88 | + } | ||
89 | + | ||
90 | + /** | ||
91 | + * Returns the element rack address. | ||
92 | + * | ||
93 | + * @return rack address; null if not set | ||
94 | + */ | ||
95 | + public String rackAddress() { | ||
96 | + return get(RACK_ADDRESS, null); | ||
97 | + } | ||
98 | + | ||
99 | + /** | ||
100 | + * Sets element rack address. | ||
101 | + * | ||
102 | + * @param address new rack address; null to clear | ||
103 | + * @return self | ||
104 | + */ | ||
105 | + public BasicElementConfig rackAddress(String address) { | ||
106 | + return (BasicElementConfig) setOrClear(RACK_ADDRESS, address); | ||
107 | + } | ||
108 | + | ||
109 | + /** | ||
110 | + * Returns owner of the element. | ||
111 | + * | ||
112 | + * @return owner or null if not set | ||
113 | + */ | ||
114 | + public String owner() { | ||
115 | + return get(OWNER, null); | ||
116 | + } | ||
117 | + | ||
118 | + /** | ||
119 | + * Sets the owner of the element. | ||
120 | + * | ||
121 | + * @param owner new owner; null to clear | ||
122 | + * @return self | ||
123 | + */ | ||
124 | + public BasicElementConfig owner(String owner) { | ||
125 | + return (BasicElementConfig) setOrClear(OWNER, owner); | ||
126 | + } | ||
127 | + | ||
128 | +} |
incubator/api/src/main/java/org/onosproject/incubator/net/config/basics/BasicHostConfig.java
0 → 100644
1 | +/* | ||
2 | + * Copyright 2015 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 | + */ | ||
16 | +package org.onosproject.incubator.net.config.basics; | ||
17 | + | ||
18 | +import org.onosproject.net.HostId; | ||
19 | + | ||
20 | +/** | ||
21 | + * Basic configuration for network end-station hosts. | ||
22 | + */ | ||
23 | +public class BasicHostConfig extends BasicElementConfig<HostId> { | ||
24 | + | ||
25 | + // TODO: determine what aspects of configuration to add for hosts | ||
26 | + | ||
27 | +} |
incubator/api/src/main/java/org/onosproject/incubator/net/config/basics/BasicLinkConfig.java
0 → 100644
1 | +/* | ||
2 | + * Copyright 2015 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 | + */ | ||
16 | +package org.onosproject.incubator.net.config.basics; | ||
17 | + | ||
18 | +import org.onosproject.net.Link; | ||
19 | +import org.onosproject.net.LinkKey; | ||
20 | + | ||
21 | +import java.time.Duration; | ||
22 | + | ||
23 | +/** | ||
24 | + * Basic configuration for network infrastructure link. | ||
25 | + */ | ||
26 | +public class BasicLinkConfig extends AllowedEntityConfig<LinkKey> { | ||
27 | + | ||
28 | + public static final String TYPE = "type"; | ||
29 | + public static final String LATENCY = "latency"; | ||
30 | + public static final String BANDWIDTH = "bandwidth"; | ||
31 | + | ||
32 | + /** | ||
33 | + * Returns the link type. | ||
34 | + * | ||
35 | + * @return link type override | ||
36 | + */ | ||
37 | + public Link.Type type() { | ||
38 | + return get(TYPE, Link.Type.DIRECT, Link.Type.class); | ||
39 | + } | ||
40 | + | ||
41 | + /** | ||
42 | + * Sets the link type. | ||
43 | + * | ||
44 | + * @param type link type override | ||
45 | + * @return self | ||
46 | + */ | ||
47 | + public BasicLinkConfig type(Link.Type type) { | ||
48 | + return (BasicLinkConfig) setOrClear(TYPE, type); | ||
49 | + } | ||
50 | + | ||
51 | + /** | ||
52 | + * Returns link latency in terms of nanos. | ||
53 | + * | ||
54 | + * @return link latency; -1 if not set | ||
55 | + */ | ||
56 | + public Duration latency() { | ||
57 | + return Duration.ofNanos(get(LATENCY, -1)); | ||
58 | + } | ||
59 | + | ||
60 | + /** | ||
61 | + * Sets the link latency. | ||
62 | + * | ||
63 | + * @param latency new latency; null to clear | ||
64 | + * @return self | ||
65 | + */ | ||
66 | + public BasicElementConfig latency(Duration latency) { | ||
67 | + Long nanos = latency == null ? null : latency.toNanos(); | ||
68 | + return (BasicElementConfig) setOrClear(LATENCY, nanos); | ||
69 | + } | ||
70 | + | ||
71 | + /** | ||
72 | + * Returns link bandwidth in terms of Mbps. | ||
73 | + * | ||
74 | + * @return link bandwidth; -1 if not set | ||
75 | + */ | ||
76 | + public long bandwidth() { | ||
77 | + return get(BANDWIDTH, -1); | ||
78 | + } | ||
79 | + | ||
80 | + /** | ||
81 | + * Sets the link bandwidth. | ||
82 | + * | ||
83 | + * @param bandwidth new bandwidth; null to clear | ||
84 | + * @return self | ||
85 | + */ | ||
86 | + public BasicElementConfig bandwidth(Long bandwidth) { | ||
87 | + return (BasicElementConfig) setOrClear(BANDWIDTH, bandwidth); | ||
88 | + } | ||
89 | + | ||
90 | +} |
incubator/api/src/main/java/org/onosproject/incubator/net/config/basics/SubjectFactories.java
0 → 100644
1 | +/* | ||
2 | + * Copyright 2015 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 | + */ | ||
16 | +package org.onosproject.incubator.net.config.basics; | ||
17 | + | ||
18 | +import org.onosproject.core.ApplicationId; | ||
19 | +import org.onosproject.incubator.net.config.SubjectFactory; | ||
20 | +import org.onosproject.net.ConnectPoint; | ||
21 | +import org.onosproject.net.DeviceId; | ||
22 | +import org.onosproject.net.HostId; | ||
23 | +import org.onosproject.net.LinkKey; | ||
24 | + | ||
25 | +import static com.google.common.base.Preconditions.checkArgument; | ||
26 | + | ||
27 | +/** | ||
28 | + * Set of subject factories for potential configuration subjects. | ||
29 | + */ | ||
30 | +public final class SubjectFactories { | ||
31 | + | ||
32 | + // Construction forbidden | ||
33 | + private SubjectFactories() { | ||
34 | + } | ||
35 | + | ||
36 | + public static final SubjectFactory<ApplicationId> APP_SUBJECT_FACTORY = | ||
37 | + new SubjectFactory<ApplicationId>(ApplicationId.class, "apps") { | ||
38 | + @Override | ||
39 | + public ApplicationId createSubject(String key) { | ||
40 | + // FIXME: figure out how to safely create sanctioned app ids | ||
41 | + return null; | ||
42 | + } | ||
43 | + }; | ||
44 | + | ||
45 | + public static final SubjectFactory<DeviceId> DEVICE_SUBJECT_FACTORY = | ||
46 | + new SubjectFactory<DeviceId>(DeviceId.class, "devices") { | ||
47 | + @Override | ||
48 | + public DeviceId createSubject(String key) { | ||
49 | + return DeviceId.deviceId(key); | ||
50 | + } | ||
51 | + }; | ||
52 | + | ||
53 | + public static final SubjectFactory<HostId> HOST_SUBJECT_FACTORY = | ||
54 | + new SubjectFactory<HostId>(HostId.class, "hosts") { | ||
55 | + @Override | ||
56 | + public HostId createSubject(String key) { | ||
57 | + return HostId.hostId(key); | ||
58 | + } | ||
59 | + }; | ||
60 | + | ||
61 | + public static final SubjectFactory<LinkKey> LINK_SUBJECT_FACTORY = | ||
62 | + new SubjectFactory<LinkKey>(LinkKey.class, "links") { | ||
63 | + @Override | ||
64 | + public LinkKey createSubject(String key) { | ||
65 | + String[] cps = key.split("-"); | ||
66 | + checkArgument(cps.length == 2, "Incorrect link key format: %s", key); | ||
67 | + return LinkKey.linkKey(ConnectPoint.deviceConnectPoint(cps[0]), | ||
68 | + ConnectPoint.deviceConnectPoint(cps[1])); | ||
69 | + } | ||
70 | + }; | ||
71 | + | ||
72 | +} |
incubator/net/src/main/java/org/onosproject/incubator/net/config/impl/BasicNetworkConfigs.java
0 → 100644
1 | +/* | ||
2 | + * Copyright 2015 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 | + */ | ||
16 | +package org.onosproject.incubator.net.config.impl; | ||
17 | + | ||
18 | +import com.google.common.collect.ImmutableSet; | ||
19 | +import org.apache.felix.scr.annotations.Activate; | ||
20 | +import org.apache.felix.scr.annotations.Component; | ||
21 | +import org.apache.felix.scr.annotations.Deactivate; | ||
22 | +import org.apache.felix.scr.annotations.Reference; | ||
23 | +import org.apache.felix.scr.annotations.ReferenceCardinality; | ||
24 | +import org.onosproject.incubator.net.config.ConfigFactory; | ||
25 | +import org.onosproject.incubator.net.config.NetworkConfigRegistry; | ||
26 | +import org.onosproject.incubator.net.config.basics.BasicDeviceConfig; | ||
27 | +import org.onosproject.incubator.net.config.basics.BasicHostConfig; | ||
28 | +import org.onosproject.incubator.net.config.basics.BasicLinkConfig; | ||
29 | +import org.onosproject.net.DeviceId; | ||
30 | +import org.onosproject.net.HostId; | ||
31 | +import org.onosproject.net.LinkKey; | ||
32 | +import org.slf4j.Logger; | ||
33 | +import org.slf4j.LoggerFactory; | ||
34 | + | ||
35 | +import java.util.Set; | ||
36 | + | ||
37 | +import static org.onosproject.incubator.net.config.basics.SubjectFactories.*; | ||
38 | + | ||
39 | +/** | ||
40 | + * Component for registration of builtin basic network configurations. | ||
41 | + */ | ||
42 | +@Component(immediate = true) | ||
43 | +public class BasicNetworkConfigs { | ||
44 | + | ||
45 | + private final Logger log = LoggerFactory.getLogger(getClass()); | ||
46 | + | ||
47 | + private final Set<ConfigFactory> factories = ImmutableSet.of( | ||
48 | + new ConfigFactory<DeviceId, BasicDeviceConfig>(DEVICE_SUBJECT_FACTORY, | ||
49 | + BasicDeviceConfig.class, | ||
50 | + "basic") { | ||
51 | + @Override | ||
52 | + public BasicDeviceConfig createConfig() { | ||
53 | + return new BasicDeviceConfig(); | ||
54 | + } | ||
55 | + }, | ||
56 | + new ConfigFactory<HostId, BasicHostConfig>(HOST_SUBJECT_FACTORY, | ||
57 | + BasicHostConfig.class, | ||
58 | + "basic") { | ||
59 | + @Override | ||
60 | + public BasicHostConfig createConfig() { | ||
61 | + return new BasicHostConfig(); | ||
62 | + } | ||
63 | + }, | ||
64 | + new ConfigFactory<LinkKey, BasicLinkConfig>(LINK_SUBJECT_FACTORY, | ||
65 | + BasicLinkConfig.class, | ||
66 | + "basic") { | ||
67 | + @Override | ||
68 | + public BasicLinkConfig createConfig() { | ||
69 | + return new BasicLinkConfig(); | ||
70 | + } | ||
71 | + } | ||
72 | + ); | ||
73 | + | ||
74 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
75 | + protected NetworkConfigRegistry registry; | ||
76 | + | ||
77 | + @Activate | ||
78 | + public void activate() { | ||
79 | + factories.forEach(registry::registerConfigFactory); | ||
80 | + log.info("Started"); | ||
81 | + } | ||
82 | + | ||
83 | + @Deactivate | ||
84 | + public void deactivate() { | ||
85 | + factories.forEach(registry::unregisterConfigFactory); | ||
86 | + log.info("Stopped"); | ||
87 | + } | ||
88 | + | ||
89 | +} |
incubator/net/src/main/java/org/onosproject/incubator/net/config/impl/NetworkConfigManager.java
0 → 100644
1 | +/* | ||
2 | + * Copyright 2015 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 | + */ | ||
16 | +package org.onosproject.incubator.net.config.impl; | ||
17 | + | ||
18 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
19 | +import com.google.common.collect.ImmutableSet; | ||
20 | +import com.google.common.collect.Maps; | ||
21 | +import org.apache.felix.scr.annotations.Activate; | ||
22 | +import org.apache.felix.scr.annotations.Component; | ||
23 | +import org.apache.felix.scr.annotations.Deactivate; | ||
24 | +import org.apache.felix.scr.annotations.Reference; | ||
25 | +import org.apache.felix.scr.annotations.ReferenceCardinality; | ||
26 | +import org.apache.felix.scr.annotations.Service; | ||
27 | +import org.onosproject.event.EventDeliveryService; | ||
28 | +import org.onosproject.event.ListenerRegistry; | ||
29 | +import org.onosproject.incubator.net.config.Config; | ||
30 | +import org.onosproject.incubator.net.config.ConfigFactory; | ||
31 | +import org.onosproject.incubator.net.config.NetworkConfigEvent; | ||
32 | +import org.onosproject.incubator.net.config.NetworkConfigListener; | ||
33 | +import org.onosproject.incubator.net.config.NetworkConfigRegistry; | ||
34 | +import org.onosproject.incubator.net.config.NetworkConfigService; | ||
35 | +import org.onosproject.incubator.net.config.NetworkConfigStore; | ||
36 | +import org.onosproject.incubator.net.config.NetworkConfigStoreDelegate; | ||
37 | +import org.onosproject.incubator.net.config.SubjectFactory; | ||
38 | +import org.slf4j.Logger; | ||
39 | +import org.slf4j.LoggerFactory; | ||
40 | + | ||
41 | +import java.util.Map; | ||
42 | +import java.util.Objects; | ||
43 | +import java.util.Set; | ||
44 | + | ||
45 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
46 | + | ||
47 | +/** | ||
48 | + * Implementation of the network configuration subsystem. | ||
49 | + */ | ||
50 | +@Component(immediate = true) | ||
51 | +@Service | ||
52 | +public class NetworkConfigManager implements NetworkConfigRegistry, NetworkConfigService { | ||
53 | + | ||
54 | + private final Logger log = LoggerFactory.getLogger(getClass()); | ||
55 | + | ||
56 | + private static final String NULL_FACTORY_MSG = "Factory cannot be null"; | ||
57 | + private static final String NULL_SCLASS_MSG = "Subject class cannot be null"; | ||
58 | + private static final String NULL_CCLASS_MSG = "Config class cannot be null"; | ||
59 | + private static final String NULL_SUBJECT_MSG = "Subject cannot be null"; | ||
60 | + | ||
61 | + // Inventory of configuration factories | ||
62 | + private final Map<ConfigKey, ConfigFactory> factories = Maps.newConcurrentMap(); | ||
63 | + | ||
64 | + // Secondary indeces to retrieve subject and config classes by keys | ||
65 | + private final Map<String, SubjectFactory> subjectClasses = Maps.newConcurrentMap(); | ||
66 | + private final Map<Class, SubjectFactory> subjectClassKeys = Maps.newConcurrentMap(); | ||
67 | + private final Map<String, Class<? extends Config>> configClasses = Maps.newConcurrentMap(); | ||
68 | + | ||
69 | + private final ListenerRegistry<NetworkConfigEvent, NetworkConfigListener> | ||
70 | + listenerRegistry = new ListenerRegistry<>(); | ||
71 | + | ||
72 | + private final NetworkConfigStoreDelegate storeDelegate = new InternalStoreDelegate(); | ||
73 | + | ||
74 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
75 | + protected NetworkConfigStore store; | ||
76 | + | ||
77 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
78 | + protected EventDeliveryService eventDispatcher; | ||
79 | + | ||
80 | + | ||
81 | + @Activate | ||
82 | + public void activate() { | ||
83 | + eventDispatcher.addSink(NetworkConfigEvent.class, listenerRegistry); | ||
84 | + store.setDelegate(storeDelegate); | ||
85 | + log.info("Started"); | ||
86 | + } | ||
87 | + | ||
88 | + @Deactivate | ||
89 | + public void deactivate() { | ||
90 | + eventDispatcher.removeSink(NetworkConfigEvent.class); | ||
91 | + store.unsetDelegate(storeDelegate); | ||
92 | + log.info("Stopped"); | ||
93 | + } | ||
94 | + | ||
95 | + | ||
96 | + @Override | ||
97 | + @SuppressWarnings("unchecked") | ||
98 | + public void registerConfigFactory(ConfigFactory configFactory) { | ||
99 | + checkNotNull(configFactory, NULL_FACTORY_MSG); | ||
100 | + factories.put(key(configFactory), configFactory); | ||
101 | + configClasses.put(configFactory.configKey(), configFactory.configClass()); | ||
102 | + | ||
103 | + SubjectFactory subjectFactory = configFactory.subjectFactory(); | ||
104 | + subjectClasses.putIfAbsent(subjectFactory.subjectKey(), subjectFactory); | ||
105 | + subjectClassKeys.putIfAbsent(subjectFactory.subjectClass(), subjectFactory); | ||
106 | + | ||
107 | + store.addConfigFactory(configFactory); | ||
108 | + } | ||
109 | + | ||
110 | + @Override | ||
111 | + public void unregisterConfigFactory(ConfigFactory configFactory) { | ||
112 | + checkNotNull(configFactory, NULL_FACTORY_MSG); | ||
113 | + factories.remove(key(configFactory)); | ||
114 | + configClasses.remove(configFactory.configKey()); | ||
115 | + | ||
116 | + // Note that we are deliberately not removing subject factory key bindings. | ||
117 | + store.removeConfigFactory(configFactory); | ||
118 | + } | ||
119 | + | ||
120 | + @Override | ||
121 | + public Set<ConfigFactory> getConfigFactories() { | ||
122 | + return ImmutableSet.copyOf(factories.values()); | ||
123 | + } | ||
124 | + | ||
125 | + | ||
126 | + @Override | ||
127 | + @SuppressWarnings("unchecked") | ||
128 | + public <S, C extends Config<S>> Set<ConfigFactory<S, C>> getConfigFactories(Class<S> subjectClass) { | ||
129 | + ImmutableSet.Builder<ConfigFactory<S, C>> builder = ImmutableSet.builder(); | ||
130 | + factories.forEach((key, factory) -> { | ||
131 | + if (factory.subjectFactory().subjectClass().equals(subjectClass)) { | ||
132 | + builder.add(factory); | ||
133 | + } | ||
134 | + }); | ||
135 | + return builder.build(); | ||
136 | + } | ||
137 | + | ||
138 | + @Override | ||
139 | + public <S, C extends Config<S>> ConfigFactory<S, C> getConfigFactory(Class<C> configClass) { | ||
140 | + checkNotNull(configClass, NULL_CCLASS_MSG); | ||
141 | + return store.getConfigFactory(configClass); | ||
142 | + } | ||
143 | + | ||
144 | + | ||
145 | + @Override | ||
146 | + public Set<Class> getSubjectClasses() { | ||
147 | + ImmutableSet.Builder<Class> builder = ImmutableSet.builder(); | ||
148 | + factories.forEach((k, v) -> builder.add(k.subjectClass)); | ||
149 | + return builder.build(); | ||
150 | + } | ||
151 | + | ||
152 | + @Override | ||
153 | + public SubjectFactory getSubjectFactory(String subjectKey) { | ||
154 | + return subjectClasses.get(subjectKey); | ||
155 | + } | ||
156 | + | ||
157 | + @Override | ||
158 | + public SubjectFactory getSubjectFactory(Class subjectClass) { | ||
159 | + return subjectClassKeys.get(subjectClass); | ||
160 | + } | ||
161 | + | ||
162 | + @Override | ||
163 | + public Class<? extends Config> getConfigClass(String configKey) { | ||
164 | + return configClasses.get(configKey); | ||
165 | + } | ||
166 | + | ||
167 | + @Override | ||
168 | + public <S> Set<S> getSubjects(Class<S> subjectClass) { | ||
169 | + checkNotNull(subjectClass, NULL_SCLASS_MSG); | ||
170 | + return store.getSubjects(subjectClass); | ||
171 | + } | ||
172 | + | ||
173 | + @Override | ||
174 | + public <S, C extends Config<S>> Set<S> getSubjects(Class<S> subjectClass, Class<C> configClass) { | ||
175 | + checkNotNull(subjectClass, NULL_SCLASS_MSG); | ||
176 | + checkNotNull(configClass, NULL_CCLASS_MSG); | ||
177 | + return store.getSubjects(subjectClass, configClass); | ||
178 | + } | ||
179 | + | ||
180 | + @Override | ||
181 | + public <S> Set<Config<S>> getConfigs(S subject) { | ||
182 | + checkNotNull(subject, NULL_SUBJECT_MSG); | ||
183 | + Set<Class<? extends Config<S>>> configClasses = store.getConfigClasses(subject); | ||
184 | + ImmutableSet.Builder<Config<S>> cfg = ImmutableSet.builder(); | ||
185 | + configClasses.forEach(cc -> cfg.add(store.getConfig(subject, cc))); | ||
186 | + return cfg.build(); | ||
187 | + } | ||
188 | + | ||
189 | + @Override | ||
190 | + public <S, T extends Config<S>> T getConfig(S subject, Class<T> configClass) { | ||
191 | + checkNotNull(subject, NULL_SUBJECT_MSG); | ||
192 | + checkNotNull(configClass, NULL_CCLASS_MSG); | ||
193 | + return store.getConfig(subject, configClass); | ||
194 | + } | ||
195 | + | ||
196 | + | ||
197 | + @Override | ||
198 | + public <S, C extends Config<S>> C addConfig(S subject, Class<C> configClass) { | ||
199 | + checkNotNull(subject, NULL_SUBJECT_MSG); | ||
200 | + checkNotNull(configClass, NULL_CCLASS_MSG); | ||
201 | + return store.createConfig(subject, configClass); | ||
202 | + } | ||
203 | + | ||
204 | + @Override | ||
205 | + public <S, C extends Config<S>> C applyConfig(S subject, Class<C> configClass, ObjectNode json) { | ||
206 | + checkNotNull(subject, NULL_SUBJECT_MSG); | ||
207 | + checkNotNull(configClass, NULL_CCLASS_MSG); | ||
208 | + return store.applyConfig(subject, configClass, json); | ||
209 | + } | ||
210 | + | ||
211 | + @Override | ||
212 | + public <S, C extends Config<S>> void removeConfig(S subject, Class<C> configClass) { | ||
213 | + checkNotNull(subject, NULL_SUBJECT_MSG); | ||
214 | + checkNotNull(configClass, NULL_CCLASS_MSG); | ||
215 | + store.clearConfig(subject, configClass); | ||
216 | + } | ||
217 | + | ||
218 | + @Override | ||
219 | + public void addListener(NetworkConfigListener listener) { | ||
220 | + listenerRegistry.addListener(listener); | ||
221 | + } | ||
222 | + | ||
223 | + @Override | ||
224 | + public void removeListener(NetworkConfigListener listener) { | ||
225 | + listenerRegistry.removeListener(listener); | ||
226 | + } | ||
227 | + | ||
228 | + | ||
229 | + // Auxiliary store delegate to receive notification about changes in | ||
230 | + // the network configuration store state - by the store itself. | ||
231 | + private class InternalStoreDelegate implements NetworkConfigStoreDelegate { | ||
232 | + @Override | ||
233 | + public void notify(NetworkConfigEvent event) { | ||
234 | + eventDispatcher.post(event); | ||
235 | + } | ||
236 | + } | ||
237 | + | ||
238 | + | ||
239 | + // Produces a key for uniquely tracking a config factory. | ||
240 | + private static ConfigKey key(ConfigFactory factory) { | ||
241 | + return new ConfigKey(factory.subjectFactory().subjectClass(), factory.configClass()); | ||
242 | + } | ||
243 | + | ||
244 | + // Auxiliary key to track config factories. | ||
245 | + private static final class ConfigKey { | ||
246 | + final Class subjectClass; | ||
247 | + final Class configClass; | ||
248 | + | ||
249 | + private ConfigKey(Class subjectClass, Class configClass) { | ||
250 | + this.subjectClass = subjectClass; | ||
251 | + this.configClass = configClass; | ||
252 | + } | ||
253 | + | ||
254 | + @Override | ||
255 | + public int hashCode() { | ||
256 | + return Objects.hash(subjectClass, configClass); | ||
257 | + } | ||
258 | + | ||
259 | + @Override | ||
260 | + public boolean equals(Object obj) { | ||
261 | + if (this == obj) { | ||
262 | + return true; | ||
263 | + } | ||
264 | + if (obj instanceof ConfigKey) { | ||
265 | + final ConfigKey other = (ConfigKey) obj; | ||
266 | + return Objects.equals(this.subjectClass, other.subjectClass) | ||
267 | + && Objects.equals(this.configClass, other.configClass); | ||
268 | + } | ||
269 | + return false; | ||
270 | + } | ||
271 | + } | ||
272 | + | ||
273 | +} |
1 | +/* | ||
2 | + * Copyright 2015 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 | + */ | ||
16 | +package org.onosproject.incubator.store.config.impl; | ||
17 | + | ||
18 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
19 | +import com.fasterxml.jackson.databind.node.BooleanNode; | ||
20 | +import com.fasterxml.jackson.databind.node.DoubleNode; | ||
21 | +import com.fasterxml.jackson.databind.node.JsonNodeFactory; | ||
22 | +import com.fasterxml.jackson.databind.node.LongNode; | ||
23 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
24 | +import com.fasterxml.jackson.databind.node.ShortNode; | ||
25 | +import com.fasterxml.jackson.databind.node.TextNode; | ||
26 | +import com.google.common.collect.ImmutableSet; | ||
27 | +import com.google.common.collect.Maps; | ||
28 | +import org.apache.felix.scr.annotations.Activate; | ||
29 | +import org.apache.felix.scr.annotations.Component; | ||
30 | +import org.apache.felix.scr.annotations.Deactivate; | ||
31 | +import org.apache.felix.scr.annotations.Reference; | ||
32 | +import org.apache.felix.scr.annotations.ReferenceCardinality; | ||
33 | +import org.apache.felix.scr.annotations.Service; | ||
34 | +import org.onlab.util.KryoNamespace; | ||
35 | +import org.onosproject.incubator.net.config.Config; | ||
36 | +import org.onosproject.incubator.net.config.ConfigApplyDelegate; | ||
37 | +import org.onosproject.incubator.net.config.ConfigFactory; | ||
38 | +import org.onosproject.incubator.net.config.NetworkConfigEvent; | ||
39 | +import org.onosproject.incubator.net.config.NetworkConfigStore; | ||
40 | +import org.onosproject.incubator.net.config.NetworkConfigStoreDelegate; | ||
41 | +import org.onosproject.store.AbstractStore; | ||
42 | +import org.onosproject.store.serializers.KryoNamespaces; | ||
43 | +import org.onosproject.store.service.ConsistentMap; | ||
44 | +import org.onosproject.store.service.MapEvent; | ||
45 | +import org.onosproject.store.service.MapEventListener; | ||
46 | +import org.onosproject.store.service.Serializer; | ||
47 | +import org.onosproject.store.service.StorageService; | ||
48 | +import org.onosproject.store.service.Versioned; | ||
49 | +import org.slf4j.Logger; | ||
50 | +import org.slf4j.LoggerFactory; | ||
51 | + | ||
52 | +import java.util.LinkedHashMap; | ||
53 | +import java.util.Map; | ||
54 | +import java.util.Objects; | ||
55 | +import java.util.Set; | ||
56 | + | ||
57 | +import static org.onosproject.incubator.net.config.NetworkConfigEvent.Type.*; | ||
58 | + | ||
59 | +/** | ||
60 | + * Implementation of a distributed network configuration store. | ||
61 | + */ | ||
62 | +@Component(immediate = true) | ||
63 | +@Service | ||
64 | +public class DistributedNetworkConfigStore | ||
65 | + extends AbstractStore<NetworkConfigEvent, NetworkConfigStoreDelegate> | ||
66 | + implements NetworkConfigStore { | ||
67 | + | ||
68 | + private final Logger log = LoggerFactory.getLogger(getClass()); | ||
69 | + | ||
70 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
71 | + protected StorageService storageService; | ||
72 | + | ||
73 | + private ConsistentMap<ConfigKey, ObjectNode> configs; | ||
74 | + | ||
75 | + private final Map<String, ConfigFactory> factoriesByConfig = Maps.newConcurrentMap(); | ||
76 | + private final ObjectMapper mapper = new ObjectMapper(); | ||
77 | + private final ConfigApplyDelegate applyDelegate = new InternalApplyDelegate(); | ||
78 | + private final MapEventListener<ConfigKey, ObjectNode> listener = new InternalMapListener(); | ||
79 | + | ||
80 | + @Activate | ||
81 | + public void activate() { | ||
82 | + KryoNamespace.Builder kryoBuilder = new KryoNamespace.Builder() | ||
83 | + .register(KryoNamespaces.API) | ||
84 | + .register(ConfigKey.class, ObjectNode.class, | ||
85 | + JsonNodeFactory.class, LinkedHashMap.class, | ||
86 | + TextNode.class, BooleanNode.class, | ||
87 | + LongNode.class, DoubleNode.class, ShortNode.class); | ||
88 | + | ||
89 | + configs = storageService.<ConfigKey, ObjectNode>consistentMapBuilder() | ||
90 | + .withSerializer(Serializer.using(kryoBuilder.build())) | ||
91 | + .withName("onos-network-configs") | ||
92 | + .build(); | ||
93 | + configs.addListener(listener); | ||
94 | + log.info("Started"); | ||
95 | + } | ||
96 | + | ||
97 | + @Deactivate | ||
98 | + public void deactivate() { | ||
99 | + configs.removeListener(listener); | ||
100 | + log.info("Stopped"); | ||
101 | + } | ||
102 | + | ||
103 | + @Override | ||
104 | + public void addConfigFactory(ConfigFactory configFactory) { | ||
105 | + factoriesByConfig.put(configFactory.configClass().getName(), configFactory); | ||
106 | + } | ||
107 | + | ||
108 | + @Override | ||
109 | + public void removeConfigFactory(ConfigFactory configFactory) { | ||
110 | + factoriesByConfig.remove(configFactory.configClass().getName()); | ||
111 | + } | ||
112 | + | ||
113 | + @Override | ||
114 | + @SuppressWarnings("unchecked") | ||
115 | + public <S, C extends Config<S>> ConfigFactory<S, C> getConfigFactory(Class<C> configClass) { | ||
116 | + return (ConfigFactory<S, C>) factoriesByConfig.get(configClass.getName()); | ||
117 | + } | ||
118 | + | ||
119 | + @Override | ||
120 | + @SuppressWarnings("unchecked") | ||
121 | + public <S> Set<S> getSubjects(Class<S> subjectClass) { | ||
122 | + ImmutableSet.Builder<S> builder = ImmutableSet.builder(); | ||
123 | + configs.keySet().forEach(k -> { | ||
124 | + if (subjectClass.isInstance(k.subject)) { | ||
125 | + builder.add((S) k.subject); | ||
126 | + } | ||
127 | + }); | ||
128 | + return builder.build(); | ||
129 | + } | ||
130 | + | ||
131 | + @Override | ||
132 | + @SuppressWarnings("unchecked") | ||
133 | + public <S, C extends Config<S>> Set<S> getSubjects(Class<S> subjectClass, Class<C> configClass) { | ||
134 | + ImmutableSet.Builder<S> builder = ImmutableSet.builder(); | ||
135 | + String cName = configClass.getName(); | ||
136 | + configs.keySet().forEach(k -> { | ||
137 | + if (subjectClass.isInstance(k.subject) && cName.equals(k.configClass)) { | ||
138 | + builder.add((S) k.subject); | ||
139 | + } | ||
140 | + }); | ||
141 | + return builder.build(); | ||
142 | + } | ||
143 | + | ||
144 | + @Override | ||
145 | + @SuppressWarnings("unchecked") | ||
146 | + public <S> Set<Class<? extends Config<S>>> getConfigClasses(S subject) { | ||
147 | + ImmutableSet.Builder<Class<? extends Config<S>>> builder = ImmutableSet.builder(); | ||
148 | + configs.keySet().forEach(k -> { | ||
149 | + if (Objects.equals(subject, k.subject) && delegate != null) { | ||
150 | + builder.add(factoriesByConfig.get(k.configClass).configClass()); | ||
151 | + } | ||
152 | + }); | ||
153 | + return builder.build(); | ||
154 | + } | ||
155 | + | ||
156 | + @Override | ||
157 | + public <S, T extends Config<S>> T getConfig(S subject, Class<T> configClass) { | ||
158 | + Versioned<ObjectNode> json = configs.get(key(subject, configClass)); | ||
159 | + return json != null ? createConfig(subject, configClass, json.value()) : null; | ||
160 | + } | ||
161 | + | ||
162 | + | ||
163 | + @Override | ||
164 | + public <S, C extends Config<S>> C createConfig(S subject, Class<C> configClass) { | ||
165 | + Versioned<ObjectNode> json = configs.computeIfAbsent(key(subject, configClass), | ||
166 | + k -> mapper.createObjectNode()); | ||
167 | + return createConfig(subject, configClass, json.value()); | ||
168 | + } | ||
169 | + | ||
170 | + @Override | ||
171 | + public <S, C extends Config<S>> C applyConfig(S subject, Class<C> configClass, ObjectNode json) { | ||
172 | + return createConfig(subject, configClass, | ||
173 | + configs.putAndGet(key(subject, configClass), json).value()); | ||
174 | + } | ||
175 | + | ||
176 | + @Override | ||
177 | + public <S, C extends Config<S>> void clearConfig(S subject, Class<C> configClass) { | ||
178 | + configs.remove(key(subject, configClass)); | ||
179 | + } | ||
180 | + | ||
181 | + /** | ||
182 | + * Produces a config from the specified subject, config class and raw JSON. | ||
183 | + * | ||
184 | + * @param subject config subject | ||
185 | + * @param configClass config class | ||
186 | + * @param json raw JSON data | ||
187 | + * @return config object or null of no factory found or if the specified | ||
188 | + * JSON is null | ||
189 | + */ | ||
190 | + @SuppressWarnings("unchecked") | ||
191 | + private <S, C extends Config<S>> C createConfig(S subject, Class<C> configClass, | ||
192 | + ObjectNode json) { | ||
193 | + if (json != null) { | ||
194 | + ConfigFactory<S, C> factory = factoriesByConfig.get(configClass.getName()); | ||
195 | + if (factory != null) { | ||
196 | + C config = factory.createConfig(); | ||
197 | + config.init(subject, factory.configKey(), json, mapper, applyDelegate); | ||
198 | + return config; | ||
199 | + } | ||
200 | + } | ||
201 | + return null; | ||
202 | + } | ||
203 | + | ||
204 | + | ||
205 | + // Auxiliary delegate to receive notifications about changes applied to | ||
206 | + // the network configuration - by the apps. | ||
207 | + private class InternalApplyDelegate implements ConfigApplyDelegate { | ||
208 | + @Override | ||
209 | + public void onApply(Config config) { | ||
210 | + configs.put(key(config.subject(), config.getClass()), config.node()); | ||
211 | + } | ||
212 | + } | ||
213 | + | ||
214 | + // Produces a key for uniquely tracking a subject config. | ||
215 | + private static ConfigKey key(Object subject, Class<?> configClass) { | ||
216 | + return new ConfigKey(subject, configClass); | ||
217 | + } | ||
218 | + | ||
219 | + // Auxiliary key to track subject configurations. | ||
220 | + private static final class ConfigKey { | ||
221 | + final Object subject; | ||
222 | + final String configClass; | ||
223 | + | ||
224 | + private ConfigKey(Object subject, Class<?> configClass) { | ||
225 | + this.subject = subject; | ||
226 | + this.configClass = configClass.getName(); | ||
227 | + } | ||
228 | + | ||
229 | + @Override | ||
230 | + public int hashCode() { | ||
231 | + return Objects.hash(subject, configClass); | ||
232 | + } | ||
233 | + | ||
234 | + @Override | ||
235 | + public boolean equals(Object obj) { | ||
236 | + if (this == obj) { | ||
237 | + return true; | ||
238 | + } | ||
239 | + if (obj instanceof ConfigKey) { | ||
240 | + final ConfigKey other = (ConfigKey) obj; | ||
241 | + return Objects.equals(this.subject, other.subject) | ||
242 | + && Objects.equals(this.configClass, other.configClass); | ||
243 | + } | ||
244 | + return false; | ||
245 | + } | ||
246 | + } | ||
247 | + | ||
248 | + private class InternalMapListener implements MapEventListener<ConfigKey, ObjectNode> { | ||
249 | + @Override | ||
250 | + public void event(MapEvent<ConfigKey, ObjectNode> event) { | ||
251 | + NetworkConfigEvent.Type type; | ||
252 | + switch (event.type()) { | ||
253 | + case INSERT: | ||
254 | + type = CONFIG_ADDED; | ||
255 | + break; | ||
256 | + case UPDATE: | ||
257 | + type = CONFIG_UPDATED; | ||
258 | + break; | ||
259 | + case REMOVE: | ||
260 | + default: | ||
261 | + type = CONFIG_REMOVED; | ||
262 | + break; | ||
263 | + } | ||
264 | + ConfigFactory factory = factoriesByConfig.get(event.key().configClass); | ||
265 | + if (factory != null) { | ||
266 | + notifyDelegate(new NetworkConfigEvent(type, event.key().subject, | ||
267 | + factory.configClass())); | ||
268 | + } | ||
269 | + } | ||
270 | + } | ||
271 | +} |
1 | +/* | ||
2 | + * Copyright 2015 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 | + */ | ||
16 | +package org.onosproject.rest.resources; | ||
17 | + | ||
18 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
19 | +import org.onosproject.incubator.net.config.NetworkConfigService; | ||
20 | +import org.onosproject.incubator.net.config.SubjectFactory; | ||
21 | +import org.onosproject.rest.AbstractWebResource; | ||
22 | + | ||
23 | +import javax.ws.rs.Consumes; | ||
24 | +import javax.ws.rs.DELETE; | ||
25 | +import javax.ws.rs.GET; | ||
26 | +import javax.ws.rs.POST; | ||
27 | +import javax.ws.rs.Path; | ||
28 | +import javax.ws.rs.PathParam; | ||
29 | +import javax.ws.rs.Produces; | ||
30 | +import javax.ws.rs.core.MediaType; | ||
31 | +import javax.ws.rs.core.Response; | ||
32 | +import java.io.IOException; | ||
33 | +import java.io.InputStream; | ||
34 | + | ||
35 | +/** | ||
36 | + * REST resource for injecting and retrieving common network configuration. | ||
37 | + */ | ||
38 | +@Path("network/configuration") | ||
39 | +public class NetworkConfigWebResource extends AbstractWebResource { | ||
40 | + | ||
41 | + /** | ||
42 | + * Returns entire network configuration base. | ||
43 | + * | ||
44 | + * @return network configuration JSON | ||
45 | + */ | ||
46 | + @GET | ||
47 | + @Produces(MediaType.APPLICATION_JSON) | ||
48 | + @SuppressWarnings("unchecked") | ||
49 | + public Response download() { | ||
50 | + NetworkConfigService service = get(NetworkConfigService.class); | ||
51 | + ObjectNode root = mapper().createObjectNode(); | ||
52 | + service.getSubjectClasses().forEach(sc -> | ||
53 | + produceJson(service, newObject(root, service.getSubjectFactory(sc).subjectKey()), sc)); | ||
54 | + return ok(root).build(); | ||
55 | + } | ||
56 | + | ||
57 | + /** | ||
58 | + * Returns the network configuration for the specified subject class. | ||
59 | + * | ||
60 | + * @param subjectKey subject class key | ||
61 | + * @return network configuration JSON | ||
62 | + */ | ||
63 | + @GET | ||
64 | + @Path("{subjectKey}") | ||
65 | + @Produces(MediaType.APPLICATION_JSON) | ||
66 | + @SuppressWarnings("unchecked") | ||
67 | + public Response download(@PathParam("subjectKey") String subjectKey) { | ||
68 | + NetworkConfigService service = get(NetworkConfigService.class); | ||
69 | + ObjectNode root = mapper().createObjectNode(); | ||
70 | + produceJson(service, root, service.getSubjectFactory(subjectKey).subjectClass()); | ||
71 | + return ok(root).build(); | ||
72 | + } | ||
73 | + | ||
74 | + /** | ||
75 | + * Returns the network configuration for the specified subject. | ||
76 | + * | ||
77 | + * @param subjectKey subject class key | ||
78 | + * @param subject subject key | ||
79 | + * @return network configuration JSON | ||
80 | + */ | ||
81 | + @GET | ||
82 | + @Path("{subjectKey}/{subject}") | ||
83 | + @Produces(MediaType.APPLICATION_JSON) | ||
84 | + @SuppressWarnings("unchecked") | ||
85 | + public Response download(@PathParam("subjectKey") String subjectKey, | ||
86 | + @PathParam("subject") String subject) { | ||
87 | + NetworkConfigService service = get(NetworkConfigService.class); | ||
88 | + ObjectNode root = mapper().createObjectNode(); | ||
89 | + produceSubjectJson(service, root, | ||
90 | + service.getSubjectFactory(subjectKey).createSubject(subject)); | ||
91 | + return ok(root).build(); | ||
92 | + } | ||
93 | + | ||
94 | + /** | ||
95 | + * Returns the network configuration for the specified subject and given | ||
96 | + * configuration class. | ||
97 | + * | ||
98 | + * @param subjectKey subject class key | ||
99 | + * @param subject subject key | ||
100 | + * @param configKey configuration class key | ||
101 | + * @return network configuration JSON | ||
102 | + */ | ||
103 | + @GET | ||
104 | + @Path("{subjectKey}/{subject}/{configKey}") | ||
105 | + @Produces(MediaType.APPLICATION_JSON) | ||
106 | + @SuppressWarnings("unchecked") | ||
107 | + public Response download(@PathParam("subjectKey") String subjectKey, | ||
108 | + @PathParam("subject") String subject, | ||
109 | + @PathParam("configKey") String configKey) { | ||
110 | + NetworkConfigService service = get(NetworkConfigService.class); | ||
111 | + return ok(service.getConfig(service.getSubjectFactory(subjectKey).createSubject(subject), | ||
112 | + service.getConfigClass(configKey)).node()).build(); | ||
113 | + } | ||
114 | + | ||
115 | + @SuppressWarnings("unchecked") | ||
116 | + private void produceJson(NetworkConfigService service, ObjectNode node, | ||
117 | + Class subjectClass) { | ||
118 | + service.getSubjects(subjectClass).forEach(s -> | ||
119 | + produceSubjectJson(service, newObject(node, s.toString()), s)); | ||
120 | + } | ||
121 | + | ||
122 | + private void produceSubjectJson(NetworkConfigService service, ObjectNode node, | ||
123 | + Object subject) { | ||
124 | + service.getConfigs(subject).forEach(c -> node.set(c.key(), c.node())); | ||
125 | + } | ||
126 | + | ||
127 | + | ||
128 | + /** | ||
129 | + * Uploads network configuration in bulk. | ||
130 | + * | ||
131 | + * @param request network configuration JSON rooted at the top node | ||
132 | + * @throws IOException | ||
133 | + * @return empty response | ||
134 | + */ | ||
135 | + @POST | ||
136 | + @Consumes(MediaType.APPLICATION_JSON) | ||
137 | + @SuppressWarnings("unchecked") | ||
138 | + public Response upload(InputStream request) throws IOException { | ||
139 | + NetworkConfigService service = get(NetworkConfigService.class); | ||
140 | + ObjectNode root = (ObjectNode) mapper().readTree(request); | ||
141 | + root.fieldNames() | ||
142 | + .forEachRemaining(sk -> consumeJson(service, (ObjectNode) root.path(sk), | ||
143 | + service.getSubjectFactory(sk))); | ||
144 | + return Response.ok().build(); | ||
145 | + } | ||
146 | + | ||
147 | + /** | ||
148 | + * Uploads network configuration for the specified subject class. | ||
149 | + * | ||
150 | + * @param subjectKey subject class key | ||
151 | + * @param request network configuration JSON rooted at the top node | ||
152 | + * @return empty response | ||
153 | + * @throws IOException | ||
154 | + */ | ||
155 | + @POST | ||
156 | + @Path("{subjectKey}") | ||
157 | + @Consumes(MediaType.APPLICATION_JSON) | ||
158 | + @SuppressWarnings("unchecked") | ||
159 | + public Response upload(@PathParam("subjectKey") String subjectKey, | ||
160 | + InputStream request) throws IOException { | ||
161 | + NetworkConfigService service = get(NetworkConfigService.class); | ||
162 | + ObjectNode root = (ObjectNode) mapper().readTree(request); | ||
163 | + consumeJson(service, root, service.getSubjectFactory(subjectKey)); | ||
164 | + return Response.ok().build(); | ||
165 | + } | ||
166 | + | ||
167 | + /** | ||
168 | + * Uploads network configuration for the specified subject. | ||
169 | + * | ||
170 | + * @param subjectKey subject class key | ||
171 | + * @param subject subject key | ||
172 | + * @param request network configuration JSON rooted at the top node | ||
173 | + * @return empty response | ||
174 | + * @throws IOException | ||
175 | + */ | ||
176 | + @POST | ||
177 | + @Path("{subjectKey}/{subject}") | ||
178 | + @Consumes(MediaType.APPLICATION_JSON) | ||
179 | + @SuppressWarnings("unchecked") | ||
180 | + public Response upload(@PathParam("subjectKey") String subjectKey, | ||
181 | + @PathParam("subject") String subject, | ||
182 | + InputStream request) throws IOException { | ||
183 | + NetworkConfigService service = get(NetworkConfigService.class); | ||
184 | + ObjectNode root = (ObjectNode) mapper().readTree(request); | ||
185 | + consumeSubjectJson(service, root, | ||
186 | + service.getSubjectFactory(subjectKey).createSubject(subject)); | ||
187 | + return Response.ok().build(); | ||
188 | + } | ||
189 | + | ||
190 | + /** | ||
191 | + * Uploads network configuration for the specified subject and given | ||
192 | + * configuration class. | ||
193 | + * | ||
194 | + * @param subjectKey subject class key | ||
195 | + * @param subject subject key | ||
196 | + * @param configKey configuration class key | ||
197 | + * @param request network configuration JSON rooted at the top node | ||
198 | + * @return empty response | ||
199 | + * @throws IOException | ||
200 | + */ | ||
201 | + @POST | ||
202 | + @Path("{subjectKey}/{subject}/{configKey}") | ||
203 | + @Consumes(MediaType.APPLICATION_JSON) | ||
204 | + @SuppressWarnings("unchecked") | ||
205 | + public Response upload(@PathParam("subjectKey") String subjectKey, | ||
206 | + @PathParam("subject") String subject, | ||
207 | + @PathParam("configKey") String configKey, | ||
208 | + InputStream request) throws IOException { | ||
209 | + NetworkConfigService service = get(NetworkConfigService.class); | ||
210 | + ObjectNode root = (ObjectNode) mapper().readTree(request); | ||
211 | + service.applyConfig(service.getSubjectFactory(subjectKey).createSubject(subject), | ||
212 | + service.getConfigClass(configKey), root); | ||
213 | + return Response.ok().build(); | ||
214 | + } | ||
215 | + | ||
216 | + private void consumeJson(NetworkConfigService service, ObjectNode classNode, | ||
217 | + SubjectFactory subjectFactory) { | ||
218 | + classNode.fieldNames().forEachRemaining(s -> | ||
219 | + consumeSubjectJson(service, (ObjectNode) classNode.path(s), | ||
220 | + subjectFactory.createSubject(s))); | ||
221 | + } | ||
222 | + | ||
223 | + private void consumeSubjectJson(NetworkConfigService service, | ||
224 | + ObjectNode subjectNode, Object subject) { | ||
225 | + subjectNode.fieldNames().forEachRemaining(c -> | ||
226 | + service.applyConfig(subject, service.getConfigClass(c), | ||
227 | + (ObjectNode) subjectNode.path(c))); | ||
228 | + } | ||
229 | + | ||
230 | + | ||
231 | + /** | ||
232 | + * Clears network configuration for the specified subject. | ||
233 | + * | ||
234 | + * @param subjectKey subject class key | ||
235 | + * @param subject subject key | ||
236 | + * @return empty response | ||
237 | + */ | ||
238 | + @DELETE | ||
239 | + @Path("{subjectKey}/{subject}") | ||
240 | + @Consumes(MediaType.APPLICATION_JSON) | ||
241 | + @SuppressWarnings("unchecked") | ||
242 | + public Response upload(@PathParam("subjectKey") String subjectKey, | ||
243 | + @PathParam("subject") String subject) { | ||
244 | + NetworkConfigService service = get(NetworkConfigService.class); | ||
245 | + Object s = service.getSubjectFactory(subjectKey).createSubject(subject); | ||
246 | + service.getConfigs(s).forEach(c -> service.removeConfig(s, c.getClass())); | ||
247 | + return Response.ok().build(); | ||
248 | + } | ||
249 | + | ||
250 | + /** | ||
251 | + * Clears network configuration for the specified subject and given | ||
252 | + * configuration class. | ||
253 | + * | ||
254 | + * @param subjectKey subject class key | ||
255 | + * @param subject subject key | ||
256 | + * @param configKey configuration class key | ||
257 | + * @return empty response | ||
258 | + */ | ||
259 | + @DELETE | ||
260 | + @Path("{subjectKey}/{subject}/{configKey}") | ||
261 | + @Consumes(MediaType.APPLICATION_JSON) | ||
262 | + @SuppressWarnings("unchecked") | ||
263 | + public Response upload(@PathParam("subjectKey") String subjectKey, | ||
264 | + @PathParam("subject") String subject, | ||
265 | + @PathParam("configKey") String configKey) { | ||
266 | + NetworkConfigService service = get(NetworkConfigService.class); | ||
267 | + service.removeConfig(service.getSubjectFactory(subjectKey).createSubject(subject), | ||
268 | + service.getConfigClass(configKey)); | ||
269 | + return Response.ok().build(); | ||
270 | + } | ||
271 | + | ||
272 | +} |
... | @@ -67,6 +67,7 @@ | ... | @@ -67,6 +67,7 @@ |
67 | 67 | ||
68 | org.onosproject.rest.resources.ApplicationsWebResource, | 68 | org.onosproject.rest.resources.ApplicationsWebResource, |
69 | org.onosproject.rest.resources.ComponentConfigWebResource, | 69 | org.onosproject.rest.resources.ComponentConfigWebResource, |
70 | + org.onosproject.rest.resources.NetworkConfigWebResource, | ||
70 | org.onosproject.rest.resources.ClusterWebResource, | 71 | org.onosproject.rest.resources.ClusterWebResource, |
71 | org.onosproject.rest.resources.DevicesWebResource, | 72 | org.onosproject.rest.resources.DevicesWebResource, |
72 | org.onosproject.rest.resources.LinksWebResource, | 73 | org.onosproject.rest.resources.LinksWebResource, | ... | ... |
web/api/src/test/resources/net-config.json
0 → 100644
-
Please register or login to post a comment