Merge "Bug 6198 - Use sal-netconf-connector to connet device costs too much time"
[netconf.git] / restconf / sal-rest-connector / src / main / java / org / opendaylight / netconf / sal / restconf / impl / RestconfDocumentedException.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
9 package org.opendaylight.netconf.sal.restconf.impl;
10
11 import com.google.common.base.Preconditions;
12 import com.google.common.base.Throwables;
13 import com.google.common.collect.ImmutableList;
14 import com.google.common.collect.Lists;
15 import java.util.Collection;
16 import java.util.List;
17 import javax.ws.rs.WebApplicationException;
18 import javax.ws.rs.core.Response.Status;
19 import org.opendaylight.netconf.sal.restconf.impl.RestconfError.ErrorTag;
20 import org.opendaylight.netconf.sal.restconf.impl.RestconfError.ErrorType;
21 import org.opendaylight.yangtools.yang.common.RpcError;
22 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
23
24 /**
25  * Unchecked exception to communicate error information, as defined in the ietf restcong draft, to be sent to the
26  * client.
27  *
28  * @author Devin Avery
29  * @author Thomas Pantelis
30  * See also <a href="https://tools.ietf.org/html/draft-bierman-netconf-restconf-02">RESTCONF</a>
31  */
32 public class RestconfDocumentedException extends WebApplicationException {
33
34     private static final long serialVersionUID = 1L;
35
36     private final List<RestconfError> errors;
37     private final Status status;
38
39     /**
40      * Constructs an instance with an error message. The error type defaults to APPLICATION and the error tag defaults
41      * to OPERATION_FAILED.
42      *
43      * @param message
44      *            A string which provides a plain text string describing the error.
45      */
46     public RestconfDocumentedException(final String message) {
47         this(message, RestconfError.ErrorType.APPLICATION, RestconfError.ErrorTag.OPERATION_FAILED);
48     }
49
50     /**
51      * Constructs an instance with an error message, error type, error tag and exception cause.
52      *
53      * @param message
54      *            A string which provides a plain text string describing the error.
55      * @param errorType
56      *            The enumerated type indicating the layer where the error occurred.
57      * @param errorTag
58      *            The enumerated tag representing a more specific error cause.
59      * @param cause
60      *            The underlying exception cause.
61      */
62     public RestconfDocumentedException(final String message, final ErrorType errorType, final ErrorTag errorTag,
63                                        final Throwable cause) {
64         this(cause, new RestconfError(errorType, errorTag, message, null,
65                 Throwables.getStackTraceAsString(cause), null));
66     }
67
68     /**
69      * Constructs an instance with an error message, error type, and error tag.
70      *
71      * @param message
72      *            A string which provides a plain text string describing the error.
73      * @param errorType
74      *            The enumerated type indicating the layer where the error occurred.
75      * @param errorTag
76      *            The enumerated tag representing a more specific error cause.
77      */
78     public RestconfDocumentedException(final String message, final ErrorType errorType, final ErrorTag errorTag) {
79         this(null, new RestconfError(errorType, errorTag, message));
80     }
81
82     /**
83      * Constructs an instance with an error message, error type, error tag and error path.
84      *
85      * @param message
86      *            A string which provides a plain text string describing the error.
87      * @param errorType
88      *            The enumerated type indicating the layer where the error occurred.
89      * @param errorTag
90      *            The enumerated tag representing a more specific error cause.
91      * @param errorPath
92      *            The instance identifier representing error path
93      */
94     public RestconfDocumentedException(final String message, final ErrorType errorType, final ErrorTag errorTag,
95                                        final YangInstanceIdentifier errorPath) {
96         this(null, new RestconfError(errorType, errorTag, message, errorPath));
97     }
98
99     /**
100      * Constructs an instance with an error message and exception cause.
101      * The stack trace of the exception is included in the error info.
102      *
103      * @param message
104      *            A string which provides a plain text string describing the error.
105      * @param cause
106      *            The underlying exception cause.
107      */
108     public RestconfDocumentedException(final String message, final Throwable cause) {
109         this(cause, new RestconfError(RestconfError.ErrorType.APPLICATION, RestconfError.ErrorTag.OPERATION_FAILED,
110                 message, null, Throwables.getStackTraceAsString(cause), null));
111     }
112
113     /**
114      * Constructs an instance with the given error.
115      */
116     public RestconfDocumentedException(final RestconfError error) {
117         this(null, error);
118     }
119
120     /**
121      * Constructs an instance with the given errors.
122      */
123     public RestconfDocumentedException(final String message, final Throwable cause, final List<RestconfError> errors) {
124         // FIXME: We override getMessage so supplied message is lost for any public access
125         // this was lost also in original code.
126         super(cause);
127         if(!errors.isEmpty()) {
128             this.errors = ImmutableList.copyOf(errors);
129         } else {
130             this.errors = ImmutableList.of(new RestconfError(RestconfError.ErrorType.APPLICATION,
131                     RestconfError.ErrorTag.OPERATION_FAILED, message));
132         }
133
134         status = null;
135     }
136
137     /**
138      * Constructs an instance with the given RpcErrors.
139      */
140     public RestconfDocumentedException(final String message, final Throwable cause,
141                                        final Collection<RpcError> rpcErrors) {
142         this(message, cause, convertToRestconfErrors(rpcErrors));
143     }
144
145     /**
146      * Constructs an instance with an HTTP status and no error information.
147      *
148      * @param status
149      *            the HTTP status.
150      */
151     public RestconfDocumentedException(final Status status) {
152         Preconditions.checkNotNull(status, "Status can't be null");
153         errors = ImmutableList.of();
154         this.status = status;
155     }
156
157     private RestconfDocumentedException(final Throwable cause, final RestconfError error) {
158         super(cause);
159         Preconditions.checkNotNull(error, "RestconfError can't be null");
160         errors = ImmutableList.of(error);
161         status = null;
162     }
163
164     private static List<RestconfError> convertToRestconfErrors(final Collection<RpcError> rpcErrors) {
165         final List<RestconfError> errorList = Lists.newArrayList();
166         if(rpcErrors != null) {
167             for (RpcError rpcError : rpcErrors) {
168                 errorList.add(new RestconfError(rpcError));
169             }
170         }
171
172         return errorList;
173     }
174
175     public List<RestconfError> getErrors() {
176         return errors;
177     }
178
179     public Status getStatus() {
180         return status;
181     }
182
183     @Override
184     public String getMessage() {
185         return "errors: " + errors + (status != null ? ", status: " + status : "");
186     }
187 }