import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.Futures;
import java.math.BigInteger;
import java.net.URI;
import java.net.URISyntaxException;
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.md.sal.dom.spi.DefaultDOMRpcResult;
import org.opendaylight.controller.sal.rest.api.Draft02;
import org.opendaylight.controller.sal.rest.api.RestconfService;
import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorTag;
import org.opendaylight.yangtools.yang.common.QNameModule;
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.MutableCompositeNode;
import org.opendaylight.yangtools.yang.data.api.Node;
import org.opendaylight.yangtools.yang.data.api.SimpleNode;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode;
import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.CollectionNodeBuilder;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.ListNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
instanceDataChildrenByName = ControllerContext.findInstanceDataChildrenByName(
((DataNodeContainer) streamSchemaNode), "events");
final DataSchemaNode eventsSchemaNode = Iterables.getFirst(instanceDataChildrenByName, null);
- streamNodeValues.add(NodeFactory.<String> createImmutableSimpleNode(eventsSchemaNode.getQName(), null, ""));
+ streamNodeValues.add(NodeFactory.<String>createImmutableSimpleNode(eventsSchemaNode.getQName(), null, ""));
return NodeFactory.createImmutableCompositeNode(streamSchemaNode.getQName(), null, streamNodeValues);
}
@Override
public NormalizedNodeContext invokeRpc(final String identifier, final NormalizedNodeContext payload, final UriInfo uriInfo) {
final SchemaPath type = payload.getInstanceIdentifierContext().getSchemaNode().getPath();
+ final URI namespace = payload.getInstanceIdentifierContext().getSchemaNode().getQName().getNamespace();
final CheckedFuture<DOMRpcResult, DOMRpcException> response;
final DOMMountPoint mountPoint = payload.getInstanceIdentifierContext().getMountPoint();
final SchemaContext schemaContext;
schemaContext = mountPoint.getSchemaContext();
response = mountRpcServices.get().invokeRpc(type, payload.getData());
} else {
- response = broker.invokeRpc(type, payload.getData());
+ if (namespace.toString().equals(SAL_REMOTE_NAMESPACE)) {
+ response = invokeSalRemoteRpcSubscribeRPC(payload);
+ } else {
+ response = broker.invokeRpc(type, payload.getData());
+ }
schemaContext = controllerContext.getGlobalSchema();
}
// }
}
- /**
- * @deprecated method wil be removed for Lithium release
- */
- @Deprecated
- private StructuredData invokeSalRemoteRpcSubscribeRPC(final CompositeNode payload, final RpcDefinition rpc,
- final boolean prettyPrint) {
- final CompositeNode value = this.normalizeNode(payload, rpc.getInput(), null);
- final SimpleNode<? extends Object> pathNode = value == null ? null : value.getFirstSimpleByName(QName.create(
- rpc.getQName(), "path"));
- final Object pathValue = pathNode == null ? null : pathNode.getValue();
+ private CheckedFuture<DOMRpcResult, DOMRpcException> invokeSalRemoteRpcSubscribeRPC(final NormalizedNodeContext payload) {
+ final ContainerNode value = (ContainerNode) payload.getData();
+ final QName rpcQName = payload.getInstanceIdentifierContext().getSchemaNode().getQName();
+ Optional<DataContainerChild<? extends PathArgument, ?>> path = value.getChild(new NodeIdentifier(
+ QName.create(payload.getInstanceIdentifierContext().getSchemaNode().getQName(), "path")));
+ final Object pathValue = path.isPresent() ? path.get().getValue() : null;
if (!(pathValue instanceof YangInstanceIdentifier)) {
throw new RestconfDocumentedException("Instance identifier was not normalized correctly.",
if (Strings.isNullOrEmpty(streamName)) {
throw new RestconfDocumentedException(
- "Path is empty or contains data node which is not Container or List build-in type.",
+ "Path is empty or contains value node which is not Container or List build-in type.",
ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
}
- final SimpleNode<String> streamNameNode = NodeFactory.<String> createImmutableSimpleNode(
- QName.create(rpc.getOutput().getQName(), "stream-name"), null, streamName);
- final List<Node<?>> output = new ArrayList<Node<?>>();
- output.add(streamNameNode);
+ QName outputQname = QName.create(rpcQName, "output");
+ QName streamNameQname = QName.create(rpcQName, "stream-name");
- final MutableCompositeNode responseData = NodeFactory.createMutableCompositeNode(rpc.getOutput().getQName(),
- null, output, null, null);
+ ContainerNode output = ImmutableContainerNodeBuilder.create().withNodeIdentifier(new NodeIdentifier(outputQname))
+ .withChild(ImmutableNodes.leafNode(streamNameQname, streamName)).build();
if (!Notificator.existListenerFor(streamName)) {
- Notificator.createListener(pathIdentifier, streamName);
+ YangInstanceIdentifier normalizedPathIdentifier = controllerContext.toNormalized(pathIdentifier);
+ Notificator.createListener(normalizedPathIdentifier, streamName);
}
- return new StructuredData(responseData, rpc.getOutput(), null, prettyPrint);
+ DOMRpcResult defaultDOMRpcResult = new DefaultDOMRpcResult(output);
+
+ return Futures.immediateCheckedFuture(defaultDOMRpcResult);
}
@Override
} catch (final NullPointerException e) {
WebSocketServer.createInstance(NOTIFICATION_PORT);
}
- final UriBuilder port = uriBuilder.port(notificationPort);
- final URI uriToWebsocketServer = port.replacePath(streamName).build();
+ final UriBuilder uriToWebsocketServerBuilder = uriBuilder.port(notificationPort).scheme("ws");
+ final URI uriToWebsocketServer = uriToWebsocketServerBuilder.replacePath(streamName).build();
return Response.status(Status.OK).location(uriToWebsocketServer).build();
}
* contains value
* @return enum object if its string value is equal to {@code paramName}. In other cases null.
*/
- private <T> T parseEnumTypeParameter(final CompositeNode compNode, final Class<T> classDescriptor,
+ private <T> T parseEnumTypeParameter(final ContainerNode value, final Class<T> classDescriptor,
final String paramName) {
final QNameModule salRemoteAugment = QNameModule.create(NAMESPACE_EVENT_SUBSCRIPTION_AUGMENT,
EVENT_SUBSCRIPTION_AUGMENT_REVISION);
- final SimpleNode<?> simpleNode = compNode.getFirstSimpleByName(QName.create(salRemoteAugment, paramName));
- if (simpleNode == null) {
+ Optional<DataContainerChild<? extends PathArgument, ?>> enumNode = value.getChild(new NodeIdentifier(
+ QName.create(salRemoteAugment, paramName)));
+ if (!enumNode.isPresent()) {
return null;
}
- final Object rawValue = simpleNode.getValue();
+ final Object rawValue = enumNode.get().getValue();
if (!(rawValue instanceof String)) {
return null;
}
* || MOUNT_POINT_MODULE_NAME .equals( namespace .
* toString( ) )
*/)
- && SchemaContext.NAME.getLocalName().equals(localName(data));
+ && SchemaContext.NAME.getLocalName().equals(localName(data));
}
private String addMountPointIdentifier(final String identifier) {
protected MapEntryNode toModuleEntryNode(final Module module, final DataSchemaNode moduleSchemaNode) {
Preconditions.checkArgument(moduleSchemaNode instanceof ListSchemaNode,
- "moduleSchemaNode has to be of type ListSchemaNode");\r final ListSchemaNode listModuleSchemaNode = (ListSchemaNode) moduleSchemaNode;\r final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> moduleNodeValues = Builders\r .mapEntryBuilder(listModuleSchemaNode);\r\r List<DataSchemaNode> instanceDataChildrenByName = ControllerContext.findInstanceDataChildrenByName(\r (listModuleSchemaNode), "name");\r final DataSchemaNode nameSchemaNode = Iterables.getFirst(instanceDataChildrenByName, null);\r Preconditions.checkState(nameSchemaNode instanceof LeafSchemaNode);\r moduleNodeValues.withChild(Builders.leafBuilder((LeafSchemaNode) nameSchemaNode).withValue(module.getName())\r .build());\r\r instanceDataChildrenByName = ControllerContext.findInstanceDataChildrenByName(\r (listModuleSchemaNode), "revision");\r final DataSchemaNode revisionSchemaNode = Iterables.getFirst(instanceDataChildrenByName, null);\r Preconditions.checkState(revisionSchemaNode instanceof LeafSchemaNode);\r final String revision = REVISION_FORMAT.format(module.getRevision());\r moduleNodeValues.withChild(Builders.leafBuilder((LeafSchemaNode) revisionSchemaNode).withValue(revision)\r .build());\r\r instanceDataChildrenByName = ControllerContext.findInstanceDataChildrenByName(\r (listModuleSchemaNode), "namespace");\r final DataSchemaNode namespaceSchemaNode = Iterables.getFirst(instanceDataChildrenByName, null);\r Preconditions.checkState(namespaceSchemaNode instanceof LeafSchemaNode);\r moduleNodeValues.withChild(Builders.leafBuilder((LeafSchemaNode) namespaceSchemaNode)\r .withValue(module.getNamespace().toString()).build());\r\r instanceDataChildrenByName = ControllerContext.findInstanceDataChildrenByName(\r (listModuleSchemaNode), "feature");\r final DataSchemaNode featureSchemaNode = Iterables.getFirst(instanceDataChildrenByName, null);\r Preconditions.checkState(featureSchemaNode instanceof LeafListSchemaNode);\r final ListNodeBuilder<Object, LeafSetEntryNode<Object>> featuresBuilder = Builders\r .leafSetBuilder((LeafListSchemaNode) featureSchemaNode);\r for (final FeatureDefinition feature : module.getFeatures()) {\r featuresBuilder.withChild(Builders.leafSetEntryBuilder(((LeafListSchemaNode) featureSchemaNode))\r .withValue(feature.getQName().getLocalName()).build());\r }\r moduleNodeValues.withChild(featuresBuilder.build());
-\r return moduleNodeValues.build();\r }
+ "moduleSchemaNode has to be of type ListSchemaNode");
+ final ListSchemaNode listModuleSchemaNode = (ListSchemaNode) moduleSchemaNode;
+ final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> moduleNodeValues = Builders
+ .mapEntryBuilder(listModuleSchemaNode);
+
+ List<DataSchemaNode> instanceDataChildrenByName = ControllerContext.findInstanceDataChildrenByName(
+ (listModuleSchemaNode), "name");
+ final DataSchemaNode nameSchemaNode = Iterables.getFirst(instanceDataChildrenByName, null);
+ Preconditions.checkState(nameSchemaNode instanceof LeafSchemaNode);
+ moduleNodeValues.withChild(Builders.leafBuilder((LeafSchemaNode) nameSchemaNode).withValue(module.getName())
+ .build());
+
+ instanceDataChildrenByName = ControllerContext.findInstanceDataChildrenByName(
+ (listModuleSchemaNode), "revision");
+ final DataSchemaNode revisionSchemaNode = Iterables.getFirst(instanceDataChildrenByName, null);
+ Preconditions.checkState(revisionSchemaNode instanceof LeafSchemaNode);
+ final String revision = REVISION_FORMAT.format(module.getRevision());
+ moduleNodeValues.withChild(Builders.leafBuilder((LeafSchemaNode) revisionSchemaNode).withValue(revision)
+ .build());
+
+ instanceDataChildrenByName = ControllerContext.findInstanceDataChildrenByName(
+ (listModuleSchemaNode), "namespace");
+ final DataSchemaNode namespaceSchemaNode = Iterables.getFirst(instanceDataChildrenByName, null);
+ Preconditions.checkState(namespaceSchemaNode instanceof LeafSchemaNode);
+ moduleNodeValues.withChild(Builders.leafBuilder((LeafSchemaNode) namespaceSchemaNode)
+ .withValue(module.getNamespace().toString()).build());
+
+ instanceDataChildrenByName = ControllerContext.findInstanceDataChildrenByName(
+ (listModuleSchemaNode), "feature");
+ final DataSchemaNode featureSchemaNode = Iterables.getFirst(instanceDataChildrenByName, null);
+ Preconditions.checkState(featureSchemaNode instanceof LeafListSchemaNode);
+ final ListNodeBuilder<Object, LeafSetEntryNode<Object>> featuresBuilder = Builders
+ .leafSetBuilder((LeafListSchemaNode) featureSchemaNode);
+ for (final FeatureDefinition feature : module.getFeatures()) {
+ featuresBuilder.withChild(Builders.leafSetEntryBuilder(((LeafListSchemaNode) featureSchemaNode))
+ .withValue(feature.getQName().getLocalName()).build());
+ }
+ moduleNodeValues.withChild(featuresBuilder.build());
+
+ return moduleNodeValues.build();
+ }
protected MapEntryNode toStreamEntryNode(final String streamName, final DataSchemaNode streamSchemaNode) {
Preconditions.checkArgument(streamSchemaNode instanceof ListSchemaNode,
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
-import java.util.Map.Entry;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.Executors;
import java.util.regex.Pattern;
-import javax.activation.UnsupportedDataTypeException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
}
/**
- * Gets event data.
+ * Gets event String.
*
* @return String representation of event data.
*/
/**
* Sets event data.
*
- * @param String
- * data.
+ * @param data String.
*/
public void setData(final String data) {
this.data = data;
* @param dataChangedNotificationEventElement
* {@link Element}
* @param change
- * {@link DataChangeEvent}
+ * {@link AsyncDataChangeEvent}
*/
private void addValuesToDataChangedNotificationEventElement(final Document doc,
final Element dataChangedNotificationEventElement,
* Set of {@link YangInstanceIdentifier}.
* @param element
* {@link Element}
- * @param store
- * {@link Store}
* @param operation
* {@link Operation}
*/
return;
}
for (final YangInstanceIdentifier path : data) {
- final Node node = createDataChangeEventElement(doc, path, null, operation);
- element.appendChild(node);
+ if (!ControllerContext.getInstance().isNodeMixin(path)) {
+ final Node node = createDataChangeEventElement(doc, path, operation);
+ element.appendChild(node);
+ }
}
}
- /**
- * Adds values from data to element.
- *
- * @param doc
- * {@link Document}
- * @param data
- * Map of {@link YangInstanceIdentifier} and {@link CompositeNode}.
- * @param element
- * {@link Element}
- * @param store
- * {@link Store}
- * @param operation
- * {@link Operation}
- */
- private void addValuesFromDataToElement(final Document doc, final Map<YangInstanceIdentifier, CompositeNode> data, final Element element,
- final Operation operation) {
- if (data == null || data.isEmpty()) {
- return;
- }
- for (final Entry<YangInstanceIdentifier, CompositeNode> entry : data.entrySet()) {
- final Node node = createDataChangeEventElement(doc, entry.getKey(), entry.getValue(), operation);
- element.appendChild(node);
- }
- }
/**
* Creates changed event element from data.
* {@link Document}
* @param path
* Path to data in data store.
- * @param data
- * {@link CompositeNode}
- * @param store
- * {@link Store}
* @param operation
* {@link Operation}
* @return {@link Node} node represented by changed event element.
*/
- private Node createDataChangeEventElement(final Document doc, final YangInstanceIdentifier path, final CompositeNode data,
- final Operation operation) {
+ private Node createDataChangeEventElement(final Document doc, final YangInstanceIdentifier path, final Operation operation) {
final Element dataChangeEventElement = doc.createElement("data-change-event");
final Element pathElement = doc.createElement("path");
addPathAsValueToElement(path, pathElement);
dataChangeEventElement.appendChild(pathElement);
- // Element storeElement = doc.createElement("store");
- // storeElement.setTextContent(store.value);
- // dataChangeEventElement.appendChild(storeElement);
-
final Element operationElement = doc.createElement("operation");
operationElement.setTextContent(operation.value);
dataChangeEventElement.appendChild(operationElement);
- if (data != null) {
- final Element dataElement = doc.createElement("data");
- final Node dataAnyXml = translateToXml(path, data);
- final Node adoptedNode = doc.adoptNode(dataAnyXml);
- dataElement.appendChild(adoptedNode);
- dataChangeEventElement.appendChild(dataElement);
- }
-
return dataChangeEventElement;
}
- /**
- * Translates {@link CompositeNode} data to XML format.
- *
- * @param path
- * Path to data in data store.
- * @param data
- * {@link CompositeNode}
- * @return Data in XML format.
- */
- private Node translateToXml(final YangInstanceIdentifier path, final CompositeNode data) {
- final DataNodeContainer schemaNode = ControllerContext.getInstance().getDataNodeContainerFor(path);
- if (schemaNode == null) {
- LOG.info(
- "Path '{}' contains node with unsupported type (supported type is Container or List) or some node was not found.",
- path);
- return null;
- }
- try {
- final Document xml = xmlMapper.write(data, schemaNode);
- return xml.getFirstChild();
- } catch (final UnsupportedDataTypeException e) {
- LOG.error("Error occured during translation of notification to XML.", e);
- return null;
- }
- }
/**
* Adds path as value to element.
private void addPathAsValueToElement(final YangInstanceIdentifier path, final Element element) {
// Map< key = namespace, value = prefix>
final Map<String, String> prefixes = new HashMap<>();
- final YangInstanceIdentifier instanceIdentifier = path;
+ final YangInstanceIdentifier normalizedPath = ControllerContext.getInstance().toXpathRepresentation(path);
final StringBuilder textContent = new StringBuilder();
// FIXME: BUG-1281: this is duplicated code from yangtools (BUG-1275)
- for (final PathArgument pathArgument : instanceIdentifier.getPathArguments()) {
+ for (final PathArgument pathArgument : normalizedPath.getPathArguments()) {
+ if (pathArgument instanceof YangInstanceIdentifier.AugmentationIdentifier) {
+ continue;
+ }
textContent.append("/");
writeIdentifierWithNamespacePrefix(element, textContent, pathArgument.getNodeType(), prefixes);
if (pathArgument instanceof NodeIdentifierWithPredicates) {