*/
package org.opendaylight.controller.sal.connect.netconf;
+import com.google.common.collect.Sets;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.FutureListener;
import java.util.Queue;
import java.util.Set;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.opendaylight.controller.netconf.api.NetconfMessage;
import org.opendaylight.controller.netconf.api.NetconfTerminationReason;
import org.opendaylight.controller.netconf.client.NetconfClientSession;
import com.google.common.util.concurrent.ListenableFuture;
class NetconfDeviceListener implements NetconfClientSessionListener {
+
private static final class Request {
final UncancellableFuture<RpcResult<CompositeNode>> future;
final NetconfMessage request;
delegate = SchemaSourceProviders.noopProvider();
}
- device.bringUp(delegate, caps);
+ device.bringUp(delegate, caps, isRollbackSupported(session.getServerCapabilities()));
+
+ }
+
+ private static boolean isRollbackSupported(final Collection<String> serverCapabilities) {
+ // TODO rollback capability cannot be searched for in Set<QName> caps
+ // since this set does not contain module-less capabilities
+ return Sets.newHashSet(serverCapabilities).contains(NetconfMapping.NETCONF_ROLLBACK_ON_ERROR_URI.toString());
}
private synchronized void tearDown(final Exception e) {
requests.poll();
LOG.debug("Matched {} to {}", r.request, message);
- // FIXME: this can throw exceptions, which should result
- // in the future failing
- NetconfMapping.checkValidReply(r.request, message);
+ try {
+ NetconfMapping.checkValidReply(r.request, message);
+ } catch (IllegalStateException e) {
+ LOG.warn("Invalid request-reply match, reply message contains different message-id", e);
+ r.future.setException(e);
+ return;
+ }
+
+ try {
+ NetconfMapping.checkSuccessReply(message);
+ } catch (NetconfDocumentedException | IllegalStateException e) {
+ LOG.warn("Error reply from remote device", e);
+ r.future.setException(e);
+ return;
+ }
+
r.future.set(Rpcs.getRpcResult(true, NetconfMapping.toNotificationNode(message, device.getSchemaContext()),
Collections.<RpcError>emptyList()));
} else {