Skip to content

Commit bdcfa19

Browse files
committed
Clean up ApiServer, ApiServlet and ApiDispatcher in handling various
exceptions, and Introduced ApiErrorCode to handle CloudStack API error code to standard Http code mapping.
1 parent e83fe47 commit bdcfa19

255 files changed

Lines changed: 1016 additions & 962 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

api/src/com/cloud/api/commands/CreatePrivateNetworkCmd.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -145,17 +145,17 @@ public void create() throws ResourceAllocationException {
145145
} catch (InsufficientCapacityException ex){
146146
s_logger.info(ex);
147147
s_logger.trace(ex);
148-
throw new ServerApiException(BaseCmd.INSUFFICIENT_CAPACITY_ERROR, ex.getMessage());
148+
throw new ServerApiException(ApiErrorCode.INSUFFICIENT_CAPACITY_ERROR, ex.getMessage());
149149
} catch (ConcurrentOperationException ex) {
150150
s_logger.warn("Exception: ", ex);
151-
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, ex.getMessage());
151+
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
152152
}
153153

154154
if (result != null) {
155155
this.setEntityId(result.getId());
156156
this.setEntityUuid(result.getUuid());
157157
} else {
158-
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to create a Private network");
158+
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create a Private network");
159159
}
160160
}
161161

@@ -167,7 +167,7 @@ public void execute() throws InsufficientCapacityException, ConcurrentOperationE
167167
response.setResponseName(getCommandName());
168168
this.setResponseObject(response);
169169
} else {
170-
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to create private network");
170+
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create private network");
171171
}
172172
}
173173

api/src/com/cloud/api/commands/DestroyConsoleProxyCmd.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ public void execute(){
8484
SuccessResponse response = new SuccessResponse(getCommandName());
8585
this.setResponseObject(response);
8686
} else {
87-
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to destroy console proxy");
87+
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to destroy console proxy");
8888
}
8989
}
9090
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
package org.apache.cloudstack.api;
18+
19+
/**
20+
* Enum class for various API error code used in CloudStack
21+
* @author minc
22+
*
23+
*/
24+
public enum ApiErrorCode {
25+
26+
MALFORMED_PARAMETER_ERROR(430),
27+
PARAM_ERROR(431),
28+
UNSUPPORTED_ACTION_ERROR(432),
29+
API_LIMIT_EXCEED(429),
30+
31+
INTERNAL_ERROR(530),
32+
ACCOUNT_ERROR(531),
33+
ACCOUNT_RESOURCE_LIMIT_ERROR(532),
34+
INSUFFICIENT_CAPACITY_ERROR(533),
35+
RESOURCE_UNAVAILABLE_ERROR(534),
36+
RESOURCE_ALLOCATION_ERROR(534),
37+
RESOURCE_IN_USE_ERROR(536),
38+
NETWORK_RULE_CONFLICT_ERROR(537);
39+
40+
private int httpCode;
41+
42+
private ApiErrorCode(int httpStatusCode){
43+
httpCode = httpStatusCode;
44+
}
45+
46+
public int getHttpCode() {
47+
return httpCode;
48+
}
49+
50+
public void setHttpCode(int httpCode) {
51+
this.httpCode = httpCode;
52+
}
53+
54+
public String toString(){
55+
return String.valueOf(this.httpCode);
56+
}
57+
58+
59+
}

api/src/org/apache/cloudstack/api/BaseCmd.java

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -81,23 +81,6 @@ public enum CommandType {
8181
BOOLEAN, DATE, FLOAT, INTEGER, SHORT, LIST, LONG, OBJECT, MAP, STRING, TZDATE, UUID
8282
}
8383

84-
// FIXME: Extract these out into a separate file
85-
// Client error codes
86-
public static final int MALFORMED_PARAMETER_ERROR = 430;
87-
public static final int PARAM_ERROR = 431;
88-
public static final int UNSUPPORTED_ACTION_ERROR = 432;
89-
public static final int PAGE_LIMIT_EXCEED = 433;
90-
public static final int API_LIMIT_EXCEED = 429;
91-
92-
// Server error codes
93-
public static final int INTERNAL_ERROR = 530;
94-
public static final int ACCOUNT_ERROR = 531;
95-
public static final int ACCOUNT_RESOURCE_LIMIT_ERROR = 532;
96-
public static final int INSUFFICIENT_CAPACITY_ERROR = 533;
97-
public static final int RESOURCE_UNAVAILABLE_ERROR = 534;
98-
public static final int RESOURCE_ALLOCATION_ERROR = 534;
99-
public static final int RESOURCE_IN_USE_ERROR = 536;
100-
public static final int NETWORK_RULE_CONFLICT_ERROR = 537;
10184

10285
public static final DateFormat INPUT_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
10386
public static final DateFormat NEW_INPUT_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@@ -231,7 +214,7 @@ public Map<String, Object> unpackParams(Map<String, String> params) {
231214
int arrayStartIndex = key.indexOf('[');
232215
int arrayStartLastIndex = key.lastIndexOf('[');
233216
if (arrayStartIndex != arrayStartLastIndex) {
234-
throw new ServerApiException(MALFORMED_PARAMETER_ERROR, "Unable to decode parameter " + key
217+
throw new ServerApiException(ApiErrorCode.MALFORMED_PARAMETER_ERROR, "Unable to decode parameter " + key
235218
+ "; if specifying an object array, please use parameter[index].field=XXX, e.g. userGroupList[0].group=httpGroup");
236219
}
237220

@@ -240,15 +223,15 @@ public Map<String, Object> unpackParams(Map<String, String> params) {
240223
int arrayEndLastIndex = key.lastIndexOf(']');
241224
if ((arrayEndIndex < arrayStartIndex) || (arrayEndIndex != arrayEndLastIndex)) {
242225
// malformed parameter
243-
throw new ServerApiException(MALFORMED_PARAMETER_ERROR, "Unable to decode parameter " + key
226+
throw new ServerApiException(ApiErrorCode.MALFORMED_PARAMETER_ERROR, "Unable to decode parameter " + key
244227
+ "; if specifying an object array, please use parameter[index].field=XXX, e.g. userGroupList[0].group=httpGroup");
245228
}
246229

247230
// Now that we have an array object, check for a field name in the case of a complex object
248231
int fieldIndex = key.indexOf('.');
249232
String fieldName = null;
250233
if (fieldIndex < arrayEndIndex) {
251-
throw new ServerApiException(MALFORMED_PARAMETER_ERROR, "Unable to decode parameter " + key
234+
throw new ServerApiException(ApiErrorCode.MALFORMED_PARAMETER_ERROR, "Unable to decode parameter " + key
252235
+ "; if specifying an object array, please use parameter[index].field=XXX, e.g. userGroupList[0].group=httpGroup");
253236
} else {
254237
fieldName = key.substring(fieldIndex + 1);
@@ -273,7 +256,7 @@ public Map<String, Object> unpackParams(Map<String, String> params) {
273256
}
274257

275258
if (!parsedIndex) {
276-
throw new ServerApiException(MALFORMED_PARAMETER_ERROR, "Unable to decode parameter " + key
259+
throw new ServerApiException(ApiErrorCode.MALFORMED_PARAMETER_ERROR, "Unable to decode parameter " + key
277260
+ "; if specifying an object array, please use parameter[index].field=XXX, e.g. userGroupList[0].group=httpGroup");
278261
}
279262

api/src/org/apache/cloudstack/api/BaseUpdateTemplateOrIsoPermissionsCmd.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ public void execute(){
119119
SuccessResponse response = new SuccessResponse(getCommandName());
120120
this.setResponseObject(response);
121121
} else {
122-
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to update template/iso permissions");
122+
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update template/iso permissions");
123123
}
124124
}
125125
}

api/src/org/apache/cloudstack/api/ServerApiException.java

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,28 +15,51 @@
1515
// specific language governing permissions and limitations
1616
// under the License.
1717
package org.apache.cloudstack.api;
18+
import java.util.ArrayList;
19+
20+
import com.cloud.exception.CloudException;
21+
import com.cloud.utils.exception.CSExceptionErrorCode;
1822
import com.cloud.utils.exception.CloudRuntimeException;
1923

2024
@SuppressWarnings("serial")
2125
public class ServerApiException extends CloudRuntimeException {
22-
private int _errorCode;
26+
private ApiErrorCode _errorCode;
2327
private String _description;
2428

2529
public ServerApiException() {
26-
_errorCode = 0;
30+
_errorCode = ApiErrorCode.INTERNAL_ERROR;
2731
_description = null;
32+
setCSErrorCode(CSExceptionErrorCode.getCSErrCode(ServerApiException.class.getName()));
33+
}
34+
35+
public ServerApiException(ApiErrorCode errorCode, String description) {
36+
_errorCode = errorCode;
37+
_description = description;
38+
setCSErrorCode(CSExceptionErrorCode.getCSErrCode(ServerApiException.class.getName()));
2839
}
2940

30-
public ServerApiException(int errorCode, String description) {
41+
// wrap a specific CloudRuntimeException to a ServerApiException
42+
public ServerApiException(ApiErrorCode errorCode, String description, Throwable cause){
43+
super(description, cause);
3144
_errorCode = errorCode;
3245
_description = description;
46+
if (cause instanceof CloudRuntimeException || cause instanceof CloudException ) {
47+
CloudRuntimeException rt = (CloudRuntimeException) cause;
48+
ArrayList<String> idList = rt.getIdProxyList();
49+
if (idList != null) {
50+
for (int i = 0; i < idList.size(); i++) {
51+
addProxyObject(idList.get(i));
52+
}
53+
}
54+
setCSErrorCode(rt.getCSErrorCode());
55+
}
3356
}
3457

35-
public int getErrorCode() {
58+
public ApiErrorCode getErrorCode() {
3659
return _errorCode;
3760
}
3861

39-
public void setErrorCode(int errorCode) {
62+
public void setErrorCode(ApiErrorCode errorCode) {
4063
_errorCode = errorCode;
4164
}
4265

api/src/org/apache/cloudstack/api/command/admin/account/CreateAccountCmd.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ public void execute(){
151151
response.setResponseName(getCommandName());
152152
this.setResponseObject(response);
153153
} else {
154-
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to create a user account");
154+
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create a user account");
155155
}
156156
}
157157
}

api/src/org/apache/cloudstack/api/command/admin/account/DeleteAccountCmd.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ public void execute(){
9191
SuccessResponse response = new SuccessResponse(getCommandName());
9292
this.setResponseObject(response);
9393
} else {
94-
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to delete user account and all corresponding users");
94+
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to delete user account and all corresponding users");
9595
}
9696
}
9797

api/src/org/apache/cloudstack/api/command/admin/account/DisableAccountCmd.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ public void execute() throws ConcurrentOperationException, ResourceUnavailableEx
115115
response.setResponseName(getCommandName());
116116
this.setResponseObject(response);
117117
} else {
118-
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, lockRequested == true ? "Failed to lock account" : "Failed to disable account" );
118+
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, lockRequested == true ? "Failed to lock account" : "Failed to disable account" );
119119
}
120120
}
121121

api/src/org/apache/cloudstack/api/command/admin/account/EnableAccountCmd.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.apache.log4j.Logger;
2020

2121
import org.apache.cloudstack.api.ApiConstants;
22+
import org.apache.cloudstack.api.ApiErrorCode;
2223
import org.apache.cloudstack.api.BaseCmd;
2324
import org.apache.cloudstack.api.APICommand;
2425
import org.apache.cloudstack.api.Parameter;
@@ -95,7 +96,7 @@ public void execute(){
9596
response.setResponseName(getCommandName());
9697
this.setResponseObject(response);
9798
} else {
98-
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to enable account");
99+
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to enable account");
99100
}
100101
}
101102
}

0 commit comments

Comments
 (0)