use of org.opendaylight.mdsal.dom.api.DOMMountPoint in project netconf by opendaylight.
the class MountedDeviceListener method trackNotificationsPerformance.
private void trackNotificationsPerformance(final YangInstanceIdentifier path) {
// 1. get nodeId from the path
final String nodeId = TestUtils.getNodeId(path).get();
// 2. extract needed services from the mount point
final DOMMountPoint mountPoint = mountPointService.getMountPoint(path).orElseThrow(() -> new RuntimeException("Unable to get mountpoint"));
final DOMRpcService rpcService = mountPoint.getService(DOMRpcService.class).orElseThrow(() -> new RuntimeException("Unable to get RPC Service from the mountpoint"));
final DOMNotificationService notificationService = mountPoint.getService(DOMNotificationService.class).orElseThrow(() -> new RuntimeException("Unable to get NotificationService from the mountpoint"));
// 3. create a listener for the notifications
listeners.put(path, notificationService.registerNotificationListener(new NotificationsCounter(nodeId, serializer), Absolute.of(VrfRouteNotification.QNAME)));
// 4. send 'create-subscription' request to the device
final StreamNameType streamNameType = new StreamNameType(STREAM_DEFAULT_NAME);
final CreateSubscriptionInputBuilder subscriptionInputBuilder = new CreateSubscriptionInputBuilder();
subscriptionInputBuilder.setStream(streamNameType);
final CreateSubscriptionInput input = subscriptionInputBuilder.build();
final ContainerNode inputNode = serializer.toNormalizedNodeRpcData(input);
final ListenableFuture<? extends DOMRpcResult> resultFuture = rpcService.invokeRpc(CREATE_SUBSCRIPTION_QNAME, inputNode);
Futures.addCallback(resultFuture, new FutureCallback<DOMRpcResult>() {
@Override
public void onSuccess(@Nullable final DOMRpcResult rpcResult) {
LOG.info("Notification stream subscription succesfully completed");
}
@Override
public void onFailure(final Throwable throwable) {
LOG.error("Notification stream subscription failed");
}
}, MoreExecutors.directExecutor());
}
use of org.opendaylight.mdsal.dom.api.DOMMountPoint in project netconf by opendaylight.
the class RestconfImpl method readOperationalData.
@Override
public NormalizedNodeContext readOperationalData(final String identifier, final UriInfo uriInfo) {
final InstanceIdentifierContext<?> iiWithData = controllerContext.toInstanceIdentifier(identifier);
final DOMMountPoint mountPoint = iiWithData.getMountPoint();
NormalizedNode data = null;
final YangInstanceIdentifier normalizedII = iiWithData.getInstanceIdentifier();
if (mountPoint != null) {
data = broker.readOperationalData(mountPoint, normalizedII);
} else {
data = broker.readOperationalData(normalizedII);
}
if (data == null) {
throw dataMissing(identifier);
}
return new NormalizedNodeContext(iiWithData, data, QueryParametersParser.parseWriterParameters(uriInfo));
}
use of org.opendaylight.mdsal.dom.api.DOMMountPoint in project netconf by opendaylight.
the class RestconfImpl method createConfigurationData.
@Override
public Response createConfigurationData(final NormalizedNodeContext payload, final UriInfo uriInfo) {
if (payload == null) {
throw new RestconfDocumentedException("Input is required.", ErrorType.PROTOCOL, ErrorTag.MALFORMED_MESSAGE);
}
final DOMMountPoint mountPoint = payload.getInstanceIdentifierContext().getMountPoint();
final InstanceIdentifierContext<?> iiWithData = payload.getInstanceIdentifierContext();
final YangInstanceIdentifier normalizedII = iiWithData.getInstanceIdentifier();
boolean insertUsed = false;
boolean pointUsed = false;
String insert = null;
String point = null;
if (uriInfo != null) {
for (final Entry<String, List<String>> entry : uriInfo.getQueryParameters().entrySet()) {
switch(entry.getKey()) {
case "insert":
if (!insertUsed) {
insertUsed = true;
insert = entry.getValue().iterator().next();
} else {
throw new RestconfDocumentedException("Insert parameter can be used only once.");
}
break;
case "point":
if (!pointUsed) {
pointUsed = true;
point = entry.getValue().iterator().next();
} else {
throw new RestconfDocumentedException("Point parameter can be used only once.");
}
break;
default:
throw new RestconfDocumentedException("Bad parameter for post: " + entry.getKey());
}
}
}
if (pointUsed && !insertUsed) {
throw new RestconfDocumentedException("Point parameter can't be used without Insert parameter.");
}
if (pointUsed && (insert.equals("first") || insert.equals("last"))) {
throw new RestconfDocumentedException("Point parameter can be used only with 'after' or 'before' values of Insert parameter.");
}
FluentFuture<? extends CommitInfo> future;
if (mountPoint != null) {
future = broker.commitConfigurationDataPost(mountPoint, normalizedII, payload.getData(), insert, point);
} else {
future = broker.commitConfigurationDataPost(controllerContext.getGlobalSchema(), normalizedII, payload.getData(), insert, point);
}
try {
future.get();
} catch (final InterruptedException e) {
LOG.info("Error creating data {}", uriInfo != null ? uriInfo.getPath() : "", e);
throw new RestconfDocumentedException(e.getMessage(), e);
} catch (final ExecutionException e) {
LOG.info("Error creating data {}", uriInfo != null ? uriInfo.getPath() : "", e);
throw RestconfDocumentedException.decodeAndThrow(e.getMessage(), Throwables.getCauseAs(e, TransactionCommitFailedException.class));
}
LOG.trace("Successfuly created data.");
final ResponseBuilder responseBuilder = Response.status(Status.NO_CONTENT);
// FIXME: Provide path to result.
final URI location = resolveLocation(uriInfo, "", mountPoint, normalizedII);
if (location != null) {
responseBuilder.location(location);
}
return responseBuilder.build();
}
use of org.opendaylight.mdsal.dom.api.DOMMountPoint in project netconf by opendaylight.
the class RestconfImpl method updateConfigurationData.
@Override
public Response updateConfigurationData(final String identifier, final NormalizedNodeContext payload, final UriInfo uriInfo) {
boolean insertUsed = false;
boolean pointUsed = false;
String insert = null;
String point = null;
for (final Entry<String, List<String>> entry : uriInfo.getQueryParameters().entrySet()) {
switch(entry.getKey()) {
case "insert":
if (!insertUsed) {
insertUsed = true;
insert = entry.getValue().iterator().next();
} else {
throw new RestconfDocumentedException("Insert parameter can be used only once.");
}
break;
case "point":
if (!pointUsed) {
pointUsed = true;
point = entry.getValue().iterator().next();
} else {
throw new RestconfDocumentedException("Point parameter can be used only once.");
}
break;
default:
throw new RestconfDocumentedException("Bad parameter for post: " + entry.getKey());
}
}
if (pointUsed && !insertUsed) {
throw new RestconfDocumentedException("Point parameter can't be used without Insert parameter.");
}
if (pointUsed && (insert.equals("first") || insert.equals("last"))) {
throw new RestconfDocumentedException("Point parameter can be used only with 'after' or 'before' values of Insert parameter.");
}
requireNonNull(identifier);
final InstanceIdentifierContext<?> iiWithData = payload.getInstanceIdentifierContext();
validateInput(iiWithData.getSchemaNode(), payload);
validateTopLevelNodeName(payload, iiWithData.getInstanceIdentifier());
validateListKeysEqualityInPayloadAndUri(payload);
final DOMMountPoint mountPoint = iiWithData.getMountPoint();
final YangInstanceIdentifier normalizedII = iiWithData.getInstanceIdentifier();
/*
* There is a small window where another write transaction could be
* updating the same data simultaneously and we get an
* OptimisticLockFailedException. This error is likely transient and The
* WriteTransaction#submit API docs state that a retry will likely
* succeed. So we'll try again if that scenario occurs. If it fails a
* third time then it probably will never succeed so we'll fail in that
* case.
*
* By retrying we're attempting to hide the internal implementation of
* the data store and how it handles concurrent updates from the
* restconf client. The client has instructed us to put the data and we
* should make every effort to do so without pushing optimistic lock
* failures back to the client and forcing them to handle it via retry
* (and having to document the behavior).
*/
PutResult result = null;
int tries = 2;
while (true) {
if (mountPoint != null) {
result = broker.commitMountPointDataPut(mountPoint, normalizedII, payload.getData(), insert, point);
} else {
result = broker.commitConfigurationDataPut(controllerContext.getGlobalSchema(), normalizedII, payload.getData(), insert, point);
}
try {
result.getFutureOfPutData().get();
} catch (final InterruptedException e) {
LOG.debug("Update failed for {}", identifier, e);
throw new RestconfDocumentedException(e.getMessage(), e);
} catch (final ExecutionException e) {
final TransactionCommitFailedException failure = Throwables.getCauseAs(e, TransactionCommitFailedException.class);
if (failure instanceof OptimisticLockFailedException) {
if (--tries <= 0) {
LOG.debug("Got OptimisticLockFailedException on last try - failing {}", identifier);
throw new RestconfDocumentedException(e.getMessage(), e, failure.getErrorList());
}
LOG.debug("Got OptimisticLockFailedException - trying again {}", identifier);
continue;
}
LOG.debug("Update failed for {}", identifier, e);
throw RestconfDocumentedException.decodeAndThrow(e.getMessage(), failure);
}
return Response.status(result.getStatus()).build();
}
}
use of org.opendaylight.mdsal.dom.api.DOMMountPoint in project netconf by opendaylight.
the class RestconfImpl method readConfigurationData.
@Override
public NormalizedNodeContext readConfigurationData(final String identifier, final UriInfo uriInfo) {
boolean withDefaUsed = false;
String withDefa = null;
for (final Entry<String, List<String>> entry : uriInfo.getQueryParameters().entrySet()) {
switch(entry.getKey()) {
case "with-defaults":
if (!withDefaUsed) {
withDefaUsed = true;
withDefa = entry.getValue().iterator().next();
} else {
throw new RestconfDocumentedException("With-defaults parameter can be used only once.");
}
break;
default:
LOG.info("Unknown key : {}.", entry.getKey());
break;
}
}
// TODO: this flag is always ignored
boolean tagged = false;
if (withDefaUsed) {
if ("report-all-tagged".equals(withDefa)) {
tagged = true;
withDefa = null;
}
if ("report-all".equals(withDefa)) {
withDefa = null;
}
}
final InstanceIdentifierContext<?> iiWithData = controllerContext.toInstanceIdentifier(identifier);
final DOMMountPoint mountPoint = iiWithData.getMountPoint();
NormalizedNode data = null;
final YangInstanceIdentifier normalizedII = iiWithData.getInstanceIdentifier();
if (mountPoint != null) {
data = broker.readConfigurationData(mountPoint, normalizedII, withDefa);
} else {
data = broker.readConfigurationData(normalizedII, withDefa);
}
if (data == null) {
throw dataMissing(identifier);
}
return new NormalizedNodeContext(iiWithData, data, QueryParametersParser.parseWriterParameters(uriInfo));
}
Aggregations