You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ki...@apache.org on 2013/02/01 07:32:04 UTC
[13/40] Added Mock ApiServer, Regions API calls with api keys
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/f0f33bf4/server/src/com/cloud/api/MockApiServer.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/MockApiServer.java b/server/src/com/cloud/api/MockApiServer.java
new file mode 100755
index 0000000..23b78a4
--- /dev/null
+++ b/server/src/com/cloud/api/MockApiServer.java
@@ -0,0 +1,638 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.api;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InterruptedIOException;
+import java.io.UnsupportedEncodingException;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.URLDecoder;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.http.ConnectionClosedException;
+import org.apache.http.HttpException;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpServerConnection;
+import org.apache.http.HttpStatus;
+import org.apache.http.entity.BasicHttpEntity;
+import org.apache.http.impl.DefaultHttpResponseFactory;
+import org.apache.http.impl.DefaultHttpServerConnection;
+import org.apache.http.impl.NoConnectionReuseStrategy;
+import org.apache.http.impl.SocketHttpServerConnection;
+import org.apache.http.params.BasicHttpParams;
+import org.apache.http.params.CoreConnectionPNames;
+import org.apache.http.params.CoreProtocolPNames;
+import org.apache.http.params.HttpParams;
+import org.apache.http.protocol.BasicHttpContext;
+import org.apache.http.protocol.BasicHttpProcessor;
+import org.apache.http.protocol.HttpContext;
+import org.apache.http.protocol.HttpRequestHandler;
+import org.apache.http.protocol.HttpRequestHandlerRegistry;
+import org.apache.http.protocol.HttpService;
+import org.apache.http.protocol.ResponseConnControl;
+import org.apache.http.protocol.ResponseContent;
+import org.apache.http.protocol.ResponseDate;
+import org.apache.http.protocol.ResponseServer;
+import org.apache.log4j.Logger;
+
+import com.cloud.api.response.ApiResponseSerializer;
+import com.cloud.api.response.ExceptionResponse;
+import com.cloud.async.AsyncJobManager;
+import com.cloud.cluster.StackMaid;
+import com.cloud.configuration.Config;
+import com.cloud.configuration.ConfigurationVO;
+import com.cloud.configuration.dao.ConfigurationDao;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.PermissionDeniedException;
+import com.cloud.region.RegionManager;
+import com.cloud.server.ManagementService;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.user.DomainManager;
+import com.cloud.user.User;
+import com.cloud.user.UserContext;
+import com.cloud.utils.IdentityProxy;
+import com.cloud.utils.PropertiesUtil;
+import com.cloud.utils.component.ComponentLocator;
+import com.cloud.utils.concurrency.NamedThreadFactory;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.exception.CSExceptionErrorCode;
+
+public class MockApiServer implements HttpRequestHandler {
+ private static final Logger s_logger = Logger.getLogger(MockApiServer.class.getName());
+
+ public static final short ADMIN_COMMAND = 1;
+ public static final short DOMAIN_ADMIN_COMMAND = 4;
+ public static final short RESOURCE_DOMAIN_ADMIN_COMMAND = 2;
+ public static final short USER_COMMAND = 8;
+ public static boolean encodeApiResponse = false;
+ public static String jsonContentType = "text/javascript";
+ private Properties _apiCommands = null;
+ private ApiDispatcher _dispatcher;
+ private AccountManager _accountMgr = null;
+ private Account _systemAccount = null;
+ private User _systemUser = null;
+
+ private static int _workerCount = 0;
+
+ private static MockApiServer s_instance = null;
+ private static List<String> s_userCommands = null;
+ private static List<String> s_resellerCommands = null; // AKA domain-admin
+ private static List<String> s_adminCommands = null;
+ private static List<String> s_resourceDomainAdminCommands = null;
+ private static List<String> s_allCommands = null;
+ private static List<String> s_pluggableServiceCommands = null;
+
+ private static ExecutorService _executor = new ThreadPoolExecutor(10, 150, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), new NamedThreadFactory("ApiServer"));
+
+ static {
+ s_userCommands = new ArrayList<String>();
+ s_resellerCommands = new ArrayList<String>();
+ s_adminCommands = new ArrayList<String>();
+ s_resourceDomainAdminCommands = new ArrayList<String>();
+ s_allCommands = new ArrayList<String>();
+ s_pluggableServiceCommands = new ArrayList<String>();
+ }
+
+ private MockApiServer() {
+ }
+
+ public static void initApiServer(String[] apiConfig) {
+ if (s_instance == null) {
+ s_instance = new MockApiServer();
+ s_instance.init(apiConfig);
+ }
+ }
+
+ public static MockApiServer getInstance() {
+ // initApiServer();
+ return s_instance;
+ }
+
+ public Properties get_apiCommands() {
+ return _apiCommands;
+ }
+
+ private void processConfigFiles(String[] apiConfig, boolean pluggableServicesConfig) {
+ try {
+ if (_apiCommands == null) {
+ _apiCommands = new Properties();
+ }
+ Properties preProcessedCommands = new Properties();
+ if (apiConfig != null) {
+ for (String configFile : apiConfig) {
+ File commandsFile = PropertiesUtil.findConfigFile(configFile);
+ if (commandsFile != null) {
+ try {
+ preProcessedCommands.load(new FileInputStream(commandsFile));
+ } catch (FileNotFoundException fnfex) {
+ // in case of a file within a jar in classpath, try to open stream using url
+ InputStream stream = PropertiesUtil.openStreamFromURL(configFile);
+ if (stream != null) {
+ preProcessedCommands.load(stream);
+ } else {
+ s_logger.error("Unable to find properites file", fnfex);
+ }
+ }
+ }
+ }
+ for (Object key : preProcessedCommands.keySet()) {
+ String preProcessedCommand = preProcessedCommands.getProperty((String) key);
+ String[] commandParts = preProcessedCommand.split(";");
+ _apiCommands.put(key, commandParts[0]);
+
+ if (pluggableServicesConfig) {
+ s_pluggableServiceCommands.add(commandParts[0]);
+ }
+
+ if (commandParts.length > 1) {
+ try {
+ short cmdPermissions = Short.parseShort(commandParts[1]);
+ if ((cmdPermissions & ADMIN_COMMAND) != 0) {
+ s_adminCommands.add((String) key);
+ }
+ if ((cmdPermissions & RESOURCE_DOMAIN_ADMIN_COMMAND) != 0) {
+ s_resourceDomainAdminCommands.add((String) key);
+ }
+ if ((cmdPermissions & DOMAIN_ADMIN_COMMAND) != 0) {
+ s_resellerCommands.add((String) key);
+ }
+ if ((cmdPermissions & USER_COMMAND) != 0) {
+ s_userCommands.add((String) key);
+ }
+ } catch (NumberFormatException nfe) {
+ s_logger.info("Malformed command.properties permissions value, key = " + key + ", value = " + preProcessedCommand);
+ }
+ }
+ }
+
+ s_allCommands.addAll(s_adminCommands);
+ s_allCommands.addAll(s_resourceDomainAdminCommands);
+ s_allCommands.addAll(s_userCommands);
+ s_allCommands.addAll(s_resellerCommands);
+ }
+ } catch (FileNotFoundException fnfex) {
+ s_logger.error("Unable to find properites file", fnfex);
+ } catch (IOException ioex) {
+ s_logger.error("Exception loading properties file", ioex);
+ }
+ }
+
+ public void init(String[] apiConfig) {
+ BaseCmd.setComponents(new ApiResponseHelper());
+ BaseListCmd.configure();
+ processConfigFiles(apiConfig, false);
+
+ ComponentLocator locator = ComponentLocator.getLocator(ManagementService.Name);
+ _accountMgr = locator.getManager(AccountManager.class);
+ _systemAccount = _accountMgr.getSystemAccount();
+ _systemUser = _accountMgr.getSystemUser();
+ _dispatcher = ApiDispatcher.getInstance();
+
+ Integer apiPort = null; // api port, null by default
+ ConfigurationDao configDao = locator.getDao(ConfigurationDao.class);
+ SearchCriteria<ConfigurationVO> sc = configDao.createSearchCriteria();
+ sc.addAnd("name", SearchCriteria.Op.EQ, "integration.api.port");
+ List<ConfigurationVO> values = configDao.search(sc, null);
+ if ((values != null) && (values.size() > 0)) {
+ ConfigurationVO apiPortConfig = values.get(0);
+ if (apiPortConfig.getValue() != null) {
+ apiPort = Integer.parseInt(apiPortConfig.getValue());
+ }
+ }
+
+ encodeApiResponse = Boolean.valueOf(configDao.getValue(Config.EncodeApiResponse.key()));
+
+ String jsonType = configDao.getValue(Config.JavaScriptDefaultContentType.key());
+ if (jsonType != null) {
+ jsonContentType = jsonType;
+ }
+
+ if (apiPort != null) {
+ ListenerThread listenerThread = new ListenerThread(this, apiPort);
+ listenerThread.start();
+ }
+ }
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ @Override
+ public void handle(HttpRequest request, HttpResponse response, HttpContext context) throws HttpException, IOException {
+ // get some information for the access log...
+ StringBuffer sb = new StringBuffer();
+ HttpServerConnection connObj = (HttpServerConnection) context.getAttribute("http.connection");
+ if (connObj instanceof SocketHttpServerConnection) {
+ InetAddress remoteAddr = ((SocketHttpServerConnection) connObj).getRemoteAddress();
+ sb.append(remoteAddr.toString() + " -- ");
+ }
+ sb.append(request.getRequestLine());
+
+ try {
+ String uri = request.getRequestLine().getUri();
+ int requestParamsStartIndex = uri.indexOf('?');
+ if (requestParamsStartIndex >= 0) {
+ uri = uri.substring(requestParamsStartIndex + 1);
+ }
+
+ String[] paramArray = uri.split("&");
+ if (paramArray.length < 1) {
+ s_logger.info("no parameters received for request: " + uri + ", aborting...");
+ return;
+ }
+
+ Map parameterMap = new HashMap<String, String[]>();
+
+ String responseType = BaseCmd.RESPONSE_TYPE_XML;
+ for (String paramEntry : paramArray) {
+ String[] paramValue = paramEntry.split("=");
+ if (paramValue.length != 2) {
+ s_logger.info("malformed parameter: " + paramEntry + ", skipping");
+ continue;
+ }
+ if ("response".equalsIgnoreCase(paramValue[0])) {
+ responseType = paramValue[1];
+ } else {
+ // according to the servlet spec, the parameter map should be in the form (name=String,
+ // value=String[]), so
+ // parameter values will be stored in an array
+ parameterMap.put(/* name */paramValue[0], /* value */new String[] { paramValue[1] });
+ }
+ }
+ try {
+ // always trust commands from API port, user context will always be UID_SYSTEM/ACCOUNT_ID_SYSTEM
+ UserContext.registerContext(_systemUser.getId(), _systemAccount, null, true);
+ sb.insert(0, "(userId=" + User.UID_SYSTEM + " accountId=" + Account.ACCOUNT_ID_SYSTEM + " sessionId=" + null + ") ");
+ String responseText = handleRequest(parameterMap, true, responseType, sb);
+ sb.append(" 200 " + ((responseText == null) ? 0 : responseText.length()));
+
+ writeResponse(response, responseText, HttpStatus.SC_OK, responseType, null);
+ } catch (ServerApiException se) {
+ String responseText = getSerializedApiError(se.getErrorCode(), se.getDescription(), parameterMap, responseType, se);
+ writeResponse(response, responseText, se.getErrorCode(), responseType, se.getDescription());
+ sb.append(" " + se.getErrorCode() + " " + se.getDescription());
+ } catch (RuntimeException e) {
+ // log runtime exception like NullPointerException to help identify the source easier
+ s_logger.error("Unhandled exception, ", e);
+ throw e;
+ } catch (Exception e){
+ s_logger.info("Error: "+e.getMessage());
+ }
+ } finally {
+ UserContext.unregisterContext();
+ }
+ }
+
+ @SuppressWarnings("rawtypes")
+ public String handleRequest(Map params, boolean decode, String responseType, StringBuffer auditTrailSb) throws ServerApiException {
+ String response = null;
+ String[] command = null;
+ try {
+ command = (String[]) params.get("command");
+ if (command == null) {
+ s_logger.error("invalid request, no command sent");
+ if (s_logger.isTraceEnabled()) {
+ s_logger.trace("dumping request parameters");
+ for (Object key : params.keySet()) {
+ String keyStr = (String) key;
+ String[] value = (String[]) params.get(key);
+ s_logger.trace(" key: " + keyStr + ", value: " + ((value == null) ? "'null'" : value[0]));
+ }
+ }
+ throw new ServerApiException(BaseCmd.UNSUPPORTED_ACTION_ERROR, "Invalid request, no command sent");
+ } else {
+ Map<String, String> paramMap = new HashMap<String, String>();
+ Set keys = params.keySet();
+ Iterator keysIter = keys.iterator();
+ while (keysIter.hasNext()) {
+ String key = (String) keysIter.next();
+ if ("command".equalsIgnoreCase(key)) {
+ continue;
+ }
+ String[] value = (String[]) params.get(key);
+
+ String decodedValue = null;
+ if (decode) {
+ try {
+ decodedValue = URLDecoder.decode(value[0], "UTF-8");
+ } catch (UnsupportedEncodingException usex) {
+ s_logger.warn(key + " could not be decoded, value = " + value[0]);
+ throw new ServerApiException(BaseCmd.PARAM_ERROR, key + " could not be decoded, received value " + value[0]);
+ } catch (IllegalArgumentException iae) {
+ s_logger.warn(key + " could not be decoded, value = " + value[0]);
+ throw new ServerApiException(BaseCmd.PARAM_ERROR, key + " could not be decoded, received value " + value[0] + " which contains illegal characters eg.%");
+ }
+ } else {
+ decodedValue = value[0];
+ }
+ paramMap.put(key, decodedValue);
+ }
+ String cmdClassName = _apiCommands.getProperty(command[0]);
+ if (cmdClassName != null) {
+ Class<?> cmdClass = Class.forName(cmdClassName);
+ BaseCmd cmdObj = (BaseCmd) cmdClass.newInstance();
+ cmdObj.setFullUrlParams(paramMap);
+ cmdObj.setResponseType(responseType);
+ // This is where the command is either serialized, or directly dispatched
+ response = queueCommand(cmdObj, paramMap);
+ } else {
+ if (!command[0].equalsIgnoreCase("login") && !command[0].equalsIgnoreCase("logout")) {
+ String errorString = "Unknown API command: " + ((command == null) ? "null" : command[0]);
+ s_logger.warn(errorString);
+ auditTrailSb.append(" " + errorString);
+ throw new ServerApiException(BaseCmd.UNSUPPORTED_ACTION_ERROR, errorString);
+ }
+ }
+ }
+ } catch (Exception ex) {
+ if (ex instanceof InvalidParameterValueException) {
+ InvalidParameterValueException ref = (InvalidParameterValueException)ex;
+ ServerApiException e = new ServerApiException(BaseCmd.PARAM_ERROR, ex.getMessage());
+ // copy over the IdentityProxy information as well and throw the serverapiexception.
+ ArrayList<IdentityProxy> idList = ref.getIdProxyList();
+ if (idList != null) {
+ // Iterate through entire arraylist and copy over each proxy id.
+ for (int i = 0 ; i < idList.size(); i++) {
+ IdentityProxy obj = idList.get(i);
+ e.addProxyObject(obj.getTableName(), obj.getValue(), obj.getidFieldName());
+ }
+ }
+ // Also copy over the cserror code and the function/layer in which it was thrown.
+ e.setCSErrorCode(ref.getCSErrorCode());
+ throw e;
+ } else if (ex instanceof PermissionDeniedException) {
+ PermissionDeniedException ref = (PermissionDeniedException)ex;
+ ServerApiException e = new ServerApiException(BaseCmd.ACCOUNT_ERROR, ex.getMessage());
+ // copy over the IdentityProxy information as well and throw the serverapiexception.
+ ArrayList<IdentityProxy> idList = ref.getIdProxyList();
+ if (idList != null) {
+ // Iterate through entire arraylist and copy over each proxy id.
+ for (int i = 0 ; i < idList.size(); i++) {
+ IdentityProxy obj = idList.get(i);
+ e.addProxyObject(obj.getTableName(), obj.getValue(), obj.getidFieldName());
+ }
+ }
+ e.setCSErrorCode(ref.getCSErrorCode());
+ throw e;
+ } else if (ex instanceof ServerApiException) {
+ throw (ServerApiException) ex;
+ } else {
+ s_logger.error("unhandled exception executing api command: " + ((command == null) ? "null" : command[0]), ex);
+ ServerApiException e = new ServerApiException(BaseCmd.INTERNAL_ERROR, "Internal server error, unable to execute request.");
+ e.setCSErrorCode(CSExceptionErrorCode.getCSErrCode("ServerApiException"));
+ throw e;
+ }
+ }
+ return response;
+ }
+
+ private String queueCommand(BaseCmd cmdObj, Map<String, String> params) {
+ params.put("ctxStartEventId", String.valueOf(0L));
+ _dispatcher.dispatch(cmdObj, params);
+ SerializationContext.current().setUuidTranslation(true);
+ return ApiResponseSerializer.toSerializedString((ResponseObject) cmdObj.getResponseObject(), cmdObj.getResponseType());
+ }
+
+ // FIXME: rather than isError, we might was to pass in the status code to give more flexibility
+ private void writeResponse(HttpResponse resp, final String responseText, final int statusCode, String responseType, String reasonPhrase) {
+ try {
+ resp.setStatusCode(statusCode);
+ resp.setReasonPhrase(reasonPhrase);
+
+ BasicHttpEntity body = new BasicHttpEntity();
+ if (BaseCmd.RESPONSE_TYPE_JSON.equalsIgnoreCase(responseType)) {
+ // JSON response
+ body.setContentType(jsonContentType);
+ if (responseText == null) {
+ body.setContent(new ByteArrayInputStream("{ \"error\" : { \"description\" : \"Internal Server Error\" } }".getBytes("UTF-8")));
+ }
+ } else {
+ body.setContentType("text/xml");
+ if (responseText == null) {
+ body.setContent(new ByteArrayInputStream("<error>Internal Server Error</error>".getBytes("UTF-8")));
+ }
+ }
+
+ if (responseText != null) {
+ body.setContent(new ByteArrayInputStream(responseText.getBytes("UTF-8")));
+ }
+ resp.setEntity(body);
+ } catch (Exception ex) {
+ s_logger.error("error!", ex);
+ }
+ }
+
+ // FIXME: the following two threads are copied from
+ // http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/httpcore/src/examples/org/apache/http/examples/ElementalHttpServer.java
+ // we have to cite a license if we are using this code directly, so we need to add the appropriate citation or
+ // modify the
+ // code to be very specific to our needs
+ static class ListenerThread extends Thread {
+ private HttpService _httpService = null;
+ private ServerSocket _serverSocket = null;
+ private HttpParams _params = null;
+
+ public ListenerThread(MockApiServer requestHandler, int port) {
+ try {
+ _serverSocket = new ServerSocket(port);
+ } catch (IOException ioex) {
+ s_logger.error("error initializing api server", ioex);
+ return;
+ }
+
+ _params = new BasicHttpParams();
+ _params.setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 30000).setIntParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE, 8 * 1024)
+ .setBooleanParameter(CoreConnectionPNames.STALE_CONNECTION_CHECK, false).setBooleanParameter(CoreConnectionPNames.TCP_NODELAY, true)
+ .setParameter(CoreProtocolPNames.ORIGIN_SERVER, "HttpComponents/1.1");
+
+ // Set up the HTTP protocol processor
+ BasicHttpProcessor httpproc = new BasicHttpProcessor();
+ httpproc.addInterceptor(new ResponseDate());
+ httpproc.addInterceptor(new ResponseServer());
+ httpproc.addInterceptor(new ResponseContent());
+ httpproc.addInterceptor(new ResponseConnControl());
+
+ // Set up request handlers
+ HttpRequestHandlerRegistry reqistry = new HttpRequestHandlerRegistry();
+ reqistry.register("*", requestHandler);
+
+ // Set up the HTTP service
+ _httpService = new HttpService(httpproc, new NoConnectionReuseStrategy(), new DefaultHttpResponseFactory());
+ _httpService.setParams(_params);
+ _httpService.setHandlerResolver(reqistry);
+ }
+
+ @Override
+ public void run() {
+ s_logger.info("ApiServer listening on port " + _serverSocket.getLocalPort());
+ while (!Thread.interrupted()) {
+ try {
+ // Set up HTTP connection
+ Socket socket = _serverSocket.accept();
+ DefaultHttpServerConnection conn = new DefaultHttpServerConnection();
+ conn.bind(socket, _params);
+
+ // Execute a new worker task to handle the request
+ _executor.execute(new WorkerTask(_httpService, conn, _workerCount++));
+ } catch (InterruptedIOException ex) {
+ break;
+ } catch (IOException e) {
+ s_logger.error("I/O error initializing connection thread", e);
+ break;
+ }
+ }
+ }
+ }
+
+ static class WorkerTask implements Runnable {
+ private final HttpService _httpService;
+ private final HttpServerConnection _conn;
+
+ public WorkerTask(final HttpService httpService, final HttpServerConnection conn, final int count) {
+ _httpService = httpService;
+ _conn = conn;
+ }
+
+ @Override
+ public void run() {
+ HttpContext context = new BasicHttpContext(null);
+ try {
+ while (!Thread.interrupted() && _conn.isOpen()) {
+ try {
+ _httpService.handleRequest(_conn, context);
+ _conn.close();
+ } finally {
+ StackMaid.current().exitCleanup();
+ }
+ }
+ } catch (ConnectionClosedException ex) {
+ if (s_logger.isTraceEnabled()) {
+ s_logger.trace("ApiServer: Client closed connection");
+ }
+ } catch (IOException ex) {
+ if (s_logger.isTraceEnabled()) {
+ s_logger.trace("ApiServer: IOException - " + ex);
+ }
+ } catch (HttpException ex) {
+ s_logger.warn("ApiServer: Unrecoverable HTTP protocol violation" + ex);
+ } finally {
+ try {
+ _conn.shutdown();
+ } catch (IOException ignore) {
+ }
+ }
+ }
+ }
+
+ public String getSerializedApiError(int errorCode, String errorText, Map<String, Object[]> apiCommandParams, String responseType, Exception ex) {
+ String responseName = null;
+ String cmdClassName = null;
+
+ String responseText = null;
+
+ try {
+ if (errorCode == BaseCmd.UNSUPPORTED_ACTION_ERROR || apiCommandParams == null || apiCommandParams.isEmpty()) {
+ responseName = "errorresponse";
+ } else {
+ Object cmdObj = apiCommandParams.get("command");
+ // cmd name can be null when "command" parameter is missing in the request
+ if (cmdObj != null) {
+ String cmdName = ((String[]) cmdObj)[0];
+ cmdClassName = _apiCommands.getProperty(cmdName);
+ if (cmdClassName != null) {
+ Class<?> claz = Class.forName(cmdClassName);
+ responseName = ((BaseCmd) claz.newInstance()).getCommandName();
+ } else {
+ responseName = "errorresponse";
+ }
+ }
+ }
+ ExceptionResponse apiResponse = new ExceptionResponse();
+ apiResponse.setErrorCode(errorCode);
+ apiResponse.setErrorText(errorText);
+ apiResponse.setResponseName(responseName);
+ // Also copy over the IdentityProxy object List into this new apiResponse, from
+ // the exception caught. When invoked from handle(), the exception here can
+ // be either ServerApiException, PermissionDeniedException or InvalidParameterValue
+ // Exception. When invoked from ApiServlet's processRequest(), this can be
+ // a standard exception like NumberFormatException. We'll leave the standard ones alone.
+ if (ex != null) {
+ if (ex instanceof ServerApiException || ex instanceof PermissionDeniedException
+ || ex instanceof InvalidParameterValueException) {
+ // Cast the exception appropriately and retrieve the IdentityProxy
+ if (ex instanceof ServerApiException) {
+ ServerApiException ref = (ServerApiException) ex;
+ ArrayList<IdentityProxy> idList = ref.getIdProxyList();
+ if (idList != null) {
+ for (int i=0; i < idList.size(); i++) {
+ IdentityProxy id = idList.get(i);
+ apiResponse.addProxyObject(id.getTableName(), id.getValue(), id.getidFieldName());
+ }
+ }
+ // Also copy over the cserror code and the function/layer in which it was thrown.
+ apiResponse.setCSErrorCode(ref.getCSErrorCode());
+ } else if (ex instanceof PermissionDeniedException) {
+ PermissionDeniedException ref = (PermissionDeniedException) ex;
+ ArrayList<IdentityProxy> idList = ref.getIdProxyList();
+ if (idList != null) {
+ for (int i=0; i < idList.size(); i++) {
+ IdentityProxy id = idList.get(i);
+ apiResponse.addProxyObject(id.getTableName(), id.getValue(), id.getidFieldName());
+ }
+ }
+ // Also copy over the cserror code and the function/layer in which it was thrown.
+ apiResponse.setCSErrorCode(ref.getCSErrorCode());
+ } else if (ex instanceof InvalidParameterValueException) {
+ InvalidParameterValueException ref = (InvalidParameterValueException) ex;
+ ArrayList<IdentityProxy> idList = ref.getIdProxyList();
+ if (idList != null) {
+ for (int i=0; i < idList.size(); i++) {
+ IdentityProxy id = idList.get(i);
+ apiResponse.addProxyObject(id.getTableName(), id.getValue(), id.getidFieldName());
+ }
+ }
+ // Also copy over the cserror code and the function/layer in which it was thrown.
+ apiResponse.setCSErrorCode(ref.getCSErrorCode());
+ }
+ }
+ }
+ SerializationContext.current().setUuidTranslation(true);
+ responseText = ApiResponseSerializer.toSerializedString(apiResponse, responseType);
+
+ } catch (Exception e) {
+ s_logger.error("Exception responding to http request", e);
+ }
+ return responseText;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/f0f33bf4/server/src/com/cloud/domain/DomainVO.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/domain/DomainVO.java b/server/src/com/cloud/domain/DomainVO.java
index 87bc559..bab1dd7 100644
--- a/server/src/com/cloud/domain/DomainVO.java
+++ b/server/src/com/cloud/domain/DomainVO.java
@@ -75,11 +75,11 @@ public class DomainVO implements Domain, Identity {
private String uuid;
@Column(name="region_id")
- private long regionId;
+ private int regionId;
public DomainVO() {}
- public DomainVO(String name, long owner, Long parentId, String networkDomain, Long regionId) {
+ public DomainVO(String name, long owner, Long parentId, String networkDomain, int regionId) {
this.parent = parentId;
this.name = name;
this.accountId = owner;
@@ -91,7 +91,7 @@ public class DomainVO implements Domain, Identity {
this.regionId = regionId;
}
- public DomainVO(String name, long owner, Long parentId, String networkDomain, String uuid, Long regionId) {
+ public DomainVO(String name, long owner, Long parentId, String networkDomain, String uuid, int regionId) {
this.parent = parentId;
this.name = name;
this.accountId = owner;
@@ -215,11 +215,11 @@ public class DomainVO implements Domain, Identity {
this.uuid = uuid;
}
- public long getRegionId() {
+ public int getRegionId() {
return regionId;
}
- public void setRegionId(long regionId) {
+ public void setRegionId(int regionId) {
this.regionId = regionId;
}
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/f0f33bf4/server/src/com/cloud/domain/dao/DomainDaoImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/domain/dao/DomainDaoImpl.java b/server/src/com/cloud/domain/dao/DomainDaoImpl.java
index 90e2891..ecf8325 100644
--- a/server/src/com/cloud/domain/dao/DomainDaoImpl.java
+++ b/server/src/com/cloud/domain/dao/DomainDaoImpl.java
@@ -29,10 +29,9 @@ import org.apache.log4j.Logger;
import com.cloud.domain.Domain;
import com.cloud.domain.DomainVO;
-import com.cloud.user.UserVO;
+import com.cloud.region.RegionManager;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.GenericDaoBase;
-import com.cloud.utils.db.GlobalLock;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.Transaction;
@@ -47,7 +46,6 @@ public class DomainDaoImpl extends GenericDaoBase<DomainVO, Long> implements Dom
protected SearchBuilder<DomainVO> ImmediateChildDomainSearch;
protected SearchBuilder<DomainVO> FindAllChildrenSearch;
protected SearchBuilder<DomainVO> AllFieldsSearch;
- private final long _regionId = 1;
public DomainDaoImpl () {
DomainNameLikeSearch = createSearchBuilder();
@@ -273,10 +271,4 @@ public class DomainDaoImpl extends GenericDaoBase<DomainVO, Long> implements Dom
return parentDomains;
}
- @Override
- @DB
- public DomainVO persist(DomainVO domain) {
- domain.setRegionId(_regionId);
- return super.persist(domain);
- }
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/f0f33bf4/server/src/com/cloud/projects/ProjectManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/projects/ProjectManagerImpl.java b/server/src/com/cloud/projects/ProjectManagerImpl.java
index 68b113c..daf185f 100755
--- a/server/src/com/cloud/projects/ProjectManagerImpl.java
+++ b/server/src/com/cloud/projects/ProjectManagerImpl.java
@@ -207,7 +207,7 @@ public class ProjectManagerImpl implements ProjectManager, Manager{
StringBuilder acctNm = new StringBuilder("PrjAcct-");
acctNm.append(name).append("-").append(owner.getDomainId());
- Account projectAccount = _accountMgr.createAccount(acctNm.toString(), Account.ACCOUNT_TYPE_PROJECT, domainId, null, null, "", 0L);
+ Account projectAccount = _accountMgr.createAccount(acctNm.toString(), Account.ACCOUNT_TYPE_PROJECT, domainId, null, null, "", 0);
Project project = _projectDao.persist(new ProjectVO(name, displayText, owner.getDomainId(), projectAccount.getId()));
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/f0f33bf4/server/src/com/cloud/region/FindDomainResponse.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/region/FindDomainResponse.java b/server/src/com/cloud/region/FindDomainResponse.java
new file mode 100644
index 0000000..075bcf2
--- /dev/null
+++ b/server/src/com/cloud/region/FindDomainResponse.java
@@ -0,0 +1,36 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.region;
+
+import com.cloud.domain.Domain;
+
+
+public class FindDomainResponse {
+
+ private Domain domain;
+
+ public FindDomainResponse(){
+ }
+
+ public Domain getDomain() {
+ return domain;
+ }
+
+ public void setDomain(Domain domain) {
+ this.domain = domain;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/f0f33bf4/server/src/com/cloud/region/FindUserResponse.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/region/FindUserResponse.java b/server/src/com/cloud/region/FindUserResponse.java
new file mode 100644
index 0000000..b6eba46
--- /dev/null
+++ b/server/src/com/cloud/region/FindUserResponse.java
@@ -0,0 +1,34 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.region;
+
+
+public class FindUserResponse {
+
+ private RegionUser user;
+
+ public FindUserResponse(){
+ }
+
+ public RegionUser getUser() {
+ return user;
+ }
+
+ public void setUser(RegionUser user) {
+ this.user = user;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/f0f33bf4/server/src/com/cloud/region/RegionAccount.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/region/RegionAccount.java b/server/src/com/cloud/region/RegionAccount.java
new file mode 100644
index 0000000..cb94210
--- /dev/null
+++ b/server/src/com/cloud/region/RegionAccount.java
@@ -0,0 +1,287 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.region;
+
+import com.cloud.user.AccountVO;
+
+public class RegionAccount extends AccountVO {
+ String accountUuid;
+ String domainUuid;
+ String domain;
+ String receivedbytes;
+ String sentbytes;
+ String vmlimit;
+ String vmtotal;
+ String vmavailable;
+ String iplimit;
+ String iptotal;
+ String ipavailable;
+ String volumelimit;
+ String volumetotal;
+ String volumeavailable;
+ String snapshotlimit;
+ String snapshottotal;
+ String snapshotavailable;
+ String templatelimit;
+ String templatetotal;
+ String templateavailable;
+ String vmstopped;
+ String vmrunning;
+ String projectlimit;
+ String projecttotal;
+ String projectavailable;
+ String networklimit;
+ String networktotal;
+ String networkavailable;
+ RegionUser user;
+
+ public RegionAccount() {
+ }
+
+ public String getAccountuuid() {
+ return accountUuid;
+ }
+
+ public void setAccountuuid(String accountUuid) {
+ this.accountUuid = accountUuid;
+ }
+
+ public String getDomainUuid() {
+ return domainUuid;
+ }
+
+ public void setDomainUuid(String domainUuid) {
+ this.domainUuid = domainUuid;
+ }
+
+ public String getDomain() {
+ return domain;
+ }
+
+ public void setDomain(String domain) {
+ this.domain = domain;
+ }
+
+ public String getReceivedbytes() {
+ return receivedbytes;
+ }
+
+ public void setReceivedbytes(String receivedbytes) {
+ this.receivedbytes = receivedbytes;
+ }
+
+ public String getSentbytes() {
+ return sentbytes;
+ }
+
+ public void setSentbytes(String sentbytes) {
+ this.sentbytes = sentbytes;
+ }
+
+ public String getVmlimit() {
+ return vmlimit;
+ }
+
+ public void setVmlimit(String vmlimit) {
+ this.vmlimit = vmlimit;
+ }
+
+ public String getVmtotal() {
+ return vmtotal;
+ }
+
+ public void setVmtotal(String vmtotal) {
+ this.vmtotal = vmtotal;
+ }
+
+ public String getVmavailable() {
+ return vmavailable;
+ }
+
+ public void setVmavailable(String vmavailable) {
+ this.vmavailable = vmavailable;
+ }
+
+ public String getIplimit() {
+ return iplimit;
+ }
+
+ public void setIplimit(String iplimit) {
+ this.iplimit = iplimit;
+ }
+
+ public String getIptotal() {
+ return iptotal;
+ }
+
+ public void setIptotal(String iptotal) {
+ this.iptotal = iptotal;
+ }
+
+ public String getIpavailable() {
+ return ipavailable;
+ }
+
+ public void setIpavailable(String ipavailable) {
+ this.ipavailable = ipavailable;
+ }
+
+ public String getVolumelimit() {
+ return volumelimit;
+ }
+
+ public void setVolumelimit(String volumelimit) {
+ this.volumelimit = volumelimit;
+ }
+
+ public String getVolumetotal() {
+ return volumetotal;
+ }
+
+ public void setVolumetotal(String volumetotal) {
+ this.volumetotal = volumetotal;
+ }
+
+ public String getVolumeavailable() {
+ return volumeavailable;
+ }
+
+ public void setVolumeavailable(String volumeavailable) {
+ this.volumeavailable = volumeavailable;
+ }
+
+ public String getSnapshotlimit() {
+ return snapshotlimit;
+ }
+
+ public void setSnapshotlimit(String snapshotlimit) {
+ this.snapshotlimit = snapshotlimit;
+ }
+
+ public String getSnapshottotal() {
+ return snapshottotal;
+ }
+
+ public void setSnapshottotal(String snapshottotal) {
+ this.snapshottotal = snapshottotal;
+ }
+
+ public String getSnapshotavailable() {
+ return snapshotavailable;
+ }
+
+ public void setSnapshotavailable(String snapshotavailable) {
+ this.snapshotavailable = snapshotavailable;
+ }
+
+ public String getTemplatelimit() {
+ return templatelimit;
+ }
+
+ public void setTemplatelimit(String templatelimit) {
+ this.templatelimit = templatelimit;
+ }
+
+ public String getTemplatetotal() {
+ return templatetotal;
+ }
+
+ public void setTemplatetotal(String templatetotal) {
+ this.templatetotal = templatetotal;
+ }
+
+ public String getTemplateavailable() {
+ return templateavailable;
+ }
+
+ public void setTemplateavailable(String templateavailable) {
+ this.templateavailable = templateavailable;
+ }
+
+ public String getVmstopped() {
+ return vmstopped;
+ }
+
+ public void setVmstopped(String vmstopped) {
+ this.vmstopped = vmstopped;
+ }
+
+ public String getVmrunning() {
+ return vmrunning;
+ }
+
+ public void setVmrunning(String vmrunning) {
+ this.vmrunning = vmrunning;
+ }
+
+ public String getProjectlimit() {
+ return projectlimit;
+ }
+
+ public void setProjectlimit(String projectlimit) {
+ this.projectlimit = projectlimit;
+ }
+
+ public String getProjecttotal() {
+ return projecttotal;
+ }
+
+ public void setProjecttotal(String projecttotal) {
+ this.projecttotal = projecttotal;
+ }
+
+ public String getProjectavailable() {
+ return projectavailable;
+ }
+
+ public void setProjectavailable(String projectavailable) {
+ this.projectavailable = projectavailable;
+ }
+
+ public String getNetworklimit() {
+ return networklimit;
+ }
+
+ public void setNetworklimit(String networklimit) {
+ this.networklimit = networklimit;
+ }
+
+ public String getNetworktotal() {
+ return networktotal;
+ }
+
+ public void setNetworktotal(String networktotal) {
+ this.networktotal = networktotal;
+ }
+
+ public String getNetworkavailable() {
+ return networkavailable;
+ }
+
+ public void setNetworkavailable(String networkavailable) {
+ this.networkavailable = networkavailable;
+ }
+
+ public RegionUser getUser() {
+ return user;
+ }
+
+ public void setUser(RegionUser user) {
+ this.user = user;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/f0f33bf4/server/src/com/cloud/region/RegionDomain.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/region/RegionDomain.java b/server/src/com/cloud/region/RegionDomain.java
new file mode 100644
index 0000000..de82654
--- /dev/null
+++ b/server/src/com/cloud/region/RegionDomain.java
@@ -0,0 +1,61 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.region;
+
+import com.cloud.domain.DomainVO;
+
+public class RegionDomain extends DomainVO {
+ String accountUuid;
+ String parentUuid;
+ String parentdomainname;
+ Boolean haschild;
+
+ public RegionDomain() {
+ }
+
+ public String getAccountuuid() {
+ return accountUuid;
+ }
+
+ public void setAccountuuid(String accountUuid) {
+ this.accountUuid = accountUuid;
+ }
+
+ public String getParentUuid() {
+ return parentUuid;
+ }
+
+ public void setParentUuid(String parentUuid) {
+ this.parentUuid = parentUuid;
+ }
+
+ public String getParentdomainname() {
+ return parentdomainname;
+ }
+
+ public void setParentdomainname(String parentdomainname) {
+ this.parentdomainname = parentdomainname;
+ }
+
+ public Boolean getHaschild() {
+ return haschild;
+ }
+
+ public void setHaschild(Boolean haschild) {
+ this.haschild = haschild;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/f0f33bf4/server/src/com/cloud/region/RegionManager.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/region/RegionManager.java b/server/src/com/cloud/region/RegionManager.java
index d74633d..20e24ba 100644
--- a/server/src/com/cloud/region/RegionManager.java
+++ b/server/src/com/cloud/region/RegionManager.java
@@ -18,14 +18,19 @@ package com.cloud.region;
import java.util.Map;
+import com.cloud.domain.DomainVO;
+import com.cloud.user.UserAccount;
+
public interface RegionManager {
public boolean propogateAddAccount(String userName, String password, String firstName, String lastName, String email, String timezone, String accountName, short accountType, Long domainId, String networkDomain,
Map<String, String> details, String accountUUID, String userUUID);
- public long getId();
- public void setId(long id);
+ public int getId();
+ public void setId(int id);
public void propogateAddUser(String userName, String password,
String firstName, String lastName, String email, String timeZone,
String accountName, String domainUUId, String userUUID);
public void propogateAddDomain(String name, Long parentId, String networkDomain, String uuid);
+ UserAccount getUserAccount(String username, Long domainId);
+ DomainVO findDomainByPath(String domainPath);
}