Clean up a few SSM-translate things, incl config validation
Change-Id: I5308fd8a73088ea6a522f22642ee834ac8a7a446
Showing
3 changed files
with
74 additions
and
8 deletions
... | @@ -84,7 +84,6 @@ import static org.slf4j.LoggerFactory.getLogger; | ... | @@ -84,7 +84,6 @@ import static org.slf4j.LoggerFactory.getLogger; |
84 | @Component(immediate = true) | 84 | @Component(immediate = true) |
85 | public class IgmpSnoop { | 85 | public class IgmpSnoop { |
86 | 86 | ||
87 | - | ||
88 | private final Logger log = getLogger(getClass()); | 87 | private final Logger log = getLogger(getClass()); |
89 | 88 | ||
90 | private static final String DEST_MAC = "01:00:5E:00:00:01"; | 89 | private static final String DEST_MAC = "01:00:5E:00:00:01"; |
... | @@ -144,6 +143,9 @@ public class IgmpSnoop { | ... | @@ -144,6 +143,9 @@ public class IgmpSnoop { |
144 | private static final Class<AccessDeviceConfig> CONFIG_CLASS = | 143 | private static final Class<AccessDeviceConfig> CONFIG_CLASS = |
145 | AccessDeviceConfig.class; | 144 | AccessDeviceConfig.class; |
146 | 145 | ||
146 | + private static final Class<IgmpSsmTranslateConfig> SSM_TRANSLATE_CONFIG_CLASS = | ||
147 | + IgmpSsmTranslateConfig.class; | ||
148 | + | ||
147 | private ConfigFactory<DeviceId, AccessDeviceConfig> configFactory = | 149 | private ConfigFactory<DeviceId, AccessDeviceConfig> configFactory = |
148 | new ConfigFactory<DeviceId, AccessDeviceConfig>( | 150 | new ConfigFactory<DeviceId, AccessDeviceConfig>( |
149 | SubjectFactories.DEVICE_SUBJECT_FACTORY, CONFIG_CLASS, "accessDevice") { | 151 | SubjectFactories.DEVICE_SUBJECT_FACTORY, CONFIG_CLASS, "accessDevice") { |
... | @@ -155,7 +157,7 @@ public class IgmpSnoop { | ... | @@ -155,7 +157,7 @@ public class IgmpSnoop { |
155 | 157 | ||
156 | private ConfigFactory<ApplicationId, IgmpSsmTranslateConfig> ssmTranslateConfigFactory = | 158 | private ConfigFactory<ApplicationId, IgmpSsmTranslateConfig> ssmTranslateConfigFactory = |
157 | new ConfigFactory<ApplicationId, IgmpSsmTranslateConfig>( | 159 | new ConfigFactory<ApplicationId, IgmpSsmTranslateConfig>( |
158 | - SubjectFactories.APP_SUBJECT_FACTORY, IgmpSsmTranslateConfig.class, "ssmTranslate", true) { | 160 | + SubjectFactories.APP_SUBJECT_FACTORY, SSM_TRANSLATE_CONFIG_CLASS, "ssmTranslate", true) { |
159 | @Override | 161 | @Override |
160 | public IgmpSsmTranslateConfig createConfig() { | 162 | public IgmpSsmTranslateConfig createConfig() { |
161 | return new IgmpSsmTranslateConfig(); | 163 | return new IgmpSsmTranslateConfig(); |
... | @@ -466,9 +468,25 @@ public class IgmpSnoop { | ... | @@ -466,9 +468,25 @@ public class IgmpSnoop { |
466 | provisionDefaultFlows((DeviceId) event.subject()); | 468 | provisionDefaultFlows((DeviceId) event.subject()); |
467 | } | 469 | } |
468 | } | 470 | } |
471 | + if (event.configClass().equals(SSM_TRANSLATE_CONFIG_CLASS)) { | ||
472 | + IgmpSsmTranslateConfig config = | ||
473 | + networkConfig.getConfig((ApplicationId) event.subject(), | ||
474 | + SSM_TRANSLATE_CONFIG_CLASS); | ||
475 | + | ||
476 | + if (config != null) { | ||
477 | + ssmTranslateTable.clear(); | ||
478 | + config.getSsmTranslations().forEach( | ||
479 | + route -> ssmTranslateTable.put(route.group(), route.source())); | ||
480 | + } | ||
481 | + } | ||
469 | break; | 482 | break; |
483 | + case CONFIG_REGISTERED: | ||
470 | case CONFIG_UNREGISTERED: | 484 | case CONFIG_UNREGISTERED: |
485 | + break; | ||
471 | case CONFIG_REMOVED: | 486 | case CONFIG_REMOVED: |
487 | + if (event.configClass().equals(SSM_TRANSLATE_CONFIG_CLASS)) { | ||
488 | + ssmTranslateTable.clear(); | ||
489 | + } | ||
472 | default: | 490 | default: |
473 | break; | 491 | break; |
474 | } | 492 | } | ... | ... |
... | @@ -17,6 +17,7 @@ | ... | @@ -17,6 +17,7 @@ |
17 | package org.onosproject.igmp; | 17 | package org.onosproject.igmp; |
18 | 18 | ||
19 | import com.fasterxml.jackson.databind.JsonNode; | 19 | import com.fasterxml.jackson.databind.JsonNode; |
20 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
20 | import org.onlab.packet.IpAddress; | 21 | import org.onlab.packet.IpAddress; |
21 | import org.onosproject.core.ApplicationId; | 22 | import org.onosproject.core.ApplicationId; |
22 | import org.onosproject.net.config.Config; | 23 | import org.onosproject.net.config.Config; |
... | @@ -26,13 +27,34 @@ import java.util.ArrayList; | ... | @@ -26,13 +27,34 @@ import java.util.ArrayList; |
26 | import java.util.List; | 27 | import java.util.List; |
27 | 28 | ||
28 | /** | 29 | /** |
29 | - * Created by jono on 2/16/16. | 30 | + * IGMP SSM translate configuration. |
30 | */ | 31 | */ |
31 | public class IgmpSsmTranslateConfig extends Config<ApplicationId> { | 32 | public class IgmpSsmTranslateConfig extends Config<ApplicationId> { |
32 | - private static final String SSM_TRANSLATE = "ssmTranslate"; | 33 | + |
33 | private static final String SOURCE = "source"; | 34 | private static final String SOURCE = "source"; |
34 | private static final String GROUP = "group"; | 35 | private static final String GROUP = "group"; |
35 | 36 | ||
37 | + @Override | ||
38 | + public boolean isValid() { | ||
39 | + for (JsonNode node : array) { | ||
40 | + if (!hasOnlyFields((ObjectNode) node, SOURCE, GROUP)) { | ||
41 | + return false; | ||
42 | + } | ||
43 | + | ||
44 | + if (!(isIpAddress((ObjectNode) node, SOURCE, FieldPresence.MANDATORY) && | ||
45 | + isIpAddress((ObjectNode) node, GROUP, FieldPresence.MANDATORY))) { | ||
46 | + return false; | ||
47 | + } | ||
48 | + | ||
49 | + } | ||
50 | + return true; | ||
51 | + } | ||
52 | + | ||
53 | + /** | ||
54 | + * Gets the list of SSM translations. | ||
55 | + * | ||
56 | + * @return SSM translations | ||
57 | + */ | ||
36 | public List<McastRoute> getSsmTranslations() { | 58 | public List<McastRoute> getSsmTranslations() { |
37 | List<McastRoute> translations = new ArrayList(); | 59 | List<McastRoute> translations = new ArrayList(); |
38 | for (JsonNode node : array) { | 60 | for (JsonNode node : array) { | ... | ... |
... | @@ -393,8 +393,20 @@ public abstract class Config<S> { | ... | @@ -393,8 +393,20 @@ public abstract class Config<S> { |
393 | * @return true if all allowedFields are present; false otherwise | 393 | * @return true if all allowedFields are present; false otherwise |
394 | */ | 394 | */ |
395 | protected boolean hasOnlyFields(String... allowedFields) { | 395 | protected boolean hasOnlyFields(String... allowedFields) { |
396 | + return hasOnlyFields(object, allowedFields); | ||
397 | + } | ||
398 | + | ||
399 | + /** | ||
400 | + * Indicates whether only the specified fields are present in a particular | ||
401 | + * JSON object. | ||
402 | + * | ||
403 | + * @param node node whose fields to check | ||
404 | + * @param allowedFields allowed field names | ||
405 | + * @return true if all allowedFields are present; false otherwise | ||
406 | + */ | ||
407 | + protected boolean hasOnlyFields(ObjectNode node, String... allowedFields) { | ||
396 | Set<String> fields = ImmutableSet.copyOf(allowedFields); | 408 | Set<String> fields = ImmutableSet.copyOf(allowedFields); |
397 | - return !Iterators.any(object.fieldNames(), f -> !fields.contains(f)); | 409 | + return !Iterators.any(node.fieldNames(), f -> !fields.contains(f)); |
398 | } | 410 | } |
399 | 411 | ||
400 | /** | 412 | /** |
... | @@ -420,9 +432,23 @@ public abstract class Config<S> { | ... | @@ -420,9 +432,23 @@ public abstract class Config<S> { |
420 | * @throws IllegalArgumentException if field is present, but not valid IP | 432 | * @throws IllegalArgumentException if field is present, but not valid IP |
421 | */ | 433 | */ |
422 | protected boolean isIpAddress(String field, FieldPresence presence) { | 434 | protected boolean isIpAddress(String field, FieldPresence presence) { |
423 | - JsonNode node = object.path(field); | 435 | + return isIpAddress(object, field, presence); |
424 | - return isValid(node, presence, node.isTextual() && | 436 | + } |
425 | - IpAddress.valueOf(node.asText()) != null); | 437 | + |
438 | + /** | ||
439 | + * Indicates whether the specified field of a particular node holds a valid | ||
440 | + * IP address. | ||
441 | + * | ||
442 | + * @param node node from whom to access the field | ||
443 | + * @param field JSON field name | ||
444 | + * @param presence specifies if field is optional or mandatory | ||
445 | + * @return true if valid; false otherwise | ||
446 | + * @throws IllegalArgumentException if field is present, but not valid IP | ||
447 | + */ | ||
448 | + protected boolean isIpAddress(ObjectNode node, String field, FieldPresence presence) { | ||
449 | + JsonNode innerNode = node.path(field); | ||
450 | + return isValid(innerNode, presence, innerNode.isTextual() && | ||
451 | + IpAddress.valueOf(innerNode.asText()) != null); | ||
426 | } | 452 | } |
427 | 453 | ||
428 | /** | 454 | /** | ... | ... |
-
Please register or login to post a comment