Add support for RESTCONF standard errors
Change-Id: I74c0997bc8e06bc10c97cd610ff70c7a6aa68c8b
diff --git a/apps/restconf/restconfmgr/src/main/java/org/onosproject/restconf/restconfmanager/RestconfManager.java b/apps/restconf/restconfmgr/src/main/java/org/onosproject/restconf/restconfmanager/RestconfManager.java
index 1b6a589..0ad6b25 100644
--- a/apps/restconf/restconfmgr/src/main/java/org/onosproject/restconf/restconfmanager/RestconfManager.java
+++ b/apps/restconf/restconfmgr/src/main/java/org/onosproject/restconf/restconfmanager/RestconfManager.java
@@ -28,6 +28,7 @@
import org.onosproject.config.DynamicConfigService;
import org.onosproject.config.FailedException;
import org.onosproject.config.Filter;
+import org.onosproject.restconf.api.RestconfError;
import org.onosproject.restconf.api.RestconfException;
import org.onosproject.restconf.api.RestconfRpcOutput;
import org.onosproject.restconf.api.RestconfService;
@@ -46,13 +47,17 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import javax.ws.rs.core.Response;
import java.net.URI;
+import java.util.Arrays;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
+import static javax.ws.rs.core.Response.Status.CONFLICT;
import static javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR;
import static org.onosproject.d.config.ResourceIds.parentOf;
import static org.onosproject.restconf.utils.RestconfUtils.convertDataNodeToJson;
@@ -119,8 +124,9 @@
dataNode = dynamicConfigService.readNode(rl.ridForDynConfig(), filter);
} catch (FailedException e) {
log.error("ERROR: DynamicConfigService: ", e);
- throw new RestconfException("ERROR: DynamicConfigService",
- INTERNAL_SERVER_ERROR);
+ throw new RestconfException("ERROR: DynamicConfigService", e,
+ RestconfError.ErrorTag.OPERATION_FAILED, INTERNAL_SERVER_ERROR,
+ Optional.of(uri.getPath()));
}
ObjectNode rootNode = convertDataNodeToJson(rl.ridForYangRuntime(), dataNode);
return rootNode;
@@ -146,9 +152,16 @@
try {
dynamicConfigService.createNode(rl.ridForDynConfig(), dataNode);
} catch (FailedException e) {
- log.error("ERROR: DynamicConfigService: ", e);
- throw new RestconfException("ERROR: DynamicConfigService",
- INTERNAL_SERVER_ERROR);
+ if (e.getMessage().startsWith("Requested node already present")) {
+ throw new RestconfException("Already exists", e,
+ RestconfError.ErrorTag.DATA_EXISTS, CONFLICT,
+ Optional.of(uri.getPath()));
+ } else {
+ log.error("ERROR: DynamicConfigService: ", e);
+ throw new RestconfException("ERROR: DynamicConfigService", e,
+ RestconfError.ErrorTag.OPERATION_FAILED, INTERNAL_SERVER_ERROR,
+ Optional.of(uri.getPath()));
+ }
}
}
@@ -176,8 +189,9 @@
} catch (FailedException e) {
log.error("ERROR: DynamicConfigService: ", e);
- throw new RestconfException("ERROR: DynamicConfigService",
- INTERNAL_SERVER_ERROR);
+ throw new RestconfException("ERROR: DynamicConfigService", e,
+ RestconfError.ErrorTag.OPERATION_FAILED, INTERNAL_SERVER_ERROR,
+ Optional.of(uri.getPath()));
}
}
@@ -191,8 +205,9 @@
}
} catch (FailedException e) {
log.error("ERROR: DynamicConfigService: ", e);
- throw new RestconfException("ERROR: DynamicConfigService",
- INTERNAL_SERVER_ERROR);
+ throw new RestconfException("ERROR: DynamicConfigService", e,
+ RestconfError.ErrorTag.OPERATION_FAILED, INTERNAL_SERVER_ERROR,
+ Optional.of(uri.getPath()));
}
}
@@ -217,8 +232,9 @@
dynamicConfigService.updateNode(parentOf(rl.ridForDynConfig()), dataNode);
} catch (FailedException e) {
log.error("ERROR: DynamicConfigService: ", e);
- throw new RestconfException("ERROR: DynamicConfigService",
- INTERNAL_SERVER_ERROR);
+ throw new RestconfException("ERROR: DynamicConfigService", e,
+ RestconfError.ErrorTag.OPERATION_FAILED, INTERNAL_SERVER_ERROR,
+ Optional.of(uri.getPath()));
}
}
@@ -240,6 +256,10 @@
ChunkedOutput<String> output)
throws RestconfException {
//TODO: to be completed
+ throw new RestconfException("Not implemented",
+ RestconfError.ErrorTag.OPERATION_NOT_SUPPORTED,
+ Response.Status.NOT_IMPLEMENTED,
+ Optional.empty(), Optional.of("subscribeEventStream not yet implemented"));
}
@Override
@@ -267,12 +287,26 @@
} catch (InterruptedException e) {
log.error("ERROR: computeResultQ.take() has been interrupted.");
log.debug("executeRpc Exception:", e);
- restconfOutput = new RestconfRpcOutput(INTERNAL_SERVER_ERROR, null);
+ RestconfError error =
+ RestconfError.builder(RestconfError.ErrorType.RPC,
+ RestconfError.ErrorTag.OPERATION_FAILED)
+ .errorMessage("RPC execution has been interrupted")
+ .errorPath(uri.getPath())
+ .build();
+ restconfOutput = new RestconfRpcOutput(INTERNAL_SERVER_ERROR,
+ RestconfError.wrapErrorAsJson(Arrays.asList(error)));
restconfOutput.reason("RPC execution has been interrupted");
} catch (Exception e) {
log.error("ERROR: executeRpc: {}", e.getMessage());
log.debug("executeRpc Exception:", e);
- restconfOutput = new RestconfRpcOutput(INTERNAL_SERVER_ERROR, null);
+ RestconfError error =
+ RestconfError.builder(RestconfError.ErrorType.RPC,
+ RestconfError.ErrorTag.OPERATION_FAILED)
+ .errorMessage(e.getMessage())
+ .errorPath(uri.getPath())
+ .build();
+ restconfOutput = new RestconfRpcOutput(INTERNAL_SERVER_ERROR,
+ RestconfError.wrapErrorAsJson(Arrays.asList(error)));
restconfOutput.reason(e.getMessage());
}