import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
+import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
+import java.util.StringJoiner;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
if (controllerDestination != null) {
Preconditions.checkArgument(controllerDestination.contains(":"), "Controller Destination needs to be in a following format <ip>:<port>");
- String[] parts = controllerDestination.split(Pattern.quote(":"));
+ final String[] parts = controllerDestination.split(Pattern.quote(":"));
Preconditions.checkArgument(Integer.parseInt(parts[1]) > 0, "Port =< 0");
}
for (final File file : files) {
final Matcher matcher = YANG_FILENAME_PATTERN.matcher(file.getName());
if (!matcher.matches()) {
- BufferedReader reader;
+ final BufferedReader reader;
try {
reader = new BufferedReader(new FileReader(file));
String line = reader.readLine();
while (!DATE_PATTERN.matcher(line).find()) {
line = reader.readLine();
}
- Matcher m = DATE_PATTERN.matcher(line);
+ final Matcher m = DATE_PATTERN.matcher(line);
if (m.find()) {
String moduleName = file.getAbsolutePath();
moduleName = moduleName.substring(0, moduleName.length() - 5);
}
final String revision = m.group(1);
- String correctName = moduleName + "@" + revision + ".yang";
- File correctNameFile = new File(correctName);
+ final String correctName = moduleName + "@" + revision + ".yang";
+ final File correctNameFile = new File(correctName);
file.renameTo(correctNameFile);
}
- } catch (IOException e) {
+ } catch (final IOException e) {
e.printStackTrace();
}
}
}
private String prepareMessage(final int openDevice, final String editContentString) {
- StringBuilder messageBuilder = new StringBuilder(editContentString);
+ final StringBuilder messageBuilder = new StringBuilder(editContentString);
if (editContentString.contains(HOST_KEY)) {
messageBuilder.replace(messageBuilder.indexOf(HOST_KEY), messageBuilder.indexOf(HOST_KEY) + HOST_KEY.length(), generateConfigsAddress);
return payloads;
}
- //TODO This may be more scalable enumerating parameters via reflection
@Override
public String toString() {
- StringBuffer params = new StringBuffer("TesttoolParameters{");
- params.append("edit-content='").append(editContent).append('\'');
- params.append(", async='").append(async).append('\'');
- params.append(", thread-amount='").append(threadAmount).append('\'');
- params.append(", throttle='").append(throttle).append('\'');
- params.append(", auth='").append(auth).append('\'');
- params.append(", controller-destination='").append(controllerDestination).append('\'');
- params.append(", schemas-dir='").append(schemasDir).append('\'');
- params.append(", devices-count='").append(deviceCount).append('\'');
- params.append(", devices-per-port='").append(devicesPerPort).append('\'');
- params.append(", starting-port='").append(startingPort).append('\'');
- params.append(", generate-config-connection-timeout='").append(generateConfigsTimeout).append('\'');
- params.append(", generate-config-address='").append(generateConfigsAddress).append('\'');
- params.append(", distro-folder='").append(distroFolder).append('\'');
- params.append(", generate-configs-batch-size='").append(generateConfigBatchSize).append('\'');
- params.append(", ssh='").append(ssh).append('\'');
- params.append(", exi='").append(exi).append('\'');
- params.append(", debug='").append(debug).append('\'');
- params.append(", notification-file='").append(notificationFile).append('\'');
- params.append(", md-sal='").append(mdSal).append('\'');
- params.append(", initial-config-xml-file='").append(initialConfigXMLFile).append('\'');
- params.append(", time-out='").append(timeOut).append('\'');
- params.append('}');
-
- return params.toString();
+ final List<Field> fields = Arrays.asList(this.getClass().getDeclaredFields());
+ final StringJoiner joiner = new StringJoiner(", \n", "TesttoolParameters{", "}\n");
+ fields.stream()
+ .filter(field -> field.getAnnotation(Arg.class) != null)
+ .map(this::getFieldString)
+ .forEach(joiner::add);
+ return joiner.toString();
+ }
+
+ private String getFieldString(final Field field) {
+ try {
+ return field.getName() + "='" + field.get(this) + "'";
+ } catch (final IllegalAccessException e) {
+ return field.getName() + "= UNKNOWN";
+ }
}
}
private ListenerRegistration<SchemaContextListener> listenerRegistration;
private static TransactionChainHandler transactionChainHandler;
private static DOMDataBroker dataBroker;
+ private static DOMMountPointServiceHandler mountPointServiceHandler;
@Override
public void onSessionInitiated(final ProviderSession session) {
final SchemaContextHandler schemaCtxHandler = new SchemaContextHandler();
this.listenerRegistration = schemaService.registerSchemaContextListener(schemaCtxHandler);
- final DOMMountPointServiceHandler domMountPointServiceHandler = new DOMMountPointServiceHandler(
+ RestConnectorProvider.mountPointServiceHandler = new DOMMountPointServiceHandler(
session.getService(DOMMountPointService.class));
RestConnectorProvider.dataBroker = session.getService(DOMDataBroker.class);
final DOMRpcService rpcService = session.getService(DOMRpcService.class);
final RpcServiceHandler rpcServiceHandler = new RpcServiceHandler(rpcService);
- wrapperServices.setHandlers(schemaCtxHandler, domMountPointServiceHandler,
+ wrapperServices.setHandlers(schemaCtxHandler, RestConnectorProvider.mountPointServiceHandler,
RestConnectorProvider.transactionChainHandler, brokerHandler, rpcServiceHandler);
}
);
}
+ /**
+ * Get current {@link DOMMountPointService} from {@link DOMMountPointServiceHandler}.
+ * @return {@link DOMMountPointService}
+ */
+ public static DOMMountPointService getMountPointService() {
+ return RestConnectorProvider.mountPointServiceHandler.get();
+ }
+
@Override
public Collection<ProviderFunctionality> getProviderFunctionality() {
return Collections.emptySet();
@Override
public NormalizedNodeContext invokeRpc(final String identifier, final NormalizedNodeContext payload,
- final UriInfo uriInfo) {
+ final UriInfo uriInfo) {
return this.delegRestconfInvokeOpsService.invokeRpc(identifier, payload, uriInfo);
}
}
public void setHandlers(final SchemaContextHandler schemaCtxHandler,
- final DOMMountPointServiceHandler domMountPointServiceHandler,
- final TransactionChainHandler transactionChainHandler, final DOMDataBrokerHandler domDataBrokerHandler,
- final RpcServiceHandler rpcServiceHandler) {
+ final DOMMountPointServiceHandler domMountPointServiceHandler,
+ final TransactionChainHandler transactionChainHandler,
+ final DOMDataBrokerHandler domDataBrokerHandler,
+ final RpcServiceHandler rpcServiceHandler) {
this.delegRestModService = new RestconfModulesServiceImpl(schemaCtxHandler, domMountPointServiceHandler);
this.delegRestOpsService = new RestconfOperationsServiceImpl(schemaCtxHandler, domMountPointServiceHandler);
this.delegRestSchService = new RestconfSchemaServiceImpl(schemaCtxHandler, domMountPointServiceHandler);
this.delegRestStrsService = new RestconfStreamsServiceImpl(schemaCtxHandler);
- this.delegRestconfDataService = new RestconfDataServiceImpl(schemaCtxHandler, transactionChainHandler);
+ this.delegRestconfDataService = new RestconfDataServiceImpl(schemaCtxHandler, transactionChainHandler,
+ domMountPointServiceHandler);
this.delegRestconfInvokeOpsService = new RestconfInvokeOperationsServiceImpl(rpcServiceHandler,
schemaCtxHandler);
this.delegRestconfSubscrService = new RestconfStreamsSubscriptionServiceImpl(domDataBrokerHandler);
package org.opendaylight.restconf.jersey.providers;
+import com.google.common.base.Optional;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Request;
import javax.ws.rs.core.UriInfo;
import org.opendaylight.netconf.sal.rest.api.RestconfConstants;
import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
import org.opendaylight.netconf.sal.restconf.impl.InstanceIdentifierContext;
+import org.opendaylight.restconf.RestConnectorProvider;
import org.opendaylight.restconf.utils.parser.ParserIdentifier;
public class AbstractIdentifierAwareJaxRsProvider {
}
protected InstanceIdentifierContext<?> getInstanceIdentifierContext() {
- return ParserIdentifier.toInstanceIdentifier(getIdentifier(),
- ControllerContext.getInstance().getGlobalSchema());
+ return ParserIdentifier.toInstanceIdentifier(
+ getIdentifier(),
+ ControllerContext.getInstance().getGlobalSchema(),
+ Optional.of(RestConnectorProvider.getMountPointService()));
}
protected UriInfo getUriInfo() {
*/
package org.opendaylight.restconf.rest.services.impl;
+import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import java.util.Collections;
import java.util.Set;
import javax.ws.rs.core.UriInfo;
import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
-import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
import org.opendaylight.netconf.sal.restconf.impl.InstanceIdentifierContext;
import org.opendaylight.netconf.sal.restconf.impl.NormalizedNodeContext;
import org.opendaylight.netconf.sal.restconf.impl.RestconfDocumentedException;
throw new RestconfDocumentedException(errMsg, ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
}
final SchemaContextRef schemaContextRef = new SchemaContextRef(this.schemaContextHandler.get());
- final InstanceIdentifierContext<?> mountPointIdentifier = ParserIdentifier.toInstanceIdentifier(identifier,
- schemaContextRef.get());
- final DOMMountPointService domMointPointService = this.domMountPointServiceHandler.get();
- final DOMMountPoint mountPoint = domMointPointService
- .getMountPoint(mountPointIdentifier.getInstanceIdentifier()).get();
+ final InstanceIdentifierContext<?> mountPointIdentifier = ParserIdentifier.toInstanceIdentifier(
+ identifier, schemaContextRef.get(), Optional.of(this.domMountPointServiceHandler.get()));
+ final DOMMountPoint mountPoint = mountPointIdentifier.getMountPoint();
return getModules(mountPoint.getSchemaContext().getModules(), schemaContextRef, mountPoint);
}
Preconditions.checkNotNull(identifier);
final SchemaContextRef schemaContextRef = new SchemaContextRef(this.schemaContextHandler.get());
final QName moduleQname = ParserIdentifier.makeQNameFromIdentifier(identifier);
- Module module = null;
+ final Module module;
DOMMountPoint mountPoint = null;
if (identifier.contains(RestconfConstants.MOUNT)) {
- final InstanceIdentifierContext<?> point = ParserIdentifier.toInstanceIdentifier(identifier,
- schemaContextRef.get());
- final DOMMountPointService domMointPointService = this.domMountPointServiceHandler.get();
- mountPoint = domMointPointService.getMountPoint(point.getInstanceIdentifier()).get();
+ // we only need to find mount point itself
+ final String mountPointPath = identifier.substring(
+ 0, identifier.indexOf(RestconfConstants.MOUNT) + RestconfConstants.MOUNT.length());
+ final InstanceIdentifierContext<?> mountPointContext = ParserIdentifier.toInstanceIdentifier(
+ mountPointPath, schemaContextRef.get(), Optional.of(this.domMountPointServiceHandler.get()));
+ mountPoint = mountPointContext.getMountPoint();
module = schemaContextRef.findModuleInMountPointByQName(mountPoint, moduleQname);
} else {
module = schemaContextRef.findModuleByQName(moduleQname);
*/
package org.opendaylight.restconf.rest.services.impl;
+import com.google.common.base.Optional;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
@Override
public NormalizedNodeContext getOperations(final String identifier, final UriInfo uriInfo) {
- Set<Module> modules = null;
- DOMMountPoint mountPoint = null;
+ final Set<Module> modules;
+ final DOMMountPoint mountPoint;
final SchemaContextRef ref = new SchemaContextRef(this.schemaContextHandler.get());
if (identifier.contains(RestconfConstants.MOUNT)) {
- final InstanceIdentifierContext<?> mountPointIdentifier = ParserIdentifier.toInstanceIdentifier(identifier,
- ref.get());
+ final InstanceIdentifierContext<?> mountPointIdentifier = ParserIdentifier.toInstanceIdentifier(
+ identifier, ref.get(), Optional.of(this.domMountPointServiceHandler.get()));
mountPoint = mountPointIdentifier.getMountPoint();
modules = ref.getModules(mountPoint);
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
+import javax.annotation.Nonnull;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
import org.opendaylight.netconf.sal.restconf.impl.InstanceIdentifierContext;
import org.opendaylight.netconf.sal.restconf.impl.RestconfError;
import org.opendaylight.restconf.RestConnectorProvider;
import org.opendaylight.restconf.common.references.SchemaContextRef;
+import org.opendaylight.restconf.handlers.DOMMountPointServiceHandler;
import org.opendaylight.restconf.handlers.SchemaContextHandler;
import org.opendaylight.restconf.handlers.TransactionChainHandler;
import org.opendaylight.restconf.restful.services.api.RestconfDataService;
private final SchemaContextHandler schemaContextHandler;
private final TransactionChainHandler transactionChainHandler;
+ private final DOMMountPointServiceHandler mountPointServiceHandler;
public RestconfDataServiceImpl(final SchemaContextHandler schemaContextHandler,
- final TransactionChainHandler transactionChainHandler) {
+ final TransactionChainHandler transactionChainHandler,
+ final DOMMountPointServiceHandler mountPointServiceHandler) {
this.schemaContextHandler = schemaContextHandler;
this.transactionChainHandler = transactionChainHandler;
+ this.mountPointServiceHandler = mountPointServiceHandler;
}
@Override
Preconditions.checkNotNull(identifier);
final SchemaContextRef schemaContextRef = new SchemaContextRef(this.schemaContextHandler.get());
- final InstanceIdentifierContext<?> instanceIdentifier = ParserIdentifier.toInstanceIdentifier(identifier,
- schemaContextRef.get());
+ final InstanceIdentifierContext<?> instanceIdentifier = ParserIdentifier.toInstanceIdentifier(
+ identifier, schemaContextRef.get(), Optional.of(this.mountPointServiceHandler.get()));
final DOMMountPoint mountPoint = instanceIdentifier.getMountPoint();
final String value = uriInfo.getQueryParameters().getFirst(RestconfDataServiceConstant.CONTENT);
- final DOMTransactionChain transaction;
+ final DOMTransactionChain transactionChain;
if (mountPoint == null) {
- transaction = this.transactionChainHandler.get();
+ transactionChain = this.transactionChainHandler.get();
} else {
- transaction = transactionOfMountPoint(mountPoint);
+ transactionChain = transactionChainOfMountPoint(mountPoint);
}
final TransactionVarsWrapper transactionNode = new TransactionVarsWrapper(instanceIdentifier, mountPoint,
- transaction);
+ transactionChain);
final NormalizedNode<?, ?> node = ReadDataTransactionUtil.readData(value, transactionNode);
if (node == null) {
throw new RestconfDocumentedException(
PutDataTransactionUtil.validateListKeysEqualityInPayloadAndUri(payload);
final DOMMountPoint mountPoint = payload.getInstanceIdentifierContext().getMountPoint();
- final DOMTransactionChain transaction;
+ final DOMTransactionChain transactionChain;
final SchemaContextRef ref;
if (mountPoint == null) {
- transaction = this.transactionChainHandler.get();
+ transactionChain = this.transactionChainHandler.get();
ref = new SchemaContextRef(this.schemaContextHandler.get());
} else {
- transaction = transactionOfMountPoint(mountPoint);
+ transactionChain = transactionChainOfMountPoint(mountPoint);
ref = new SchemaContextRef(mountPoint.getSchemaContext());
}
final TransactionVarsWrapper transactionNode = new TransactionVarsWrapper(
- payload.getInstanceIdentifierContext(), mountPoint, transaction);
+ payload.getInstanceIdentifierContext(), mountPoint, transactionChain);
return PutDataTransactionUtil.putData(payload, ref, transactionNode);
}
Preconditions.checkNotNull(payload);
final DOMMountPoint mountPoint = payload.getInstanceIdentifierContext().getMountPoint();
- final DOMTransactionChain transaction;
+ final DOMTransactionChain transactionChain;
final SchemaContextRef ref;
if (mountPoint == null) {
- transaction = this.transactionChainHandler.get();
+ transactionChain = this.transactionChainHandler.get();
ref = new SchemaContextRef(this.schemaContextHandler.get());
} else {
- transaction = transactionOfMountPoint(mountPoint);
+ transactionChain = transactionChainOfMountPoint(mountPoint);
ref = new SchemaContextRef(mountPoint.getSchemaContext());
}
final TransactionVarsWrapper transactionNode = new TransactionVarsWrapper(
- payload.getInstanceIdentifierContext(), mountPoint, transaction);
+ payload.getInstanceIdentifierContext(), mountPoint, transactionChain);
return PostDataTransactionUtil.postData(uriInfo, payload, transactionNode, ref);
}
@Override
public Response deleteData(final String identifier) {
final SchemaContextRef schemaContextRef = new SchemaContextRef(this.schemaContextHandler.get());
- final InstanceIdentifierContext<?> instanceIdentifier = ParserIdentifier.toInstanceIdentifier(identifier,
- schemaContextRef.get());
+ final InstanceIdentifierContext<?> instanceIdentifier = ParserIdentifier.toInstanceIdentifier(
+ identifier, schemaContextRef.get(), Optional.of(this.mountPointServiceHandler.get()));
final DOMMountPoint mountPoint = instanceIdentifier.getMountPoint();
- final DOMTransactionChain transaction;
+ final DOMTransactionChain transactionChain;
if (mountPoint == null) {
- transaction = this.transactionChainHandler.get();
+ transactionChain = this.transactionChainHandler.get();
} else {
- transaction = transactionOfMountPoint(mountPoint);
+ transactionChain = transactionChainOfMountPoint(mountPoint);
}
final TransactionVarsWrapper transactionNode = new TransactionVarsWrapper(instanceIdentifier, mountPoint,
- transaction);
+ transactionChain);
return DeleteDataTransactionUtil.deleteData(transactionNode);
}
Preconditions.checkNotNull(context);
final DOMMountPoint mountPoint = context.getInstanceIdentifierContext().getMountPoint();
- final DOMTransactionChain transaction;
+ final DOMTransactionChain transactionChain;
final SchemaContextRef ref;
if (mountPoint == null) {
- transaction = this.transactionChainHandler.get();
+ transactionChain = this.transactionChainHandler.get();
ref = new SchemaContextRef(this.schemaContextHandler.get());
} else {
- transaction = transactionOfMountPoint(mountPoint);
+ transactionChain = transactionChainOfMountPoint(mountPoint);
ref = new SchemaContextRef(mountPoint.getSchemaContext());
}
final TransactionVarsWrapper transactionNode = new TransactionVarsWrapper(
- context.getInstanceIdentifierContext(), mountPoint, transaction);
+ context.getInstanceIdentifierContext(), mountPoint, transactionChain);
return PatchDataTransactionUtil.patchData(context, transactionNode, ref);
}
/**
- * Prepare transaction to read data of mount point, if these data are
- * present.
+ * Prepare transaction chain to access data of mount point
* @param mountPoint
- * @return {@link DOMDataReadWriteTransaction}
+ * - mount point reference
+ * @return {@link DOMTransactionChain}
*/
- private static DOMTransactionChain transactionOfMountPoint(final DOMMountPoint mountPoint) {
+ private static DOMTransactionChain transactionChainOfMountPoint(@Nonnull final DOMMountPoint mountPoint) {
final Optional<DOMDataBroker> domDataBrokerService = mountPoint.getService(DOMDataBroker.class);
if (domDataBrokerService.isPresent()) {
return domDataBrokerService.get().createTransactionChain(RestConnectorProvider.transactionListener);
package org.opendaylight.restconf.restful.utils;
import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
import com.google.common.util.concurrent.CheckedFuture;
import java.util.Collection;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
import org.opendaylight.netconf.sal.restconf.impl.RestconfDocumentedException;
import org.opendaylight.netconf.sal.restconf.impl.RestconfError.ErrorType;
import org.opendaylight.restconf.restful.transaction.TransactionVarsWrapper;
import org.opendaylight.yangtools.yang.common.QNameModule;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
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.AugmentationNode;
import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
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.DataContainerNode;
import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
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.DataContainerNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeContainerBuilder;
import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
/**
* - {@link TransactionVarsWrapper} - wrapper for variables
* @return {@link NormalizedNode}
*/
- public static NormalizedNode<?, ?> readData(final String valueOfContent, final TransactionVarsWrapper transactionNode) {
+ public static @Nullable NormalizedNode<?, ?> readData(@Nullable final String valueOfContent,
+ @Nonnull final TransactionVarsWrapper transactionNode) {
final NormalizedNode<?, ?> data;
if (valueOfContent != null) {
switch (valueOfContent) {
data = readAllData(transactionNode);
break;
default:
- throw new RestconfDocumentedException("Bad querry parameter for content.", ErrorType.APPLICATION,
+ throw new RestconfDocumentedException("Bad query parameter for content.", ErrorType.APPLICATION,
ErrorTag.INVALID_VALUE);
}
} else {
* - {@link TransactionVarsWrapper} - wrapper for variables
* @return {@link NormalizedNode}
*/
- private static NormalizedNode<?, ?> readDataViaTransaction(final TransactionVarsWrapper transactionNode) {
- final CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> listenableFuture = transactionNode
- .getTransactionChain().newReadOnlyTransaction().read(transactionNode.getLogicalDatastoreType(),
- transactionNode.getInstanceIdentifier().getInstanceIdentifier());
- final NormalizedNodeFactory dataFactory = new NormalizedNodeFactory();
- FutureCallbackTx.addCallback(listenableFuture, RestconfDataServiceConstant.ReadData.READ_TYPE_TX,
- dataFactory);
- return dataFactory.build();
+ private static @Nullable NormalizedNode<?, ?> readDataViaTransaction(
+ @Nonnull final TransactionVarsWrapper transactionNode) {
+ final CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> listenableFuture = transactionNode
+ .getTransactionChain().newReadOnlyTransaction().read(transactionNode.getLogicalDatastoreType(),
+ transactionNode.getInstanceIdentifier().getInstanceIdentifier());
+ final NormalizedNodeFactory dataFactory = new NormalizedNodeFactory();
+ FutureCallbackTx.addCallback(listenableFuture, RestconfDataServiceConstant.ReadData.READ_TYPE_TX,
+ dataFactory);
+ return dataFactory.build();
}
/**
* - {@link TransactionVarsWrapper} - wrapper for variables
* @return {@link NormalizedNode}
*/
- private static NormalizedNode<?, ?> readAllData(final TransactionVarsWrapper transactionNode) {
+ private static @Nullable NormalizedNode<?, ?> readAllData(@Nonnull final TransactionVarsWrapper transactionNode) {
// PREPARE STATE DATA NODE
transactionNode.setLogicalDatastoreType(LogicalDatastoreType.OPERATIONAL);
final NormalizedNode<?, ?> stateDataNode = readDataViaTransaction(transactionNode);
* - data node of config data
* @return {@link NormalizedNode}
*/
- private static NormalizedNode<?, ?> mapNode(final NormalizedNode<?, ?> stateDataNode,
- final NormalizedNode<?, ?> configDataNode) {
+ private static @Nonnull NormalizedNode<?, ?> mapNode(@Nonnull final NormalizedNode<?, ?> stateDataNode,
+ @Nonnull final NormalizedNode<?, ?> configDataNode) {
validPossibilityOfMergeNodes(stateDataNode, configDataNode);
if (configDataNode instanceof RpcDefinition) {
return prepareRpcData(configDataNode, stateDataNode);
}
}
+ /**
+ * Valid of can be data merged together.
+ *
+ * @param stateDataNode
+ * - data node of state data
+ * @param configDataNode
+ * - data node of config data
+ */
+ private static void validPossibilityOfMergeNodes(@Nonnull final NormalizedNode<?, ?> stateDataNode,
+ @Nonnull final NormalizedNode<?, ?> configDataNode) {
+ final QNameModule moduleOfStateData = stateDataNode.getIdentifier().getNodeType().getModule();
+ final QNameModule moduleOfConfigData = configDataNode.getIdentifier().getNodeType().getModule();
+ if (moduleOfStateData != moduleOfConfigData) {
+ throw new RestconfDocumentedException("It is not possible to merge ");
+ }
+ }
+
/**
* Prepare and map data for rpc
*
* - data node of state data
* @return {@link NormalizedNode}
*/
- private static NormalizedNode<?, ?> prepareRpcData(final NormalizedNode<?, ?> configDataNode,
- final NormalizedNode<?, ?> stateDataNode) {
+ private static @Nonnull NormalizedNode<?, ?> prepareRpcData(@Nonnull final NormalizedNode<?, ?> configDataNode,
+ @Nonnull final NormalizedNode<?, ?> stateDataNode) {
final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> mapEntryBuilder = ImmutableNodes
.mapEntryBuilder();
mapEntryBuilder.withNodeIdentifier((NodeIdentifierWithPredicates) configDataNode.getIdentifier());
* @param mapEntryBuilder
* - builder for mapping data
*/
- private static void mapRpcDataNode(final NormalizedNode<?, ?> dataNode,
- final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> mapEntryBuilder) {
- for (final DataContainerChild<? extends PathArgument, ?> child : ((ContainerNode) dataNode).getValue()) {
- mapEntryBuilder.addChild(child);
- }
+ private static void mapRpcDataNode(@Nonnull final NormalizedNode<?, ?> dataNode,
+ @Nonnull final DataContainerNodeBuilder<
+ NodeIdentifierWithPredicates, MapEntryNode> mapEntryBuilder) {
+ ((ContainerNode) dataNode).getValue().forEach(mapEntryBuilder::addChild);
}
/**
* - data node of state data
* @return {@link NormalizedNode}
*/
- private static NormalizedNode<?, ?> prepareData(final NormalizedNode<?, ?> configDataNode,
- final NormalizedNode<?, ?> stateDataNode) {
+ private static @Nonnull NormalizedNode<?, ?> prepareData(@Nonnull final NormalizedNode<?, ?> configDataNode,
+ @Nonnull final NormalizedNode<?, ?> stateDataNode) {
+ if (configDataNode instanceof MapNode) {
+ final CollectionNodeBuilder<MapEntryNode, MapNode> builder = ImmutableNodes
+ .mapNodeBuilder().withNodeIdentifier(((MapNode) configDataNode).getIdentifier());
- if (configDataNode instanceof MapNode) { // part for lists mapping
- final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> mapEntryBuilder = ImmutableNodes
- .mapEntryBuilder();
- final NodeIdentifierWithPredicates node = ((MapNode) configDataNode).getValue().iterator().next().getIdentifier();
- mapEntryBuilder.withNodeIdentifier(node);
-
- // MAP CONFIG DATA
- mapDataNode((MapNode) configDataNode, mapEntryBuilder);
- // MAP STATE DATA
- mapDataNode((MapNode) stateDataNode, mapEntryBuilder);
- return ImmutableNodes.mapNodeBuilder(configDataNode.getNodeType()).addChild(mapEntryBuilder.build()).build();
- } else if (configDataNode instanceof ContainerNode) { // part for containers mapping
- final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> containerBuilder = Builders
- .containerBuilder((ContainerNode) configDataNode);
-
- // MAP CONFIG DATA
- mapCont(containerBuilder, ((ContainerNode) configDataNode).getValue());
- // MAP STATE DATA
- mapCont(containerBuilder, ((ContainerNode) stateDataNode).getValue());
- return containerBuilder.build();
+ mapValueToBuilder(
+ ((MapNode) configDataNode).getValue(), ((MapNode) stateDataNode).getValue(), builder);
+
+ return builder.build();
+ } else if (configDataNode instanceof MapEntryNode) {
+ final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> builder = ImmutableNodes
+ .mapEntryBuilder().withNodeIdentifier(((MapEntryNode) configDataNode).getIdentifier());
+
+ mapValueToBuilder(
+ ((MapEntryNode) configDataNode).getValue(), ((MapEntryNode) stateDataNode).getValue(), builder);
+
+ return builder.build();
+ } else if (configDataNode instanceof ContainerNode) {
+ final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> builder = Builders
+ .containerBuilder().withNodeIdentifier(((ContainerNode) configDataNode).getIdentifier());
+
+ mapValueToBuilder(
+ ((ContainerNode) configDataNode).getValue(), ((ContainerNode) stateDataNode).getValue(), builder);
+
+ return builder.build();
+ } else if (configDataNode instanceof AugmentationNode) {
+ final DataContainerNodeBuilder<AugmentationIdentifier, AugmentationNode> builder = Builders
+ .augmentationBuilder().withNodeIdentifier(((AugmentationNode) configDataNode).getIdentifier());
+
+ mapValueToBuilder(
+ ((AugmentationNode) configDataNode).getValue(), ((AugmentationNode) stateDataNode).getValue(), builder);
+
+ return builder.build();
+ } else if (configDataNode instanceof ChoiceNode) {
+ final DataContainerNodeBuilder<NodeIdentifier, ChoiceNode> builder = Builders
+ .choiceBuilder().withNodeIdentifier(((ChoiceNode) configDataNode).getIdentifier());
+
+ mapValueToBuilder(
+ ((ChoiceNode) configDataNode).getValue(), ((ChoiceNode) stateDataNode).getValue(), builder);
+
+ return builder.build();
+ } else if (configDataNode instanceof LeafNode) {
+ return ImmutableNodes.leafNode(configDataNode.getNodeType(), configDataNode.getValue());
} else {
throw new RestconfDocumentedException("Bad type of node.");
}
}
/**
- * Map data to builder
+ * Map value from container node to builder.
*
- * @param containerBuilder
- * - builder for mapping data
- * @param childs
- * - childs of data (container)
+ * @param configData
+ * - collection of config data nodes
+ * @param stateData
+ * - collection of state data nodes
+ * @param builder
+ * - builder
*/
- private static void mapCont(final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> containerBuilder,
- final Collection<DataContainerChild<? extends PathArgument, ?>> childs) {
- for (final DataContainerChild<? extends PathArgument, ?> child : childs) {
- containerBuilder.addChild(child);
- }
- }
+ private static <T extends NormalizedNode<? extends PathArgument, ?>> void mapValueToBuilder(
+ @Nonnull final Collection<T> configData,
+ @Nonnull final Collection<T> stateData,
+ @Nonnull final NormalizedNodeContainerBuilder<?, PathArgument, T, ?> builder) {
+ final Map<PathArgument, T> configMap = configData.stream().collect(
+ Collectors.toMap(NormalizedNode::getIdentifier, Function.identity()));
+ final Map<PathArgument, T> stateMap = stateData.stream().collect(
+ Collectors.toMap(NormalizedNode::getIdentifier, Function.identity()));
- /**
- * Map data to builder
- *
- * @param immutableData
- * - immutable data - {@link MapNode}
- * @param mapEntryBuilder
- * - builder for mapping data
- */
- private static void mapDataNode(final MapNode immutableData,
- final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> mapEntryBuilder) {
- for (final DataContainerChild<? extends PathArgument, ?> child : immutableData.getValue().iterator()
- .next().getValue()) {
- Preconditions.checkNotNull(child);
- if (child instanceof ContainerNode) {
- addChildToMap(ContainerNode.class, child, mapEntryBuilder);
- } else if (child instanceof AugmentationNode) {
- addChildToMap(AugmentationNode.class, child, mapEntryBuilder);
- } else if(child instanceof MapNode){
- final MapNode listNode = (MapNode) child;
- for (final MapEntryNode listChild : listNode.getValue()) {
- for (final DataContainerChild<? extends PathArgument, ?> entryChild : listChild.getValue()) {
- addChildToMap(MapEntryNode.class, entryChild, mapEntryBuilder);
- }
- }
- } else if (child instanceof ChoiceNode) {
- addChildToMap(ChoiceNode.class, child, mapEntryBuilder);
- } else if ((child instanceof LeafSetNode<?>) || (child instanceof LeafNode)) {
- mapEntryBuilder.addChild(child);
- }
+ // merge config and state data of children with different identifiers
+ mapDataToBuilder(configMap, stateMap, builder);
- }
+ // merge config and state data of children with the same identifiers
+ mergeDataToBuilder(configMap, stateMap, builder);
}
/**
- * Mapping child
+ * Map data with different identifiers to builder. Data with different identifiers can be just added
+ * as childs to parent node.
*
- * @param type
- * - type of data
- * @param child
- * - child to map
- * @param mapEntryBuilder
- * - builder for mapping child
+ * @param configMap
+ * - map of config data nodes
+ * @param stateMap
+ * - map of state data nodes
+ * @param builder
+ * - builder
*/
- private static <T extends DataContainerNode<? extends PathArgument>> void addChildToMap(final Class<T> type,
- final DataContainerChild<? extends PathArgument, ?> child,
- final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> mapEntryBuilder) {
- @SuppressWarnings("unchecked")
- final T node = (T) child;
- for (final DataContainerChild<? extends PathArgument, ?> childNode : node.getValue()) {
- mapEntryBuilder.addChild(childNode);
- }
+ private static <T extends NormalizedNode<? extends PathArgument, ?>> void mapDataToBuilder(
+ @Nonnull final Map<PathArgument, T> configMap,
+ @Nonnull final Map<PathArgument, T> stateMap,
+ @Nonnull final NormalizedNodeContainerBuilder<?, PathArgument, T, ?> builder) {
+ configMap.entrySet().stream().filter(x -> !stateMap.containsKey(x.getKey())).forEach(
+ y -> builder.addChild(y.getValue()));
+ stateMap.entrySet().stream().filter(x -> !configMap.containsKey(x.getKey())).forEach(
+ y -> builder.addChild(y.getValue()));
}
/**
- * Valid of can be data merged together.
+ * Map data with the same identifiers to builder. Data with the same identifiers cannot be just added but we need to
+ * go one level down with {@code prepareData} method.
*
- * @param stateDataNode
- * - data node of state data
- * @param configDataNode
- * - data node of config data
+ * @param configMap
+ * - immutable config data
+ * @param stateMap
+ * - immutable state data
+ * @param builder
+ * - builder
*/
- private static void validPossibilityOfMergeNodes(@Nonnull final NormalizedNode<?, ?> stateDataNode,
- @Nonnull final NormalizedNode<?, ?> configDataNode) {
- final QNameModule moduleOfStateData = stateDataNode.getIdentifier().getNodeType().getModule();
- final QNameModule moduleOfConfigData = configDataNode.getIdentifier().getNodeType().getModule();
- if (moduleOfStateData != moduleOfConfigData) {
- throw new RestconfDocumentedException("It is not possible to merge ");
- }
+ @SuppressWarnings("unchecked")
+ private static <T extends NormalizedNode<? extends PathArgument, ?>> void mergeDataToBuilder(
+ @Nonnull final Map<PathArgument, T> configMap,
+ @Nonnull final Map<PathArgument, T> stateMap,
+ @Nonnull final NormalizedNodeContainerBuilder<?, PathArgument, T, ?> builder) {
+ // it is enough to process only config data because operational contains the same data
+ configMap.entrySet().stream().filter(x -> stateMap.containsKey(x.getKey())).forEach(
+ y -> builder.addChild((T) prepareData(y.getValue(), stateMap.get(y.getKey()))));
}
}
*/
package org.opendaylight.restconf.utils.parser;
+import com.google.common.base.Optional;
import com.google.common.base.Splitter;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
-import javax.annotation.Nullable;
import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
import org.opendaylight.netconf.md.sal.rest.schema.SchemaExportContext;
}
/**
- * Make {@link InstanceIdentifierContext} from identifier.
+ * Make {@link InstanceIdentifierContext} from {@link String} identifier
+ * <br>
+ * For identifiers of data NOT behind mount points returned
+ * {@link InstanceIdentifierContext} is prepared with {@code null} reference of {@link DOMMountPoint} and with
+ * controller's {@link SchemaContext}.
+ * <br>
+ * For identifiers of data behind mount points returned
+ * {@link InstanceIdentifierContext} is prepared with reference of {@link DOMMountPoint} and its
+ * own {@link SchemaContext}.
*
* @param identifier
- * - path identifier
+ * - path identifier
* @param schemaContext
- * - {@link SchemaContext}
+ * - controller schema context
+ * @param mountPointService
+ * - mount point service
* @return {@link InstanceIdentifierContext}
*/
- public static InstanceIdentifierContext<?> toInstanceIdentifier(@Nullable final String identifier,
- final SchemaContext schemaContext) {
- final YangInstanceIdentifier deserialize;
+ public static InstanceIdentifierContext<?> toInstanceIdentifier(
+ final String identifier,
+ final SchemaContext schemaContext,
+ final Optional<DOMMountPointService> mountPointService) {
if (identifier != null && identifier.contains(RestconfConstants.MOUNT)) {
- final String mountPointId = identifier.substring(0, identifier.indexOf("/" + RestconfConstants.MOUNT));
- deserialize = IdentifierCodec.deserialize(mountPointId, schemaContext);
+ if (!mountPointService.isPresent()) {
+ throw new RestconfDocumentedException("Mount point service is not available");
+ }
+
+ final Iterator<String> pathsIt = Splitter.on("/" + RestconfConstants.MOUNT).split(identifier).iterator();
+
+ final String mountPointId = pathsIt.next();
+ final YangInstanceIdentifier mountYangInstanceIdentifier = IdentifierCodec.deserialize(
+ mountPointId, schemaContext);
+ final Optional<DOMMountPoint> mountPoint = mountPointService.get().getMountPoint(mountYangInstanceIdentifier);
+
+ if (!mountPoint.isPresent()) {
+ throw new RestconfDocumentedException(
+ "Mount point does not exist.", ErrorType.PROTOCOL, ErrorTag.DATA_MISSING);
+ }
+
+ final String pathId = pathsIt.next().replaceFirst("/", "");
+ final YangInstanceIdentifier pathYangInstanceIdentifier = IdentifierCodec.deserialize(
+ pathId, mountPoint.get().getSchemaContext());
+
+ final DataSchemaContextNode<?> child = DataSchemaContextTree.from(
+ mountPoint.get().getSchemaContext()).getChild(pathYangInstanceIdentifier);
+
+ return new InstanceIdentifierContext<SchemaNode>(
+ pathYangInstanceIdentifier, child.getDataSchemaNode(), mountPoint.get(),
+ mountPoint.get().getSchemaContext());
} else {
- deserialize = IdentifierCodec.deserialize(identifier, schemaContext);
+ final YangInstanceIdentifier deserialize = IdentifierCodec.deserialize(identifier, schemaContext);
+ final DataSchemaContextNode<?> child = DataSchemaContextTree.from(schemaContext).getChild(deserialize);
+
+ return new InstanceIdentifierContext<SchemaNode>(
+ deserialize, child.getDataSchemaNode(), null, schemaContext);
}
- final DataSchemaContextNode<?> child = DataSchemaContextTree.from(schemaContext).getChild(deserialize);
- return new InstanceIdentifierContext<SchemaNode>(deserialize, child.getDataSchemaNode(), null, schemaContext);
}
/**
pathBuilder.append(current);
}
final InstanceIdentifierContext<?> point = ParserIdentifier
- .toInstanceIdentifier(pathBuilder.toString(), schemaContext);
- final DOMMountPoint mountPoint = domMountPointService.getMountPoint(point.getInstanceIdentifier()).get();
+ .toInstanceIdentifier(pathBuilder.toString(), schemaContext, Optional.of(domMountPointService));
final String moduleName = RestconfValidation.validateAndGetModulName(componentIter);
final Date revision = RestconfValidation.validateAndGetRevision(componentIter);
- final Module module = mountPoint.getSchemaContext().findModuleByName(moduleName, revision);
- return new SchemaExportContext(mountPoint.getSchemaContext(), module);
+ final Module module = point.getMountPoint().getSchemaContext().findModuleByName(moduleName, revision);
+ return new SchemaExportContext(point.getMountPoint().getSchemaContext(), module);
}
}
}
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.controller.sal.rest.impl.test.providers;
+package org.opendaylight.restconf.jersey.providers;
import static org.junit.Assert.assertNotNull;
import static org.mockito.Mockito.mock;
import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
import org.opendaylight.netconf.sal.restconf.impl.NormalizedNodeContext;
import org.opendaylight.netconf.sal.restconf.impl.PATCHContext;
-import org.opendaylight.restconf.jersey.providers.AbstractIdentifierAwareJaxRsProvider;
+import org.opendaylight.restconf.RestConnectorProvider;
+import org.opendaylight.restconf.handlers.DOMMountPointServiceHandler;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-public abstract class Draft17AbstractBodyReaderTest {
+abstract class AbstractBodyReaderTest {
protected final static ControllerContext controllerContext = ControllerContext.getInstance();
protected final MediaType mediaType;
private static Field uriField;
private static Field requestField;
+ protected final static DOMMountPointServiceHandler mountPointServiceHandler = mock(
+ DOMMountPointServiceHandler.class);
- public Draft17AbstractBodyReaderTest() throws NoSuchFieldException,
- SecurityException {
+ AbstractBodyReaderTest() throws NoSuchFieldException, IllegalAccessException {
uriField = AbstractIdentifierAwareJaxRsProvider.class
.getDeclaredField("uriInfo");
uriField.setAccessible(true);
+
requestField = AbstractIdentifierAwareJaxRsProvider.class
.getDeclaredField("request");
requestField.setAccessible(true);
+
mediaType = getMediaType();
+
+ final Field mountPointServiceHandlerField = RestConnectorProvider.class.
+ getDeclaredField("mountPointServiceHandler");
+ mountPointServiceHandlerField.setAccessible(true);
+ mountPointServiceHandlerField.set(RestConnectorProvider.class, mountPointServiceHandler);
}
protected abstract MediaType getMediaType();
requestField.set(normalizedNodeProvider, request);
}
- protected static void checkMountPointNormalizedNodeContext(
- final NormalizedNodeContext nnContext) {
- checkNormalizedNodeContext(nnContext);
- assertNotNull(nnContext.getInstanceIdentifierContext().getMountPoint());
- }
-
protected static void checkNormalizedNodeContext(
final NormalizedNodeContext nnContext) {
assertNotNull(nnContext.getData());
assertNotNull(patchContext.getInstanceIdentifierContext().getSchemaContext());
assertNotNull(patchContext.getInstanceIdentifierContext().getSchemaNode());
}
+
+ protected static void checkPATCHContextMountPoint(final PATCHContext patchContext) {
+ checkPATCHContext(patchContext);
+ assertNotNull(patchContext.getInstanceIdentifierContext().getMountPoint());
+ assertNotNull(patchContext.getInstanceIdentifierContext().getMountPoint().getSchemaContext());
+ }
}
-/**
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+/*
+ * Copyright (c) 2016 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.rest.impl.test.providers;
+package org.opendaylight.restconf.jersey.providers;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import com.google.common.collect.Sets;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.InputStream;
import javax.ws.rs.core.MediaType;
import org.junit.BeforeClass;
import org.junit.Test;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
import org.opendaylight.controller.md.sal.rest.common.TestRestconfUtils;
+import org.opendaylight.controller.sal.rest.impl.test.providers.TestXmlBodyReader;
import org.opendaylight.netconf.sal.restconf.impl.NormalizedNodeContext;
-import org.opendaylight.restconf.jersey.providers.JsonNormalizedNodeBodyReader;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.common.QNameModule;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
-import com.google.common.collect.Sets;
-public class Draft17JsonBodyReaderTest extends Draft17AbstractBodyReaderTest {
+public class JsonBodyReaderTest extends AbstractBodyReaderTest {
private final JsonNormalizedNodeBodyReader jsonBodyReader;
private static SchemaContext schemaContext;
}
}
- public Draft17JsonBodyReaderTest() throws NoSuchFieldException, SecurityException {
+ public JsonBodyReaderTest() throws Exception {
super();
this.jsonBodyReader = new JsonNormalizedNodeBodyReader();
}
testFiles.addAll(TestRestconfUtils.loadFiles("/invoke-rpc"));
schemaContext = TestRestconfUtils.parseYangSources(testFiles);
controllerContext.setSchemas(schemaContext);
+ when(mountPointServiceHandler.get()).thenReturn(mock(DOMMountPointService.class));
}
@Test
final YangInstanceIdentifier dataII = YangInstanceIdentifier.of(dataSchemaNode.getQName());
final String uri = "instance-identifier-module:cont";
mockBodyReader(uri, this.jsonBodyReader, false);
- final InputStream inputStream = Draft17JsonBodyReaderTest.class
+ final InputStream inputStream = JsonBodyReaderTest.class
.getResourceAsStream("/instanceidentifier/json/jsondata.json");
final NormalizedNodeContext returnValue = this.jsonBodyReader.readFrom(null, null, null, this.mediaType, null,
inputStream);
final DataSchemaNode dataSchemaNodeOnPath = ((DataNodeContainer) dataSchemaNode).getDataChildByName(cont1QName);
final String uri = "instance-identifier-module:cont/cont1";
mockBodyReader(uri, this.jsonBodyReader, false);
- final InputStream inputStream = Draft17JsonBodyReaderTest.class
+ final InputStream inputStream = JsonBodyReaderTest.class
.getResourceAsStream("/instanceidentifier/json/json_sub_container.json");
final NormalizedNodeContext returnValue = this.jsonBodyReader.readFrom(null, null, null, this.mediaType, null,
inputStream);
final YangInstanceIdentifier dataII = YangInstanceIdentifier.of(dataSchemaNode.getQName()).node(cont1QName);
final String uri = "instance-identifier-module:cont";
mockBodyReader(uri, this.jsonBodyReader, true);
- final InputStream inputStream = Draft17JsonBodyReaderTest.class
+ final InputStream inputStream = JsonBodyReaderTest.class
.getResourceAsStream("/instanceidentifier/json/json_sub_container.json");
final NormalizedNodeContext returnValue = this.jsonBodyReader.readFrom(null, null, null, this.mediaType, null,
inputStream);
--- /dev/null
+/*
+ * Copyright (c) 2016 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.restconf.jersey.providers;
+
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import com.google.common.base.Optional;
+import java.io.InputStream;
+import javax.ws.rs.core.MediaType;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
+import org.opendaylight.controller.sal.rest.impl.test.providers.TestJsonBodyReader;
+import org.opendaylight.netconf.sal.restconf.impl.PATCHContext;
+import org.opendaylight.netconf.sal.restconf.impl.RestconfDocumentedException;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+public class JsonPATCHBodyReaderMountPointTest extends AbstractBodyReaderTest {
+
+ private final JsonToPATCHBodyReader jsonPATCHBodyReader;
+ private static SchemaContext schemaContext;
+ private static final String MOUNT_POINT = "instance-identifier-module:cont/yang-ext:mount/";
+
+ public JsonPATCHBodyReaderMountPointTest() throws Exception {
+ super();
+ jsonPATCHBodyReader = new JsonToPATCHBodyReader();
+ }
+
+ @Override
+ protected MediaType getMediaType() {
+ return new MediaType(APPLICATION_JSON, null);
+ }
+
+ @BeforeClass
+ public static void initialization() {
+ schemaContext = schemaContextLoader("/instanceidentifier/yang", schemaContext);
+
+ final DOMMountPointService mountPointService = mock(DOMMountPointService.class);
+ final DOMMountPoint mountPoint = mock(DOMMountPoint.class);
+
+ when(mountPointServiceHandler.get()).thenReturn(mountPointService);
+ when(mountPointService.getMountPoint(any(YangInstanceIdentifier.class))).thenReturn(Optional.of(mountPoint));
+ when(mountPoint.getSchemaContext()).thenReturn(schemaContext);
+
+ controllerContext.setSchemas(schemaContext);
+ }
+
+ @Test
+ public void modulePATCHDataTest() throws Exception {
+ final String uri = MOUNT_POINT + "instance-identifier-patch-module:patch-cont/my-list1=leaf1";
+ mockBodyReader(uri, jsonPATCHBodyReader, false);
+
+ final InputStream inputStream = TestJsonBodyReader.class
+ .getResourceAsStream("/instanceidentifier/json/jsonPATCHdata.json");
+
+ final PATCHContext returnValue = jsonPATCHBodyReader
+ .readFrom(null, null, null, mediaType, null, inputStream);
+ checkPATCHContextMountPoint(returnValue);
+ }
+
+ /**
+ * Test of successful PATCH consisting of create and delete PATCH operations.
+ */
+ @Test
+ public void modulePATCHCreateAndDeleteTest() throws Exception {
+ final String uri = MOUNT_POINT + "instance-identifier-patch-module:patch-cont/my-list1=leaf1";
+ mockBodyReader(uri, jsonPATCHBodyReader, false);
+
+ final InputStream inputStream = TestJsonBodyReader.class
+ .getResourceAsStream("/instanceidentifier/json/jsonPATCHdataCreateAndDelete.json");
+
+ final PATCHContext returnValue = jsonPATCHBodyReader
+ .readFrom(null, null, null, mediaType, null, inputStream);
+ checkPATCHContextMountPoint(returnValue);
+ }
+
+ /**
+ * Test trying to use PATCH create operation which requires value without value. Test should fail with
+ * {@link RestconfDocumentedException} with error code 400.
+ */
+ @Test
+ public void modulePATCHValueMissingNegativeTest() throws Exception {
+ final String uri = MOUNT_POINT + "instance-identifier-patch-module:patch-cont/my-list1=leaf1";
+ mockBodyReader(uri, jsonPATCHBodyReader, false);
+
+ final InputStream inputStream = TestJsonBodyReader.class
+ .getResourceAsStream("/instanceidentifier/json/jsonPATCHdataValueMissing.json");
+
+ try {
+ jsonPATCHBodyReader.readFrom(null, null, null, mediaType, null, inputStream);
+ fail("Test should return error 400 due to missing value node when attempt to invoke create operation");
+ } catch (final RestconfDocumentedException e) {
+ assertEquals("Error code 400 expected", 400, e.getErrors().get(0).getErrorTag().getStatusCode());
+ }
+ }
+
+ /**
+ * Test trying to use value with PATCH delete operation which does not support value. Test should fail with
+ * {@link RestconfDocumentedException} with error code 400.
+ */
+ @Test
+ public void modulePATCHValueNotSupportedNegativeTest() throws Exception {
+ final String uri = MOUNT_POINT + "instance-identifier-patch-module:patch-cont/my-list1=leaf1";
+ mockBodyReader(uri, jsonPATCHBodyReader, false);
+
+ final InputStream inputStream = TestJsonBodyReader.class
+ .getResourceAsStream("/instanceidentifier/json/jsonPATCHdataValueNotSupported.json");
+
+ try {
+ jsonPATCHBodyReader.readFrom(null, null, null, mediaType, null, inputStream);
+ fail("Test should return error 400 due to present value node when attempt to invoke delete operation");
+ } catch (final RestconfDocumentedException e) {
+ assertEquals("Error code 400 expected", 400, e.getErrors().get(0).getErrorTag().getStatusCode());
+ }
+ }
+
+ /**
+ * Test using PATCH when target is completely specified in request URI and thus target leaf contains only '/' sign.
+ */
+ @Test
+ public void modulePATCHCompleteTargetInURITest() throws Exception {
+ final String uri = MOUNT_POINT + "instance-identifier-patch-module:patch-cont";
+ mockBodyReader(uri, jsonPATCHBodyReader, false);
+
+ final InputStream inputStream = TestJsonBodyReader.class
+ .getResourceAsStream("/instanceidentifier/json/jsonPATCHdataCompleteTargetInURI.json");
+
+ final PATCHContext returnValue = jsonPATCHBodyReader
+ .readFrom(null, null, null, mediaType, null, inputStream);
+ checkPATCHContextMountPoint(returnValue);
+ }
+
+ /**
+ * Test of Yang PATCH merge operation on list. Test consists of two edit operations - replace and merge.
+ */
+ @Test
+ public void modulePATCHMergeOperationOnListTest() throws Exception {
+ final String uri = MOUNT_POINT + "instance-identifier-patch-module:patch-cont/my-list1=leaf1";
+ mockBodyReader(uri, jsonPATCHBodyReader, false);
+
+ final InputStream inputStream = TestJsonBodyReader.class
+ .getResourceAsStream("/instanceidentifier/json/jsonPATCHMergeOperationOnList.json");
+
+ final PATCHContext returnValue = jsonPATCHBodyReader
+ .readFrom(null, null, null, mediaType, null, inputStream);
+ checkPATCHContextMountPoint(returnValue);
+ }
+
+ /**
+ * Test of Yang PATCH merge operation on container. Test consists of two edit operations - create and merge.
+ */
+ @Test
+ public void modulePATCHMergeOperationOnContainerTest() throws Exception {
+ final String uri = MOUNT_POINT + "instance-identifier-patch-module:patch-cont";
+ mockBodyReader(uri, jsonPATCHBodyReader, false);
+
+ final InputStream inputStream = TestJsonBodyReader.class
+ .getResourceAsStream("/instanceidentifier/json/jsonPATCHMergeOperationOnContainer.json");
+
+ final PATCHContext returnValue = jsonPATCHBodyReader
+ .readFrom(null, null, null, mediaType, null, inputStream);
+ checkPATCHContextMountPoint(returnValue);
+ }
+}
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.controller.sal.rest.impl.test.providers;
+package org.opendaylight.restconf.jersey.providers;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
import java.io.InputStream;
import javax.ws.rs.core.MediaType;
import org.junit.BeforeClass;
import org.junit.Test;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
+import org.opendaylight.controller.sal.rest.impl.test.providers.TestJsonBodyReader;
import org.opendaylight.netconf.sal.restconf.impl.PATCHContext;
import org.opendaylight.netconf.sal.restconf.impl.RestconfDocumentedException;
-import org.opendaylight.restconf.jersey.providers.JsonToPATCHBodyReader;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-public class TestDraft17JsonPATCHBodyReader extends Draft17AbstractBodyReaderTest {
+public class JsonPATCHBodyReaderTest extends AbstractBodyReaderTest {
private final JsonToPATCHBodyReader jsonPATCHBodyReader;
private static SchemaContext schemaContext;
- public TestDraft17JsonPATCHBodyReader() throws NoSuchFieldException, SecurityException {
+ public JsonPATCHBodyReaderTest() throws Exception {
super();
jsonPATCHBodyReader = new JsonToPATCHBodyReader();
}
@BeforeClass
public static void initialization() {
schemaContext = schemaContextLoader("/instanceidentifier/yang", schemaContext);
+ when(mountPointServiceHandler.get()).thenReturn(mock(DOMMountPointService.class));
controllerContext.setSchemas(schemaContext);
}
-/**
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+/*
+ * Copyright (c) 2016 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.rest.impl.test.providers;
+package org.opendaylight.restconf.jersey.providers;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import com.google.common.collect.Sets;
import java.io.File;
import java.io.InputStream;
import java.net.URI;
import javax.ws.rs.core.MediaType;
import org.junit.BeforeClass;
import org.junit.Test;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
import org.opendaylight.controller.md.sal.rest.common.TestRestconfUtils;
import org.opendaylight.netconf.sal.restconf.impl.NormalizedNodeContext;
-import org.opendaylight.restconf.jersey.providers.XmlNormalizedNodeBodyReader;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.common.QNameModule;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
import org.opendaylight.yangtools.yang.model.api.Module;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import com.google.common.collect.Sets;
-public class Draft17XmlBodyReaderTest extends Draft17AbstractBodyReaderTest {
+public class XmlBodyReaderTest extends AbstractBodyReaderTest {
private final XmlNormalizedNodeBodyReader xmlBodyReader;
private static SchemaContext schemaContext;
}
}
- public Draft17XmlBodyReaderTest() throws NoSuchFieldException, SecurityException {
+ public XmlBodyReaderTest() throws Exception {
super();
this.xmlBodyReader = new XmlNormalizedNodeBodyReader();
}
testFiles.addAll(TestRestconfUtils.loadFiles("/invoke-rpc"));
schemaContext = TestRestconfUtils.parseYangSources(testFiles);
controllerContext.setSchemas(schemaContext);
+ when(mountPointServiceHandler.get()).thenReturn(mock(DOMMountPointService.class));
}
@Test
final YangInstanceIdentifier dataII = YangInstanceIdentifier.of(dataSchemaNode.getQName());
final String uri = "instance-identifier-module:cont";
mockBodyReader(uri, this.xmlBodyReader, false);
- final InputStream inputStream = Draft17XmlBodyReaderTest.class
+ final InputStream inputStream = XmlBodyReaderTest.class
.getResourceAsStream("/instanceidentifier/xml/xmldata.xml");
final NormalizedNodeContext returnValue = this.xmlBodyReader.readFrom(null, null, null, this.mediaType, null,
inputStream);
final DataSchemaNode dataSchemaNodeOnPath = ((DataNodeContainer) dataSchemaNode).getDataChildByName(cont1QName);
final String uri = "instance-identifier-module:cont/cont1";
mockBodyReader(uri, this.xmlBodyReader, false);
- final InputStream inputStream = Draft17XmlBodyReaderTest.class
+ final InputStream inputStream = XmlBodyReaderTest.class
.getResourceAsStream("/instanceidentifier/xml/xml_sub_container.xml");
final NormalizedNodeContext returnValue = this.xmlBodyReader.readFrom(null, null, null, this.mediaType, null,
inputStream);
final YangInstanceIdentifier dataII = YangInstanceIdentifier.of(dataSchemaNode.getQName()).node(cont1QName);
final String uri = "instance-identifier-module:cont";
mockBodyReader(uri, this.xmlBodyReader, true);
- final InputStream inputStream = Draft17XmlBodyReaderTest.class
+ final InputStream inputStream = XmlBodyReaderTest.class
.getResourceAsStream("/instanceidentifier/xml/xml_sub_container.xml");
final NormalizedNodeContext returnValue = this.xmlBodyReader.readFrom(null, null, null, this.mediaType, null,
inputStream);
.node(contAugmentQName);
final String uri = "instance-identifier-module:cont";
mockBodyReader(uri, this.xmlBodyReader, true);
- final InputStream inputStream = Draft17XmlBodyReaderTest.class
+ final InputStream inputStream = XmlBodyReaderTest.class
.getResourceAsStream("/instanceidentifier/xml/xml_augment_container.xml");
final NormalizedNodeContext returnValue = this.xmlBodyReader.readFrom(null, null, null, this.mediaType, null,
inputStream);
.node(augmentChoice1QName).node(augChoice2II).node(augmentChoice2QName).node(containerQName);
final String uri = "instance-identifier-module:cont";
mockBodyReader(uri, this.xmlBodyReader, true);
- final InputStream inputStream = Draft17XmlBodyReaderTest.class
+ final InputStream inputStream = XmlBodyReaderTest.class
.getResourceAsStream("/instanceidentifier/xml/xml_augment_choice_container.xml");
final NormalizedNodeContext returnValue = this.xmlBodyReader.readFrom(null, null, null, this.mediaType, null,
inputStream);
@Test
public void findFooContainerUsingNamespaceTest() throws Exception {
mockBodyReader("", this.xmlBodyReader, true);
- final InputStream inputStream = Draft17XmlBodyReaderTest.class
+ final InputStream inputStream = XmlBodyReaderTest.class
.getResourceAsStream("/instanceidentifier/xml/xmlDataFindFooContainer.xml");
final NormalizedNodeContext returnValue = this.xmlBodyReader.readFrom(null, null, null, this.mediaType, null,
inputStream);
@Test
public void findBarContainerUsingNamespaceTest() throws Exception {
mockBodyReader("", this.xmlBodyReader, true);
- final InputStream inputStream = Draft17XmlBodyReaderTest.class
+ final InputStream inputStream = XmlBodyReaderTest.class
.getResourceAsStream("/instanceidentifier/xml/xmlDataFindBarContainer.xml");
final NormalizedNodeContext returnValue = this.xmlBodyReader.readFrom(null, null, null, this.mediaType, null,
inputStream);
--- /dev/null
+/*
+ * Copyright (c) 2016 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.restconf.jersey.providers;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import com.google.common.base.Optional;
+import java.io.InputStream;
+import javax.ws.rs.core.MediaType;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
+import org.opendaylight.controller.sal.rest.impl.test.providers.TestXmlBodyReader;
+import org.opendaylight.netconf.sal.restconf.impl.PATCHContext;
+import org.opendaylight.netconf.sal.restconf.impl.RestconfDocumentedException;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+public class XmlPATCHBodyReaderMountPointTest extends AbstractBodyReaderTest {
+
+ private final XmlToPATCHBodyReader xmlPATCHBodyReader;
+ private static SchemaContext schemaContext;
+ private static final String MOUNT_POINT = "instance-identifier-module:cont/yang-ext:mount/";
+
+ public XmlPATCHBodyReaderMountPointTest() throws Exception {
+ super();
+ xmlPATCHBodyReader = new XmlToPATCHBodyReader();
+ }
+
+ @Override
+ protected MediaType getMediaType() {
+ return new MediaType(MediaType.APPLICATION_XML, null);
+ }
+
+ @BeforeClass
+ public static void initialization() {
+ schemaContext = schemaContextLoader("/instanceidentifier/yang", schemaContext);
+
+ final DOMMountPointService mountPointService = mock(DOMMountPointService.class);
+ final DOMMountPoint mountPoint = mock(DOMMountPoint.class);
+
+ when(mountPointServiceHandler.get()).thenReturn(mountPointService);
+ when(mountPointService.getMountPoint(any(YangInstanceIdentifier.class))).thenReturn(Optional.of(mountPoint));
+ when(mountPoint.getSchemaContext()).thenReturn(schemaContext);
+
+ controllerContext.setSchemas(schemaContext);
+ }
+
+ @Test
+ public void moduleDataTest() throws Exception {
+ final String uri = MOUNT_POINT + "instance-identifier-patch-module:patch-cont/my-list1=leaf1";
+ mockBodyReader(uri, xmlPATCHBodyReader, false);
+ final InputStream inputStream = TestXmlBodyReader.class
+ .getResourceAsStream("/instanceidentifier/xml/xmlPATCHdata.xml");
+ final PATCHContext returnValue = xmlPATCHBodyReader
+ .readFrom(null, null, null, mediaType, null, inputStream);
+ checkPATCHContextMountPoint(returnValue);
+ }
+
+ /**
+ * Test trying to use PATCH create operation which requires value without value. Error code 400 should be returned.
+ */
+ @Test
+ public void moduleDataValueMissingNegativeTest() throws Exception {
+ final String uri = MOUNT_POINT + "instance-identifier-patch-module:patch-cont/my-list1=leaf1";
+ mockBodyReader(uri, xmlPATCHBodyReader, false);
+ final InputStream inputStream = TestXmlBodyReader.class
+ .getResourceAsStream("/instanceidentifier/xml/xmlPATCHdataValueMissing.xml");
+ try {
+ xmlPATCHBodyReader.readFrom(null, null, null, mediaType, null, inputStream);
+ fail("Test should return error 400 due to missing value node when attempt to invoke create operation");
+ } catch (final RestconfDocumentedException e) {
+ assertEquals("Error code 400 expected", 400, e.getErrors().get(0).getErrorTag().getStatusCode());
+ }
+ }
+
+ /**
+ * Test trying to use value with PATCH delete operation which does not support value. Error code 400 should be
+ * returned.
+ */
+ @Test
+ public void moduleDataNotValueNotSupportedNegativeTest() throws Exception {
+ final String uri = MOUNT_POINT + "instance-identifier-patch-module:patch-cont/my-list1=leaf1";
+ mockBodyReader(uri, xmlPATCHBodyReader, false);
+ final InputStream inputStream = TestXmlBodyReader.class
+ .getResourceAsStream("/instanceidentifier/xml/xmlPATCHdataValueNotSupported.xml");
+ try {
+ xmlPATCHBodyReader.readFrom(null, null, null, mediaType, null, inputStream);
+ fail("Test should return error 400 due to present value node when attempt to invoke delete operation");
+ } catch (final RestconfDocumentedException e) {
+ assertEquals("Error code 400 expected", 400, e.getErrors().get(0).getErrorTag().getStatusCode());
+ }
+ }
+
+
+ /**
+ * Test of Yang PATCH with absolute target path.
+ */
+ @Test
+ public void moduleDataAbsoluteTargetPathTest() throws Exception {
+ final String uri = MOUNT_POINT;
+ mockBodyReader(uri, xmlPATCHBodyReader, false);
+ final InputStream inputStream = TestXmlBodyReader.class
+ .getResourceAsStream("/instanceidentifier/xml/xmlPATCHdataAbsoluteTargetPath.xml");
+ final PATCHContext returnValue = xmlPATCHBodyReader
+ .readFrom(null, null, null, mediaType, null, inputStream);
+ checkPATCHContextMountPoint(returnValue);
+ }
+
+ /**
+ * Test using PATCH when target is completely specified in request URI and thus target leaf contains only '/' sign.
+ */
+ @Test
+ public void modulePATCHCompleteTargetInURITest() throws Exception {
+ final String uri = MOUNT_POINT + "instance-identifier-patch-module:patch-cont";
+ mockBodyReader(uri, xmlPATCHBodyReader, false);
+ final InputStream inputStream = TestXmlBodyReader.class
+ .getResourceAsStream("/instanceidentifier/xml/xmlPATCHdataCompleteTargetInURI.xml");
+ final PATCHContext returnValue = xmlPATCHBodyReader
+ .readFrom(null, null, null, mediaType, null, inputStream);
+ checkPATCHContextMountPoint(returnValue);
+ }
+
+ /**
+ * Test of Yang PATCH merge operation on list. Test consists of two edit operations - replace and merge.
+ */
+ @Test
+ public void moduleDataMergeOperationOnListTest() throws Exception {
+ final String uri = MOUNT_POINT + "instance-identifier-patch-module:patch-cont/my-list1=leaf1";
+ mockBodyReader(uri, xmlPATCHBodyReader, false);
+ final InputStream inputStream = TestXmlBodyReader.class
+ .getResourceAsStream("/instanceidentifier/xml/xmlPATCHdataMergeOperationOnList.xml");
+ final PATCHContext returnValue = xmlPATCHBodyReader
+ .readFrom(null, null, null, mediaType, null, inputStream);
+ checkPATCHContextMountPoint(returnValue);
+ }
+
+ /**
+ * Test of Yang PATCH merge operation on container. Test consists of two edit operations - create and merge.
+ */
+ @Test
+ public void moduleDataMergeOperationOnContainerTest() throws Exception {
+ final String uri = MOUNT_POINT + "instance-identifier-patch-module:patch-cont";
+ mockBodyReader(uri, xmlPATCHBodyReader, false);
+ final InputStream inputStream = TestXmlBodyReader.class
+ .getResourceAsStream("/instanceidentifier/xml/xmlPATCHdataMergeOperationOnContainer.xml");
+ final PATCHContext returnValue = xmlPATCHBodyReader
+ .readFrom(null, null, null, mediaType, null, inputStream);
+ checkPATCHContextMountPoint(returnValue);
+ }
+}
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.controller.sal.rest.impl.test.providers;
+package org.opendaylight.restconf.jersey.providers;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
import java.io.InputStream;
import javax.ws.rs.core.MediaType;
import org.junit.BeforeClass;
import org.junit.Test;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
+import org.opendaylight.controller.sal.rest.impl.test.providers.TestXmlBodyReader;
import org.opendaylight.netconf.sal.restconf.impl.PATCHContext;
import org.opendaylight.netconf.sal.restconf.impl.RestconfDocumentedException;
-import org.opendaylight.restconf.jersey.providers.XmlToPATCHBodyReader;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-public class TestDraft17XmlPATCHBodyReader extends Draft17AbstractBodyReaderTest {
+public class XmlPATCHBodyReaderTest extends AbstractBodyReaderTest {
private final XmlToPATCHBodyReader xmlPATCHBodyReader;
private static SchemaContext schemaContext;
- public TestDraft17XmlPATCHBodyReader() throws NoSuchFieldException, SecurityException {
+ public XmlPATCHBodyReaderTest() throws Exception {
super();
xmlPATCHBodyReader = new XmlToPATCHBodyReader();
}
}
@BeforeClass
- public static void initialization() throws NoSuchFieldException, SecurityException {
+ public static void initialization() {
schemaContext = schemaContextLoader("/instanceidentifier/yang", schemaContext);
+ when(mountPointServiceHandler.get()).thenReturn(mock(DOMMountPointService.class));
controllerContext.setSchemas(schemaContext);
}
/**
* Negative test of getting specific module supported by the mount point when specified mount point is not found
* (it is not registered in <code>DOMMountPointService</code>). Test is expected to fail with
- * <code>IllegalStateException</code>.
+ * <code>RestconfDocumentedException</code> and error type, error tag and error status code are compared to
+ * expected values.
*/
@Test
public void getModuleMountPointNotFoundNegativeTest() throws Exception {
final RestconfModulesService modulesService = setupNormalMountPoint();
// make test
- this.thrown.expect(IllegalStateException.class);
- modulesService.getModule(TEST_MODULE_BEHIND_NOT_REGISTERED_MOUNT_POINT, null);
+ try {
+ modulesService.getModule(TEST_MODULE_BEHIND_NOT_REGISTERED_MOUNT_POINT, null);
+ fail("Test should fail due to missing mount point");
+ } catch (final RestconfDocumentedException e) {
+ assertEquals("Error type is not correct", ErrorType.PROTOCOL, e.getErrors().get(0).getErrorType());
+ assertEquals("Error tag is not correct", ErrorTag.DATA_MISSING, e.getErrors().get(0).getErrorTag());
+ assertEquals("Error code is not correct", 404, e.getErrors().get(0).getErrorTag().getStatusCode());
+ }
}
/**
* Negative test of getting all modules supported by the mount point when specified mount point is not found (it
* is not registered in <code>DOMMountPointService</code>). Test is expected to fail with
- * <code>IllegalStateException</code>.
+ * <code>RestconfDocumentedException</code> and error type, error tag and error status code are compared to
+ * expected values.
*/
@Test
public void getModulesMountPointNotFoundNegativeTest() throws Exception {
final RestconfModulesService modulesService = setupNormalMountPoint();
// make test
- this.thrown.expect(IllegalStateException.class);
- modulesService.getModules(NOT_REGISTERED_MOUNT_POINT, null);
+ try {
+ modulesService.getModules(NOT_REGISTERED_MOUNT_POINT, null);
+ fail("Test should fail due to missing mount point");
+ } catch (final RestconfDocumentedException e) {
+ assertEquals("Error type is not correct", ErrorType.PROTOCOL, e.getErrors().get(0).getErrorType());
+ assertEquals("Error tag is not correct", ErrorTag.DATA_MISSING, e.getErrors().get(0).getErrorTag());
+ assertEquals("Error code is not correct", 404, e.getErrors().get(0).getErrorTag().getStatusCode());
+ }
}
}
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
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.DOMMountPointService;
import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
import org.opendaylight.controller.md.sal.rest.common.TestRestconfUtils;
import org.opendaylight.netconf.sal.restconf.impl.InstanceIdentifierContext;
import org.opendaylight.netconf.sal.restconf.impl.RestconfDocumentedException;
import org.opendaylight.restconf.RestConnectorProvider;
import org.opendaylight.restconf.common.references.SchemaContextRef;
+import org.opendaylight.restconf.handlers.DOMMountPointServiceHandler;
import org.opendaylight.restconf.handlers.SchemaContextHandler;
import org.opendaylight.restconf.handlers.TransactionChainHandler;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
import org.opendaylight.yangtools.yang.data.util.DataSchemaContextTree;
import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
private static final String PATH_FOR_NEW_SCHEMA_CONTEXT = "/jukebox";
private ContainerNode buildBaseCont;
+ private ContainerNode buildBaseContConfig;
+ private ContainerNode buildBaseContOperational;
private SchemaContextRef contextRef;
private YangInstanceIdentifier iidBase;
private DataSchemaNode schemaNode;
private RestconfDataServiceImpl dataService;
private QName baseQName;
- private QName containerQname;
+ private QName containerPlayerQname;
private QName leafQname;
- private ContainerNode buildBaseContToReplace;
+ private ContainerNode buildPlayerCont;
+ private ContainerNode buildLibraryCont;
+ private MapNode buildPlaylistList;
@Mock
private TransactionChainHandler transactionChainHandler;
private DOMDataReadOnlyTransaction read;
@Mock
private DOMDataWriteTransaction write;
+ @Mock
+ private DOMMountPointServiceHandler mountPointServiceHandler;
+ @Mock
+ private DOMMountPointService mountPointService;
+ @Mock
+ private DOMMountPoint mountPoint;
+ @Mock
+ private DOMDataBroker mountDataBroker;
+ @Mock
+ private DOMTransactionChain transactionChain;
@Before
public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+
baseQName = QName.create("http://example.com/ns/example-jukebox", "2015-04-04", "jukebox");
- containerQname = QName.create(baseQName, "player");
+ containerPlayerQname = QName.create(baseQName, "player");
leafQname = QName.create(baseQName, "gap");
- LeafNode buildLeaf = Builders.leafBuilder()
+
+ final QName containerLibraryQName = QName.create(baseQName, "library");
+ final QName listPlaylistQName = QName.create(baseQName, "playlist");
+
+ final LeafNode buildLeaf = Builders.leafBuilder()
.withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(leafQname))
.withValue(0.2)
.build();
- ContainerNode buildPlayerCont = Builders.containerBuilder()
- .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(containerQname))
+ buildPlayerCont = Builders.containerBuilder()
+ .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(containerPlayerQname))
.withChild(buildLeaf)
.build();
+
+ buildLibraryCont = Builders.containerBuilder()
+ .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(containerLibraryQName))
+ .build();
+
+ buildPlaylistList = Builders.mapBuilder()
+ .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(listPlaylistQName))
+ .build();
+
buildBaseCont = Builders.containerBuilder()
.withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(baseQName))
.withChild(buildPlayerCont)
.build();
- buildLeaf = Builders.leafBuilder()
- .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(leafQname))
- .withValue(0.5)
- .build();
- buildPlayerCont = Builders.containerBuilder()
- .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(containerQname))
- .withChild(buildLeaf)
+
+ // config contains one child the same as in operational and one additional
+ buildBaseContConfig = Builders.containerBuilder()
+ .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(baseQName))
+ .withChild(buildPlayerCont)
+ .withChild(buildLibraryCont)
.build();
- buildBaseContToReplace = Builders.containerBuilder()
+
+ // operational contains one child the same as in config and one additional
+ buildBaseContOperational = Builders.containerBuilder()
.withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(baseQName))
.withChild(buildPlayerCont)
+ .withChild(buildPlaylistList)
.build();
+
iidBase = YangInstanceIdentifier.builder()
.node(baseQName)
.build();
contextRef = new SchemaContextRef(TestRestconfUtils.loadSchemaContext(PATH_FOR_NEW_SCHEMA_CONTEXT));
schemaNode = DataSchemaContextTree.from(contextRef.get()).getChild(iidBase).getDataSchemaNode();
- MockitoAnnotations.initMocks(this);
+
final SchemaContextHandler schemaContextHandler = new SchemaContextHandler();
schemaContextHandler.onGlobalContextUpdated(contextRef.get());
- dataService = new RestconfDataServiceImpl(schemaContextHandler, transactionChainHandler);
+ dataService = new RestconfDataServiceImpl(schemaContextHandler, transactionChainHandler, mountPointServiceHandler);
doReturn(domTransactionChain).when(transactionChainHandler).get();
doReturn(read).when(domTransactionChain).newReadOnlyTransaction();
doReturn(readWrite).when(domTransactionChain).newReadWriteTransaction();
doReturn(write).when(domTransactionChain).newWriteOnlyTransaction();
+ doReturn(mountPointService).when(mountPointServiceHandler).get();
+ doReturn(Optional.of(mountPoint)).when(mountPointService).getMountPoint(any(YangInstanceIdentifier.class));
+ doReturn(contextRef.get()).when(mountPoint).getSchemaContext();
+ doReturn(Optional.of(mountDataBroker)).when(mountPoint).getService(DOMDataBroker.class);
+ doReturn(transactionChain).when(mountDataBroker).createTransactionChain(any(TransactionChainListener.class));
+ doReturn(read).when(transactionChain).newReadOnlyTransaction();
+ doReturn(readWrite).when(transactionChain).newReadWriteTransaction();
}
@Test
assertEquals(buildBaseCont, ((NormalizedNodeContext) response.getEntity()).getData());
}
+ /**
+ * Test read data from mount point when both {@link LogicalDatastoreType#CONFIGURATION} and
+ * {@link LogicalDatastoreType#OPERATIONAL} contains the same data and some additional data to be merged.
+ */
+ @Test
+ public void testReadDataMountPoint() {
+ doReturn(new MultivaluedHashMap<String, String>()).when(uriInfo).getQueryParameters();
+ doReturn(Futures.immediateCheckedFuture(Optional.of(buildBaseContConfig))).when(read)
+ .read(LogicalDatastoreType.CONFIGURATION, iidBase);
+ doReturn(Futures.immediateCheckedFuture(Optional.of(buildBaseContOperational))).when(read)
+ .read(LogicalDatastoreType.OPERATIONAL, iidBase);
+
+ final Response response = dataService.readData(
+ "example-jukebox:jukebox/yang-ext:mount/example-jukebox:jukebox", uriInfo);
+
+ assertNotNull(response);
+ assertEquals(200, response.getStatus());
+
+ // response must contain all child nodes from config and operational containers merged in one container
+ final NormalizedNode<?, ?> data = ((NormalizedNodeContext) response.getEntity()).getData();
+ assertTrue(data instanceof ContainerNode);
+ assertEquals(3, ((ContainerNode) data).getValue().size());
+ assertTrue(((ContainerNode) data).getChild(buildPlayerCont.getIdentifier()).isPresent());
+ assertTrue(((ContainerNode) data).getChild(buildLibraryCont.getIdentifier()).isPresent());
+ assertTrue(((ContainerNode) data).getChild(buildPlaylistList.getIdentifier()).isPresent());
+ }
+
@Test(expected = RestconfDocumentedException.class)
public void testReadDataNoData() {
doReturn(new MultivaluedHashMap<String, String>()).when(uriInfo).getQueryParameters();
iidBase);
doReturn(Futures.immediateCheckedFuture(Optional.absent())).when(read).read(LogicalDatastoreType.OPERATIONAL,
iidBase);
- final Response response = dataService.readData("example-jukebox:jukebox", uriInfo);
+ dataService.readData("example-jukebox:jukebox", uriInfo);
}
@Test
assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
}
+ /**
+ * Test of deleting data on mount point
+ */
+ @Test
+ public void testDeleteDataMountPoint() {
+ doNothing().when(readWrite).delete(LogicalDatastoreType.CONFIGURATION, iidBase);
+ doReturn(Futures.immediateCheckedFuture(null)).when(readWrite).submit();
+ doReturn(Futures.immediateCheckedFuture(true)).when(readWrite).exists(LogicalDatastoreType.CONFIGURATION, iidBase);
+ final Response response = dataService.deleteData("example-jukebox:jukebox/yang-ext:mount/example-jukebox:jukebox");
+ assertNotNull(response);
+ assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
+ }
+
@Test
public void testPatchData() throws Exception {
final InstanceIdentifierContext<? extends SchemaNode> iidContext = new InstanceIdentifierContext<>(iidBase, schemaNode, null, contextRef.get());
final List<PATCHEntity> entity = new ArrayList<>();
final YangInstanceIdentifier iidleaf = YangInstanceIdentifier.builder(iidBase)
- .node(containerQname)
+ .node(containerPlayerQname)
.node(leafQname)
.build();
entity.add(new PATCHEntity("create data", "CREATE", iidBase, buildBaseCont));
- entity.add(new PATCHEntity("replace data", "REPLACE", iidBase, buildBaseContToReplace));
+ entity.add(new PATCHEntity("replace data", "REPLACE", iidBase, buildBaseCont));
entity.add(new PATCHEntity("delete data", "DELETE", iidleaf));
final PATCHContext patch = new PATCHContext(iidContext, entity, "test patch id");
assertEquals("replace data", status.getEditCollection().get(1).getEditId());
}
+ @Test
+ public void testPatchDataMountPoint() throws Exception {
+ final InstanceIdentifierContext<? extends SchemaNode> iidContext = new InstanceIdentifierContext<>(
+ iidBase, schemaNode, mountPoint, contextRef.get());
+ final List<PATCHEntity> entity = new ArrayList<>();
+ final YangInstanceIdentifier iidleaf = YangInstanceIdentifier.builder(iidBase)
+ .node(containerPlayerQname)
+ .node(leafQname)
+ .build();
+ entity.add(new PATCHEntity("create data", "CREATE", iidBase, buildBaseCont));
+ entity.add(new PATCHEntity("replace data", "REPLACE", iidBase, buildBaseCont));
+ entity.add(new PATCHEntity("delete data", "DELETE", iidleaf));
+ final PATCHContext patch = new PATCHContext(iidContext, entity, "test patch id");
+
+ doReturn(Futures.immediateCheckedFuture(Optional.of(buildBaseCont))).when(read)
+ .read(LogicalDatastoreType.CONFIGURATION, iidBase);
+ doNothing().when(write).put(LogicalDatastoreType.CONFIGURATION, iidBase, buildBaseCont);
+ doReturn(Futures.immediateCheckedFuture(null)).when(write).submit();
+ doNothing().when(readWrite).delete(LogicalDatastoreType.CONFIGURATION, iidleaf);
+ doReturn(Futures.immediateCheckedFuture(null)).when(readWrite).submit();
+ doReturn(Futures.immediateCheckedFuture(false)).when(readWrite).exists(LogicalDatastoreType.CONFIGURATION, iidBase);
+ doReturn(Futures.immediateCheckedFuture(true)).when(readWrite).exists(LogicalDatastoreType.CONFIGURATION, iidleaf);
+
+ final PATCHStatusContext status = dataService.patchData(patch, uriInfo);
+ assertTrue(status.isOk());
+ assertEquals(3, status.getEditCollection().size());
+ assertNull(status.getGlobalErrors());
+ }
+
@Test
public void testPatchDataDeleteNotExist() throws Exception {
final Field handler = RestConnectorProvider.class.getDeclaredField("transactionChainHandler");
final InstanceIdentifierContext<? extends SchemaNode> iidContext = new InstanceIdentifierContext<>(iidBase, schemaNode, null, contextRef.get());
final List<PATCHEntity> entity = new ArrayList<>();
final YangInstanceIdentifier iidleaf = YangInstanceIdentifier.builder(iidBase)
- .node(containerQname)
+ .node(containerPlayerQname)
.node(leafQname)
.build();
entity.add(new PATCHEntity("create data", "CREATE", iidBase, buildBaseCont));
final String errorMessage = status.getEditCollection().get(2).getEditErrors().get(0).getErrorMessage();
assertEquals("Data does not exist", errorMessage);
}
-
}
\ No newline at end of file
import org.opendaylight.netconf.sal.restconf.impl.InstanceIdentifierContext;
import org.opendaylight.netconf.sal.restconf.impl.RestconfDocumentedException;
import org.opendaylight.netconf.sal.restconf.impl.RestconfError;
+import org.opendaylight.netconf.sal.restconf.impl.RestconfError.ErrorTag;
+import org.opendaylight.netconf.sal.restconf.impl.RestconfError.ErrorType;
import org.opendaylight.restconf.utils.RestconfConstants;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil;
* Unit tests for {@link ParserIdentifier}
*/
public class ParserIdentifierTest {
- // mount point identifier + expected result
+ // mount point identifier
private static final String MOUNT_POINT_IDENT =
"mount-point:mount-container/point-number" + "/" + RestconfConstants.MOUNT;
- private static final String MOUNT_POINT_IDENT_RESULT =
- "/(mount:point?revision=2016-06-02)mount-container/point-number";
-
// invalid mount point identifier
private static final String INVALID_MOUNT_POINT_IDENT =
"mount-point:point-number" + "/" + RestconfConstants.MOUNT;
// schema context with test modules
private SchemaContext schemaContext;
+ // contains the same modules but it is different object (it can be compared with equals)
+ private SchemaContext schemaContextOnMountPoint;
private static final String TEST_MODULE_NAME = "test-module";
private static final String TEST_MODULE_REVISION = "2016-06-02";
private DOMMountPointService mountPointService;
// mock mount point and mount point service
- @Mock DOMMountPoint mockMountPoint;
- @Mock DOMMountPointService mockMountPointService;
+ @Mock
+ private DOMMountPoint mockMountPoint;
+ @Mock
+ private DOMMountPointService mockMountPointService;
@Rule
public final ExpectedException thrown = ExpectedException.none();
public void setup() throws Exception {
MockitoAnnotations.initMocks(this);
schemaContext = TestRestconfUtils.loadSchemaContext("/parser-identifier");
+ schemaContextOnMountPoint = TestRestconfUtils.loadSchemaContext("/parser-identifier");
// create and register mount point
mountPoint = SimpleDOMMountPoint.create(
.node(QName.create("mount:point", "2016-06-02", "point-number"))
.build(),
ImmutableClassToInstanceMap.copyOf(Maps.newHashMap()),
- schemaContext
+ schemaContextOnMountPoint
);
mountPointService = new DOMMountPointServiceImpl();
@Test
public void toInstanceIdentifierTest() {
final InstanceIdentifierContext<?> context = ParserIdentifier.toInstanceIdentifier(
- TEST_IDENT, schemaContext);
+ TEST_IDENT, schemaContext, Optional.absent());
assertEquals("Returned not expected identifier",
TEST_IDENT_RESULT, context .getInstanceIdentifier().toString());
@Test
public void toInstanceIdentifierOtherModulesTest() {
final InstanceIdentifierContext<?> context = ParserIdentifier.toInstanceIdentifier(
- TEST_IDENT_OTHERS, schemaContext);
+ TEST_IDENT_OTHERS, schemaContext, Optional.absent());
assertEquals("Returned not expected identifier",
TEST_IDENT_OTHERS_RESULT, context.getInstanceIdentifier().toString());
@Test
public void toInstanceIdentifierMountPointTest() {
final InstanceIdentifierContext<?> context = ParserIdentifier.toInstanceIdentifier(
- MOUNT_POINT_IDENT, schemaContext);
+ MOUNT_POINT_IDENT + "/" + TEST_IDENT, schemaContext, Optional.of(mountPointService));
assertEquals("Returned not expected identifier",
- MOUNT_POINT_IDENT_RESULT, context.getInstanceIdentifier().toString());
+ TEST_IDENT_RESULT.toString(), context.getInstanceIdentifier().toString());
+
+ assertEquals("Mount point not found",
+ mountPoint, context.getMountPoint());
+
+ assertEquals("Schema context from mount point expected",
+ schemaContextOnMountPoint, context.getSchemaContext());
}
/**
*/
@Test
public void toInstanceIdentifierNullIdentifierTest() {
- final InstanceIdentifierContext<?> context = ParserIdentifier.toInstanceIdentifier(null, schemaContext);
+ final InstanceIdentifierContext<?> context = ParserIdentifier.toInstanceIdentifier(
+ null, schemaContext, Optional.absent());
assertEquals("Returned not expected identifier",
YangInstanceIdentifier.EMPTY, context.getInstanceIdentifier());
}
@Test
public void toInstanceIdentifierNullSchemaContextNegativeTest() {
thrown.expect(NullPointerException.class);
- ParserIdentifier.toInstanceIdentifier(TEST_IDENT, null);
+ ParserIdentifier.toInstanceIdentifier(TEST_IDENT, null, Optional.absent());
}
/**
*/
@Test
public void toInstanceIdentifierEmptyIdentifierTest() {
- final InstanceIdentifierContext<?> context = ParserIdentifier.toInstanceIdentifier("", schemaContext);
- assertEquals("Returned not expected identifier",
- YangInstanceIdentifier.EMPTY, context.getInstanceIdentifier());
- }
-
- /**
- * Api path can be empty. <code>YangInstanceIdentifier.EMPTY</code> is expected to be returned.
- * Test when identifier contains {@link RestconfConstants#MOUNT}.
- */
- @Test
- public void toInstanceIdentifierEmptyIdentifierMountPointTest() {
final InstanceIdentifierContext<?> context = ParserIdentifier.toInstanceIdentifier(
- "" + "/" + RestconfConstants.MOUNT, schemaContext);
+ "", schemaContext, Optional.absent());
assertEquals("Returned not expected identifier",
YangInstanceIdentifier.EMPTY, context.getInstanceIdentifier());
}
@Test
public void toInstanceIdentifierInvalidIdentifierNegativeTest() {
thrown.expect(IllegalArgumentException.class);
- ParserIdentifier.toInstanceIdentifier(INVALID_TEST_IDENT, schemaContext);
+ ParserIdentifier.toInstanceIdentifier(INVALID_TEST_IDENT, schemaContext, Optional.absent());
}
/**
@Test
public void toInstanceIdentifierMountPointInvalidIdentifierNegativeTest() {
thrown.expect(IllegalArgumentException.class);
- ParserIdentifier.toInstanceIdentifier(INVALID_MOUNT_POINT_IDENT, schemaContext);
+ ParserIdentifier.toInstanceIdentifier(INVALID_MOUNT_POINT_IDENT, schemaContext, Optional.of(mountPointService));
+ }
+
+ /**
+ * Negative test when <code>DOMMountPoint</code> cannot be found. Test is expected to fail with
+ * <code>RestconfDocumentedException</code> error type, error tag and error status code are
+ * compared to expected values.
+ */
+ @Test
+ public void toInstanceIdentifierMissingMountPointNegativeTest() {
+ try {
+ ParserIdentifier.toInstanceIdentifier(
+ "" + "/" + RestconfConstants.MOUNT, schemaContext, Optional.of(mountPointService));
+ fail("Test should fail due to missing mount point");
+ } catch (final RestconfDocumentedException e) {
+ assertEquals("Not expected error type",
+ RestconfError.ErrorType.PROTOCOL, e.getErrors().get(0).getErrorType());
+ assertEquals("Not expected error tag",
+ ErrorTag.DATA_MISSING, e.getErrors().get(0).getErrorTag());
+ assertEquals("Not expected error status code",
+ 404, e.getErrors().get(0).getErrorTag().getStatusCode());
+ }
+ }
+
+ /**
+ * Negative test when <code>{@link DOMMountPointService}</code> is absent. Test is expected to fail with
+ * <code>RestconfDocumentedException</code> error type, error tag and error status code are
+ * compared to expected values.
+ */
+ @Test
+ public void toInstanceIdentifierMissingMountPointServiceNegativeTest() {
+ try {
+ ParserIdentifier.toInstanceIdentifier(RestconfConstants.MOUNT, schemaContext, Optional.absent());
+ fail("Test should fail due to absent mount point service");
+ } catch (final RestconfDocumentedException e) {
+ assertEquals("Not expected error type",
+ ErrorType.APPLICATION, e.getErrors().get(0).getErrorType());
+ assertEquals("Not expected error tag",
+ ErrorTag.OPERATION_FAILED, e.getErrors().get(0).getErrorTag());
+ assertEquals("Not expected error status code",
+ 500, e.getErrors().get(0).getErrorTag().getStatusCode());
+ }
}
/**