From: Ed Warnicke Date: Thu, 30 Jan 2014 11:02:43 +0000 (+0000) Subject: Merge "Add javadoc generation for yang modules in netconf subsystem" X-Git-Tag: autorelease-tag-v20140601202136_82eb3f9~551 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=0c327766c89e6e31c2c6e7581ac79722d01e3bf6;hp=35953712dfdb524d8a320a1d61e904732538cac7;p=controller.git Merge "Add javadoc generation for yang modules in netconf subsystem" --- diff --git a/opendaylight/md-sal/pom.xml b/opendaylight/md-sal/pom.xml index fa6f94bfed..521ec23859 100644 --- a/opendaylight/md-sal/pom.xml +++ b/opendaylight/md-sal/pom.xml @@ -464,23 +464,6 @@ maven-jar-plugin 2.4 - - org.apache.maven.plugins - maven-javadoc-plugin - 2.8.1 - - maven - false - - - - - aggregate - - site - - - org.apache.maven.plugins diff --git a/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/NotificationProviderService.java b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/NotificationProviderService.java index cb201c5fd1..c28b03eb65 100644 --- a/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/NotificationProviderService.java +++ b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/NotificationProviderService.java @@ -7,14 +7,17 @@ */ package org.opendaylight.controller.sal.binding.api; +import java.util.EventListener; import java.util.concurrent.ExecutorService; import org.opendaylight.controller.md.sal.common.api.notify.NotificationPublishService; +import org.opendaylight.yangtools.concepts.ListenerRegistration; import org.opendaylight.yangtools.concepts.Registration; import org.opendaylight.yangtools.yang.binding.Notification; public interface NotificationProviderService extends NotificationService, NotificationPublishService { + /** * Deprecated. Use {@link #publish(Notification)}. * @@ -34,7 +37,8 @@ public interface NotificationProviderService extends NotificationService, Notifi /** * Publishes a notification. * - * @param Notification notification to publish. + * @param Notification + * notification to publish. * */ @Override @@ -46,4 +50,12 @@ public interface NotificationProviderService extends NotificationService, Notifi */ @Override void publish(Notification notification, ExecutorService service); + + ListenerRegistration registerInterestListener( + NotificationInterestListener interestListener); + + public interface NotificationInterestListener extends EventListener { + + void onNotificationSubscribtion(Class notificationType); + } } diff --git a/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/data/SynchronizedTransaction.java b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/data/SynchronizedTransaction.java new file mode 100644 index 0000000000..d7cb926775 --- /dev/null +++ b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/data/SynchronizedTransaction.java @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.sal.binding.api.data; + +import java.util.Map; +import java.util.Set; +import java.util.concurrent.Future; + +import org.opendaylight.controller.md.sal.common.api.TransactionStatus; +import org.opendaylight.yangtools.concepts.Delegator; +import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.common.RpcResult; + +import com.google.common.base.Preconditions; + +/** + * Synchronized wrapper for DataModificationTransaction. + * + * To get instance of synchronized wrapper use {@link #from(DataModificationTransaction)} + * + */ +public final class SynchronizedTransaction implements DataModificationTransaction,Delegator { + + private final DataModificationTransaction delegate; + + private SynchronizedTransaction(DataModificationTransaction delegate) { + this.delegate = delegate; + } + + /** + * Returns synchronized wrapper on supplied transaction. + * + * @param transaction Transaction for which synchronized wrapper should be created. + * @return Synchronized wrapper over transaction. + */ + public static final SynchronizedTransaction from(DataModificationTransaction transaction) { + Preconditions.checkArgument(transaction != null, "Transaction must not be null."); + if (transaction instanceof SynchronizedTransaction) { + return (SynchronizedTransaction) transaction; + } + return new SynchronizedTransaction(transaction); + } + + @Override + public synchronized Map, DataObject> getCreatedOperationalData() { + return delegate.getCreatedOperationalData(); + } + + @Override + public synchronized Map, DataObject> getCreatedConfigurationData() { + return delegate.getCreatedConfigurationData(); + } + + @Override + public synchronized DataObject readOperationalData(InstanceIdentifier path) { + return delegate.readOperationalData(path); + } + + @Override + public synchronized TransactionStatus getStatus() { + return delegate.getStatus(); + } + + @Override + public synchronized Map, DataObject> getUpdatedOperationalData() { + return delegate.getUpdatedOperationalData(); + } + + @Deprecated + public synchronized void putRuntimeData(InstanceIdentifier path, DataObject data) { + delegate.putRuntimeData(path, data); + } + + @Override + public synchronized Object getIdentifier() { + return delegate.getIdentifier(); + } + + @Override + public synchronized DataObject readConfigurationData(InstanceIdentifier path) { + return delegate.readConfigurationData(path); + } + + @Override + public synchronized Future> commit() { + return delegate.commit(); + } + + @Override + public synchronized void putOperationalData(InstanceIdentifier path, DataObject data) { + delegate.putOperationalData(path, data); + } + + @Override + public synchronized void putConfigurationData(InstanceIdentifier path, DataObject data) { + delegate.putConfigurationData(path, data); + } + + @Override + public synchronized Map, DataObject> getUpdatedConfigurationData() { + return delegate.getUpdatedConfigurationData(); + } + + @Deprecated + public synchronized void removeRuntimeData(InstanceIdentifier path) { + delegate.removeRuntimeData(path); + } + + @Override + public synchronized void removeOperationalData(InstanceIdentifier path) { + delegate.removeOperationalData(path); + } + + @Override + public synchronized void removeConfigurationData(InstanceIdentifier path) { + delegate.removeConfigurationData(path); + } + + @Override + public synchronized Set> getRemovedConfigurationData() { + return delegate.getRemovedConfigurationData(); + } + + @Override + public synchronized Set> getRemovedOperationalData() { + return delegate.getRemovedOperationalData(); + } + + @Override + public synchronized Map, DataObject> getOriginalConfigurationData() { + return delegate.getOriginalConfigurationData(); + } + + @Override + public synchronized ListenerRegistration registerListener(DataTransactionListener listener) { + return delegate.registerListener(listener); + } + + @Override + public synchronized Map, DataObject> getOriginalOperationalData() { + return delegate.getOriginalOperationalData(); + } + + @Override + public synchronized DataModificationTransaction getDelegate() { + return delegate; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((delegate == null) ? 0 : delegate.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()){ + return false; + } + SynchronizedTransaction other = (SynchronizedTransaction) obj; + if (delegate == null) { + if (other.delegate != null) { + return false; + } + } else if (!delegate.equals(other.delegate)) { + return false; + } + return true; + } +} + diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationBrokerImpl.xtend b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationBrokerImpl.xtend index 52aa8d0290..d997af5912 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationBrokerImpl.xtend +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationBrokerImpl.xtend @@ -21,14 +21,20 @@ import org.opendaylight.yangtools.concepts.ListenerRegistration import org.opendaylight.yangtools.concepts.Registration import org.opendaylight.yangtools.yang.binding.Notification import org.slf4j.LoggerFactory -import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder import com.google.common.collect.Multimaps - -class NotificationBrokerImpl implements NotificationProviderService, AutoCloseable { +import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder import com.google.common.collect.Multimaps +import org.opendaylight.yangtools.concepts.util.ListenerRegistry +import org.opendaylight.controller.sal.binding.api.NotificationProviderService.NotificationInterestListener +class NotificationBrokerImpl implements NotificationProviderService, AutoCloseable { + + val ListenerRegistry interestListeners = ListenerRegistry.create; + val Multimap, NotificationListener> listeners; @Property var ExecutorService executor; + + val logger = LoggerFactory.getLogger(NotificationBrokerImpl) new() { listeners = Multimaps.synchronizedSetMultimap(HashMultimap.create()) @@ -101,14 +107,26 @@ class NotificationBrokerImpl implements NotificationProviderService, AutoCloseab NotificationListener listener) { val reg = new GenericNotificationRegistration(notificationType, listener, this); listeners.put(notificationType, listener); + announceNotificationSubscription(notificationType); return reg; } + + def announceNotificationSubscription(Class notification) { + for (listener : interestListeners) { + try { + listener.instance.onNotificationSubscribtion(notification); + } catch (Exception e) { + logger.error("", e.message) + } + } + } override registerNotificationListener( org.opendaylight.yangtools.yang.binding.NotificationListener listener) { val invoker = SingletonHolder.INVOKER_FACTORY.invokerFor(listener); for (notifyType : invoker.supportedNotifications) { listeners.put(notifyType, invoker.invocationProxy) + announceNotificationSubscription(notifyType) } val registration = new GeneratedListenerRegistration(listener, invoker,this); return registration as Registration; @@ -128,6 +146,14 @@ class NotificationBrokerImpl implements NotificationProviderService, AutoCloseab //FIXME: implement properly. } + override registerInterestListener(NotificationInterestListener interestListener) { + val registration = interestListeners.register(interestListener); + + for(notification : listeners.keySet) { + interestListener.onNotificationSubscribtion(notification); + } + return registration + } } class GenericNotificationRegistration extends AbstractObjectRegistration> implements ListenerRegistration> { diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingDomConnectorDeployer.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingDomConnectorDeployer.java index a21b3f1a61..978c79ea02 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingDomConnectorDeployer.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingDomConnectorDeployer.java @@ -80,12 +80,14 @@ public class BindingDomConnectorDeployer { connector.startDataForwarding(); } - public static void startNotificationForwarding(BindingIndependentConnector connector, NotificationProviderService baService, NotificationPublishService domService) { + public static void startNotificationForwarding(BindingIndependentConnector connector, + NotificationProviderService baService, NotificationPublishService domService) { if(connector.isNotificationForwarding()) { return; } - - // FIXME + connector.setBindingNotificationService(baService); + connector.setDomNotificationService(domService); + connector.startNotificationForwarding(); } // diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentConnector.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentConnector.java index aaed12f740..5630664a67 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentConnector.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentConnector.java @@ -17,6 +17,7 @@ import java.lang.reflect.Proxy; import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; import java.util.Map.Entry; import java.util.Set; @@ -37,6 +38,8 @@ import org.opendaylight.controller.md.sal.common.api.data.DataReader; import org.opendaylight.controller.md.sal.common.api.routing.RouteChange; import org.opendaylight.controller.md.sal.common.api.routing.RouteChangeListener; import org.opendaylight.controller.md.sal.common.api.routing.RouteChangePublisher; +import org.opendaylight.controller.sal.binding.api.NotificationProviderService; +import org.opendaylight.controller.sal.binding.api.NotificationProviderService.NotificationInterestListener; import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry; import org.opendaylight.controller.sal.binding.api.data.DataProviderService; import org.opendaylight.controller.sal.binding.api.data.RuntimeDataProvider; @@ -55,6 +58,8 @@ import org.opendaylight.controller.sal.core.api.Provider; import org.opendaylight.controller.sal.core.api.RpcImplementation; import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry; import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction; +import org.opendaylight.controller.sal.core.api.notify.NotificationListener; +import org.opendaylight.controller.sal.core.api.notify.NotificationPublishService; import org.opendaylight.yangtools.concepts.ListenerRegistration; import org.opendaylight.yangtools.concepts.Registration; import org.opendaylight.yangtools.concepts.util.ClassLoaderUtils; @@ -65,6 +70,7 @@ import org.opendaylight.yangtools.yang.binding.BindingMapping; import org.opendaylight.yangtools.yang.binding.DataContainer; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.binding.Notification; import org.opendaylight.yangtools.yang.binding.RpcService; import org.opendaylight.yangtools.yang.binding.util.BindingReflections; import org.opendaylight.yangtools.yang.common.QName; @@ -93,7 +99,7 @@ public class BindingIndependentConnector implements // private final Logger LOG = LoggerFactory.getLogger(BindingIndependentConnector.class); - @SuppressWarnings( "deprecation") + @SuppressWarnings("deprecation") private static final InstanceIdentifier ROOT = InstanceIdentifier.builder().toInstance(); private static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier ROOT_BI = org.opendaylight.yangtools.yang.data.api.InstanceIdentifier @@ -101,7 +107,6 @@ public class BindingIndependentConnector implements // private final static Method EQUALS_METHOD; - private BindingIndependentMappingService mappingService; private org.opendaylight.controller.sal.core.api.data.DataProviderService biDataService; @@ -146,10 +151,13 @@ public class BindingIndependentConnector implements // private org.opendaylight.controller.sal.dom.broker.spi.RpcRouter biRouter; + private NotificationProviderService baNotifyService; + + private NotificationPublishService domNotificationService; static { try { - EQUALS_METHOD = Object.class.getMethod("equals", Object.class); + EQUALS_METHOD = Object.class.getMethod("equals", Object.class); } catch (Exception e) { throw new RuntimeException(e); } @@ -311,7 +319,7 @@ public class BindingIndependentConnector implements // baRpcRegistryImpl.registerRouterInstantiationListener(domToBindingRpcManager.getInstance()); baRpcRegistryImpl.registerGlobalRpcRegistrationListener(domToBindingRpcManager.getInstance()); } - if(biRpcRegistry instanceof org.opendaylight.controller.sal.dom.broker.spi.RpcRouter) { + if (biRpcRegistry instanceof org.opendaylight.controller.sal.dom.broker.spi.RpcRouter) { biRouter = (org.opendaylight.controller.sal.dom.broker.spi.RpcRouter) biRpcRegistry; } rpcForwarding = true; @@ -320,7 +328,11 @@ public class BindingIndependentConnector implements // public void startNotificationForwarding() { checkState(!notificationForwarding, "Connector is already forwarding notifications."); - notificationForwarding = true; + if (baNotifyService != null && domNotificationService != null) { + baNotifyService.registerInterestListener(new DomToBindingNotificationForwarder()); + + notificationForwarding = true; + } } protected void setMappingService(BindingIndependentMappingService mappingService) { @@ -616,7 +628,7 @@ public class BindingIndependentConnector implements // } createDefaultDomForwarder(); } catch (Exception e) { - LOG.error("Could not forward Rpcs of type {}", service.getName(),e); + LOG.error("Could not forward Rpcs of type {}", service.getName(), e); } registrations = registrationsBuilder.build(); } @@ -635,13 +647,13 @@ public class BindingIndependentConnector implements // @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - if(EQUALS_METHOD.equals(method)) { + if (EQUALS_METHOD.equals(method)) { return false; } RpcInvocationStrategy strategy = strategiesByMethod.get(method); checkState(strategy != null); checkArgument(args.length <= 2); - if(args.length == 1) { + if (args.length == 1) { checkArgument(args[0] instanceof DataObject); return strategy.forwardToDomBroker((DataObject) args[0]); } @@ -719,9 +731,10 @@ public class BindingIndependentConnector implements // RpcInvocationStrategy strategy = null; if (outputClass.isPresent()) { if (inputClass.isPresent()) { - strategy = new DefaultInvocationStrategy(rpc,targetMethod, outputClass.get(), inputClass.get()); + strategy = new DefaultInvocationStrategy(rpc, targetMethod, outputClass.get(), inputClass + .get()); } else { - strategy = new NoInputNoOutputInvocationStrategy(rpc,targetMethod); + strategy = new NoInputNoOutputInvocationStrategy(rpc, targetMethod); } } else if(inputClass.isPresent()){ strategy = new NoOutputInvocationStrategy(rpc,targetMethod, inputClass.get()); @@ -740,7 +753,7 @@ public class BindingIndependentConnector implements // protected final Method targetMethod; protected final QName rpc; - public RpcInvocationStrategy(QName rpc,Method targetMethod) { + public RpcInvocationStrategy(QName rpc, Method targetMethod) { this.targetMethod = targetMethod; this.rpc = rpc; } @@ -766,19 +779,25 @@ public class BindingIndependentConnector implements // @SuppressWarnings({ "rawtypes", "unchecked" }) public DefaultInvocationStrategy(QName rpc, Method targetMethod, Class outputClass, Class inputClass) { - super(rpc,targetMethod); + super(rpc, targetMethod); this.outputClass = new WeakReference(outputClass); this.inputClass = new WeakReference(inputClass); } + @SuppressWarnings("unchecked") @Override public RpcResult uncheckedInvoke(RpcService rpcService, CompositeNode domInput) throws Exception { DataContainer bindingInput = mappingService.dataObjectFromDataDom(inputClass.get(), domInput); - Future> result = (Future>) targetMethod.invoke(rpcService, bindingInput); - if (result == null) { + Future> futureResult = (Future>) targetMethod.invoke(rpcService, bindingInput); + if (futureResult == null) { return Rpcs.getRpcResult(false); } - RpcResult bindingResult = result.get(); + RpcResult bindingResult = futureResult.get(); + final Object resultObj = bindingResult.getResult(); + if (resultObj instanceof DataObject) { + final CompositeNode output = mappingService.toDataDom((DataObject)resultObj); + return Rpcs.getRpcResult(true, output, Collections.emptySet()); + } return Rpcs.getRpcResult(true); } @@ -786,16 +805,16 @@ public class BindingIndependentConnector implements // public Future> forwardToDomBroker(DataObject input) { if(biRouter != null) { CompositeNode xml = mappingService.toDataDom(input); - CompositeNode wrappedXml = ImmutableCompositeNode.create(rpc,ImmutableList.>of(xml)); + CompositeNode wrappedXml = ImmutableCompositeNode.create(rpc, ImmutableList.> of(xml)); RpcResult result = biRouter.invokeRpc(rpc, wrappedXml); Object baResultValue = null; - if(result.getResult() != null) { + if (result.getResult() != null) { baResultValue = mappingService.dataObjectFromDataDom(outputClass.get(), result.getResult()); } RpcResult baResult = Rpcs.getRpcResult(result.isSuccessful(), baResultValue, result.getErrors()); - return Futures.>immediateFuture(baResult); + return Futures.> immediateFuture(baResult); } - return Futures.>immediateFuture(Rpcs.getRpcResult(false)); + return Futures.> immediateFuture(Rpcs.getRpcResult(false)); } } @@ -803,7 +822,7 @@ public class BindingIndependentConnector implements // private class NoInputNoOutputInvocationStrategy extends RpcInvocationStrategy { public NoInputNoOutputInvocationStrategy(QName rpc, Method targetMethod) { - super(rpc,targetMethod); + super(rpc, targetMethod); } public RpcResult uncheckedInvoke(RpcService rpcService, CompositeNode domInput) throws Exception { @@ -874,4 +893,54 @@ public class BindingIndependentConnector implements // public BindingIndependentMappingService getMappingService() { return mappingService; } + + public void setBindingNotificationService(NotificationProviderService baService) { + this.baNotifyService = baService; + + } + + public void setDomNotificationService(NotificationPublishService domService) { + this.domNotificationService = domService; + } + + private class DomToBindingNotificationForwarder implements NotificationInterestListener, NotificationListener { + + private ConcurrentMap>> notifications = new ConcurrentHashMap<>(); + private Set supportedNotifications = new HashSet<>(); + + @Override + public Set getSupportedNotifications() { + return Collections.unmodifiableSet(supportedNotifications); + } + + @Override + public void onNotification(CompositeNode notification) { + QName qname = notification.getNodeType(); + WeakReference> potential = notifications.get(qname); + if (potential != null) { + Class potentialClass = potential.get(); + if (potentialClass != null) { + final DataContainer baNotification = mappingService.dataObjectFromDataDom(potentialClass, + notification); + + if (baNotification instanceof Notification) { + baNotifyService.publish((Notification) baNotification); + } + } + } + } + + @Override + public void onNotificationSubscribtion(Class notificationType) { + QName qname = BindingReflections.findQName(notificationType); + if (qname != null) { + WeakReference> already = notifications.putIfAbsent(qname, + new WeakReference>(notificationType)); + if (already == null) { + domNotificationService.addNotificationListener(qname, this); + supportedNotifications.add(qname); + } + } + } + } } diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentMountPointForwarder.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentMountPointForwarder.java deleted file mode 100644 index 7b94845e8c..0000000000 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentMountPointForwarder.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.sal.binding.impl.connect.dom; - -import java.util.concurrent.ConcurrentMap; - -import org.opendaylight.controller.sal.binding.api.mount.MountProviderInstance; -import org.opendaylight.controller.sal.binding.api.mount.MountProviderService; -import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService; -import org.opendaylight.yangtools.yang.data.impl.codec.DeserializationException; -import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance; -import org.opendaylight.controller.sal.core.api.mount.MountProvisionService; -import org.opendaylight.controller.sal.core.api.mount.MountProvisionService.MountProvisionListener; -import org.opendaylight.yangtools.concepts.ListenerRegistration; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public class BindingIndependentMountPointForwarder { - - private MountProvisionService domMountService; - private MountProviderService baMountService; - private BindingIndependentMappingService mappingService; - - private final DomMountPointForwardingManager domForwardingManager = new DomMountPointForwardingManager(); - private final BindingMountPointForwardingManager bindingForwardingManager = new BindingMountPointForwardingManager(); - - private ConcurrentMap, BindingIndependentConnector> connectors; - private ConcurrentMap, org.opendaylight.yangtools.yang.data.api.InstanceIdentifier> forwarded; - private ListenerRegistration domListenerRegistration; - private ListenerRegistration baListenerRegistration; - - public MountProvisionService getDomMountService() { - return domMountService; - } - - public void setDomMountService(MountProvisionService domMountService) { - this.domMountService = domMountService; - } - - public void start() { - if(domMountService != null && baMountService != null) { - domListenerRegistration = domMountService.registerProvisionListener(domForwardingManager); - baListenerRegistration = baMountService.registerProvisionListener(bindingForwardingManager); - } - } - - private void tryToDeployConnector(InstanceIdentifier baPath, - org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath) { - org.opendaylight.yangtools.yang.data.api.InstanceIdentifier previous = forwarded.putIfAbsent(baPath, biPath); - if(previous != null) { - return; - } - MountProviderInstance baMountPoint = baMountService.getMountPoint(baPath); - MountProvisionInstance domMountPoint = domMountService.getMountPoint(biPath); - BindingIndependentConnector connector = createForwarder(baPath, baMountPoint, domMountPoint); - connectors.put(baPath, connector); - connector.startDataForwarding(); - connector.startRpcForwarding(); - connector.startNotificationForwarding(); - } - - private BindingIndependentConnector createForwarder(InstanceIdentifier path, MountProviderInstance baMountPoint, - MountProvisionInstance domMountPoint) { - BindingIndependentConnector connector = new BindingIndependentConnector(); - - connector.setBindingDataService(baMountPoint); - connector.setBindingRpcRegistry(baMountPoint); - //connector.setBindingNotificationBroker(baMountPoint); - - connector.setDomDataService(domMountPoint); - connector.setDomRpcRegistry(domMountPoint); - //connector.setDomNotificationBroker(domMountPoint); - return connector; - } - - public synchronized void tryToDeployDomForwarder(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier domPath) { - InstanceIdentifier baPath; - try { - baPath = mappingService.fromDataDom(domPath); - BindingIndependentConnector potentialConnector = connectors.get(baPath); - if(potentialConnector != null) { - return; - } - tryToDeployConnector(baPath,domPath); - } catch (DeserializationException e) { - - } - } - - public synchronized void tryToDeployBindingForwarder(InstanceIdentifier baPath) { - BindingIndependentConnector potentialConnector =connectors.get(baPath); - if(potentialConnector != null) { - return; - } - org.opendaylight.yangtools.yang.data.api.InstanceIdentifier domPath = mappingService.toDataDom(baPath); - tryToDeployConnector(baPath, domPath); - } - - public synchronized void undeployBindingForwarder(InstanceIdentifier baPath) { - // FIXME: Implement closeMountPoint - } - - public synchronized void undeployDomForwarder(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath) { - // FIXME: Implement closeMountPoint - } - - private class DomMountPointForwardingManager implements MountProvisionListener { - - @Override - public void onMountPointCreated(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier path) { - tryToDeployDomForwarder(path); - } - - @Override - public void onMountPointRemoved(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier path) { - undeployDomForwarder(path); - } - } - - private class BindingMountPointForwardingManager implements - org.opendaylight.controller.sal.binding.api.mount.MountProviderService.MountProvisionListener { - - @Override - public void onMountPointCreated(InstanceIdentifier path) { - tryToDeployBindingForwarder(path); - } - - @Override - public void onMountPointRemoved(InstanceIdentifier path) { - undeployBindingForwarder(path); - } - } -} diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/forward/DomForwardedBindingBrokerImpl.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/forward/DomForwardedBindingBrokerImpl.java index c90f6fdb47..8c74008990 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/forward/DomForwardedBindingBrokerImpl.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/forward/DomForwardedBindingBrokerImpl.java @@ -108,7 +108,7 @@ public class DomForwardedBindingBrokerImpl extends RootBindingAwareBroker implem BindingDomConnectorDeployer.startRpcForwarding(mountConnector, baMountPoint, domMountPoint); BindingDomConnectorDeployer.startNotificationForwarding(mountConnector, baMountPoint, domMountPoint); // connector.setDomNotificationBroker(domMountPoint); - return connector; + return mountConnector; } public synchronized void tryToDeployDomForwarder(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier domPath) { diff --git a/opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/AbstractBindingSalProviderInstance.java b/opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/AbstractBindingSalProviderInstance.java index 2a8ebe869c..c7d6640ce1 100644 --- a/opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/AbstractBindingSalProviderInstance.java +++ b/opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/AbstractBindingSalProviderInstance.java @@ -99,4 +99,10 @@ public abstract class AbstractBindingSalProviderInstance registerInterestListener( + NotificationInterestListener interestListener) { + return getNotificationBrokerChecked().registerInterestListener(interestListener); + } } diff --git a/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/service/AbstractDataBroker.xtend b/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/service/AbstractDataBroker.xtend index 927975ca53..2c3b0188f4 100644 --- a/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/service/AbstractDataBroker.xtend +++ b/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/service/AbstractDataBroker.xtend @@ -45,6 +45,8 @@ import org.slf4j.LoggerFactory import static com.google.common.base.Preconditions.* import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent import com.google.common.collect.Multimaps +import java.util.concurrent.locks.Lock +import java.util.concurrent.locks.ReentrantLock abstract class AbstractDataBroker

, D, DCL extends DataChangeListener> implements DataModificationTransactionFactory, // DataReader, // @@ -70,16 +72,20 @@ DataProvisionService { Multimap> listeners = Multimaps.synchronizedSetMultimap(HashMultimap.create()); Multimap> commitHandlers = Multimaps.synchronizedSetMultimap(HashMultimap.create()); + + private val Lock registrationLock = new ReentrantLock; val ListenerRegistry>> commitHandlerRegistrationListeners = new ListenerRegistry(); public new() { } protected def /*Iterator>,D>>*/ affectedCommitHandlers( - HashSet

paths) { - return FluentIterable.from(commitHandlers.asMap.entrySet).filter[key.isAffectedBy(paths)] // - .transformAndConcat[value] // - .transform[instance].toList() + HashSet

paths) { + return withLock(registrationLock) [| + return FluentIterable.from(commitHandlers.asMap.entrySet).filter[key.isAffectedBy(paths)] // + .transformAndConcat[value] // + .transform[instance].toList() + ] } override final readConfigurationData(P path) { @@ -88,43 +94,56 @@ DataProvisionService { override final readOperationalData(P path) { return dataReadRouter.readOperationalData(path); - } - - override final registerCommitHandler(P path, DataCommitHandler commitHandler) { - val registration = new DataCommitHandlerRegistrationImpl(path, commitHandler, this); - commitHandlers.put(path, registration) - LOG.trace("Registering Commit Handler {} for path: {}",commitHandler,path); - for(listener : commitHandlerRegistrationListeners) { - try { - listener.instance.onRegister(registration); - } catch (Exception e) { - LOG.error("Unexpected exception in listener {} during invoking onRegister",listener.instance,e); - } - } - return registration; + } + + private static def withLock(Lock lock,Callable method) { + lock.lock + try { + return method.call + } finally { + lock.unlock + } + } + + override final registerCommitHandler(P path, DataCommitHandler commitHandler) { + return withLock(registrationLock) [| + val registration = new DataCommitHandlerRegistrationImpl(path, commitHandler, this); + commitHandlers.put(path, registration) + LOG.trace("Registering Commit Handler {} for path: {}",commitHandler,path); + for(listener : commitHandlerRegistrationListeners) { + try { + listener.instance.onRegister(registration); + } catch (Exception e) { + LOG.error("Unexpected exception in listener {} during invoking onRegister",listener.instance,e); + } + } + return registration; + ] } override final def registerDataChangeListener(P path, DCL listener) { - val reg = new DataChangeListenerRegistration(path, listener, this); - listeners.put(path, reg); - val initialConfig = dataReadRouter.readConfigurationData(path); - val initialOperational = dataReadRouter.readOperationalData(path); - val event = createInitialListenerEvent(path,initialConfig,initialOperational); - listener.onDataChanged(event); - return reg; + return withLock(registrationLock) [| + val reg = new DataChangeListenerRegistration(path, listener, this); + listeners.put(path, reg); + val initialConfig = dataReadRouter.readConfigurationData(path); + val initialOperational = dataReadRouter.readOperationalData(path); + val event = createInitialListenerEvent(path,initialConfig,initialOperational); + listener.onDataChanged(event); + return reg; + ] } final def registerDataReader(P path, DataReader reader) { - - val confReg = dataReadRouter.registerConfigurationReader(path, reader); - val dataReg = dataReadRouter.registerOperationalReader(path, reader); - - return new CompositeObjectRegistration(reader, Arrays.asList(confReg, dataReg)); + return withLock(registrationLock) [| + val confReg = dataReadRouter.registerConfigurationReader(path, reader); + val dataReg = dataReadRouter.registerOperationalReader(path, reader); + + return new CompositeObjectRegistration(reader, Arrays.asList(confReg, dataReg)); + ] } override registerCommitHandlerListener(RegistrationListener> commitHandlerListener) { val ret = commitHandlerRegistrationListeners.register(commitHandlerListener); - return ret; } @@ -133,21 +152,25 @@ DataProvisionService { } - protected final def removeListener(DataChangeListenerRegistration registration) { - listeners.remove(registration.path, registration); + protected final def removeListener(DataChangeListenerRegistration registration) { + return withLock(registrationLock) [| + listeners.remove(registration.path, registration); + ] } protected final def removeCommitHandler(DataCommitHandlerRegistrationImpl registration) { - commitHandlers.remove(registration.path, registration); - - LOG.trace("Removing Commit Handler {} for path: {}",registration.instance,registration.path); - for(listener : commitHandlerRegistrationListeners) { - try { - listener.instance.onUnregister(registration); - } catch (Exception e) { - LOG.error("Unexpected exception in listener {} during invoking onUnregister",listener.instance,e); - } - } + return withLock(registrationLock) [| + commitHandlers.remove(registration.path, registration); + LOG.trace("Removing Commit Handler {} for path: {}",registration.instance,registration.path); + for(listener : commitHandlerRegistrationListeners) { + try { + listener.instance.onUnregister(registration); + } catch (Exception e) { + LOG.error("Unexpected exception in listener {} during invoking onUnregister",listener.instance,e); + } + } + return null; + ] } protected final def getActiveCommitHandlers() { @@ -155,12 +178,14 @@ DataProvisionService { } protected def /*Iterator>,D>>*/ affectedListenersWithInitialState( - HashSet

paths) { - return FluentIterable.from(listeners.asMap.entrySet).filter[key.isAffectedBy(paths)].transform [ - val operationalState = readOperationalData(key) - val configurationState = readConfigurationData(key) - return new ListenerStateCapture(key, value, operationalState, configurationState) - ].toList() + HashSet

paths) { + return withLock(registrationLock) [| + return FluentIterable.from(listeners.asMap.entrySet).filter[key.isAffectedBy(paths)].transform [ + val operationalState = readOperationalData(key) + val configurationState = readConfigurationData(key) + return new ListenerStateCapture(key, value, operationalState, configurationState) + ].toList() + ] } protected def boolean isAffectedBy(P key, Set

paths) { @@ -267,12 +292,13 @@ package class TwoPhaseCommit

, D, DCL extends DataChangeListene affectedPaths.addAll(transaction.createdOperationalData.keySet); affectedPaths.addAll(transaction.updatedOperationalData.keySet); affectedPaths.addAll(transaction.removedOperationalData); - + val listeners = dataBroker.affectedListenersWithInitialState(affectedPaths); val transactionId = transaction.identifier; log.trace("Transaction: {} Started.",transactionId); + log.trace("Transaction: {} Affected Subtrees:",transactionId,affectedPaths); // requesting commits val Iterable> commitHandlers = dataBroker.affectedCommitHandlers(affectedPaths); val List> handlerTransactions = new ArrayList(); @@ -283,6 +309,7 @@ package class TwoPhaseCommit

, D, DCL extends DataChangeListene } catch (Exception e) { log.error("Transaction: {} Request Commit failed", transactionId,e); dataBroker.failedTransactionsCount.andIncrement + transaction.changeStatus(TransactionStatus.FAILED) return rollback(handlerTransactions, e); } val List> results = new ArrayList(); @@ -293,11 +320,13 @@ package class TwoPhaseCommit

, D, DCL extends DataChangeListene listeners.publishDataChangeEvent(); } catch (Exception e) { log.error("Transaction: {} Finish Commit failed",transactionId, e); - dataBroker.failedTransactionsCount.andIncrement + dataBroker.failedTransactionsCount.andIncrement + transaction.changeStatus(TransactionStatus.FAILED) return rollback(handlerTransactions, e); } log.trace("Transaction: {} Finished successfully.",transactionId); - dataBroker.finishedTransactionsCount.andIncrement; + dataBroker.finishedTransactionsCount.andIncrement; + transaction.changeStatus(TransactionStatus.COMMITED) return Rpcs.getRpcResult(true, TransactionStatus.COMMITED, Collections.emptySet()); } diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/MountPointManagerImpl.xtend b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/MountPointManagerImpl.xtend index 098cd922ed..023f906a67 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/MountPointManagerImpl.xtend +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/MountPointManagerImpl.xtend @@ -44,7 +44,6 @@ class MountPointManagerImpl implements MountProvisionService { def registerMountPoint(MountPointImpl impl) { //dataBroker?.registerConfigurationReader(impl.mountPath,impl.readWrapper); //dataBroker?.registerOperationalReader(impl.mountPath,impl.readWrapper); - } override registerProvisionListener(MountProvisionListener listener) { diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/NotificationRouterImpl.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/NotificationRouterImpl.java index 763407f23a..0b184fc86e 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/NotificationRouterImpl.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/NotificationRouterImpl.java @@ -40,14 +40,15 @@ public class NotificationRouterImpl implements NotificationRouter { private static Logger log = LoggerFactory.getLogger(NotificationRouterImpl.class); private Multimap> listeners = Multimaps.synchronizedSetMultimap(HashMultimap.>create()); - +// private Registration defaultListener; + private void sendNotification(CompositeNode notification) { - QName type = notification.getNodeType(); - Collection> toNotify = listeners.get(type); + final QName type = notification.getNodeType(); + final Collection> toNotify = listeners.get(type); log.trace("Publishing notification " + type); - if (toNotify == null) { - // No listeners were registered - returns. + if ((toNotify == null) || toNotify.isEmpty()) { + log.debug("No listener registered for handling of notification {}", type); return; } @@ -59,17 +60,17 @@ public class NotificationRouterImpl implements NotificationRouter { log.error("Uncaught exception in NotificationListener", e); } } - } @Override public void publish(CompositeNode notification) { sendNotification(notification); } - + @Override public Registration addNotificationListener(QName notification, NotificationListener listener) { ListenerRegistration ret = new ListenerRegistration(notification, listener); + listeners.put(notification, ret); return ret; } diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceListener.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceListener.java index 87cbf13ea0..69fe4aa190 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceListener.java +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceListener.java @@ -78,17 +78,11 @@ class NetconfDeviceListener extends NetconfClientSessionListener { */ public void onNotification(final NetconfClientSession session, final NetconfMessage message) { this.device.logger.debug("Received NETCONF notification.", message); - CompositeNode _notificationBody = null; - CompositeNode _compositeNode = null; + CompositeNode domNotification = null; if (message != null) { - _compositeNode = NetconfMapping.toCompositeNode(message,device.getSchemaContext()); + domNotification = NetconfMapping.toNotificationNode(message, device.getSchemaContext()); } - if (_compositeNode != null) { - _notificationBody = NetconfDeviceListener.getNotificationBody(_compositeNode); - } - final CompositeNode domNotification = _notificationBody; - boolean _notEquals = (!Objects.equal(domNotification, null)); - if (_notEquals) { + if (domNotification != null) { MountProvisionInstance _mountInstance = null; if (this.device != null) { _mountInstance = this.device.getMountInstance(); diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfMapping.xtend b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfMapping.xtend index 965df60cfb..76a5506df3 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfMapping.xtend +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfMapping.xtend @@ -33,6 +33,8 @@ import com.google.common.base.Preconditions import com.google.common.base.Optional import org.opendaylight.yangtools.yang.model.api.SchemaContext import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlDocumentUtils +import org.opendaylight.yangtools.yang.model.api.NotificationDefinition +import java.util.Set class NetconfMapping { @@ -103,7 +105,19 @@ class NetconfMapping { } static def CompositeNode toCompositeNode(NetconfMessage message,Optional ctx) { - return null//message.toRpcResult().result; + //TODO: implement general normalization to normalize incoming Netconf Message + // for Schema Context counterpart + return null + } + + static def CompositeNode toNotificationNode(NetconfMessage message,Optional ctx) { + if (ctx.present) { + val schemaContext = ctx.get + val notifications = schemaContext.notifications + val document = message.document + return XmlDocumentUtils.notificationToDomNodes(document, Optional.>fromNullable(notifications)) + } + return null } static def NetconfMessage toRpcMessage(QName rpc, CompositeNode node,Optional ctx) { @@ -134,11 +148,11 @@ class NetconfMapping { if(isDataRetrievalReply(rpc)) { val xmlData = message.document.dataSubtree - val dataNodes = XmlDocumentUtils.toDomNodes(xmlData,Optional.of(context.get.dataDefinitions)) + val dataNodes = XmlDocumentUtils.toDomNodes(xmlData, Optional.of(context.get.dataDefinitions)) val it = ImmutableCompositeNode.builder() setQName(NETCONF_RPC_REPLY_QNAME) - add(ImmutableCompositeNode.create(NETCONF_DATA_QNAME,dataNodes)); + add(ImmutableCompositeNode.create(NETCONF_DATA_QNAME, dataNodes)); rawRpc = it.toInstance; //sys(xmlData) diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonMapper.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonMapper.java index 357b599ec7..226eff44e1 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonMapper.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonMapper.java @@ -134,7 +134,7 @@ class JsonMapper { private DataSchemaNode findFirstSchemaForNode(Node node, Set dataSchemaNode) { for (DataSchemaNode dsn : dataSchemaNode) { - if (node.getNodeType().getLocalName().equals(dsn.getQName().getLocalName())) { + if (node.getNodeType().equals(dsn.getQName())) { return dsn; } else if (dsn instanceof ChoiceNode) { for (ChoiceCaseNode choiceCase : ((ChoiceNode) dsn).getCases()) { @@ -252,14 +252,18 @@ class JsonMapper { result.append("/"); writeModuleNameAndIdentifier(result, identityValue); - if (identityValue.getPredicates() != null) { + if (identityValue.getPredicates() != null && !identityValue.getPredicates().isEmpty()) { for (Predicate predicate : identityValue.getPredicates()) { IdentityValue identityValuePredicate = predicate.getName(); result.append("["); - writeModuleNameAndIdentifier(result, identityValuePredicate); - result.append("=\""); + if (identityValuePredicate == null) { + result.append("."); + } else { + writeModuleNameAndIdentifier(result, identityValuePredicate); + } + result.append("='"); result.append(predicate.getValue()); - result.append("\""); + result.append("'"); result.append("]"); } } @@ -300,10 +304,16 @@ class JsonMapper { String nameForOutput = node.getNodeType().getLocalName(); if (schema.isAugmenting()) { ControllerContext contContext = ControllerContext.getInstance(); - CharSequence moduleName; - moduleName = contContext.toRestconfIdentifier(schema.getQName()); + CharSequence moduleName = null; + if (mountPoint == null) { + moduleName = contContext.toRestconfIdentifier(schema.getQName()); + } else { + moduleName = contContext.toRestconfIdentifier(mountPoint, schema.getQName()); + } if (moduleName != null) { nameForOutput = moduleName.toString(); + } else { + logger.info("Module '{}' was not found in schema from mount point", schema.getQName()); } } writer.name(nameForOutput); diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ControllerContext.xtend b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ControllerContext.xtend index 7d32194b1f..2dfe5062c8 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ControllerContext.xtend +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ControllerContext.xtend @@ -216,13 +216,20 @@ class ControllerContext implements SchemaServiceListener { var module = uriToModuleName.get(qname.namespace) if (module === null) { val moduleSchema = globalSchema.findModuleByNamespaceAndRevision(qname.namespace, qname.revision); - if(moduleSchema === null) throw new IllegalArgumentException() + if(moduleSchema === null) return null uriToModuleName.put(qname.namespace, moduleSchema.name) module = moduleSchema.name; } return '''«module»:«qname.localName»'''; } + def CharSequence toRestconfIdentifier(MountInstance mountPoint, QName qname) { + val moduleSchema = mountPoint?.schemaContext.findModuleByNamespaceAndRevision(qname.namespace, qname.revision); + if(moduleSchema === null) return null + val module = moduleSchema.name; + return '''«module»:«qname.localName»'''; + } + private static dispatch def DataSchemaNode childByQName(ChoiceNode container, QName name) { for (caze : container.cases) { val ret = caze.childByQName(name) diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestCodec.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestCodec.java index 4f643fe34d..d6b530039e 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestCodec.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestCodec.java @@ -212,6 +212,11 @@ public class RestCodec { List predicates = keyValuesToPredicateList(((NodeIdentifierWithPredicates) pathArgument) .getKeyValues()); identityValue.setPredicates(predicates); + } else if (pathArgument instanceof NodeWithValue && identityValue != null) { + List predicates = new ArrayList<>(); + String value = String.valueOf(((NodeWithValue) pathArgument).getValue()); + predicates.add(new Predicate(null, value)); + identityValue.setPredicates(predicates); } identityValuesDTO.add(identityValue); } diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnJsonBasicYangTypesTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnJsonBasicYangTypesTest.java index f3612969b9..318159063a 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnJsonBasicYangTypesTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnJsonBasicYangTypesTest.java @@ -21,6 +21,7 @@ import java.util.Set; import javax.ws.rs.WebApplicationException; import org.junit.BeforeClass; +import org.junit.Ignore; import org.junit.Test; import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider; import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider; @@ -51,6 +52,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { * Test of json output when as input are specified composite node with empty * data + YANG file */ + @Ignore @Test public void compositeNodeAndYangWithJsonReaderEmptyDataTest() { CompositeNode compositeNode = prepareCompositeNodeWithEmpties(); diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonIdentityrefTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonIdentityrefTest.java index d664001d8c..392f444cf2 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonIdentityrefTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonIdentityrefTest.java @@ -17,6 +17,7 @@ import java.util.regex.Pattern; import javax.ws.rs.WebApplicationException; import org.junit.BeforeClass; +import org.junit.Ignore; import org.junit.Test; import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider; import org.opendaylight.controller.sal.restconf.impl.test.TestUtils; @@ -32,6 +33,7 @@ public class CnSnToJsonIdentityrefTest extends YangAndXmlAndDataSchemaLoader { dataLoad("/cnsn-to-json/identityref", 2, "identityref-module", "cont"); } + @Ignore @Test public void identityrefToJsonTest() { String json = null; @@ -51,6 +53,7 @@ public class CnSnToJsonIdentityrefTest extends YangAndXmlAndDataSchemaLoader { assertTrue(mtch.matches()); } + @Ignore @Test public void identityrefToJsonWithoutQNameTest() { String json = null; diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonWithDataFromSeveralModulesTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonWithDataFromSeveralModulesTest.java index baefd93d18..54664ae069 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonWithDataFromSeveralModulesTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonWithDataFromSeveralModulesTest.java @@ -18,6 +18,7 @@ import java.util.regex.Pattern; import javax.ws.rs.WebApplicationException; import org.junit.BeforeClass; +import org.junit.Ignore; import org.junit.Test; import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider; import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider; @@ -35,6 +36,7 @@ public class CnSnToJsonWithDataFromSeveralModulesTest extends YangAndXmlAndDataS dataLoad("/xml-to-cnsn/data-of-several-modules/yang",2,"module1","cont_m1"); } + @Ignore @Test public void dataFromSeveralModulesToJsonTest() throws WebApplicationException, IOException, URISyntaxException { SchemaContext schemaContext = TestUtils.loadSchemaContext(modules); diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/CnSnToXmlAndJsonInstanceIdentifierTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/CnSnToXmlAndJsonInstanceIdentifierTest.java index 7da572f45c..9723af7671 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/CnSnToXmlAndJsonInstanceIdentifierTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/CnSnToXmlAndJsonInstanceIdentifierTest.java @@ -28,6 +28,7 @@ import javax.xml.stream.events.StartElement; import javax.xml.stream.events.XMLEvent; import org.junit.BeforeClass; +import org.junit.Ignore; import org.junit.Test; import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider; import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider; @@ -57,6 +58,7 @@ public class CnSnToXmlAndJsonInstanceIdentifierTest extends YangAndXmlAndDataSch } + @Ignore @Test public void saveCnSnToJson() throws WebApplicationException, IOException, URISyntaxException { CompositeNode cnSn = prepareCnSn(); diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsUpdateCommiter.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsUpdateCommiter.java index 19f25944b4..5f264abc2c 100644 --- a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsUpdateCommiter.java +++ b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsUpdateCommiter.java @@ -412,8 +412,6 @@ public class StatisticsUpdateCommiter implements OpendaylightGroupStatisticsList cache.put(notification.getId(), new NodeStatisticsAger(statisticsManager,key)); } NodeStatisticsAger nsa = cache.get(notification.getId()); - FlowEntry flowStatsEntry = nsa.new FlowEntry(tableId,flowRule); - cache.get(notification.getId()).updateFlowStats(flowStatsEntry); //Augment the data to the flow node @@ -466,6 +464,11 @@ public class StatisticsUpdateCommiter implements OpendaylightGroupStatisticsList flowBuilder.addAugmentation(FlowStatisticsData.class, flowStatisticsData.build()); sucLogger.debug("Found matching flow in the datastore, augmenting statistics"); foundOriginalFlow = true; + // Update entry with timestamp of latest response + flow.setKey(existingFlow.getKey()); + FlowEntry flowStatsEntry = nsa.new FlowEntry(tableId,flow.build()); + cache.get(notification.getId()).updateFlowStats(flowStatsEntry); + it.putOperationalData(flowRef, flowBuilder.build()); it.commit(); } @@ -490,6 +493,12 @@ public class StatisticsUpdateCommiter implements OpendaylightGroupStatisticsList flowBuilder.addAugmentation(FlowStatisticsData.class, flowStatisticsData.build()); sucLogger.debug("Found matching unaccounted flow in the operational datastore, augmenting statistics"); foundOriginalFlow = true; + + // Update entry with timestamp of latest response + flow.setKey(existingFlow.getKey()); + FlowEntry flowStatsEntry = nsa.new FlowEntry(tableId,flow.build()); + cache.get(notification.getId()).updateFlowStats(flowStatsEntry); + it.putOperationalData(flowRef, flowBuilder.build()); it.commit(); break; @@ -498,9 +507,9 @@ public class StatisticsUpdateCommiter implements OpendaylightGroupStatisticsList } } if(!foundOriginalFlow){ - long flowKey = Long.parseLong(new String("1"+Short.toString(tableId)+"0"+Integer.toString(this.unaccountedFlowsCounter))); + String flowKey = "#UF$TABLE*"+Short.toString(tableId)+"*"+Integer.toString(this.unaccountedFlowsCounter); this.unaccountedFlowsCounter++; - FlowKey newFlowKey = new FlowKey(new FlowId(Long.toString(flowKey))); + FlowKey newFlowKey = new FlowKey(new FlowId(flowKey)); InstanceIdentifier flowRef = InstanceIdentifier.builder(Nodes.class).child(Node.class, key) .augmentation(FlowCapableNode.class) .child(Table.class, new TableKey(tableId)) @@ -508,6 +517,12 @@ public class StatisticsUpdateCommiter implements OpendaylightGroupStatisticsList flowBuilder.setKey(newFlowKey); flowBuilder.addAugmentation(FlowStatisticsData.class, flowStatisticsData.build()); sucLogger.debug("Flow {} is not present in config data store, augmenting statistics as an unaccounted flow",flowBuilder.build()); + + // Update entry with timestamp of latest response + flow.setKey(newFlowKey); + FlowEntry flowStatsEntry = nsa.new FlowEntry(tableId,flow.build()); + cache.get(notification.getId()).updateFlowStats(flowStatsEntry); + it.putOperationalData(flowRef, flowBuilder.build()); it.commit(); } diff --git a/opendaylight/web/troubleshoot/src/main/java/org/opendaylight/controller/troubleshoot/web/Troubleshoot.java b/opendaylight/web/troubleshoot/src/main/java/org/opendaylight/controller/troubleshoot/web/Troubleshoot.java index e46b89ac2a..6d79f3cb05 100644 --- a/opendaylight/web/troubleshoot/src/main/java/org/opendaylight/controller/troubleshoot/web/Troubleshoot.java +++ b/opendaylight/web/troubleshoot/src/main/java/org/opendaylight/controller/troubleshoot/web/Troubleshoot.java @@ -62,7 +62,7 @@ import org.springframework.web.bind.annotation.ResponseBody; public class Troubleshoot implements IDaylightWeb { private static final UserLevel AUTH_LEVEL = UserLevel.CONTAINERUSER; private static final List flowStatsColumnNames = Arrays.asList("Node", "In Port", - "DL Src", "DL Dst", "DL Type", "DL Vlan", "NW Src", "NW Dst", + "DL Src", "DL Dst", "DL Type", "DL Vlan", "NW Src", "NW Dst","ToS Bits", "NW Proto", "TP Src", "TP Dst", "Actions", "Bytes", "Packets", "Time (s)", "Timeout (s)", "Priority"); @@ -229,6 +229,7 @@ public class Troubleshoot implements IDaylightWeb { private Map convertPortsStatistics( NodeConnectorStatistics ncStats, String containerName) { + Map row = new HashMap(); ISwitchManager switchManager = (ISwitchManager) ServiceHelper @@ -325,6 +326,12 @@ public class Troubleshoot implements IDaylightWeb { } else { row.put(MatchType.NW_DST.id(), "*"); } + if (match.isPresent(MatchType.NW_TOS)) { + row.put(MatchType.NW_TOS.id(), ((Byte) flow.getMatch() + .getField(MatchType.NW_TOS).getValue()).toString()); + } else { + row.put(MatchType.NW_TOS.id(), "*"); + } if (match.isPresent(MatchType.NW_PROTO)) { row.put(MatchType.NW_PROTO.id(), IPProtocols.getProtocolName(((Byte) flow.getMatch() diff --git a/opendaylight/web/troubleshoot/src/main/resources/js/page.js b/opendaylight/web/troubleshoot/src/main/resources/js/page.js index a8673b0031..4b5e51a071 100644 --- a/opendaylight/web/troubleshoot/src/main/resources/js/page.js +++ b/opendaylight/web/troubleshoot/src/main/resources/js/page.js @@ -373,6 +373,11 @@ one.f.troubleshooting.existingNodes = { label: 'NW Dst', sortable: true }, + { + property: 'nwTOS', + label: 'ToS Bits', + sortable: true + }, { property: 'nwProto', label: 'NW Proto', @@ -437,6 +442,7 @@ one.f.troubleshooting.existingNodes = { entry.push(value["dlVlan"]); entry.push(value["nwSrc"]); entry.push(value["nwDst"]); + entry.push(value["nwTOS"]); entry.push(value["nwProto"]); entry.push(value["tpSrc"]); entry.push(value["tpDst"]);