@Override
public void onComplete(final Throwable failure, final Object success) throws Throwable {
if (failure != null) { // ask timeout
- Exception exception = new DocumentedException(id + ":Master is down. Please try again.",
- DocumentedException.ErrorType.APPLICATION, DocumentedException.ErrorTag.OPERATION_FAILED,
- DocumentedException.ErrorSeverity.WARNING);
+ final Exception exception = new DocumentedException(
+ id + ":Master is down. Please try again.",
+ DocumentedException.ErrorType.TRANSPORT,
+ DocumentedException.ErrorTag.RESOURCE_DENIED,
+ DocumentedException.ErrorSeverity.ERROR);
promise.failure(exception);
return;
}
@Override
public void onComplete(final Throwable failure, final Object success) throws Throwable {
if (failure != null) { // ask timeout
- Exception exception = new DocumentedException(id + ":Master is down. Please try again.",
- DocumentedException.ErrorType.APPLICATION, DocumentedException.ErrorTag.OPERATION_FAILED,
- DocumentedException.ErrorSeverity.WARNING);
+ final Exception exception = new DocumentedException(
+ id + ":Master is down. Please try again.",
+ DocumentedException.ErrorType.TRANSPORT,
+ DocumentedException.ErrorTag.RESOURCE_DENIED,
+ DocumentedException.ErrorSeverity.ERROR);
promise.failure(exception);
return;
}
LOG.trace("{}: Write {} via NETCONF: {} with payload {}", id, store, data.getIdentifier(), data.getNode());
masterContextRef.tell(new PutRequest(store, data), ActorRef.noSender());
-
}
@Override
@Override
public void onComplete(final Throwable failure, final Object success) throws Throwable {
if (failure != null) { // ask timeout
- Exception exception = new DocumentedException(id + ":Master is down. Please try again.",
- DocumentedException.ErrorType.APPLICATION, DocumentedException.ErrorTag.OPERATION_FAILED,
- DocumentedException.ErrorSeverity.WARNING);
+ final Exception exception = new DocumentedException(
+ id + ":Master is down. Please try again.",
+ DocumentedException.ErrorType.TRANSPORT,
+ DocumentedException.ErrorTag.RESOURCE_DENIED,
+ DocumentedException.ErrorSeverity.ERROR);
promise.failure(exception);
return;
}
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.SettableFuture;
import javax.annotation.Nullable;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
import org.opendaylight.netconf.topology.singleton.api.NetconfDOMTransaction;
import org.opendaylight.netconf.topology.singleton.messages.NormalizedNodeMessage;
+import org.opendaylight.yangtools.yang.common.RpcError;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.slf4j.Logger;
@Nullable
@Override
public ReadFailedException apply(Exception cause) {
+ if (cause.getCause() instanceof DocumentedException) {
+ final DocumentedException exception = (DocumentedException) cause.getCause();
+ if (exception.getErrorSeverity() == DocumentedException.ErrorSeverity.ERROR &&
+ exception.getErrorType() == DocumentedException.ErrorType.TRANSPORT &&
+ exception.getErrorTag() == DocumentedException.ErrorTag.RESOURCE_DENIED) {
+ final RpcError error = RpcResultBuilder.newError(
+ RpcError.ErrorType.TRANSPORT,
+ exception.getErrorTag().getTagValue(),
+ exception.getMessage());
+ return new ReadFailedException("Read from transaction failed", error);
+ }
+ }
return new ReadFailedException("Read from transaction failed", cause);
}
});
import org.opendaylight.netconf.sal.streams.listeners.NotificationListenerAdapter;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.RpcError;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
prepareDataByParamWithDef(optional.get(), path, withDefa);
} catch (ReadFailedException e) {
LOG.warn("Error reading {} from datastore {}", path, datastore.name(), e);
+ for (final RpcError error : e.getErrorList()) {
+ if (error.getErrorType() == RpcError.ErrorType.TRANSPORT
+ && error.getTag().equals(ErrorTag.RESOURCE_DENIED.getTagValue())) {
+ throw new RestconfDocumentedException(
+ error.getMessage(),
+ ErrorType.TRANSPORT,
+ ErrorTag.RESOURCE_DENIED_TRANSPORT);
+ }
+ }
throw new RestconfDocumentedException("Error reading data.", e, e.getErrorList());
}
}
OPERATION_NOT_SUPPORTED("operation-not-supported", 501 /* Not Implemented */),
OPERATION_FAILED("operation-failed", 500 /* INTERNAL_SERVER_ERROR */),
PARTIAL_OPERATION("partial-operation", 500 /* INTERNAL_SERVER_ERROR */),
- MALFORMED_MESSAGE("malformed-message", 400 /* Bad Request */);
+ MALFORMED_MESSAGE("malformed-message", 400 /* Bad Request */),
+ RESOURCE_DENIED_TRANSPORT("resource-denied-transport", 503 /* Service Unavailable */);
private final String tagValue;
private final int statusCode;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import org.opendaylight.yang.gen.v1.urn.sal.restconf.event.subscription.rev140708.NotificationOutputTypeGrouping.NotificationOutputType;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.RpcError;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
this.brokerFacade.readOperationalData(this.instanceID);
}
+ @Test
+ public void test503() throws Exception {
+ final RpcError error = RpcResultBuilder.newError(
+ RpcError.ErrorType.TRANSPORT,
+ ErrorTag.RESOURCE_DENIED.getTagValue(),
+ "Master is down. Please try again.");
+ final ReadFailedException exception503 = new ReadFailedException("Read from transaction failed", error);
+ doReturn(Futures.immediateFailedCheckedFuture(exception503))
+ .when(rTransaction).read(any(LogicalDatastoreType.class), any(YangInstanceIdentifier.class));
+ try {
+ brokerFacade.readConfigurationData(this.instanceID, "explicit");
+ fail("This test should fail.");
+ } catch (final RestconfDocumentedException e) {
+ assertEquals("getErrorTag", ErrorTag.RESOURCE_DENIED_TRANSPORT, e.getErrors().get(0).getErrorTag());
+ assertEquals("getErrorType", ErrorType.TRANSPORT, e.getErrors().get(0).getErrorType());
+ assertEquals("getErrorMessage", "Master is down. Please try again.", e.getErrors().get(0).getErrorMessage());
+ }
+ }
+
@Test
public void testInvokeRpc() throws Exception {
final DOMRpcResult expResult = mock(DOMRpcResult.class);
lookUpMap.put("operation-failed", 500);
lookUpMap.put("partial-operation", 500);
lookUpMap.put("malformed-message", 400);
+ lookUpMap.put("resource-denied-transport", 503);
for (ErrorTag tag : ErrorTag.values()) {
Integer expectedStatusCode = lookUpMap.get(tag.getTagValue());