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