X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=netconf%2Fnetconf-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fnetconf%2Fimpl%2Fosgi%2FNetconfCapabilityMonitoringService.java;h=543f657cb9e9afb523f825cc6b5044a2eb177558;hb=bd5fe730fdef0d990163e60fdbbc957df34bdba9;hp=afc1da6ea21a1d00b8459760b0a96f94bfc8b9e6;hpb=3d564a1d55182060945f473bcfff0174cfeca4ee;p=netconf.git diff --git a/netconf/netconf-impl/src/main/java/org/opendaylight/netconf/impl/osgi/NetconfCapabilityMonitoringService.java b/netconf/netconf-impl/src/main/java/org/opendaylight/netconf/impl/osgi/NetconfCapabilityMonitoringService.java index afc1da6ea2..543f657cb9 100644 --- a/netconf/netconf-impl/src/main/java/org/opendaylight/netconf/impl/osgi/NetconfCapabilityMonitoringService.java +++ b/netconf/netconf-impl/src/main/java/org/opendaylight/netconf/impl/osgi/NetconfCapabilityMonitoringService.java @@ -7,31 +7,31 @@ */ package org.opendaylight.netconf.impl.osgi; +import static com.google.common.base.Preconditions.checkState; +import static org.opendaylight.netconf.api.xml.XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_CAPABILITY_CANDIDATE_1_0; +import static org.opendaylight.netconf.api.xml.XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_CAPABILITY_URL_1_0; + import com.google.common.base.Function; -import com.google.common.base.Optional; -import com.google.common.base.Preconditions; import com.google.common.collect.Collections2; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList.Builder; import com.google.common.collect.Lists; import com.google.common.collect.Maps; -import com.google.common.collect.Sets; -import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; -import org.opendaylight.controller.config.util.capability.BasicCapability; -import org.opendaylight.controller.config.util.capability.Capability; +import org.opendaylight.netconf.api.capability.BasicCapability; +import org.opendaylight.netconf.api.capability.Capability; import org.opendaylight.netconf.api.monitoring.CapabilityListener; -import org.opendaylight.netconf.api.monitoring.NetconfManagementSession; import org.opendaylight.netconf.api.monitoring.NetconfMonitoringService; import org.opendaylight.netconf.mapping.api.NetconfOperationServiceFactory; import org.opendaylight.netconf.notifications.BaseNotificationPublisherRegistration; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.Yang; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.Capabilities; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.CapabilitiesBuilder; @@ -44,26 +44,24 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.not import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfCapabilityChangeBuilder; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.changed.by.parms.ChangedByBuilder; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.changed.by.parms.changed.by.server.or.user.ServerBuilder; +import org.opendaylight.yangtools.yang.common.Empty; class NetconfCapabilityMonitoringService implements CapabilityListener, AutoCloseable { private static final Schema.Location NETCONF_LOCATION = new Schema.Location(Schema.Location.Enumeration.NETCONF); private static final List NETCONF_LOCATIONS = ImmutableList.of(NETCONF_LOCATION); - private static final BasicCapability CANDIDATE_CAPABILITY = new BasicCapability("urn:ietf:params:netconf:capability:candidate:1.0"); - private static final Function CAPABILITY_TO_URI = new Function() { - @Override - public Uri apply(final Capability input) { - return new Uri(input.getCapabilityUri()); - } - }; + private static final BasicCapability CANDIDATE_CAPABILITY = + new BasicCapability(URN_IETF_PARAMS_NETCONF_CAPABILITY_CANDIDATE_1_0); + private static final BasicCapability URL_CAPABILITY = + new BasicCapability(URN_IETF_PARAMS_NETCONF_CAPABILITY_URL_1_0); + private static final Function CAPABILITY_TO_URI = input -> new Uri(input.getCapabilityUri()); - private final Set sessions = new HashSet<>(); private final NetconfOperationServiceFactory netconfOperationProvider; private final Map capabilities = new HashMap<>(); - private final Map> mappedModulesToRevisionToSchema = Maps.newHashMap(); + private final Map> mappedModulesToRevisionToSchema = new HashMap<>(); - private final Set listeners = Sets.newHashSet(); + private final Set listeners = new HashSet<>(); private volatile BaseNotificationPublisherRegistration notificationPublisher; NetconfCapabilityMonitoringService(final NetconfOperationServiceFactory netconfOperationProvider) { @@ -71,6 +69,7 @@ class NetconfCapabilityMonitoringService implements CapabilityListener, AutoClos netconfOperationProvider.registerCapabilityListener(this); } + @SuppressWarnings("checkstyle:IllegalCatch") synchronized Schemas getSchemas() { try { return transformSchemas(netconfOperationProvider.getCapabilities()); @@ -82,65 +81,54 @@ class NetconfCapabilityMonitoringService implements CapabilityListener, AutoClos } synchronized String getSchemaForModuleRevision(final String moduleName, final Optional revision) { - - Map revisionMapRequest = mappedModulesToRevisionToSchema.get(moduleName); - Preconditions.checkState(revisionMapRequest != null, "Capability for module %s not present, " + "" - + "available modules : %s", moduleName, Collections2.transform(capabilities.values(), CAPABILITY_TO_URI)); - - if (revision.isPresent()) { - String schema = revisionMapRequest.get(revision.get()); - - Preconditions.checkState(schema != null, - "Capability for module %s:%s not present, available revisions for module: %s", moduleName, - revision.get(), revisionMapRequest.keySet()); - + final Map revisionMapRequest = mappedModulesToRevisionToSchema.get(moduleName); + checkState(revisionMapRequest != null, + "Capability for module %s not present, available modules : %s", + moduleName, Collections2.transform(capabilities.values(), CAPABILITY_TO_URI)); + + final String revToLookup = revision.orElse(""); + final String schema = revisionMapRequest.get(revToLookup); + if (schema != null) { + // Exact match found return schema; - } else { - Preconditions.checkState(revisionMapRequest.size() == 1, - "Expected 1 capability for module %s, available revisions : %s", moduleName, - revisionMapRequest.keySet()); - //Only one revision is present, so return it - return revisionMapRequest.values().iterator().next(); } + + // We can recover only if the revision was not specified + checkState(revision.isEmpty(), + "Capability for module %s:%s not present, available revisions for module: %s", moduleName, + revToLookup, revisionMapRequest.keySet()); + + checkState(revisionMapRequest.size() == 1, + "Expected 1 capability for module %s, available revisions : %s", moduleName, + revisionMapRequest.keySet()); + // Only one revision is present, so return it + return revisionMapRequest.values().iterator().next(); } private void updateCapabilityToSchemaMap(final Set added, final Set removed) { for (final Capability cap : added) { - if (!isValidModuleCapability(cap)){ - continue; + if (isValidModuleCapability(cap)) { + mappedModulesToRevisionToSchema.computeIfAbsent(cap.getModuleName().get(), k -> new HashMap<>()) + .put(cap.getRevision().orElse(""), cap.getCapabilitySchema().get()); } - - final String currentModuleName = cap.getModuleName().get(); - Map revisionMap = mappedModulesToRevisionToSchema.get(currentModuleName); - if (revisionMap == null) { - revisionMap = Maps.newHashMap(); - mappedModulesToRevisionToSchema.put(currentModuleName, revisionMap); - } - - final String currentRevision = cap.getRevision().get(); - revisionMap.put(currentRevision, cap.getCapabilitySchema().get()); } for (final Capability cap : removed) { - if (!isValidModuleCapability(cap)){ - continue; - } - final Map revisionMap = mappedModulesToRevisionToSchema.get(cap.getModuleName().get()); - if (revisionMap != null) { - revisionMap.remove(cap.getRevision().get()); - if (revisionMap.isEmpty()) { - mappedModulesToRevisionToSchema.remove(cap.getModuleName().get()); + if (isValidModuleCapability(cap)) { + final Map revisionMap = mappedModulesToRevisionToSchema.get(cap.getModuleName().get()); + if (revisionMap != null) { + revisionMap.remove(cap.getRevision().get()); + if (revisionMap.isEmpty()) { + mappedModulesToRevisionToSchema.remove(cap.getModuleName().get()); + } } } } } - private static boolean isValidModuleCapability(Capability cap) { - return cap.getModuleName().isPresent() - && cap.getRevision().isPresent() - && cap.getCapabilitySchema().isPresent(); + private static boolean isValidModuleCapability(final Capability cap) { + return cap.getModuleName().isPresent() && cap.getCapabilitySchema().isPresent(); } - synchronized Capabilities getCapabilities() { return new CapabilitiesBuilder().setCapability(Lists.newArrayList(capabilities.keySet())).build(); } @@ -149,39 +137,24 @@ class NetconfCapabilityMonitoringService implements CapabilityListener, AutoClos listeners.add(listener); listener.onCapabilitiesChanged(getCapabilities()); listener.onSchemasChanged(getSchemas()); - return new AutoCloseable() { - @Override - public void close() throws Exception { - synchronized (NetconfCapabilityMonitoringService.this) { - listeners.remove(listener); - } + return () -> { + synchronized (NetconfCapabilityMonitoringService.this) { + listeners.remove(listener); } }; } private static Schemas transformSchemas(final Set caps) { - final List schemas = new ArrayList<>(caps.size()); + final Map schemas = Maps.newHashMapWithExpectedSize(caps.size()); for (final Capability cap : caps) { - if (cap.getCapabilitySchema().isPresent()) { - final SchemaBuilder builder = new SchemaBuilder(); - - Preconditions.checkState(isValidModuleCapability(cap)); - - builder.setNamespace(new Uri(cap.getModuleNamespace().get())); - - final String version = cap.getRevision().get(); - builder.setVersion(version); - - final String identifier = cap.getModuleName().get(); - builder.setIdentifier(identifier); - - builder.setFormat(Yang.class); - - builder.setLocation(transformLocations(cap.getLocation())); - - builder.setKey(new SchemaKey(Yang.class, identifier, version)); - - schemas.add(builder.build()); + if (isValidModuleCapability(cap)) { + final SchemaKey key = new SchemaKey(Yang.class, cap.getModuleName().get(), + cap.getRevision().orElse("")); + schemas.put(key, new SchemaBuilder() + .withKey(key) + .setNamespace(new Uri(cap.getModuleNamespace().get())) + .setLocation(transformLocations(cap.getLocation())) + .build()); } } @@ -206,6 +179,7 @@ class NetconfCapabilityMonitoringService implements CapabilityListener, AutoClos private static Set setupCapabilities(final Set caps) { Set capabilities = new HashSet<>(caps); capabilities.add(CANDIDATE_CAPABILITY); + capabilities.add(URL_CAPABILITY); // TODO rollback on error not supported EditConfigXmlParser:100 // [RFC6241] 8.5. Rollback-on-Error Capability // capabilities.add(new BasicCapability("urn:ietf:params:netconf:capability:rollback-on-error:1.0")); @@ -213,14 +187,13 @@ class NetconfCapabilityMonitoringService implements CapabilityListener, AutoClos } @Override - public synchronized void close() throws Exception { + public synchronized void close() { listeners.clear(); - sessions.clear(); capabilities.clear(); } @Override - public synchronized void onCapabilitiesChanged(Set added, Set removed) { + public synchronized void onCapabilitiesChanged(final Set added, final Set removed) { onCapabilitiesAdded(added); onCapabilitiesRemoved(removed); updateCapabilityToSchemaMap(added, removed); @@ -232,9 +205,9 @@ class NetconfCapabilityMonitoringService implements CapabilityListener, AutoClos } } - private void notifyCapabilityChanged(Capabilities capabilities) { + private void notifyCapabilityChanged(final Capabilities newCapabilities) { for (NetconfMonitoringService.CapabilitiesListener listener : listeners) { - listener.onCapabilitiesChanged(capabilities); + listener.onCapabilitiesChanged(newCapabilities); listener.onSchemasChanged(getSchemas()); } } @@ -242,11 +215,15 @@ class NetconfCapabilityMonitoringService implements CapabilityListener, AutoClos private static NetconfCapabilityChange computeDiff(final Set added, final Set removed) { final NetconfCapabilityChangeBuilder netconfCapabilityChangeBuilder = new NetconfCapabilityChangeBuilder(); - netconfCapabilityChangeBuilder.setChangedBy(new ChangedByBuilder().setServerOrUser(new ServerBuilder().setServer(true).build()).build()); - netconfCapabilityChangeBuilder.setDeletedCapability(Lists.newArrayList(Collections2.transform(removed, CAPABILITY_TO_URI))); - netconfCapabilityChangeBuilder.setAddedCapability(Lists.newArrayList(Collections2.transform(added, CAPABILITY_TO_URI))); + netconfCapabilityChangeBuilder + .setChangedBy(new ChangedByBuilder().setServerOrUser( + new ServerBuilder().setServer(Empty.value()).build()).build()); + netconfCapabilityChangeBuilder.setDeletedCapability(Lists.newArrayList(Collections2 + .transform(removed, CAPABILITY_TO_URI))); + netconfCapabilityChangeBuilder.setAddedCapability(Lists.newArrayList(Collections2 + .transform(added, CAPABILITY_TO_URI))); // TODO modified should be computed ... but why ? - netconfCapabilityChangeBuilder.setModifiedCapability(Collections.emptyList()); + netconfCapabilityChangeBuilder.setModifiedCapability(Collections.emptyList()); return netconfCapabilityChangeBuilder.build(); } @@ -257,7 +234,7 @@ class NetconfCapabilityMonitoringService implements CapabilityListener, AutoClos private void onCapabilitiesRemoved(final Set removedCaps) { for (final Capability addedCap : removedCaps) { - capabilities.remove(CAPABILITY_TO_URI.apply(addedCap)); + capabilities.remove(new Uri(addedCap.getCapabilityUri())); } }