X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-rest-connector%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fsal%2Frestconf%2Fimpl%2FBrokerFacade.java;h=346d54a77382f210b36e22cd1a64a8fe6fa21012;hb=06e889c9c78457590b6a0b62d89a6b9f44242a9f;hp=8dbc5b50ee5dbd8ac374ef7d1452384442923085;hpb=9cd4e7995210f8381892004373acc71c8b3ae7af;p=controller.git diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/BrokerFacade.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/BrokerFacade.java index 8dbc5b50ee..346d54a773 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/BrokerFacade.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/BrokerFacade.java @@ -7,9 +7,17 @@ */ package org.opendaylight.controller.sal.restconf.impl; +import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.CONFIGURATION; +import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.OPERATIONAL; + import com.google.common.base.Optional; import com.google.common.util.concurrent.CheckedFuture; import com.google.common.util.concurrent.ListenableFuture; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.ExecutionException; +import javax.ws.rs.core.Response.Status; import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException; @@ -23,40 +31,37 @@ import org.opendaylight.controller.md.sal.dom.api.DOMDataReadTransaction; import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction; import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction; import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint; +import org.opendaylight.controller.md.sal.dom.api.DOMRpcException; +import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult; +import org.opendaylight.controller.md.sal.dom.api.DOMRpcService; import org.opendaylight.controller.sal.core.api.Broker.ConsumerSession; import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorTag; import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorType; import org.opendaylight.controller.sal.streams.listeners.ListenerAdapter; import org.opendaylight.yangtools.concepts.ListenerRegistration; -import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.common.RpcResult; -import org.opendaylight.yangtools.yang.data.api.CompositeNode; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument; +import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; +import org.opendaylight.yangtools.yang.model.api.SchemaPath; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.ws.rs.core.Response.Status; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; - -import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.CONFIGURATION; -import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.OPERATIONAL; - public class BrokerFacade { private final static Logger LOG = LoggerFactory.getLogger(BrokerFacade.class); private final static BrokerFacade INSTANCE = new BrokerFacade(); + private volatile DOMRpcService rpcService; private volatile ConsumerSession context; private DOMDataBroker domDataBroker; private BrokerFacade() { } + public void setRpcService(final DOMRpcService router) { + rpcService = router; + } + public void setContext(final ConsumerSession context) { this.context = context; } @@ -103,7 +108,7 @@ public class BrokerFacade { public CheckedFuture commitConfigurationDataPut( final YangInstanceIdentifier path, final NormalizedNode payload) { checkPreconditions(); - DataNormalizationOperation rootOp = ControllerContext.getInstance().getRootOperation(); + final DataNormalizationOperation rootOp = ControllerContext.getInstance().getRootOperation(); return putDataViaTransaction(domDataBroker.newReadWriteTransaction(), CONFIGURATION, path, payload, rootOp); } @@ -111,7 +116,7 @@ public class BrokerFacade { final DOMMountPoint mountPoint, final YangInstanceIdentifier path, final NormalizedNode payload) { final Optional domDataBrokerService = mountPoint.getService(DOMDataBroker.class); if (domDataBrokerService.isPresent()) { - DataNormalizationOperation rootOp = new DataNormalizer(mountPoint.getSchemaContext()).getRootOperation(); + final DataNormalizationOperation rootOp = new DataNormalizer(mountPoint.getSchemaContext()).getRootOperation(); return putDataViaTransaction(domDataBrokerService.get().newReadWriteTransaction(), CONFIGURATION, path, payload, rootOp); } @@ -122,7 +127,7 @@ public class BrokerFacade { public CheckedFuture commitConfigurationDataPost( final YangInstanceIdentifier path, final NormalizedNode payload) { checkPreconditions(); - DataNormalizationOperation rootOp = ControllerContext.getInstance().getRootOperation(); + final DataNormalizationOperation rootOp = ControllerContext.getInstance().getRootOperation(); return postDataViaTransaction(domDataBroker.newReadWriteTransaction(), CONFIGURATION, path, payload, rootOp); } @@ -130,7 +135,7 @@ public class BrokerFacade { final DOMMountPoint mountPoint, final YangInstanceIdentifier path, final NormalizedNode payload) { final Optional domDataBrokerService = mountPoint.getService(DOMDataBroker.class); if (domDataBrokerService.isPresent()) { - DataNormalizationOperation rootOp = new DataNormalizer(mountPoint.getSchemaContext()).getRootOperation(); + final DataNormalizationOperation rootOp = new DataNormalizer(mountPoint.getSchemaContext()).getRootOperation(); return postDataViaTransaction(domDataBrokerService.get().newReadWriteTransaction(), CONFIGURATION, path, payload, rootOp); } @@ -154,21 +159,23 @@ public class BrokerFacade { } // RPC - public Future> invokeRpc(final QName type, final CompositeNode payload) { - this.checkPreconditions(); - - return context.rpc(type, payload); + public CheckedFuture invokeRpc(final SchemaPath type, final NormalizedNode input) { + checkPreconditions(); + if (rpcService == null) { + throw new RestconfDocumentedException(Status.SERVICE_UNAVAILABLE); + } + return rpcService.invokeRpc(type, input); } public void registerToListenDataChanges(final LogicalDatastoreType datastore, final DataChangeScope scope, final ListenerAdapter listener) { - this.checkPreconditions(); + checkPreconditions(); if (listener.isListening()) { return; } - YangInstanceIdentifier path = listener.getPath(); + final YangInstanceIdentifier path = listener.getPath(); final ListenerRegistration registration = domDataBroker.registerDataChangeListener( datastore, path, listener, scope); @@ -176,7 +183,7 @@ public class BrokerFacade { } private NormalizedNode readDataViaTransaction(final DOMDataReadTransaction transaction, - LogicalDatastoreType datastore, YangInstanceIdentifier path) { + final LogicalDatastoreType datastore, final YangInstanceIdentifier path) { LOG.trace("Read " + datastore.name() + " via Restconf: {}", path); final ListenableFuture>> listenableFuture = transaction.read(datastore, path); if (listenableFuture != null) { @@ -199,13 +206,23 @@ public class BrokerFacade { private CheckedFuture postDataViaTransaction( final DOMDataReadWriteTransaction rWTransaction, final LogicalDatastoreType datastore, - final YangInstanceIdentifier path, final NormalizedNode payload, DataNormalizationOperation root) { - ListenableFuture>> futureDatastoreData = rWTransaction.read(datastore, path); + final YangInstanceIdentifier parentPath, final NormalizedNode payload, final DataNormalizationOperation root) { + // FIXME: This is doing correct post for container and list children + // not sure if this will work for choice case + final YangInstanceIdentifier path; + if(payload instanceof MapEntryNode) { + path = parentPath.node(payload.getNodeType()).node(payload.getIdentifier()); + } else { + path = parentPath.node(payload.getIdentifier()); + } + + final ListenableFuture>> futureDatastoreData = rWTransaction.read(datastore, path); try { final Optional> optionalDatastoreData = futureDatastoreData.get(); if (optionalDatastoreData.isPresent() && payload.equals(optionalDatastoreData.get())) { - String errMsg = "Post Configuration via Restconf was not executed because data already exists"; + final String errMsg = "Post Configuration via Restconf was not executed because data already exists"; LOG.trace(errMsg + ":{}", path); + rWTransaction.cancel(); throw new RestconfDocumentedException("Data already exists for path: " + path, ErrorType.PROTOCOL, ErrorTag.DATA_EXISTS); } @@ -221,7 +238,7 @@ public class BrokerFacade { private CheckedFuture putDataViaTransaction( final DOMDataReadWriteTransaction writeTransaction, final LogicalDatastoreType datastore, - final YangInstanceIdentifier path, final NormalizedNode payload, DataNormalizationOperation root) { + final YangInstanceIdentifier path, final NormalizedNode payload, final DataNormalizationOperation root) { LOG.trace("Put " + datastore.name() + " via Restconf: {}", path); ensureParentsByMerge(datastore, path, writeTransaction, root); writeTransaction.put(datastore, path, payload); @@ -230,46 +247,46 @@ public class BrokerFacade { private CheckedFuture deleteDataViaTransaction( final DOMDataWriteTransaction writeTransaction, final LogicalDatastoreType datastore, - YangInstanceIdentifier path) { - LOG.info("Delete " + datastore.name() + " via Restconf: {}", path); + final YangInstanceIdentifier path) { + LOG.trace("Delete " + datastore.name() + " via Restconf: {}", path); writeTransaction.delete(datastore, path); return writeTransaction.submit(); } - public void setDomDataBroker(DOMDataBroker domDataBroker) { + public void setDomDataBroker(final DOMDataBroker domDataBroker) { this.domDataBroker = domDataBroker; } private final void ensureParentsByMerge(final LogicalDatastoreType store, final YangInstanceIdentifier normalizedPath, final DOMDataReadWriteTransaction rwTx, final DataNormalizationOperation root) { - List currentArguments = new ArrayList<>(); - Iterator iterator = normalizedPath.getPathArguments().iterator(); + final List currentArguments = new ArrayList<>(); + final Iterator iterator = normalizedPath.getPathArguments().iterator(); DataNormalizationOperation currentOp = root; while (iterator.hasNext()) { - PathArgument currentArg = iterator.next(); + final PathArgument currentArg = iterator.next(); try { currentOp = currentOp.getChild(currentArg); - } catch (DataNormalizationException e) { + } catch (final DataNormalizationException e) { + rwTx.cancel(); throw new IllegalArgumentException( String.format("Invalid child encountered in path %s", normalizedPath), e); } currentArguments.add(currentArg); - YangInstanceIdentifier currentPath = YangInstanceIdentifier.create(currentArguments); + final YangInstanceIdentifier currentPath = YangInstanceIdentifier.create(currentArguments); final Boolean exists; try { - CheckedFuture future = - rwTx.exists(store, currentPath); + final CheckedFuture future = rwTx.exists(store, currentPath); exists = future.checkedGet(); - } catch (ReadFailedException e) { + } catch (final ReadFailedException e) { LOG.error("Failed to read pre-existing data from store {} path {}", store, currentPath, e); + rwTx.cancel(); throw new IllegalStateException("Failed to read pre-existing data", e); } - if (!exists && iterator.hasNext()) { rwTx.merge(store, currentPath, currentOp.createDefault(currentArg)); }