Bug 5529 - Restconf M5 - Clean-up sonar issues
[netconf.git] / restconf / sal-rest-connector / src / main / java / org / opendaylight / netconf / sal / restconf / impl / RestconfError.java
1 /*
2  * Copyright (c) 2014 Brocade Communications Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.netconf.sal.restconf.impl;
9
10 import com.google.common.base.Preconditions;
11 import com.google.common.base.Throwables;
12 import org.opendaylight.yangtools.yang.common.RpcError;
13
14 /**
15  * Encapsulates a restconf error as defined in the ietf restconf draft.
16  *
17  * <br>
18  * <br>
19  * <b>Note:</b> Enumerations defined within are provided by the ietf restconf draft.
20  *
21  * @author Devin Avery
22  * See also <a href="https://tools.ietf.org/html/draft-bierman-netconf-restconf-02">RESTCONF</a>.
23  */
24 public class RestconfError {
25
26     public static enum ErrorType {
27         /** Errors relating to the transport layer */
28         TRANSPORT,
29         /** Errors relating to the RPC or notification layer */
30         RPC,
31         /** Errors relating to the protocol operation layer. */
32         PROTOCOL,
33         /** Errors relating to the server application layer. */
34         APPLICATION;
35
36         public String getErrorTypeTag() {
37             return name().toLowerCase();
38         }
39
40         public static ErrorType valueOfCaseInsensitive(String value) {
41             try {
42                 return ErrorType.valueOf(ErrorType.class, value.toUpperCase());
43             } catch (IllegalArgumentException e) {
44                 return APPLICATION;
45             }
46         }
47     }
48
49     public static enum ErrorTag {
50         IN_USE("in-use", 409 /* Conflict */),
51         INVALID_VALUE("invalid-value", 400 /* Bad Request */),
52         TOO_BIG("too-big", 413 /* Request Entity Too Large */),
53         MISSING_ATTRIBUTE("missing-attribute", 400 /* Bad Request */),
54         BAD_ATTRIBUTE("bad-attribute", 400 /* Bad Request */),
55         UNKNOWN_ATTRIBUTE("unknown-attribute", 400 /* Bad Request */),
56         MISSING_ELEMENT("missing-element", 400 /* Bad Request */),
57         BAD_ELEMENT("bad-element", 400 /* Bad Request */),
58         UNKNOWN_ELEMENT("unknown-element", 400 /* Bad Request */),
59         UNKNOWN_NAMESPACE("unknown-namespace", 400 /* Bad Request */),
60         ACCESS_DENIED("access-denied", 403 /* Forbidden */),
61         LOCK_DENIED("lock-denied", 409 /* Conflict */),
62         RESOURCE_DENIED("resource-denied", 409 /* Conflict */),
63         ROLLBACK_FAILED("rollback-failed", 500 /* INTERNAL_SERVER_ERROR */),
64         DATA_EXISTS("data-exists", 409 /* Conflict */),
65         DATA_MISSING("data-missing", 404 /* Resource Not Found */),
66         OPERATION_NOT_SUPPORTED("operation-not-supported", 501 /* Not Implemented */),
67         OPERATION_FAILED("operation-failed", 500 /* INTERNAL_SERVER_ERROR */),
68         PARTIAL_OPERATION("partial-operation", 500 /* INTERNAL_SERVER_ERROR */),
69         MALFORMED_MESSAGE("malformed-message", 400 /* Bad Request */);
70
71         private final String tagValue;
72         private final int statusCode;
73
74         ErrorTag(final String tagValue, final int statusCode) {
75             this.tagValue = tagValue;
76             this.statusCode = statusCode;
77         }
78
79         public String getTagValue() {
80             return this.tagValue.toLowerCase();
81         }
82
83         public static ErrorTag valueOfCaseInsensitive(String value) {
84             try {
85                 return ErrorTag.valueOf(ErrorTag.class, value.toUpperCase().replaceAll("-", "_"));
86             } catch (IllegalArgumentException e) {
87                 return OPERATION_FAILED;
88             }
89         }
90
91         public int getStatusCode() {
92             return statusCode;
93         }
94     }
95
96     private final ErrorType errorType;
97     private final ErrorTag errorTag;
98     private final String errorInfo;
99     private final String errorAppTag;
100     private final String errorMessage;
101     // TODO: Add in the error-path concept as defined in the ietf draft.
102
103     /**
104      * Constructs a RestConfError
105      *
106      * @param errorType
107      *            The enumerated type indicating the layer where the error occurred.
108      * @param errorTag
109      *            The enumerated tag representing a more specific error cause.
110      * @param errorMessage
111      *            A string which provides a plain text string describing the error.
112      */
113     public RestconfError(ErrorType errorType, ErrorTag errorTag, String errorMessage) {
114         this(errorType, errorTag, errorMessage, null);
115     }
116
117     /**
118      * Constructs a RestConfError object.
119      *
120      * @param errorType
121      *            The enumerated type indicating the layer where the error occurred.
122      * @param errorTag
123      *            The enumerated tag representing a more specific error cause.
124      * @param errorMessage
125      *            A string which provides a plain text string describing the error.
126      * @param errorAppTag
127      *            A string which represents an application-specific error tag that further specifies the error cause.
128      */
129     public RestconfError(ErrorType errorType, ErrorTag errorTag, String errorMessage, String errorAppTag) {
130         this(errorType, errorTag, errorMessage, errorAppTag, null);
131     }
132
133     /**
134      * Constructs a RestConfError object.
135      *
136      * @param errorType
137      *            The enumerated type indicating the layer where the error occurred.
138      * @param errorTag
139      *            The enumerated tag representing a more specific error cause.
140      * @param errorMessage
141      *            A string which provides a plain text string describing the error.
142      * @param errorAppTag
143      *            A string which represents an application-specific error tag that further specifies the error cause.
144      * @param errorInfo
145      *            A string, <b>formatted as XML</b>, which contains additional error information.
146      */
147     public RestconfError(ErrorType errorType, ErrorTag errorTag, String errorMessage, String errorAppTag,
148             String errorInfo) {
149         Preconditions.checkNotNull(errorType, "Error type is required for RestConfError");
150         Preconditions.checkNotNull(errorTag, "Error tag is required for RestConfError");
151         this.errorType = errorType;
152         this.errorTag = errorTag;
153         this.errorMessage = errorMessage;
154         this.errorAppTag = errorAppTag;
155         this.errorInfo = errorInfo;
156     }
157
158     /**
159      * Constructs a RestConfError object from an RpcError.
160      */
161     public RestconfError(RpcError rpcError) {
162
163         this.errorType = rpcError.getErrorType() == null ? ErrorType.APPLICATION : ErrorType
164                 .valueOfCaseInsensitive(rpcError.getErrorType().name());
165
166         this.errorTag = rpcError.getTag() == null ? ErrorTag.OPERATION_FAILED : ErrorTag
167                 .valueOfCaseInsensitive(rpcError.getTag().toString());
168
169         this.errorMessage = rpcError.getMessage();
170         this.errorAppTag = rpcError.getApplicationTag();
171
172         String errorInfo = null;
173         if (rpcError.getInfo() == null) {
174             if (rpcError.getCause() != null) {
175                 errorInfo = Throwables.getStackTraceAsString(rpcError.getCause());
176             } else if (rpcError.getSeverity() != null) {
177                 errorInfo = "<severity>" + rpcError.getSeverity().toString().toLowerCase() + "</severity>";
178             }
179         } else {
180             errorInfo = rpcError.getInfo();
181         }
182
183         this.errorInfo = errorInfo;
184     }
185
186     public ErrorType getErrorType() {
187         return errorType;
188     }
189
190     public ErrorTag getErrorTag() {
191         return errorTag;
192     }
193
194     public String getErrorInfo() {
195         return errorInfo;
196     }
197
198     public String getErrorAppTag() {
199         return errorAppTag;
200     }
201
202     public String getErrorMessage() {
203         return errorMessage;
204     }
205
206     @Override
207     public String toString() {
208         return "error-type: " + errorType.getErrorTypeTag() + ", error-tag: " + errorTag.getTagValue() + ", "
209                 + (errorAppTag != null ? "error-app-tag: " + errorAppTag + ", " : "")
210                 + (errorMessage != null ? "error-message: " + errorMessage : "")
211                 + (errorInfo != null ? "error-info: " + errorInfo + ", " : "") + "]";
212     }
213
214 }