Skip to content

Commit 3dabd5f

Browse files
committed
Clean up ApiServer, ApiServlet and ApiDispatcher flow to handle various CloudRuntimeException
and CloudException in one place, and Introduced ApiErrorCode to handle CloudStack API error code to standard Http code mapping. Signed-off-by: Min Chen <[email protected]>
1 parent c08d151 commit 3dabd5f

256 files changed

Lines changed: 1040 additions & 995 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-
91-
// Server error codes
92-
public static final int INTERNAL_ERROR = 530;
93-
public static final int ACCOUNT_ERROR = 531;
94-
public static final int ACCOUNT_RESOURCE_LIMIT_ERROR = 532;
95-
public static final int INSUFFICIENT_CAPACITY_ERROR = 533;
96-
public static final int RESOURCE_UNAVAILABLE_ERROR = 534;
97-
public static final int RESOURCE_ALLOCATION_ERROR = 534;
98-
public static final int RESOURCE_IN_USE_ERROR = 536;
99-
public static final int NETWORK_RULE_CONFLICT_ERROR = 537;
100-
10184
public static final DateFormat INPUT_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
10285
public static final DateFormat NEW_INPUT_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
10386
public static Pattern newInputDateFormat = Pattern.compile("[\\d]+-[\\d]+-[\\d]+ [\\d]+:[\\d]+:[\\d]+");
@@ -230,7 +213,7 @@ public Map<String, Object> unpackParams(Map<String, String> params) {
230213
int arrayStartIndex = key.indexOf('[');
231214
int arrayStartLastIndex = key.lastIndexOf('[');
232215
if (arrayStartIndex != arrayStartLastIndex) {
233-
throw new ServerApiException(MALFORMED_PARAMETER_ERROR, "Unable to decode parameter " + key
216+
throw new ServerApiException(ApiErrorCode.MALFORMED_PARAMETER_ERROR, "Unable to decode parameter " + key
234217
+ "; if specifying an object array, please use parameter[index].field=XXX, e.g. userGroupList[0].group=httpGroup");
235218
}
236219

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

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

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

‎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)