--- /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.handlers;
+
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
+
+/**
+ * Implementation of {@link RpcServiceHandler}
+ *
+ */
+public class RpcServiceHandler implements Handler<DOMRpcService> {
+
+ private final DOMRpcService rpcService;
+
+ public RpcServiceHandler(final DOMRpcService rpcService) {
+ this.rpcService = rpcService;
+ }
+
+ @Override
+ public DOMRpcService get() {
+ return this.rpcService;
+ }
+
+
+}
package org.opendaylight.restconf.restful.services.impl;
import javax.ws.rs.core.UriInfo;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
+import org.opendaylight.netconf.sal.restconf.impl.InstanceIdentifierContext;
import org.opendaylight.netconf.sal.restconf.impl.NormalizedNodeContext;
+import org.opendaylight.restconf.common.references.SchemaContextRef;
+import org.opendaylight.restconf.handlers.RpcServiceHandler;
+import org.opendaylight.restconf.handlers.SchemaContextHandler;
import org.opendaylight.restconf.restful.services.api.RestconfInvokeOperationsService;
+import org.opendaylight.restconf.restful.utils.RestconfInvokeOperationsUtil;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+/**
+ * Implementation of {@link RestconfInvokeOperationsService}
+ *
+ */
public class RestconfInvokeOperationsServiceImpl implements RestconfInvokeOperationsService {
+ private RpcServiceHandler rpcServiceHandler;
+ private SchemaContextHandler schemaContextHandler;
+
@Override
public NormalizedNodeContext invokeRpc(final String identifier, final NormalizedNodeContext payload, final UriInfo uriInfo) {
- throw new UnsupportedOperationException("Not yet impemented.");
+ final SchemaPath schemaPath = payload.getInstanceIdentifierContext().getSchemaNode().getPath();
+ final DOMMountPoint mountPoint = payload.getInstanceIdentifierContext().getMountPoint();
+ DOMRpcResult response;
+ SchemaContextRef schemaContextRef;
+ if (mountPoint == null) {
+ response = RestconfInvokeOperationsUtil.invokeRpc(payload.getData(), schemaPath, this.rpcServiceHandler);
+ schemaContextRef = new SchemaContextRef(this.schemaContextHandler.get());
+ } else {
+ response = RestconfInvokeOperationsUtil.invokeRpcViaMountPoint(mountPoint, payload.getData(), schemaPath);
+ schemaContextRef = new SchemaContextRef(mountPoint.getSchemaContext());
+ }
+ final DOMRpcResult result = RestconfInvokeOperationsUtil.checkResponse(response);
+
+ RpcDefinition resultNodeSchema = null;
+ final NormalizedNode<?, ?> resultData = result.getResult();
+ if ((result != null) && (result.getResult() != null)) {
+ resultNodeSchema = (RpcDefinition) payload.getInstanceIdentifierContext().getSchemaNode();
+ }
+ return new NormalizedNodeContext(new InstanceIdentifierContext<RpcDefinition>(null, resultNodeSchema,
+ mountPoint, schemaContextRef.get()), resultData);
}
}
final CheckedFuture<Void, TransactionCommitFailedException> future = submitData(
transactionNode.getTransaction(), transactionNode.getInstanceIdentifier().getInstanceIdentifier());
final ResponseFactory response = new ResponseFactory();
- FutureCallbackTx.addCallback(future, transactionNode.getTransaction(),
- RestconfDataServiceConstant.DeleteData.DELETE_TX_TYPE, response);
+ FutureCallbackTx.addCallback(future, RestconfDataServiceConstant.DeleteData.DELETE_TX_TYPE, response);
return response.build();
}
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import javax.annotation.Nullable;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.netconf.sal.restconf.impl.RestconfDocumentedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
*
* @param listenableFuture
* - future object
- * @param transaction
- * - transaction used for read of future object
* @param txType
* - type of operation (READ, POST, PUT, DELETE)
* @param dataFactory
* - factory setting result
*/
- static <T, X extends Exception> void addCallback(final CheckedFuture<T, X> listenableFuture,
- final AsyncTransaction<YangInstanceIdentifier, NormalizedNode<?, ?>> transaction, final String txType,
+ static <T, X extends Exception> void addCallback(final CheckedFuture<T, X> listenableFuture, final String txType,
final FutureDataFactory<T> dataFactory) {
Futures.addCallback(listenableFuture, new FutureCallback<T>() {
@Override
public void onFailure(final Throwable t) {
- handlingLoggerAndValues(t, txType, transaction, null, null);
+ handlingLoggerAndValues(t, txType, null, null);
}
@Override
public void onSuccess(final T result) {
- handlingLoggerAndValues(null, txType, transaction, result, dataFactory);
+ handlingLoggerAndValues(null, txType, result, dataFactory);
}
});
* - exception - if callback is onFailure
* @param txType
* - type of operation (READ, POST, PUT, DELETE)
- * @param transaction
- * - transaction used for read of future object
- * @param optionalNN
- * - result - if callback is on Success
+ * @param result
+ * - result of future - if callback is on Success
* @param dataFactory
* - setter for result - in callback is onSuccess
*/
protected static <T> void handlingLoggerAndValues(@Nullable final Throwable t, final String txType,
- final AsyncTransaction<YangInstanceIdentifier, NormalizedNode<?, ?>> transaction,
final T result, final FutureDataFactory<T> dataFactory) {
if (t != null) {
- LOG.info("Transaction({}) {} FAILED!", txType, transaction.getIdentifier(), t);
- throw new IllegalStateException(" Transaction(" + txType + ") not committed correctly", t);
+ LOG.info("Transaction({}) FAILED!", txType, t);
+ throw new RestconfDocumentedException(" Transaction(" + txType + ") not committed correctly", t);
} else {
- LOG.trace("Transaction({}) {} SUCCESSFUL!", txType, transaction.getIdentifier());
+ LOG.trace("Transaction({}) SUCCESSFUL!", txType);
dataFactory.setResult(result);
}
}
final ResponseFactory dataFactory = new ResponseFactory(
ReadDataTransactionUtil.readData(RestconfDataServiceConstant.ReadData.CONFIG, transactionNode),
location);
- FutureCallbackTx.addCallback(future, transactionNode.getTransaction(),
- RestconfDataServiceConstant.PostData.POST_TX_TYPE, dataFactory);
+ FutureCallbackTx.addCallback(future, RestconfDataServiceConstant.PostData.POST_TX_TYPE, dataFactory);
return dataFactory.build();
}
ReadDataTransactionUtil.readData(RestconfDataServiceConstant.ReadData.CONFIG, transactionNode));
final CheckedFuture<Void, TransactionCommitFailedException> submitData = submitData(path, schemaCtxRef.get(),
transactionNode.getTransaction(), payload.getData());
- FutureCallbackTx.addCallback(submitData, transactionNode.getTransaction(),
- RestconfDataServiceConstant.PutData.PUT_TX_TYPE, responseFactory);
+ FutureCallbackTx.addCallback(submitData, RestconfDataServiceConstant.PutData.PUT_TX_TYPE, responseFactory);
return responseFactory.build();
}
.getTransaction().read(transactionNode.getLogicalDatastoreType(),
transactionNode.getInstanceIdentifier().getInstanceIdentifier());
final NormalizedNodeFactory dataFactory = new NormalizedNodeFactory();
- FutureCallbackTx.addCallback(listenableFuture, transactionNode.getTransaction(),
- RestconfDataServiceConstant.ReadData.READ_TYPE_TX, dataFactory);
+ FutureCallbackTx.addCallback(listenableFuture, RestconfDataServiceConstant.ReadData.READ_TYPE_TX,
+ dataFactory);
return dataFactory.build();
} else {
return readAllData(transactionNode);
--- /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.restful.utils;
+
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.CheckedFuture;
+import java.util.concurrent.CancellationException;
+import javax.ws.rs.core.Response.Status;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcException;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
+import org.opendaylight.netconf.sal.restconf.impl.RestconfDocumentedException;
+import org.opendaylight.netconf.sal.restconf.impl.RestconfError.ErrorTag;
+import org.opendaylight.netconf.sal.restconf.impl.RestconfError.ErrorType;
+import org.opendaylight.restconf.handlers.RpcServiceHandler;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Util class for rpc
+ *
+ */
+public class RestconfInvokeOperationsUtil {
+
+ private static final Logger LOG = LoggerFactory.getLogger(RestconfInvokeOperationsUtil.class);
+
+ private RestconfInvokeOperationsUtil() {
+ throw new UnsupportedOperationException("Util class");
+ }
+
+ /**
+ * Invoking rpc via mount point
+ *
+ * @param mountPoint
+ * - mount point
+ * @param data
+ * - input data
+ * @param schemaPath
+ * - schema path of data
+ * @return {@link CheckedFuture}
+ */
+ public static DOMRpcResult invokeRpcViaMountPoint(final DOMMountPoint mountPoint, final NormalizedNode<?, ?> data,
+ final SchemaPath schemaPath) {
+ final Optional<DOMRpcService> mountPointService = mountPoint.getService(DOMRpcService.class);
+ if (mountPointService.isPresent()) {
+ final CheckedFuture<DOMRpcResult, DOMRpcException> rpc = mountPointService.get().invokeRpc(schemaPath,
+ data);
+ return prepareResult(rpc);
+ }
+ final String errmsg = "RPC service is missing.";
+ LOG.debug(errmsg);
+ throw new RestconfDocumentedException(errmsg);
+ }
+
+ /**
+ * Invoke rpc
+ *
+ * @param data
+ * - input data
+ * @param schemaPath
+ * - schema path of data
+ * @param rpcServiceHandler
+ * - rpc service handler to invoke rpc
+ * @return {@link CheckedFuture}
+ */
+ public static DOMRpcResult invokeRpc(final NormalizedNode<?, ?> data, final SchemaPath schemaPath,
+ final RpcServiceHandler rpcServiceHandler) {
+ final DOMRpcService rpcService = rpcServiceHandler.get();
+ if (rpcService == null) {
+ throw new RestconfDocumentedException(Status.SERVICE_UNAVAILABLE);
+ }
+
+ final CheckedFuture<DOMRpcResult, DOMRpcException> rpc = rpcService.invokeRpc(schemaPath, data);
+ return prepareResult(rpc);
+ }
+
+ /**
+ * Check the validity of the result
+ *
+ * @param response
+ * - response of rpc
+ * @return {@link DOMRpcResult} result
+ */
+ public static DOMRpcResult checkResponse(final DOMRpcResult response) {
+ if (response == null) {
+ return null;
+ }
+ try {
+ if ((response.getErrors() == null) || response.getErrors().isEmpty()) {
+ return response;
+ }
+ LOG.debug("RpcError message", response.getErrors());
+ throw new RestconfDocumentedException("RPCerror message ", null, response.getErrors());
+ } catch (final CancellationException e) {
+ final String errMsg = "The operation was cancelled while executing.";
+ LOG.debug("Cancel RpcExecution: " + errMsg, e);
+ throw new RestconfDocumentedException(errMsg, ErrorType.RPC, ErrorTag.PARTIAL_OPERATION);
+ }
+ }
+
+ private static DOMRpcResult prepareResult(final CheckedFuture<DOMRpcResult, DOMRpcException> rpc) {
+ final RpcResultFactory dataFactory = new RpcResultFactory();
+ FutureCallbackTx.addCallback(rpc, RestconfDataServiceConstant.PostData.POST_TX_TYPE, dataFactory);
+ return dataFactory.build();
+ }
+}
--- /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.restful.utils;
+
+import org.apache.commons.lang3.builder.Builder;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
+
+public class RpcResultFactory extends FutureDataFactory<DOMRpcResult> implements Builder<DOMRpcResult> {
+
+ @Override
+ public DOMRpcResult build() {
+ return this.result;
+ }
+
+}