mirror of https://github.com/apache/cloudstack.git
Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/incubator-cloudstack
This commit is contained in:
commit
dd949aebaf
|
|
@ -1,22 +1,4 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="src" path="test"/>
|
||||
|
|
|
|||
|
|
@ -241,7 +241,7 @@
|
|||
<available file="${setup.db.dir}/override/templates.sql" />
|
||||
</condition>
|
||||
|
||||
<echo message="deploydb ${server-setup.file} ${templates.file} ${DBROOTPW}" />
|
||||
<echo message="${db.scripts.dir}\\deploy-db-dev.sh ${server-setup.file} ${templates.file} ${DBROOTPW}" />
|
||||
<exec dir="${db.scripts.dir}" executable="bash" failonerror="true">
|
||||
<arg value="deploy-db-dev.sh" />
|
||||
<arg value="${server-setup.file}" />
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ import javax.crypto.spec.SecretKeySpec;
|
|||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.http.ConnectionClosedException;
|
||||
import org.apache.http.HttpException;
|
||||
import org.apache.http.HttpRequest;
|
||||
|
|
@ -112,7 +113,6 @@ import com.cloud.utils.component.PluggableService;
|
|||
import com.cloud.utils.concurrency.NamedThreadFactory;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.utils.db.Transaction;
|
||||
import com.cloud.utils.encoding.Base64;
|
||||
import com.cloud.utils.exception.CSExceptionErrorCode;
|
||||
import com.cloud.uuididentity.dao.IdentityDao;
|
||||
|
||||
|
|
@ -432,31 +432,31 @@ public class ApiServer implements HttpRequestHandler {
|
|||
}
|
||||
} catch (Exception ex) {
|
||||
if (ex instanceof InvalidParameterValueException) {
|
||||
InvalidParameterValueException ref = (InvalidParameterValueException)ex;
|
||||
ServerApiException e = new ServerApiException(BaseCmd.PARAM_ERROR, ex.getMessage());
|
||||
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());
|
||||
}
|
||||
// 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());
|
||||
e.setCSErrorCode(ref.getCSErrorCode());
|
||||
throw e;
|
||||
} else if (ex instanceof PermissionDeniedException) {
|
||||
PermissionDeniedException ref = (PermissionDeniedException)ex;
|
||||
ServerApiException e = new ServerApiException(BaseCmd.ACCOUNT_ERROR, ex.getMessage());
|
||||
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();
|
||||
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());
|
||||
}
|
||||
// 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;
|
||||
|
|
@ -751,7 +751,7 @@ public class ApiServer implements HttpRequestHandler {
|
|||
mac.init(keySpec);
|
||||
mac.update(unsignedRequest.getBytes());
|
||||
byte[] encryptedBytes = mac.doFinal();
|
||||
String computedSignature = Base64.encodeBytes(encryptedBytes);
|
||||
String computedSignature = Base64.encodeBase64URLSafeString(encryptedBytes);
|
||||
boolean equalSig = signature.equals(computedSignature);
|
||||
if (!equalSig) {
|
||||
s_logger.info("User signature: " + signature + " is not equaled to computed signature: " + computedSignature);
|
||||
|
|
@ -765,7 +765,7 @@ public class ApiServer implements HttpRequestHandler {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public Long fetchDomainId(String domainUUID){
|
||||
ComponentLocator locator = ComponentLocator.getLocator(ManagementServer.Name);
|
||||
IdentityDao identityDao = locator.getDao(IdentityDao.class);
|
||||
|
|
@ -816,19 +816,19 @@ public class ApiServer implements HttpRequestHandler {
|
|||
if(user.getUuid() != null){
|
||||
session.setAttribute("user_UUID", user.getUuid());
|
||||
}
|
||||
|
||||
|
||||
session.setAttribute("username", userAcct.getUsername());
|
||||
session.setAttribute("firstname", userAcct.getFirstname());
|
||||
session.setAttribute("lastname", userAcct.getLastname());
|
||||
session.setAttribute("accountobj", account);
|
||||
session.setAttribute("account", account.getAccountName());
|
||||
|
||||
|
||||
session.setAttribute("domainid", account.getDomainId());
|
||||
DomainVO domain = (DomainVO) _domainMgr.getDomain(account.getDomainId());
|
||||
if(domain.getUuid() != null){
|
||||
session.setAttribute("domain_UUID", domain.getUuid());
|
||||
}
|
||||
|
||||
|
||||
session.setAttribute("type", Short.valueOf(account.getType()).toString());
|
||||
session.setAttribute("registrationtoken", userAcct.getRegistrationToken());
|
||||
session.setAttribute("registered", new Boolean(userAcct.isRegistered()).toString());
|
||||
|
|
@ -843,7 +843,7 @@ public class ApiServer implements HttpRequestHandler {
|
|||
SecureRandom sesssionKeyRandom = new SecureRandom();
|
||||
byte sessionKeyBytes[] = new byte[20];
|
||||
sesssionKeyRandom.nextBytes(sessionKeyBytes);
|
||||
String sessionKey = Base64.encodeBytes(sessionKeyBytes);
|
||||
String sessionKey = Base64.encodeBase64URLSafeString(sessionKeyBytes);
|
||||
session.setAttribute("sessionkey", sessionKey);
|
||||
|
||||
return;
|
||||
|
|
@ -938,8 +938,8 @@ public class ApiServer implements HttpRequestHandler {
|
|||
|
||||
_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");
|
||||
.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();
|
||||
|
|
@ -1053,44 +1053,44 @@ public class ApiServer implements HttpRequestHandler {
|
|||
// 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());
|
||||
}
|
||||
}
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -58,61 +58,61 @@ import com.cloud.vm.VirtualMachineManager;
|
|||
* Authentication : /console?cmd=auth&vm=xxx&sid=xxx
|
||||
*/
|
||||
public class ConsoleProxyServlet extends HttpServlet {
|
||||
private static final long serialVersionUID = -5515382620323808168L;
|
||||
public static final Logger s_logger = Logger.getLogger(ConsoleProxyServlet.class.getName());
|
||||
private static final int DEFAULT_THUMBNAIL_WIDTH = 144;
|
||||
private static final int DEFAULT_THUMBNAIL_HEIGHT = 110;
|
||||
|
||||
private final static AccountManager _accountMgr = ComponentLocator.getLocator(ManagementServer.Name).getManager(AccountManager.class);
|
||||
private final static VirtualMachineManager _vmMgr = ComponentLocator.getLocator(ManagementServer.Name).getManager(VirtualMachineManager.class);
|
||||
private final static ManagementServer _ms = (ManagementServer)ComponentLocator.getComponent(ManagementServer.Name);
|
||||
private final static IdentityService _identityService = (IdentityService)ComponentLocator.getLocator(ManagementServer.Name).getManager(IdentityService.class);
|
||||
|
||||
@Override
|
||||
private static final long serialVersionUID = -5515382620323808168L;
|
||||
public static final Logger s_logger = Logger.getLogger(ConsoleProxyServlet.class.getName());
|
||||
private static final int DEFAULT_THUMBNAIL_WIDTH = 144;
|
||||
private static final int DEFAULT_THUMBNAIL_HEIGHT = 110;
|
||||
|
||||
private final static AccountManager _accountMgr = ComponentLocator.getLocator(ManagementServer.Name).getManager(AccountManager.class);
|
||||
private final static VirtualMachineManager _vmMgr = ComponentLocator.getLocator(ManagementServer.Name).getManager(VirtualMachineManager.class);
|
||||
private final static ManagementServer _ms = (ManagementServer)ComponentLocator.getComponent(ManagementServer.Name);
|
||||
private final static IdentityService _identityService = ComponentLocator.getLocator(ManagementServer.Name).getManager(IdentityService.class);
|
||||
|
||||
@Override
|
||||
protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
|
||||
doGet(req, resp);
|
||||
}
|
||||
|
||||
@Override
|
||||
doGet(req, resp);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
|
||||
|
||||
try {
|
||||
if(_accountMgr == null || _vmMgr == null || _ms == null) {
|
||||
sendResponse(resp, "Service is not ready");
|
||||
return;
|
||||
}
|
||||
|
||||
if(_ms.getHashKey() == null) {
|
||||
s_logger.debug("Console/thumbnail access denied. Ticket service is not ready yet");
|
||||
sendResponse(resp, "Service is not ready");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
if(_accountMgr == null || _vmMgr == null || _ms == null) {
|
||||
sendResponse(resp, "Service is not ready");
|
||||
return;
|
||||
}
|
||||
|
||||
if(_ms.getHashKey() == null) {
|
||||
s_logger.debug("Console/thumbnail access denied. Ticket service is not ready yet");
|
||||
sendResponse(resp, "Service is not ready");
|
||||
return;
|
||||
}
|
||||
|
||||
String userId = null;
|
||||
String account = null;
|
||||
Account accountObj = null;
|
||||
|
||||
|
||||
Map<String, Object[]> params = new HashMap<String, Object[]>();
|
||||
params.putAll(req.getParameterMap());
|
||||
|
||||
HttpSession session = req.getSession(false);
|
||||
if(session == null) {
|
||||
if(verifyRequest(params)) {
|
||||
if(verifyRequest(params)) {
|
||||
userId = (String)params.get("userid")[0];
|
||||
account = (String)params.get("account")[0];
|
||||
accountObj = (Account)params.get("accountobj")[0];
|
||||
} else {
|
||||
s_logger.debug("Invalid web session or API key in request, reject console/thumbnail access");
|
||||
sendResponse(resp, "Access denied. Invalid web session or API key in request");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
s_logger.debug("Invalid web session or API key in request, reject console/thumbnail access");
|
||||
sendResponse(resp, "Access denied. Invalid web session or API key in request");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// adjust to latest API refactoring changes
|
||||
if(session.getAttribute("userid") != null) {
|
||||
// adjust to latest API refactoring changes
|
||||
if(session.getAttribute("userid") != null) {
|
||||
userId = ((Long)session.getAttribute("userid")).toString();
|
||||
}
|
||||
|
||||
accountObj = (Account)session.getAttribute("accountobj");
|
||||
|
||||
accountObj = (Account)session.getAttribute("accountobj");
|
||||
if(accountObj != null) {
|
||||
account = "" + accountObj.getId();
|
||||
}
|
||||
|
|
@ -120,381 +120,381 @@ public class ConsoleProxyServlet extends HttpServlet {
|
|||
|
||||
// Do a sanity check here to make sure the user hasn't already been deleted
|
||||
if ((userId == null) || (account == null) || (accountObj == null) || !verifyUser(Long.valueOf(userId))) {
|
||||
s_logger.debug("Invalid user/account, reject console/thumbnail access");
|
||||
sendResponse(resp, "Access denied. Invalid or inconsistent account is found");
|
||||
return;
|
||||
s_logger.debug("Invalid user/account, reject console/thumbnail access");
|
||||
sendResponse(resp, "Access denied. Invalid or inconsistent account is found");
|
||||
return;
|
||||
}
|
||||
|
||||
String cmd = req.getParameter("cmd");
|
||||
if(cmd == null || !isValidCmd(cmd)) {
|
||||
s_logger.debug("invalid console servlet command: " + cmd);
|
||||
sendResponse(resp, "");
|
||||
return;
|
||||
}
|
||||
String cmd = req.getParameter("cmd");
|
||||
if(cmd == null || !isValidCmd(cmd)) {
|
||||
s_logger.debug("invalid console servlet command: " + cmd);
|
||||
sendResponse(resp, "");
|
||||
return;
|
||||
}
|
||||
|
||||
String vmIdString = req.getParameter("vm");
|
||||
Long vmId = _identityService.getIdentityId("vm_instance", vmIdString);
|
||||
if(vmId == null) {
|
||||
s_logger.info("invalid console servlet command parameter: " + vmIdString);
|
||||
sendResponse(resp, "");
|
||||
return;
|
||||
}
|
||||
|
||||
if(!checkSessionPermision(req, vmId, accountObj)) {
|
||||
sendResponse(resp, "Permission denied");
|
||||
return;
|
||||
}
|
||||
|
||||
if(cmd.equalsIgnoreCase("thumbnail")) {
|
||||
String vmIdString = req.getParameter("vm");
|
||||
Long vmId = _identityService.getIdentityId("vm_instance", vmIdString);
|
||||
if(vmId == null) {
|
||||
s_logger.info("invalid console servlet command parameter: " + vmIdString);
|
||||
sendResponse(resp, "");
|
||||
return;
|
||||
}
|
||||
|
||||
if(!checkSessionPermision(req, vmId, accountObj)) {
|
||||
sendResponse(resp, "Permission denied");
|
||||
return;
|
||||
}
|
||||
|
||||
if(cmd.equalsIgnoreCase("thumbnail")) {
|
||||
handleThumbnailRequest(req, resp, vmId);
|
||||
} else if(cmd.equalsIgnoreCase("access")) {
|
||||
handleAccessRequest(req, resp, vmId);
|
||||
} else {
|
||||
handleAuthRequest(req, resp, vmId);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
s_logger.error("Unexepected exception in ConsoleProxyServlet", e);
|
||||
sendResponse(resp, "Server Internal Error");
|
||||
}
|
||||
}
|
||||
|
||||
private void handleThumbnailRequest(HttpServletRequest req, HttpServletResponse resp, long vmId) {
|
||||
VMInstanceVO vm = _vmMgr.findById(vmId);
|
||||
if(vm == null) {
|
||||
s_logger.warn("VM " + vmId + " does not exist, sending blank response for thumbnail request");
|
||||
sendResponse(resp, "");
|
||||
return;
|
||||
}
|
||||
|
||||
if(vm.getHostId() == null) {
|
||||
s_logger.warn("VM " + vmId + " lost host info, sending blank response for thumbnail request");
|
||||
sendResponse(resp, "");
|
||||
return;
|
||||
}
|
||||
|
||||
HostVO host = _ms.getHostBy(vm.getHostId());
|
||||
if(host == null) {
|
||||
s_logger.warn("VM " + vmId + "'s host does not exist, sending blank response for thumbnail request");
|
||||
sendResponse(resp, "");
|
||||
return;
|
||||
}
|
||||
|
||||
String rootUrl = _ms.getConsoleAccessUrlRoot(vmId);
|
||||
if(rootUrl == null) {
|
||||
sendResponse(resp, "");
|
||||
return;
|
||||
}
|
||||
|
||||
int w = DEFAULT_THUMBNAIL_WIDTH;
|
||||
int h = DEFAULT_THUMBNAIL_HEIGHT;
|
||||
|
||||
String value = req.getParameter("w");
|
||||
try {
|
||||
w = Integer.parseInt(value);
|
||||
} catch(NumberFormatException e) {
|
||||
}
|
||||
|
||||
value = req.getParameter("h");
|
||||
try {
|
||||
h = Integer.parseInt(value);
|
||||
} catch(NumberFormatException e) {
|
||||
}
|
||||
|
||||
try {
|
||||
resp.sendRedirect(composeThumbnailUrl(rootUrl, vm, host, w, h));
|
||||
} catch (IOException e) {
|
||||
if(s_logger.isInfoEnabled()) {
|
||||
} catch (Throwable e) {
|
||||
s_logger.error("Unexepected exception in ConsoleProxyServlet", e);
|
||||
sendResponse(resp, "Server Internal Error");
|
||||
}
|
||||
}
|
||||
|
||||
private void handleThumbnailRequest(HttpServletRequest req, HttpServletResponse resp, long vmId) {
|
||||
VMInstanceVO vm = _vmMgr.findById(vmId);
|
||||
if(vm == null) {
|
||||
s_logger.warn("VM " + vmId + " does not exist, sending blank response for thumbnail request");
|
||||
sendResponse(resp, "");
|
||||
return;
|
||||
}
|
||||
|
||||
if(vm.getHostId() == null) {
|
||||
s_logger.warn("VM " + vmId + " lost host info, sending blank response for thumbnail request");
|
||||
sendResponse(resp, "");
|
||||
return;
|
||||
}
|
||||
|
||||
HostVO host = _ms.getHostBy(vm.getHostId());
|
||||
if(host == null) {
|
||||
s_logger.warn("VM " + vmId + "'s host does not exist, sending blank response for thumbnail request");
|
||||
sendResponse(resp, "");
|
||||
return;
|
||||
}
|
||||
|
||||
String rootUrl = _ms.getConsoleAccessUrlRoot(vmId);
|
||||
if(rootUrl == null) {
|
||||
sendResponse(resp, "");
|
||||
return;
|
||||
}
|
||||
|
||||
int w = DEFAULT_THUMBNAIL_WIDTH;
|
||||
int h = DEFAULT_THUMBNAIL_HEIGHT;
|
||||
|
||||
String value = req.getParameter("w");
|
||||
try {
|
||||
w = Integer.parseInt(value);
|
||||
} catch(NumberFormatException e) {
|
||||
}
|
||||
|
||||
value = req.getParameter("h");
|
||||
try {
|
||||
h = Integer.parseInt(value);
|
||||
} catch(NumberFormatException e) {
|
||||
}
|
||||
|
||||
try {
|
||||
resp.sendRedirect(composeThumbnailUrl(rootUrl, vm, host, w, h));
|
||||
} catch (IOException e) {
|
||||
if(s_logger.isInfoEnabled()) {
|
||||
s_logger.info("Client may already close the connection");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleAccessRequest(HttpServletRequest req, HttpServletResponse resp, long vmId) {
|
||||
VMInstanceVO vm = _vmMgr.findById(vmId);
|
||||
if(vm == null) {
|
||||
s_logger.warn("VM " + vmId + " does not exist, sending blank response for console access request");
|
||||
sendResponse(resp, "");
|
||||
return;
|
||||
}
|
||||
|
||||
if(vm.getHostId() == null) {
|
||||
s_logger.warn("VM " + vmId + " lost host info, sending blank response for console access request");
|
||||
sendResponse(resp, "");
|
||||
return;
|
||||
}
|
||||
|
||||
HostVO host = _ms.getHostBy(vm.getHostId());
|
||||
if(host == null) {
|
||||
s_logger.warn("VM " + vmId + "'s host does not exist, sending blank response for console access request");
|
||||
sendResponse(resp, "");
|
||||
return;
|
||||
}
|
||||
|
||||
String rootUrl = _ms.getConsoleAccessUrlRoot(vmId);
|
||||
if(rootUrl == null) {
|
||||
sendResponse(resp, "<html><body><p>Console access will be ready in a few minutes. Please try it again later.</p></body></html>");
|
||||
return;
|
||||
}
|
||||
|
||||
String vmName = vm.getHostName();
|
||||
if(vm.getType() == VirtualMachine.Type.User) {
|
||||
UserVm userVm = (UserVm)_vmMgr.findByIdAndType(VirtualMachine.Type.User, vmId);
|
||||
String displayName = userVm.getDisplayName();
|
||||
if(displayName != null && !displayName.isEmpty() && !displayName.equals(vmName)) {
|
||||
vmName += "(" + displayName + ")";
|
||||
}
|
||||
}
|
||||
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append("<html><title>").append(escapeHTML(vmName)).append("</title><frameset><frame src=\"").append(composeConsoleAccessUrl(rootUrl, vm, host));
|
||||
sb.append("\"></frame></frameset></html>");
|
||||
s_logger.debug("the console url is :: " + sb.toString());
|
||||
sendResponse(resp, sb.toString());
|
||||
}
|
||||
|
||||
private void handleAuthRequest(HttpServletRequest req, HttpServletResponse resp, long vmId) {
|
||||
|
||||
// TODO authentication channel between console proxy VM and management server needs to be secured,
|
||||
// the data is now being sent through private network, but this is apparently not enough
|
||||
VMInstanceVO vm = _vmMgr.findById(vmId);
|
||||
if(vm == null) {
|
||||
s_logger.warn("VM " + vmId + " does not exist, sending failed response for authentication request from console proxy");
|
||||
sendResponse(resp, "failed");
|
||||
return;
|
||||
}
|
||||
|
||||
if(vm.getHostId() == null) {
|
||||
s_logger.warn("VM " + vmId + " lost host info, failed response for authentication request from console proxy");
|
||||
sendResponse(resp, "failed");
|
||||
return;
|
||||
}
|
||||
|
||||
HostVO host = _ms.getHostBy(vm.getHostId());
|
||||
if(host == null) {
|
||||
s_logger.warn("VM " + vmId + "'s host does not exist, sending failed response for authentication request from console proxy");
|
||||
sendResponse(resp, "failed");
|
||||
return;
|
||||
}
|
||||
|
||||
String sid = req.getParameter("sid");
|
||||
if(sid == null || !sid.equals(vm.getVncPassword())) {
|
||||
s_logger.warn("sid " + sid + " in url does not match stored sid " + vm.getVncPassword());
|
||||
sendResponse(resp, "failed");
|
||||
return;
|
||||
}
|
||||
|
||||
sendResponse(resp, "success");
|
||||
}
|
||||
|
||||
// put the ugly stuff here
|
||||
static public Ternary<String, String, String> parseHostInfo(String hostInfo) {
|
||||
String host = null;
|
||||
String tunnelUrl = null;
|
||||
String tunnelSession = null;
|
||||
|
||||
s_logger.info("Parse host info returned from executing GetVNCPortCommand. host info: " + hostInfo);
|
||||
|
||||
if(hostInfo != null && hostInfo.startsWith("consoleurl")) {
|
||||
String tokens[] = hostInfo.split("&");
|
||||
|
||||
if(hostInfo.length() > 19 && hostInfo.indexOf('/', 19) > 19) {
|
||||
host = hostInfo.substring(19, hostInfo.indexOf('/', 19)).trim();
|
||||
tunnelUrl = tokens[0].substring("consoleurl=".length());
|
||||
tunnelSession = tokens[1].split("=")[1];
|
||||
} else {
|
||||
host = "";
|
||||
}
|
||||
} else {
|
||||
host = hostInfo;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void handleAccessRequest(HttpServletRequest req, HttpServletResponse resp, long vmId) {
|
||||
VMInstanceVO vm = _vmMgr.findById(vmId);
|
||||
if(vm == null) {
|
||||
s_logger.warn("VM " + vmId + " does not exist, sending blank response for console access request");
|
||||
sendResponse(resp, "");
|
||||
return;
|
||||
}
|
||||
|
||||
if(vm.getHostId() == null) {
|
||||
s_logger.warn("VM " + vmId + " lost host info, sending blank response for console access request");
|
||||
sendResponse(resp, "");
|
||||
return;
|
||||
}
|
||||
|
||||
HostVO host = _ms.getHostBy(vm.getHostId());
|
||||
if(host == null) {
|
||||
s_logger.warn("VM " + vmId + "'s host does not exist, sending blank response for console access request");
|
||||
sendResponse(resp, "");
|
||||
return;
|
||||
}
|
||||
|
||||
String rootUrl = _ms.getConsoleAccessUrlRoot(vmId);
|
||||
if(rootUrl == null) {
|
||||
sendResponse(resp, "<html><body><p>Console access will be ready in a few minutes. Please try it again later.</p></body></html>");
|
||||
return;
|
||||
}
|
||||
|
||||
String vmName = vm.getHostName();
|
||||
if(vm.getType() == VirtualMachine.Type.User) {
|
||||
UserVm userVm = (UserVm)_vmMgr.findByIdAndType(VirtualMachine.Type.User, vmId);
|
||||
String displayName = userVm.getDisplayName();
|
||||
if(displayName != null && !displayName.isEmpty() && !displayName.equals(vmName)) {
|
||||
vmName += "(" + displayName + ")";
|
||||
}
|
||||
}
|
||||
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append("<html><title>").append(escapeHTML(vmName)).append("</title><frameset><frame src=\"").append(composeConsoleAccessUrl(rootUrl, vm, host));
|
||||
sb.append("\"></frame></frameset></html>");
|
||||
s_logger.debug("the console url is :: " + sb.toString());
|
||||
sendResponse(resp, sb.toString());
|
||||
}
|
||||
|
||||
private void handleAuthRequest(HttpServletRequest req, HttpServletResponse resp, long vmId) {
|
||||
|
||||
// TODO authentication channel between console proxy VM and management server needs to be secured,
|
||||
// the data is now being sent through private network, but this is apparently not enough
|
||||
VMInstanceVO vm = _vmMgr.findById(vmId);
|
||||
if(vm == null) {
|
||||
s_logger.warn("VM " + vmId + " does not exist, sending failed response for authentication request from console proxy");
|
||||
sendResponse(resp, "failed");
|
||||
return;
|
||||
}
|
||||
|
||||
if(vm.getHostId() == null) {
|
||||
s_logger.warn("VM " + vmId + " lost host info, failed response for authentication request from console proxy");
|
||||
sendResponse(resp, "failed");
|
||||
return;
|
||||
}
|
||||
|
||||
HostVO host = _ms.getHostBy(vm.getHostId());
|
||||
if(host == null) {
|
||||
s_logger.warn("VM " + vmId + "'s host does not exist, sending failed response for authentication request from console proxy");
|
||||
sendResponse(resp, "failed");
|
||||
return;
|
||||
}
|
||||
|
||||
String sid = req.getParameter("sid");
|
||||
if(sid == null || !sid.equals(vm.getVncPassword())) {
|
||||
s_logger.warn("sid " + sid + " in url does not match stored sid " + vm.getVncPassword());
|
||||
sendResponse(resp, "failed");
|
||||
return;
|
||||
}
|
||||
|
||||
sendResponse(resp, "success");
|
||||
}
|
||||
|
||||
// put the ugly stuff here
|
||||
static public Ternary<String, String, String> parseHostInfo(String hostInfo) {
|
||||
String host = null;
|
||||
String tunnelUrl = null;
|
||||
String tunnelSession = null;
|
||||
|
||||
s_logger.info("Parse host info returned from executing GetVNCPortCommand. host info: " + hostInfo);
|
||||
|
||||
if(hostInfo != null && hostInfo.startsWith("consoleurl")) {
|
||||
String tokens[] = hostInfo.split("&");
|
||||
|
||||
if(hostInfo.length() > 19 && hostInfo.indexOf('/', 19) > 19) {
|
||||
host = hostInfo.substring(19, hostInfo.indexOf('/', 19)).trim();
|
||||
tunnelUrl = tokens[0].substring("consoleurl=".length());
|
||||
tunnelSession = tokens[1].split("=")[1];
|
||||
} else {
|
||||
host = "";
|
||||
}
|
||||
} else {
|
||||
host = hostInfo;
|
||||
}
|
||||
|
||||
return new Ternary<String, String, String>(host, tunnelUrl, tunnelSession);
|
||||
}
|
||||
|
||||
private String composeThumbnailUrl(String rootUrl, VMInstanceVO vm, HostVO hostVo, int w, int h) {
|
||||
StringBuffer sb = new StringBuffer(rootUrl);
|
||||
}
|
||||
|
||||
String host = hostVo.getPrivateIpAddress();
|
||||
|
||||
Pair<String, Integer> portInfo = _ms.getVncPort(vm);
|
||||
Ternary<String, String, String> parsedHostInfo = parseHostInfo(portInfo.first());
|
||||
|
||||
String sid = vm.getVncPassword();
|
||||
String tag = String.valueOf(vm.getId());
|
||||
tag = _identityService.getIdentityUuid("vm_instance", tag);
|
||||
String ticket = genAccessTicket(host, String.valueOf(portInfo.second()), sid, tag);
|
||||
private String composeThumbnailUrl(String rootUrl, VMInstanceVO vm, HostVO hostVo, int w, int h) {
|
||||
StringBuffer sb = new StringBuffer(rootUrl);
|
||||
|
||||
ConsoleProxyPasswordBasedEncryptor encryptor = new ConsoleProxyPasswordBasedEncryptor(_ms.getHashKey());
|
||||
ConsoleProxyClientParam param = new ConsoleProxyClientParam();
|
||||
param.setClientHostAddress(parsedHostInfo.first());
|
||||
param.setClientHostPort(portInfo.second());
|
||||
param.setClientHostPassword(sid);
|
||||
param.setClientTag(tag);
|
||||
param.setTicket(ticket);
|
||||
if(parsedHostInfo.second() != null && parsedHostInfo.third() != null) {
|
||||
param.setClientTunnelUrl(parsedHostInfo.second());
|
||||
param.setClientTunnelSession(parsedHostInfo.third());
|
||||
}
|
||||
|
||||
sb.append("/ajax?token=" + encryptor.encryptObject(ConsoleProxyClientParam.class, param));
|
||||
sb.append("&w=").append(w).append("&h=").append(h);
|
||||
|
||||
if(s_logger.isDebugEnabled()) {
|
||||
String host = hostVo.getPrivateIpAddress();
|
||||
|
||||
Pair<String, Integer> portInfo = _ms.getVncPort(vm);
|
||||
Ternary<String, String, String> parsedHostInfo = parseHostInfo(portInfo.first());
|
||||
|
||||
String sid = vm.getVncPassword();
|
||||
String tag = String.valueOf(vm.getId());
|
||||
tag = _identityService.getIdentityUuid("vm_instance", tag);
|
||||
String ticket = genAccessTicket(host, String.valueOf(portInfo.second()), sid, tag);
|
||||
|
||||
ConsoleProxyPasswordBasedEncryptor encryptor = new ConsoleProxyPasswordBasedEncryptor(_ms.getHashKey());
|
||||
ConsoleProxyClientParam param = new ConsoleProxyClientParam();
|
||||
param.setClientHostAddress(parsedHostInfo.first());
|
||||
param.setClientHostPort(portInfo.second());
|
||||
param.setClientHostPassword(sid);
|
||||
param.setClientTag(tag);
|
||||
param.setTicket(ticket);
|
||||
if(parsedHostInfo.second() != null && parsedHostInfo.third() != null) {
|
||||
param.setClientTunnelUrl(parsedHostInfo.second());
|
||||
param.setClientTunnelSession(parsedHostInfo.third());
|
||||
}
|
||||
|
||||
sb.append("/ajax?token=" + encryptor.encryptObject(ConsoleProxyClientParam.class, param));
|
||||
sb.append("&w=").append(w).append("&h=").append(h);
|
||||
|
||||
if(s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Compose thumbnail url: " + sb.toString());
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private String composeConsoleAccessUrl(String rootUrl, VMInstanceVO vm, HostVO hostVo) {
|
||||
StringBuffer sb = new StringBuffer(rootUrl);
|
||||
String host = hostVo.getPrivateIpAddress();
|
||||
|
||||
Pair<String, Integer> portInfo = _ms.getVncPort(vm);
|
||||
if(s_logger.isDebugEnabled())
|
||||
s_logger.debug("Port info " + portInfo.first());
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
Ternary<String, String, String> parsedHostInfo = parseHostInfo(portInfo.first());
|
||||
private String composeConsoleAccessUrl(String rootUrl, VMInstanceVO vm, HostVO hostVo) {
|
||||
StringBuffer sb = new StringBuffer(rootUrl);
|
||||
String host = hostVo.getPrivateIpAddress();
|
||||
|
||||
String sid = vm.getVncPassword();
|
||||
String tag = String.valueOf(vm.getId());
|
||||
tag = _identityService.getIdentityUuid("vm_instance", tag);
|
||||
String ticket = genAccessTicket(host, String.valueOf(portInfo.second()), sid, tag);
|
||||
ConsoleProxyPasswordBasedEncryptor encryptor = new ConsoleProxyPasswordBasedEncryptor(_ms.getHashKey());
|
||||
ConsoleProxyClientParam param = new ConsoleProxyClientParam();
|
||||
param.setClientHostAddress(parsedHostInfo.first());
|
||||
param.setClientHostPort(portInfo.second());
|
||||
param.setClientHostPassword(sid);
|
||||
param.setClientTag(tag);
|
||||
param.setTicket(ticket);
|
||||
if(parsedHostInfo.second() != null && parsedHostInfo.third() != null) {
|
||||
param.setClientTunnelUrl(parsedHostInfo.second());
|
||||
param.setClientTunnelSession(parsedHostInfo.third());
|
||||
}
|
||||
|
||||
sb.append("/ajax?token=" + encryptor.encryptObject(ConsoleProxyClientParam.class, param));
|
||||
|
||||
// for console access, we need guest OS type to help implement keyboard
|
||||
long guestOs = vm.getGuestOSId();
|
||||
GuestOSVO guestOsVo = _ms.getGuestOs(guestOs);
|
||||
if(guestOsVo.getCategoryId() == 6)
|
||||
sb.append("&guest=windows");
|
||||
|
||||
if(s_logger.isDebugEnabled()) {
|
||||
Pair<String, Integer> portInfo = _ms.getVncPort(vm);
|
||||
if(s_logger.isDebugEnabled())
|
||||
s_logger.debug("Port info " + portInfo.first());
|
||||
|
||||
Ternary<String, String, String> parsedHostInfo = parseHostInfo(portInfo.first());
|
||||
|
||||
String sid = vm.getVncPassword();
|
||||
String tag = String.valueOf(vm.getId());
|
||||
tag = _identityService.getIdentityUuid("vm_instance", tag);
|
||||
String ticket = genAccessTicket(host, String.valueOf(portInfo.second()), sid, tag);
|
||||
ConsoleProxyPasswordBasedEncryptor encryptor = new ConsoleProxyPasswordBasedEncryptor(_ms.getHashKey());
|
||||
ConsoleProxyClientParam param = new ConsoleProxyClientParam();
|
||||
param.setClientHostAddress(parsedHostInfo.first());
|
||||
param.setClientHostPort(portInfo.second());
|
||||
param.setClientHostPassword(sid);
|
||||
param.setClientTag(tag);
|
||||
param.setTicket(ticket);
|
||||
if(parsedHostInfo.second() != null && parsedHostInfo.third() != null) {
|
||||
param.setClientTunnelUrl(parsedHostInfo.second());
|
||||
param.setClientTunnelSession(parsedHostInfo.third());
|
||||
}
|
||||
|
||||
sb.append("/ajax?token=" + encryptor.encryptObject(ConsoleProxyClientParam.class, param));
|
||||
|
||||
// for console access, we need guest OS type to help implement keyboard
|
||||
long guestOs = vm.getGuestOSId();
|
||||
GuestOSVO guestOsVo = _ms.getGuestOs(guestOs);
|
||||
if(guestOsVo.getCategoryId() == 6)
|
||||
sb.append("&guest=windows");
|
||||
|
||||
if(s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Compose console url: " + sb.toString());
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static String genAccessTicket(String host, String port, String sid, String tag) {
|
||||
return genAccessTicket(host, port, sid, tag, new Date());
|
||||
}
|
||||
|
||||
public static String genAccessTicket(String host, String port, String sid, String tag, Date normalizedHashTime) {
|
||||
String params = "host=" + host + "&port=" + port + "&sid=" + sid + "&tag=" + tag;
|
||||
|
||||
try {
|
||||
Mac mac = Mac.getInstance("HmacSHA1");
|
||||
|
||||
long ts = normalizedHashTime.getTime();
|
||||
ts = ts/60000; // round up to 1 minute
|
||||
String secretKey = _ms.getHashKey();
|
||||
|
||||
SecretKeySpec keySpec = new SecretKeySpec(secretKey.getBytes(), "HmacSHA1");
|
||||
mac.init(keySpec);
|
||||
mac.update(params.getBytes());
|
||||
mac.update(String.valueOf(ts).getBytes());
|
||||
|
||||
byte[] encryptedBytes = mac.doFinal();
|
||||
|
||||
return Base64.encodeBase64URLSafeString(encryptedBytes);
|
||||
} catch(Exception e) {
|
||||
s_logger.error("Unexpected exception ", e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private void sendResponse(HttpServletResponse resp, String content) {
|
||||
try {
|
||||
resp.setContentType("text/html");
|
||||
resp.getWriter().print(content);
|
||||
} catch(IOException e) {
|
||||
if(s_logger.isInfoEnabled()) {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static String genAccessTicket(String host, String port, String sid, String tag) {
|
||||
return genAccessTicket(host, port, sid, tag, new Date());
|
||||
}
|
||||
|
||||
public static String genAccessTicket(String host, String port, String sid, String tag, Date normalizedHashTime) {
|
||||
String params = "host=" + host + "&port=" + port + "&sid=" + sid + "&tag=" + tag;
|
||||
|
||||
try {
|
||||
Mac mac = Mac.getInstance("HmacSHA1");
|
||||
|
||||
long ts = normalizedHashTime.getTime();
|
||||
ts = ts/60000; // round up to 1 minute
|
||||
String secretKey = _ms.getHashKey();
|
||||
|
||||
SecretKeySpec keySpec = new SecretKeySpec(secretKey.getBytes(), "HmacSHA1");
|
||||
mac.init(keySpec);
|
||||
mac.update(params.getBytes());
|
||||
mac.update(String.valueOf(ts).getBytes());
|
||||
|
||||
byte[] encryptedBytes = mac.doFinal();
|
||||
|
||||
return Base64.encodeBase64URLSafeString(encryptedBytes);
|
||||
} catch(Exception e) {
|
||||
s_logger.error("Unexpected exception ", e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private void sendResponse(HttpServletResponse resp, String content) {
|
||||
try {
|
||||
resp.setContentType("text/html");
|
||||
resp.getWriter().print(content);
|
||||
} catch(IOException e) {
|
||||
if(s_logger.isInfoEnabled()) {
|
||||
s_logger.info("Client may already close the connection");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean checkSessionPermision(HttpServletRequest req, long vmId, Account accountObj) {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean checkSessionPermision(HttpServletRequest req, long vmId, Account accountObj) {
|
||||
|
||||
VMInstanceVO vm = _vmMgr.findById(vmId);
|
||||
if(vm == null) {
|
||||
s_logger.debug("Console/thumbnail access denied. VM " + vmId + " does not exist in system any more");
|
||||
return false;
|
||||
s_logger.debug("Console/thumbnail access denied. VM " + vmId + " does not exist in system any more");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// root admin can access anything
|
||||
if(accountObj.getType() == Account.ACCOUNT_TYPE_ADMIN)
|
||||
return true;
|
||||
if(accountObj.getType() == Account.ACCOUNT_TYPE_ADMIN)
|
||||
return true;
|
||||
|
||||
switch(vm.getType())
|
||||
{
|
||||
case User :
|
||||
try {
|
||||
_accountMgr.checkAccess(accountObj, null, true, vm);
|
||||
} catch (PermissionDeniedException ex) {
|
||||
if (accountObj.getType() == Account.ACCOUNT_TYPE_NORMAL) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("VM access is denied. VM owner account " + vm.getAccountId()
|
||||
+ " does not match the account id in session " + accountObj.getId() + " and caller is a normal user");
|
||||
}
|
||||
} else if(accountObj.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN || accountObj.getType() == Account.ACCOUNT_TYPE_READ_ONLY_ADMIN) {
|
||||
if(s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("VM access is denied. VM owner account " + vm.getAccountId()
|
||||
+ " does not match the account id in session " + accountObj.getId() + " and the domain-admin caller does not manage the target domain");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
try {
|
||||
_accountMgr.checkAccess(accountObj, null, true, vm);
|
||||
} catch (PermissionDeniedException ex) {
|
||||
if (accountObj.getType() == Account.ACCOUNT_TYPE_NORMAL) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("VM access is denied. VM owner account " + vm.getAccountId()
|
||||
+ " does not match the account id in session " + accountObj.getId() + " and caller is a normal user");
|
||||
}
|
||||
} else if(accountObj.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN || accountObj.getType() == Account.ACCOUNT_TYPE_READ_ONLY_ADMIN) {
|
||||
if(s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("VM access is denied. VM owner account " + vm.getAccountId()
|
||||
+ " does not match the account id in session " + accountObj.getId() + " and the domain-admin caller does not manage the target domain");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case DomainRouter:
|
||||
case ConsoleProxy :
|
||||
case SecondaryStorageVm:
|
||||
return false;
|
||||
|
||||
default :
|
||||
s_logger.warn("Unrecoginized virtual machine type, deny access by default. type: " + vm.getType());
|
||||
return false;
|
||||
return false;
|
||||
|
||||
default :
|
||||
s_logger.warn("Unrecoginized virtual machine type, deny access by default. type: " + vm.getType());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean isValidCmd(String cmd) {
|
||||
if(cmd.equalsIgnoreCase("thumbnail") || cmd.equalsIgnoreCase("access") || cmd.equalsIgnoreCase("auth")) {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean isValidCmd(String cmd) {
|
||||
if(cmd.equalsIgnoreCase("thumbnail") || cmd.equalsIgnoreCase("access") || cmd.equalsIgnoreCase("auth")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean verifyUser(Long userId) {
|
||||
// copy from ApiServer.java, a bit ugly here
|
||||
User user = _accountMgr.getUserIncludingRemoved(userId);
|
||||
Account account = null;
|
||||
if (user != null) {
|
||||
account = _accountMgr.getAccount(user.getAccountId());
|
||||
}
|
||||
|
||||
if ((user == null) || (user.getRemoved() != null) || !user.getState().equals(Account.State.enabled)
|
||||
|| (account == null) || !account.getState().equals(Account.State.enabled)) {
|
||||
s_logger.warn("Deleted/Disabled/Locked user with id=" + userId + " attempting to access public API");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// copied and modified from ApiServer.java.
|
||||
|
||||
public boolean verifyUser(Long userId) {
|
||||
// copy from ApiServer.java, a bit ugly here
|
||||
User user = _accountMgr.getUserIncludingRemoved(userId);
|
||||
Account account = null;
|
||||
if (user != null) {
|
||||
account = _accountMgr.getAccount(user.getAccountId());
|
||||
}
|
||||
|
||||
if ((user == null) || (user.getRemoved() != null) || !user.getState().equals(Account.State.enabled)
|
||||
|| (account == null) || !account.getState().equals(Account.State.enabled)) {
|
||||
s_logger.warn("Deleted/Disabled/Locked user with id=" + userId + " attempting to access public API");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// copied and modified from ApiServer.java.
|
||||
// TODO need to replace the whole servlet with a API command
|
||||
private boolean verifyRequest(Map<String, Object[]> requestParameters) {
|
||||
try {
|
||||
|
|
@ -516,7 +516,7 @@ public class ConsoleProxyServlet extends HttpServlet {
|
|||
for (String paramName : parameterNames) {
|
||||
// parameters come as name/value pairs in the form String/String[]
|
||||
String paramValue = ((String[])requestParameters.get(paramName))[0];
|
||||
|
||||
|
||||
if ("signature".equalsIgnoreCase(paramName)) {
|
||||
signature = paramValue;
|
||||
} else {
|
||||
|
|
@ -531,7 +531,7 @@ public class ConsoleProxyServlet extends HttpServlet {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// if api/secret key are passed to the parameters
|
||||
if ((signature == null) || (apiKey == null)) {
|
||||
|
|
@ -573,16 +573,16 @@ public class ConsoleProxyServlet extends HttpServlet {
|
|||
mac.init(keySpec);
|
||||
mac.update(unsignedRequest.getBytes());
|
||||
byte[] encryptedBytes = mac.doFinal();
|
||||
String computedSignature = com.cloud.utils.encoding.Base64.encodeBytes(encryptedBytes);
|
||||
String computedSignature = Base64.encodeBase64URLSafeString(encryptedBytes);
|
||||
boolean equalSig = signature.equals(computedSignature);
|
||||
if (!equalSig) {
|
||||
s_logger.debug("User signature: " + signature + " is not equaled to computed signature: " + computedSignature);
|
||||
s_logger.debug("User signature: " + signature + " is not equaled to computed signature: " + computedSignature);
|
||||
}
|
||||
|
||||
|
||||
if(equalSig) {
|
||||
requestParameters.put("userid", new Object[] {String.valueOf(user.getId())});
|
||||
requestParameters.put("account", new Object[] {account.getAccountName()});
|
||||
requestParameters.put("accountobj", new Object[] { account });
|
||||
requestParameters.put("userid", new Object[] {String.valueOf(user.getId())});
|
||||
requestParameters.put("account", new Object[] {account.getAccountName()});
|
||||
requestParameters.put("accountobj", new Object[] { account });
|
||||
}
|
||||
return equalSig;
|
||||
} catch (Exception ex) {
|
||||
|
|
@ -590,23 +590,23 @@ public class ConsoleProxyServlet extends HttpServlet {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public static final String escapeHTML(String content){
|
||||
if(content == null || content.isEmpty())
|
||||
return content;
|
||||
|
||||
|
||||
StringBuffer sb = new StringBuffer();
|
||||
for (int i = 0; i < content.length(); i++) {
|
||||
char c = content.charAt(i);
|
||||
switch (c) {
|
||||
case '<': sb.append("<"); break;
|
||||
case '>': sb.append(">"); break;
|
||||
case '&': sb.append("&"); break;
|
||||
case '"': sb.append("""); break;
|
||||
case ' ': sb.append(" ");break;
|
||||
default: sb.append(c); break;
|
||||
}
|
||||
char c = content.charAt(i);
|
||||
switch (c) {
|
||||
case '<': sb.append("<"); break;
|
||||
case '>': sb.append(">"); break;
|
||||
case '&': sb.append("&"); break;
|
||||
case '"': sb.append("""); break;
|
||||
case ' ': sb.append(" ");break;
|
||||
default: sb.append(c); break;
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,10 +31,9 @@ import org.apache.commons.httpclient.HttpClient;
|
|||
import org.apache.commons.httpclient.HttpMethod;
|
||||
import org.apache.commons.httpclient.methods.GetMethod;
|
||||
|
||||
import com.cloud.utils.encoding.Base64;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -49,7 +49,6 @@ import org.w3c.dom.Element;
|
|||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
import com.cloud.utils.encoding.Base64;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.trilead.ssh2.ChannelCondition;
|
||||
import com.trilead.ssh2.Connection;
|
||||
|
|
@ -182,7 +181,7 @@ public class TestClientWithAPI {
|
|||
if (arg.equals("-no")) {
|
||||
networkOfferingId = iter.next();
|
||||
}
|
||||
|
||||
|
||||
if (arg.equals("-pass")) {
|
||||
vmPassword = iter.next();
|
||||
}
|
||||
|
|
@ -210,6 +209,7 @@ public class TestClientWithAPI {
|
|||
|
||||
for (int i = 0; i < numThreads; i++) {
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
do {
|
||||
String username = null;
|
||||
|
|
@ -440,7 +440,7 @@ public class TestClientWithAPI {
|
|||
for (int j = 0; j < childNodes.getLength(); j++) {
|
||||
Node n = childNodes.item(j);
|
||||
if ("id".equals(n.getNodeName())) {
|
||||
// if ("ipaddress".equals(n.getNodeName())) {
|
||||
// if ("ipaddress".equals(n.getNodeName())) {
|
||||
ipAddress = n.getTextContent();
|
||||
} else if ("issourcenat".equals(n.getNodeName())) {
|
||||
isSourceNat = Boolean.parseBoolean(n.getTextContent());
|
||||
|
|
@ -478,7 +478,7 @@ public class TestClientWithAPI {
|
|||
}
|
||||
else if("ipaddress".equals(n.getNodeName()))
|
||||
{
|
||||
ipAddress = n.getTextContent();
|
||||
ipAddress = n.getTextContent();
|
||||
}
|
||||
else if ("issourcenat".equals(n.getNodeName())) {
|
||||
isSourceNat = Boolean.parseBoolean(n.getTextContent());
|
||||
|
|
@ -609,7 +609,7 @@ public class TestClientWithAPI {
|
|||
s_logger.error("Create virtual network failed for account " + username + " with error code :" + responseCode + ", aborting deployment test. The command was sent with url " + url);
|
||||
return -1;
|
||||
}
|
||||
/*
|
||||
/*
|
||||
// ---------------------------------
|
||||
// CREATE DIRECT NETWORK
|
||||
// ---------------------------------
|
||||
|
|
@ -629,9 +629,9 @@ public class TestClientWithAPI {
|
|||
s_logger.error("Create direct network failed for account " + username + " with error code :" + responseCode + ", aborting deployment test. The command was sent with url " + url);
|
||||
return -1;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
// ---------------------------------
|
||||
// DEPLOY LINUX VM
|
||||
// ---------------------------------
|
||||
|
|
@ -706,7 +706,7 @@ public class TestClientWithAPI {
|
|||
}
|
||||
else
|
||||
{
|
||||
s_logger.info("Associate IP Address response code: " + responseCode);
|
||||
s_logger.info("Associate IP Address response code: " + responseCode);
|
||||
long publicIpId = Long.parseLong(values.get("id"));
|
||||
s_logger.info("Associate IP's Id: " + publicIpId);
|
||||
_publicIpId.set(values.get("id"));
|
||||
|
|
@ -715,13 +715,13 @@ public class TestClientWithAPI {
|
|||
s_logger.error("associate ip address for windows vm failed with error code: " + responseCode + ". Following URL was sent: " + url);
|
||||
return responseCode;
|
||||
}
|
||||
|
||||
|
||||
String encodedPublicIpId = URLEncoder.encode(_publicIpId.get(), "UTF-8");
|
||||
requestToSign = "apikey=" + encodedApiKey + "&command=listPublicIpAddresses"+"&id="+ encodedPublicIpId;
|
||||
requestToSign = requestToSign.toLowerCase();
|
||||
signature = signRequest(requestToSign, _secretKey.get());
|
||||
encodedSignature = URLEncoder.encode(signature, "UTF-8");
|
||||
|
||||
|
||||
url = developerServer + "?command=listPublicIpAddresses&apikey=" + encodedApiKey + "&id=" + encodedPublicIpId + "&signature=" + encodedSignature;
|
||||
client = new HttpClient();
|
||||
method = new GetMethod(url);
|
||||
|
|
@ -730,9 +730,9 @@ public class TestClientWithAPI {
|
|||
s_logger.info("list ip addresses for user " + userId + " response code: " + responseCode);
|
||||
if (responseCode == 200) {
|
||||
InputStream is = method.getResponseBodyAsStream();
|
||||
// InputStream ips = method.getResponseBodyAsStream();
|
||||
// InputStream ips = method.getResponseBodyAsStream();
|
||||
List<String> ipAddressValues = getIPs(is, false);
|
||||
// List<String> ipAddressVals = getIPs(is, false, true);
|
||||
// List<String> ipAddressVals = getIPs(is, false, true);
|
||||
if ((ipAddressValues != null) && !ipAddressValues.isEmpty()) {
|
||||
_windowsIpId.set(ipAddressValues.get(0));
|
||||
_windowsIP.set(ipAddressValues.get(1));
|
||||
|
|
@ -743,7 +743,7 @@ public class TestClientWithAPI {
|
|||
s_logger.error("list ip addresses failed with error code: " + responseCode + ". Following URL was sent: " + url);
|
||||
return responseCode;
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------
|
||||
// Use the SourceNat IP for linux
|
||||
// ---------------------------------
|
||||
|
|
@ -776,17 +776,17 @@ public class TestClientWithAPI {
|
|||
return responseCode;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------
|
||||
// Enable Static NAT for the Source NAT Ip
|
||||
//--------------------------------------------
|
||||
String encodedSourceNatPublicIpId = URLEncoder.encode(_linuxIpId.get(), "UTF-8");
|
||||
|
||||
/* requestToSign = "apikey=" + encodedApiKey + "&command=enableStaticNat"+"&id=" + encodedSourceNatPublicIpId + "&virtualMachineId=" + encodedVmId;;
|
||||
|
||||
/* requestToSign = "apikey=" + encodedApiKey + "&command=enableStaticNat"+"&id=" + encodedSourceNatPublicIpId + "&virtualMachineId=" + encodedVmId;;
|
||||
requestToSign = requestToSign.toLowerCase();
|
||||
signature = signRequest(requestToSign, _secretKey.get());
|
||||
encodedSignature = URLEncoder.encode(signature, "UTF-8");
|
||||
|
||||
|
||||
url = developerServer + "?command=enableStaticNat&apikey=" + encodedApiKey + "&signature=" + encodedSignature + "&id=" + encodedSourceNatPublicIpId + "&virtualMachineId=" + encodedVmId;
|
||||
client = new HttpClient();
|
||||
method = new GetMethod(url);
|
||||
|
|
@ -801,7 +801,7 @@ public class TestClientWithAPI {
|
|||
s_logger.error("Enable Static NAT failed with error code: " + responseCode + ". Following URL was sent: " + url);
|
||||
return responseCode;
|
||||
}
|
||||
*/
|
||||
*/
|
||||
// -------------------------------------------------------------
|
||||
// CREATE IP FORWARDING RULE -- Linux VM
|
||||
// -------------------------------------------------------------
|
||||
|
|
@ -825,7 +825,7 @@ public class TestClientWithAPI {
|
|||
long ipfwdid = Long.parseLong(values.get("id"));
|
||||
s_logger.info("got Port Forwarding Rule's Id:" + ipfwdid);
|
||||
_linipfwdid.set(values.get("id"));
|
||||
|
||||
|
||||
} else {
|
||||
s_logger.error("Port forwarding rule creation failed with error code: " + responseCode + ". Following URL was sent: " + url);
|
||||
return responseCode;
|
||||
|
|
@ -882,7 +882,7 @@ public class TestClientWithAPI {
|
|||
String encodedTemplateId = URLEncoder.encode("" + templateId, "UTF-8");
|
||||
encodedApiKey = URLEncoder.encode(_apiKey.get(), "UTF-8");
|
||||
String encodedNetworkIds = URLEncoder.encode(_networkId.get()+",206","UTF-8");
|
||||
|
||||
|
||||
requestToSign = "apikey=" + encodedApiKey + "&command=deployVirtualMachine&diskofferingid=" + diskOfferingId + "&networkids=" + encodedNetworkIds + "&serviceofferingid=" + encodedServiceOfferingId + "&templateid=" + encodedTemplateId
|
||||
+ "&zoneid=" + encodedZoneId;
|
||||
requestToSign = requestToSign.toLowerCase();
|
||||
|
|
@ -918,14 +918,14 @@ public class TestClientWithAPI {
|
|||
//--------------------------------------------
|
||||
// Enable Static NAT for the Non Source NAT Ip
|
||||
//--------------------------------------------
|
||||
|
||||
|
||||
encodedVmId = URLEncoder.encode(_windowsVmId.get(), "UTF-8");
|
||||
encodedPublicIpId = URLEncoder.encode(_publicIpId.get(), "UTF-8");
|
||||
requestToSign = "apikey=" + encodedApiKey + "&command=enableStaticNat"+"&ipaddressid="+ encodedPublicIpId + "&virtualMachineId=" + encodedVmId;
|
||||
requestToSign = requestToSign.toLowerCase();
|
||||
signature = signRequest(requestToSign, _secretKey.get());
|
||||
encodedSignature = URLEncoder.encode(signature, "UTF-8");
|
||||
|
||||
|
||||
url = developerServer + "?command=enableStaticNat&apikey=" + encodedApiKey + "&ipaddressid=" + encodedPublicIpId + "&signature=" + encodedSignature + "&virtualMachineId=" + encodedVmId;
|
||||
client = new HttpClient();
|
||||
method = new GetMethod(url);
|
||||
|
|
@ -941,7 +941,7 @@ public class TestClientWithAPI {
|
|||
return responseCode;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// -------------------------------------------------------------
|
||||
// CREATE IP FORWARDING RULE -- Windows VM
|
||||
// -------------------------------------------------------------
|
||||
|
|
@ -972,7 +972,7 @@ public class TestClientWithAPI {
|
|||
s_logger.error("Port forwarding rule creation failed with error code: " + responseCode + ". Following URL was sent: " + url);
|
||||
return responseCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return responseCode;
|
||||
}
|
||||
|
|
@ -1178,7 +1178,7 @@ public class TestClientWithAPI {
|
|||
}
|
||||
|
||||
// Create volume from the snapshot created on the previous step and attach it to the running vm
|
||||
/* encodedApiKey = URLEncoder.encode(_apiKey.get(), "UTF-8");
|
||||
/* encodedApiKey = URLEncoder.encode(_apiKey.get(), "UTF-8");
|
||||
requestToSign = "apikey=" + encodedApiKey + "&command=createVolume&name=" + _account.get() + "&snapshotid=" + _snapshot.get();
|
||||
requestToSign = requestToSign.toLowerCase();
|
||||
signature = signRequest(requestToSign, _secretKey.get());
|
||||
|
|
@ -1222,7 +1222,7 @@ public class TestClientWithAPI {
|
|||
return responseCode;
|
||||
}
|
||||
}
|
||||
*/
|
||||
*/
|
||||
// -----------------------------
|
||||
// Execute reboot/stop/start commands for the VMs before deleting the account - made to exercise xen
|
||||
// -----------------------------
|
||||
|
|
@ -1896,7 +1896,7 @@ public class TestClientWithAPI {
|
|||
InputStream input = method.getResponseBodyAsStream();
|
||||
Element el = queryAsyncJobResult(server, input);
|
||||
s_logger.info("IP forwarding rule was successfully deleted");
|
||||
|
||||
|
||||
} else {
|
||||
s_logger.error("IP forwarding rule creation failed with error code: " + responseCode + ". Following URL was sent: " + url);
|
||||
return responseCode;
|
||||
|
|
@ -1911,7 +1911,7 @@ public class TestClientWithAPI {
|
|||
requestToSign = requestToSign.toLowerCase();
|
||||
signature = signRequest(requestToSign, _secretKey.get());
|
||||
encodedSignature = URLEncoder.encode(signature, "UTF-8");
|
||||
|
||||
|
||||
url = developerServer + "?command=disableStaticNat&apikey=" + encodedApiKey + "&id=" + encodedPublicIpId + "&signature=" + encodedSignature ;
|
||||
client = new HttpClient();
|
||||
method = new GetMethod(url);
|
||||
|
|
@ -1926,7 +1926,7 @@ public class TestClientWithAPI {
|
|||
s_logger.error("Disable Static NAT failed with error code: " + responseCode + ". Following URL was sent: " + url);
|
||||
return responseCode;
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------
|
||||
// DISASSOCIATE IP ADDRESSES
|
||||
// -----------------------------------------
|
||||
|
|
@ -1946,7 +1946,7 @@ public class TestClientWithAPI {
|
|||
InputStream input = method.getResponseBodyAsStream();
|
||||
Element disassocipel = queryAsyncJobResult(server, input);
|
||||
Map<String, String> success = getSingleValueFromXML(disassocipel, new String[] {"success"});
|
||||
// Map<String, String> success = getSingleValueFromXML(input, new String[] { "success" });
|
||||
// Map<String, String> success = getSingleValueFromXML(input, new String[] { "success" });
|
||||
s_logger.info("disassociate ip address..success? " + success.get("success"));
|
||||
} else {
|
||||
s_logger.error("disassociate ip address failed with error code: " + responseCode + ". Following URL was sent: " + url);
|
||||
|
|
@ -1977,7 +1977,7 @@ public class TestClientWithAPI {
|
|||
mac.init(keySpec);
|
||||
mac.update(request.getBytes());
|
||||
byte[] encryptedBytes = mac.doFinal();
|
||||
return Base64.encodeBytes(encryptedBytes);
|
||||
return org.apache.commons.codec.binary.Base64.encodeBase64URLSafeString(encryptedBytes);
|
||||
} catch (Exception ex) {
|
||||
s_logger.error("unable to sign request", ex);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,208 +30,208 @@ import javax.crypto.spec.SecretKeySpec;
|
|||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
import com.cloud.utils.encoding.Base64;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
|
||||
public class UtilsForTest {
|
||||
|
||||
private static DocumentBuilderFactory factory = DocumentBuilderFactory
|
||||
.newInstance();
|
||||
|
||||
public static boolean verifyTags (Map<String, String> params) {
|
||||
boolean result = true;
|
||||
for (String value : params.keySet()) {
|
||||
if (params.get(value) == null) {
|
||||
result=false;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static boolean verifyTagValues (Map<String, String> params, Map<String, String> pattern) {
|
||||
boolean result = true;
|
||||
|
||||
if (pattern != null) {
|
||||
for (String value : pattern.keySet()) {
|
||||
if (!pattern.get(value).equals(params.get(value))) {
|
||||
result=false;
|
||||
System.out.println("Tag " + value + " has " + params.get(value) + " while expected value is: " + pattern.get(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public static Map<String, String> parseXML(InputStream is,
|
||||
String[] tagNames) {
|
||||
Map<String, String> returnValues = new HashMap<String, String>();
|
||||
try {
|
||||
DocumentBuilder docBuilder = factory.newDocumentBuilder();
|
||||
Document doc = docBuilder.parse(is);
|
||||
Element rootElement = doc.getDocumentElement();
|
||||
|
||||
for (int i = 0; i < tagNames.length; i++) {
|
||||
NodeList targetNodes = rootElement
|
||||
.getElementsByTagName(tagNames[i]);
|
||||
if (targetNodes.getLength() <= 0) {
|
||||
System.out.println("no " + tagNames[i]
|
||||
+ " tag in the response");
|
||||
returnValues.put(tagNames[i], null);
|
||||
} else {
|
||||
returnValues.put(tagNames[i], targetNodes.item(0)
|
||||
.getTextContent());
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
System.out.println("error processing XML");
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return returnValues;
|
||||
}
|
||||
|
||||
|
||||
public static ArrayList<HashMap<String, String>> parseMulXML (InputStream is, String[] tagNames){
|
||||
ArrayList<HashMap<String, String>> returnValues = new ArrayList<HashMap <String, String>>();
|
||||
|
||||
try {
|
||||
DocumentBuilder docBuilder = factory.newDocumentBuilder();
|
||||
Document doc = docBuilder.parse(is);
|
||||
Element rootElement = doc.getDocumentElement();
|
||||
for (int i = 0; i < tagNames.length; i++) {
|
||||
NodeList targetNodes = rootElement
|
||||
.getElementsByTagName(tagNames[i]);
|
||||
if (targetNodes.getLength() <= 0) {
|
||||
System.out.println("no " + tagNames[i]
|
||||
+ " tag in XML response...returning null");
|
||||
} else {
|
||||
for (int j = 0; j < targetNodes.getLength(); j++) {
|
||||
HashMap<String, String> valueList = new HashMap<String,String> ();
|
||||
Node node = targetNodes.item(j);
|
||||
//parse child nodes
|
||||
NodeList child = node.getChildNodes();
|
||||
for (int c=0; c<node.getChildNodes().getLength(); c++){
|
||||
child.item(c).getNodeName();
|
||||
valueList.put(child.item(c).getNodeName(), child.item(c).getTextContent());
|
||||
}
|
||||
returnValues.add(valueList);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
System.out.println(ex);
|
||||
}
|
||||
|
||||
return returnValues;
|
||||
}
|
||||
|
||||
|
||||
public static String createMD5String(String password) {
|
||||
MessageDigest md5;
|
||||
try {
|
||||
md5 = MessageDigest.getInstance("MD5");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new CloudRuntimeException("Error", e);
|
||||
}
|
||||
private static DocumentBuilderFactory factory = DocumentBuilderFactory
|
||||
.newInstance();
|
||||
|
||||
md5.reset();
|
||||
BigInteger pwInt = new BigInteger(1, md5.digest(password.getBytes()));
|
||||
public static boolean verifyTags (Map<String, String> params) {
|
||||
boolean result = true;
|
||||
for (String value : params.keySet()) {
|
||||
if (params.get(value) == null) {
|
||||
result=false;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// make sure our MD5 hash value is 32 digits long...
|
||||
StringBuffer sb = new StringBuffer();
|
||||
String pwStr = pwInt.toString(16);
|
||||
int padding = 32 - pwStr.length();
|
||||
for (int i = 0; i < padding; i++) {
|
||||
sb.append('0');
|
||||
}
|
||||
sb.append(pwStr);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public static Map<String, String> getSingleValueFromXML(InputStream is,
|
||||
String[] tagNames) {
|
||||
Map<String, String> returnValues = new HashMap<String, String>();
|
||||
try {
|
||||
DocumentBuilder docBuilder = factory.newDocumentBuilder();
|
||||
Document doc = docBuilder.parse(is);
|
||||
Element rootElement = doc.getDocumentElement();
|
||||
public static boolean verifyTagValues (Map<String, String> params, Map<String, String> pattern) {
|
||||
boolean result = true;
|
||||
|
||||
if (pattern != null) {
|
||||
for (String value : pattern.keySet()) {
|
||||
if (!pattern.get(value).equals(params.get(value))) {
|
||||
result=false;
|
||||
System.out.println("Tag " + value + " has " + params.get(value) + " while expected value is: " + pattern.get(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public static Map<String, String> parseXML(InputStream is,
|
||||
String[] tagNames) {
|
||||
Map<String, String> returnValues = new HashMap<String, String>();
|
||||
try {
|
||||
DocumentBuilder docBuilder = factory.newDocumentBuilder();
|
||||
Document doc = docBuilder.parse(is);
|
||||
Element rootElement = doc.getDocumentElement();
|
||||
|
||||
for (int i = 0; i < tagNames.length; i++) {
|
||||
NodeList targetNodes = rootElement
|
||||
.getElementsByTagName(tagNames[i]);
|
||||
if (targetNodes.getLength() <= 0) {
|
||||
System.out.println("no " + tagNames[i]
|
||||
+ " tag in the response");
|
||||
returnValues.put(tagNames[i], null);
|
||||
} else {
|
||||
returnValues.put(tagNames[i], targetNodes.item(0)
|
||||
.getTextContent());
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
System.out.println("error processing XML");
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return returnValues;
|
||||
}
|
||||
|
||||
|
||||
public static ArrayList<HashMap<String, String>> parseMulXML (InputStream is, String[] tagNames){
|
||||
ArrayList<HashMap<String, String>> returnValues = new ArrayList<HashMap <String, String>>();
|
||||
|
||||
try {
|
||||
DocumentBuilder docBuilder = factory.newDocumentBuilder();
|
||||
Document doc = docBuilder.parse(is);
|
||||
Element rootElement = doc.getDocumentElement();
|
||||
for (int i = 0; i < tagNames.length; i++) {
|
||||
NodeList targetNodes = rootElement
|
||||
.getElementsByTagName(tagNames[i]);
|
||||
if (targetNodes.getLength() <= 0) {
|
||||
System.out.println("no " + tagNames[i]
|
||||
+ " tag in XML response...returning null");
|
||||
} else {
|
||||
for (int j = 0; j < targetNodes.getLength(); j++) {
|
||||
HashMap<String, String> valueList = new HashMap<String,String> ();
|
||||
Node node = targetNodes.item(j);
|
||||
//parse child nodes
|
||||
NodeList child = node.getChildNodes();
|
||||
for (int c=0; c<node.getChildNodes().getLength(); c++){
|
||||
child.item(c).getNodeName();
|
||||
valueList.put(child.item(c).getNodeName(), child.item(c).getTextContent());
|
||||
}
|
||||
returnValues.add(valueList);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
System.out.println(ex);
|
||||
}
|
||||
|
||||
return returnValues;
|
||||
}
|
||||
|
||||
|
||||
public static String createMD5String(String password) {
|
||||
MessageDigest md5;
|
||||
try {
|
||||
md5 = MessageDigest.getInstance("MD5");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new CloudRuntimeException("Error", e);
|
||||
}
|
||||
|
||||
md5.reset();
|
||||
BigInteger pwInt = new BigInteger(1, md5.digest(password.getBytes()));
|
||||
|
||||
// make sure our MD5 hash value is 32 digits long...
|
||||
StringBuffer sb = new StringBuffer();
|
||||
String pwStr = pwInt.toString(16);
|
||||
int padding = 32 - pwStr.length();
|
||||
for (int i = 0; i < padding; i++) {
|
||||
sb.append('0');
|
||||
}
|
||||
sb.append(pwStr);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public static Map<String, String> getSingleValueFromXML(InputStream is,
|
||||
String[] tagNames) {
|
||||
Map<String, String> returnValues = new HashMap<String, String>();
|
||||
try {
|
||||
DocumentBuilder docBuilder = factory.newDocumentBuilder();
|
||||
Document doc = docBuilder.parse(is);
|
||||
Element rootElement = doc.getDocumentElement();
|
||||
|
||||
for (int i = 0; i < tagNames.length; i++) {
|
||||
NodeList targetNodes = rootElement
|
||||
.getElementsByTagName(tagNames[i]);
|
||||
if (targetNodes.getLength() <= 0) {
|
||||
System.out.println("no " + tagNames[i]
|
||||
+ " tag in XML response...returning null");
|
||||
} else {
|
||||
returnValues.put(tagNames[i], targetNodes.item(0)
|
||||
.getTextContent());
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
System.out.println("error processing XML");
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return returnValues;
|
||||
}
|
||||
|
||||
|
||||
public static Map<String, List<String>> getMultipleValuesFromXML(
|
||||
InputStream is, String[] tagNames) {
|
||||
Map<String, List<String>> returnValues = new HashMap<String, List<String>>();
|
||||
try {
|
||||
DocumentBuilder docBuilder = factory.newDocumentBuilder();
|
||||
Document doc = docBuilder.parse(is);
|
||||
Element rootElement = doc.getDocumentElement();
|
||||
for (int i = 0; i < tagNames.length; i++) {
|
||||
NodeList targetNodes = rootElement
|
||||
.getElementsByTagName(tagNames[i]);
|
||||
if (targetNodes.getLength() <= 0) {
|
||||
System.out.println("no " + tagNames[i]
|
||||
+ " tag in XML response...returning null");
|
||||
} else {
|
||||
List<String> valueList = new ArrayList<String>();
|
||||
for (int j = 0; j < targetNodes.getLength(); j++) {
|
||||
Node node = targetNodes.item(j);
|
||||
valueList.add(node.getTextContent());
|
||||
}
|
||||
returnValues.put(tagNames[i], valueList);
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
System.out.println(ex);
|
||||
}
|
||||
return returnValues;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static String signRequest(String request, String key) {
|
||||
try {
|
||||
Mac mac = Mac.getInstance("HmacSHA1");
|
||||
SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(),
|
||||
"HmacSHA1");
|
||||
mac.init(keySpec);
|
||||
mac.update(request.getBytes());
|
||||
byte[] encryptedBytes = mac.doFinal();
|
||||
//System.out.println("HmacSHA1 hash: " + encryptedBytes);
|
||||
return Base64.encodeBase64URLSafeString(encryptedBytes);
|
||||
} catch (Exception ex) {
|
||||
System.out.println("unable to sign request");
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
for (int i = 0; i < tagNames.length; i++) {
|
||||
NodeList targetNodes = rootElement
|
||||
.getElementsByTagName(tagNames[i]);
|
||||
if (targetNodes.getLength() <= 0) {
|
||||
System.out.println("no " + tagNames[i]
|
||||
+ " tag in XML response...returning null");
|
||||
} else {
|
||||
returnValues.put(tagNames[i], targetNodes.item(0)
|
||||
.getTextContent());
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
System.out.println("error processing XML");
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return returnValues;
|
||||
}
|
||||
|
||||
|
||||
public static Map<String, List<String>> getMultipleValuesFromXML(
|
||||
InputStream is, String[] tagNames) {
|
||||
Map<String, List<String>> returnValues = new HashMap<String, List<String>>();
|
||||
try {
|
||||
DocumentBuilder docBuilder = factory.newDocumentBuilder();
|
||||
Document doc = docBuilder.parse(is);
|
||||
Element rootElement = doc.getDocumentElement();
|
||||
for (int i = 0; i < tagNames.length; i++) {
|
||||
NodeList targetNodes = rootElement
|
||||
.getElementsByTagName(tagNames[i]);
|
||||
if (targetNodes.getLength() <= 0) {
|
||||
System.out.println("no " + tagNames[i]
|
||||
+ " tag in XML response...returning null");
|
||||
} else {
|
||||
List<String> valueList = new ArrayList<String>();
|
||||
for (int j = 0; j < targetNodes.getLength(); j++) {
|
||||
Node node = targetNodes.item(j);
|
||||
valueList.add(node.getTextContent());
|
||||
}
|
||||
returnValues.put(tagNames[i], valueList);
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
System.out.println(ex);
|
||||
}
|
||||
return returnValues;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static String signRequest(String request, String key) {
|
||||
try {
|
||||
Mac mac = Mac.getInstance("HmacSHA1");
|
||||
SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(),
|
||||
"HmacSHA1");
|
||||
mac.init(keySpec);
|
||||
mac.update(request.getBytes());
|
||||
byte[] encryptedBytes = mac.doFinal();
|
||||
//System.out.println("HmacSHA1 hash: " + encryptedBytes);
|
||||
return Base64.encodeBytes(encryptedBytes);
|
||||
} catch (Exception ex) {
|
||||
System.out.println("unable to sign request");
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
44
ui/index.jsp
44
ui/index.jsp
|
|
@ -56,22 +56,18 @@ under the License.
|
|||
<label for="username"><fmt:message key="label.username"/></label>
|
||||
<input type="text" name="username" class="required" />
|
||||
</div>
|
||||
|
||||
<!-- Password -->
|
||||
<div class="field password">
|
||||
<label for="password"><fmt:message key="label.password"/></label>
|
||||
<input type="password" name="password" class="required" />
|
||||
</div>
|
||||
|
||||
<!-- Domain -->
|
||||
<div class="field domain">
|
||||
<label for="domain"><fmt:message key="label.domain"/></label>
|
||||
<input type="text" name="domain" />
|
||||
</div>
|
||||
|
||||
<!-- Submit (login) -->
|
||||
<input type="submit" value="<fmt:message key="label.login"/>" />
|
||||
|
||||
<!-- Select language -->
|
||||
<div class="select-language">
|
||||
<select name="language">
|
||||
|
|
@ -84,7 +80,6 @@ under the License.
|
|||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- Instance wizard -->
|
||||
<div class="multi-wizard instance-wizard">
|
||||
<div class="progress">
|
||||
|
|
@ -113,7 +108,6 @@ under the License.
|
|||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Select template -->
|
||||
<div class="section select-template">
|
||||
<h3><fmt:message key="label.select.iso.or.template" /></h3>
|
||||
|
|
@ -303,7 +297,6 @@ under the License.
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Step 5c: Select security group -->
|
||||
<div class="wizard-step-conditional select-security-group">
|
||||
<div class="main-desc">
|
||||
|
|
@ -315,7 +308,6 @@ under the License.
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Step 6: Review -->
|
||||
<div class="step review" wizard-step-id="review">
|
||||
<div class="main-desc">
|
||||
|
|
@ -332,7 +324,6 @@ under the License.
|
|||
<input type="text" name="displayname" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Add to group -->
|
||||
<div class="select odd">
|
||||
<div class="name">
|
||||
|
|
@ -342,7 +333,6 @@ under the License.
|
|||
<input type="text" name="groupname" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Zone -->
|
||||
<div class="select">
|
||||
<div class="name">
|
||||
|
|
@ -355,7 +345,6 @@ under the License.
|
|||
<a href="1"><fmt:message key="label.edit"/></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Hypervisor -->
|
||||
<div class="select odd">
|
||||
<div class="name">
|
||||
|
|
@ -368,7 +357,6 @@ under the License.
|
|||
<a href="2"><fmt:message key="label.edit"/></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Template -->
|
||||
<div class="select">
|
||||
<div class="name">
|
||||
|
|
@ -381,7 +369,6 @@ under the License.
|
|||
<a href="2"><fmt:message key="label.edit"/></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Service offering -->
|
||||
<div class="select odd">
|
||||
<div class="name">
|
||||
|
|
@ -394,7 +381,6 @@ under the License.
|
|||
<a href="3"><fmt:message key="label.edit"/></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Data disk offering -->
|
||||
<div class="select">
|
||||
<div class="name">
|
||||
|
|
@ -407,7 +393,6 @@ under the License.
|
|||
<a href="4"><fmt:message key="label.edit"/></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Primary network -->
|
||||
<div class="select odd">
|
||||
<div class="name">
|
||||
|
|
@ -438,7 +423,6 @@ under the License.
|
|||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<!-- Computer diagram -->
|
||||
<div class="diagram">
|
||||
<div>
|
||||
|
|
@ -451,7 +435,6 @@ under the License.
|
|||
<div class="part hd"></div>
|
||||
<div class="part network-card"></div>
|
||||
</div>
|
||||
|
||||
<!-- Buttons -->
|
||||
<div class="buttons">
|
||||
<div class="button previous"><span><fmt:message key="label.previous"/></span></div>
|
||||
|
|
@ -459,7 +442,6 @@ under the License.
|
|||
<div class="button next"><span><fmt:message key="label.next"/></span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Zone wizard -->
|
||||
<div class="multi-wizard zone-wizard">
|
||||
<div class="progress">
|
||||
|
|
@ -505,7 +487,6 @@ under the License.
|
|||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- Step 2: Add zone -->
|
||||
<div class="setup-zone" zone-wizard-form="zone"
|
||||
zone-wizard-step-id="addZone">
|
||||
|
|
@ -516,7 +497,6 @@ under the License.
|
|||
<div class="select-container"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Step 3.1: Setup Physical Network -->
|
||||
<div class="setup-physical-network"
|
||||
zone-wizard-step-id="setupPhysicalNetwork"
|
||||
|
|
@ -535,7 +515,6 @@ under the License.
|
|||
<fmt:message key="message.setup.physical.network.during.zone.creation.basic"/>
|
||||
</div>
|
||||
<div class="button add new-physical-network"><span class="icon"> </span><span><fmt:message key="label.add.physical.network"/></span></div>
|
||||
|
||||
<!-- Traffic types drag area -->
|
||||
<div class="traffic-types-drag-area">
|
||||
<div class="header"><fmt:message key="label.traffic.types"/></div>
|
||||
|
|
@ -610,13 +589,11 @@ under the License.
|
|||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="drag-helper-icon"></div>
|
||||
<div class="content input-area">
|
||||
<form></form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Step 3.1b: Add Netscaler device -->
|
||||
<div class="setup-physical-network-basic"
|
||||
zone-wizard-step-id="addNetscalerDevice"
|
||||
|
|
@ -629,13 +606,11 @@ under the License.
|
|||
<li class="guest-traffic"><fmt:message key="label.guest.traffic"/></li>
|
||||
<li class="conditional storage-traffic"><fmt:message key="label.storage.traffic"/></li>
|
||||
</ul>
|
||||
|
||||
<div class="info-desc"><fmt:message key="label.please.specify.netscaler.info"/></div>
|
||||
<div class="content input-area">
|
||||
<div class="select-container"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Step 3.2: Configure public traffic -->
|
||||
<div class="setup-public-traffic" zone-wizard-prefilter="addPublicNetwork"
|
||||
zone-wizard-step-id="configurePublicTraffic">
|
||||
|
|
@ -646,14 +621,12 @@ under the License.
|
|||
<li class="guest-traffic"><fmt:message key="label.guest.traffic"/></li>
|
||||
<li class="conditional storage-traffic"><fmt:message key="label.storage.traffic"/></li>
|
||||
</ul>
|
||||
|
||||
<div class="info-desc" id="add_zone_public_traffic_desc">
|
||||
<span id="for_basic_zone" style="display:none"><fmt:message key="message.public.traffic.in.basic.zone"/></span>
|
||||
<span id="for_advanced_zone" style="display:none"><fmt:message key="message.public.traffic.in.advanced.zone"/></span>
|
||||
</div>
|
||||
<div ui-custom="publicTrafficIPRange"></div>
|
||||
</div>
|
||||
|
||||
<!-- Step 3.3: Add pod -->
|
||||
<div class="add-pod" zone-wizard-form="pod"
|
||||
zone-wizard-step-id="addPod">
|
||||
|
|
@ -664,7 +637,6 @@ under the License.
|
|||
<li class="guest-traffic"><fmt:message key="label.guest.traffic"/></li>
|
||||
<li class="conditional storage-traffic"><fmt:message key="label.storage.traffic"/></li>
|
||||
</ul>
|
||||
|
||||
<div class="info-desc">
|
||||
<fmt:message key="message.add.pod.during.zone.creation"/>
|
||||
</div>
|
||||
|
|
@ -672,7 +644,6 @@ under the License.
|
|||
<div class="select-container"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Step 3.4: Configure guest traffic -->
|
||||
<div class="setup-guest-traffic"
|
||||
zone-wizard-form="guestTraffic"
|
||||
|
|
@ -685,7 +656,6 @@ under the License.
|
|||
<li class="guest-traffic active"><fmt:message key="label.guest.traffic"/></li>
|
||||
<li class="conditional storage-traffic"><fmt:message key="label.storage.traffic"/></li>
|
||||
</ul>
|
||||
|
||||
<div class="info-desc" id="add_zone_guest_traffic_desc">
|
||||
<span id="for_basic_zone" style="display:none"><fmt:message key="message.guest.traffic.in.basic.zone"/></span>
|
||||
<span id="for_advanced_zone" style="display:none"><fmt:message key="message.guest.traffic.in.advanced.zone"/></span>
|
||||
|
|
@ -694,7 +664,6 @@ under the License.
|
|||
<div class="select-container"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Step 3.5: Configure storage traffic -->
|
||||
<div class="setup-storage-traffic" zone-wizard-prefilter="configureStorageTraffic"
|
||||
zone-wizard-step-id="configureStorageTraffic">
|
||||
|
|
@ -705,13 +674,11 @@ under the License.
|
|||
<li class="guest-traffic"><fmt:message key="label.guest.traffic"/></li>
|
||||
<li class="storage-traffic active"><fmt:message key="label.storage.traffic"/></li>
|
||||
</ul>
|
||||
|
||||
<div class="info-desc">
|
||||
<fmt:message key="message.storage.traffic"/>
|
||||
</div>
|
||||
<div ui-custom="storageTrafficIPRange"></div>
|
||||
</div>
|
||||
|
||||
<!-- Step 4.1: Add cluster -->
|
||||
<div class="add-cluster" zone-wizard-form="cluster"
|
||||
zone-wizard-step-id="addCluster">
|
||||
|
|
@ -729,7 +696,6 @@ under the License.
|
|||
<div class="select-container"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Step 4.2: Add host -->
|
||||
<div class="add-cluster" zone-wizard-form="host"
|
||||
zone-wizard-step-id="addHost" zone-wizard-prefilter="addHost">
|
||||
|
|
@ -746,7 +712,6 @@ under the License.
|
|||
<div class="select-container"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Step 4.3: Add primary storage -->
|
||||
<div class="add-cluster" zone-wizard-form="primaryStorage" zone-wizard-prefilter="addPrimaryStorage"
|
||||
zone-wizard-step-id="addPrimaryStorage">
|
||||
|
|
@ -763,7 +728,6 @@ under the License.
|
|||
<div class="select-container"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Step 4.4: Add secondary storage -->
|
||||
<div class="add-cluster" zone-wizard-form="secondaryStorage"
|
||||
zone-wizard-step-id="addSecondaryStorage">
|
||||
|
|
@ -780,7 +744,6 @@ under the License.
|
|||
<div class="select-container"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Step 5: Launch -->
|
||||
<div class="review" zone-wizard-step-id="launch">
|
||||
<div class="main-desc pre-setup"><fmt:message key="message.launch.zone"/></div>
|
||||
|
|
@ -794,7 +757,6 @@ under the License.
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Buttons -->
|
||||
<div class="buttons">
|
||||
<div class="button previous"><span><fmt:message key="label.previous"/></span></div>
|
||||
|
|
@ -802,7 +764,6 @@ under the License.
|
|||
<div class="button next"><span><fmt:message key="label.next"/></span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Network chart -->
|
||||
<div class="network-chart normal">
|
||||
<ul>
|
||||
|
|
@ -820,7 +781,6 @@ under the License.
|
|||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- Static NAT network chart -->
|
||||
<div class="network-chart static-nat">
|
||||
<ul>
|
||||
|
|
@ -835,7 +795,6 @@ under the License.
|
|||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- Project dashboard -->
|
||||
<div class="project-dashboard-view">
|
||||
<div class="overview-area">
|
||||
|
|
@ -903,7 +862,6 @@ under the License.
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="info-boxes">
|
||||
<!-- Networking and security -->
|
||||
<div class="info-box networking-and-security">
|
||||
|
|
@ -947,7 +905,6 @@ under the License.
|
|||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- Events -->
|
||||
<div class="info-box events">
|
||||
<div class="title">
|
||||
|
|
@ -966,7 +923,6 @@ under the License.
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- System dashboard -->
|
||||
<div class="system-dashboard-view">
|
||||
<div class="toolbar">
|
||||
|
|
|
|||
|
|
@ -66,7 +66,26 @@
|
|||
listViewArgs.activeSection
|
||||
] = [$instanceRow.data('jsonObj')];
|
||||
|
||||
if (action.custom && !action.noAdd) {
|
||||
var externalLinkAction = action.externalLink;
|
||||
if (externalLinkAction) {
|
||||
// Show popup immediately, do not proceed through normal action process
|
||||
window.open(
|
||||
// URL
|
||||
externalLinkAction.url({
|
||||
context: context
|
||||
}),
|
||||
|
||||
// Title
|
||||
externalLinkAction.title({
|
||||
context: context
|
||||
}),
|
||||
|
||||
// Window options
|
||||
'menubar=0,resizable=0,'
|
||||
+ 'width=' + externalLinkAction.width + ','
|
||||
+ 'height=' + externalLinkAction.height
|
||||
);
|
||||
} else if (action.custom && !action.noAdd) {
|
||||
action.custom({
|
||||
data: data,
|
||||
ref: options.ref,
|
||||
|
|
@ -254,7 +273,8 @@
|
|||
listViewArgs.activeSection
|
||||
] = [$instanceRow.data('jsonObj')];
|
||||
|
||||
if (!args.action.createForm &&
|
||||
if (!args.action.action.externalLink &&
|
||||
!args.action.createForm &&
|
||||
args.action.addRow != 'true' &&
|
||||
!action.custom && !action.uiCustom)
|
||||
cloudStack.dialog.confirm({
|
||||
|
|
@ -274,7 +294,26 @@
|
|||
var isHeader = args.action.isHeader;
|
||||
var createFormContext = $.extend({}, context);
|
||||
|
||||
if (args.action.createForm) {
|
||||
var externalLinkAction = action.externalLink;
|
||||
if (externalLinkAction) {
|
||||
// Show popup immediately, do not proceed through normal action process
|
||||
window.open(
|
||||
// URL
|
||||
externalLinkAction.url({
|
||||
context: context
|
||||
}),
|
||||
|
||||
// Title
|
||||
externalLinkAction.title({
|
||||
context: context
|
||||
}),
|
||||
|
||||
// Window options
|
||||
'menubar=0,resizable=0,'
|
||||
+ 'width=' + externalLinkAction.width + ','
|
||||
+ 'height=' + externalLinkAction.height
|
||||
);
|
||||
} else if (args.action.createForm) {
|
||||
cloudStack.dialog.createForm({
|
||||
form: args.action.createForm,
|
||||
after: function(args) {
|
||||
|
|
|
|||
|
|
@ -71,15 +71,48 @@ import com.cloud.utils.mgmt.JmxUtil;
|
|||
import com.cloud.utils.mgmt.ManagementBean;
|
||||
|
||||
/**
|
||||
* ComponentLocator manages all of the adapters within a system. It operates on
|
||||
* top of an components.xml and uses reflection to instantiate all of the
|
||||
* adapters. It also supports rereading of all of the adapters.
|
||||
* ComponentLocator ties together several different concepts. First, it
|
||||
* deals with how a system should be put together. It manages different
|
||||
* types of components:
|
||||
* - Manager: Singleton implementation of a certain process.
|
||||
* - Adapter: Different singleton implementations for the same functions.
|
||||
* - SystemIntegrityChecker: Singletons that are called at the load time.
|
||||
* - Dao: Data Access Objects.
|
||||
*
|
||||
* These components can be declared in several ways:
|
||||
* - ComponentLibrary - A Java class that declares the above components. The
|
||||
* advantage of declaring components here is they change automatically
|
||||
* with any refactoring.
|
||||
* - components specification - An xml file that overrides the
|
||||
* ComponentLibrary. The advantage of declaring components here is
|
||||
* they can change by hand on every deployment.
|
||||
*
|
||||
* The two are NOT mutually exclusive. ComponentLocator basically locates
|
||||
* the components specification, which specifies the ComponentLibrary within.
|
||||
* Components found in the ComponentLibrary are overridden by components
|
||||
* found in components specification.
|
||||
*
|
||||
* Components specification can also be nested. One components specification
|
||||
* can point to another components specification and, therefore, "inherits"
|
||||
* those components but still override one or more components. ComponentLocator
|
||||
* reads the child components specification first and follow the chain up.
|
||||
* the child's components overrides the ones in the parent.
|
||||
*
|
||||
* ComponentLocator looks for the components specification as follows:
|
||||
* 1. By following the path specified by "cloud-stack-components-specification"
|
||||
* within the environment.properties file.
|
||||
* 2. Look for components.xml in the class path.
|
||||
*
|
||||
* ComponentLocator also ties in component injection. Components can specify
|
||||
* an @Inject annotation to components ComponentLocator knows. When
|
||||
* instantiating components, ComponentLocator attempts to inject these
|
||||
* components.
|
||||
*
|
||||
**/
|
||||
@SuppressWarnings("unchecked")
|
||||
public class ComponentLocator implements ComponentLocatorMBean {
|
||||
protected static final Logger s_logger = Logger.getLogger(ComponentLocator.class);
|
||||
|
||||
|
||||
protected static final ThreadLocal<ComponentLocator> s_tl = new ThreadLocal<ComponentLocator>();
|
||||
protected static final ConcurrentHashMap<Class<?>, Singleton> s_singletons = new ConcurrentHashMap<Class<?>, Singleton>(111);
|
||||
protected static final HashMap<String, ComponentLocator> s_locators = new HashMap<String, ComponentLocator>();
|
||||
|
|
@ -90,7 +123,7 @@ public class ComponentLocator implements ComponentLocatorMBean {
|
|||
protected static CallbackFilter s_callbackFilter = new DatabaseCallbackFilter();
|
||||
protected static final List<AnnotationInterceptor<?>> s_interceptors = new ArrayList<AnnotationInterceptor<?>>();
|
||||
protected static CleanupThread s_janitor = null;
|
||||
|
||||
|
||||
protected HashMap<String, Adapters<? extends Adapter>> _adapterMap;
|
||||
protected HashMap<String, ComponentInfo<Manager>> _managerMap;
|
||||
protected LinkedHashMap<String, ComponentInfo<SystemIntegrityChecker>> _checkerMap;
|
||||
|
|
@ -98,8 +131,8 @@ public class ComponentLocator implements ComponentLocatorMBean {
|
|||
protected String _serverName;
|
||||
protected Object _component;
|
||||
protected HashMap<Class<?>, Class<?>> _factories;
|
||||
protected HashMap<String, ComponentInfo<PluggableService>> _pluggableServicesMap;
|
||||
|
||||
protected HashMap<String, ComponentInfo<PluggableService>> _pluginsMap;
|
||||
|
||||
static {
|
||||
if (s_janitor == null) {
|
||||
s_janitor = new CleanupThread();
|
||||
|
|
@ -118,7 +151,7 @@ public class ComponentLocator implements ComponentLocatorMBean {
|
|||
public String getLocatorName() {
|
||||
return _serverName;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return getLocatorName();
|
||||
|
|
@ -133,7 +166,7 @@ public class ComponentLocator implements ComponentLocatorMBean {
|
|||
_checkerMap = new LinkedHashMap<String, ComponentInfo<SystemIntegrityChecker>>();
|
||||
_adapterMap = new HashMap<String, Adapters<? extends Adapter>>();
|
||||
_factories = new HashMap<Class<?>, Class<?>>();
|
||||
_pluggableServicesMap = new LinkedHashMap<String, ComponentInfo<PluggableService>>();
|
||||
_pluginsMap = new LinkedHashMap<String, ComponentInfo<PluggableService>>();
|
||||
File file = PropertiesUtil.findConfigFile(filename);
|
||||
if (file == null) {
|
||||
s_logger.info("Unable to find " + filename);
|
||||
|
|
@ -157,7 +190,7 @@ public class ComponentLocator implements ComponentLocatorMBean {
|
|||
_daoMap.putAll(parentLocator._daoMap);
|
||||
_managerMap.putAll(parentLocator._managerMap);
|
||||
_factories.putAll(parentLocator._factories);
|
||||
_pluggableServicesMap.putAll(parentLocator._pluggableServicesMap);
|
||||
_pluginsMap.putAll(parentLocator._pluginsMap);
|
||||
}
|
||||
|
||||
ComponentLibrary library = null;
|
||||
|
|
@ -168,15 +201,15 @@ public class ComponentLocator implements ComponentLocatorMBean {
|
|||
_managerMap.putAll(library.getManagers());
|
||||
adapters.putAll(library.getAdapters());
|
||||
_factories.putAll(library.getFactories());
|
||||
_pluggableServicesMap.putAll(library.getPluggableServices());
|
||||
_pluginsMap.putAll(library.getPluggableServices());
|
||||
}
|
||||
|
||||
_daoMap.putAll(handler.daos);
|
||||
_managerMap.putAll(handler.managers);
|
||||
_checkerMap.putAll(handler.checkers);
|
||||
adapters.putAll(handler.adapters);
|
||||
_pluggableServicesMap.putAll(handler.pluggableServices);
|
||||
|
||||
_pluginsMap.putAll(handler.pluggableServices);
|
||||
|
||||
return new Pair<XmlHandler, HashMap<String, List<ComponentInfo<Adapter>>>>(handler, adapters);
|
||||
} catch (ParserConfigurationException e) {
|
||||
s_logger.error("Unable to load " + _serverName + " due to errors while parsing " + filename, e);
|
||||
|
|
@ -203,7 +236,9 @@ public class ComponentLocator implements ComponentLocatorMBean {
|
|||
s_logger.info("Skipping configuration using " + filename);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
instantiatePluggableServices();
|
||||
|
||||
XmlHandler handler = result.first();
|
||||
HashMap<String, List<ComponentInfo<Adapter>>> adapters = result.second();
|
||||
try {
|
||||
|
|
@ -220,13 +255,12 @@ public class ComponentLocator implements ComponentLocatorMBean {
|
|||
startAdapters();
|
||||
//TODO do we need to follow the instantiate -> inject -> configure -> start -> stop flow of singletons like managers/adapters?
|
||||
//TODO do we need to expose pluggableServices to MBean (provide getNames?)
|
||||
instantiatePluggableServices();
|
||||
} catch (CloudRuntimeException e) {
|
||||
s_logger.error("Unable to load configuration for " + _serverName + " from " + filename, e);
|
||||
System.exit(1);
|
||||
} catch (Exception e) {
|
||||
s_logger.error("Unable to load configuration for " + _serverName + " from " + filename, e);
|
||||
System.exit(1);
|
||||
s_logger.error("Unable to load configuration for " + _serverName + " from " + filename, e);
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -288,7 +322,7 @@ public class ComponentLocator implements ComponentLocatorMBean {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static Object createInstance(Class<?> clazz, boolean inject, boolean singleton, Object... args) {
|
||||
Factory factory = null;
|
||||
Singleton entity = null;
|
||||
|
|
@ -313,8 +347,8 @@ public class ComponentLocator implements ComponentLocatorMBean {
|
|||
factory = info.factory;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Class<?>[] argTypes = null;
|
||||
if (args != null && args.length > 0) {
|
||||
Constructor<?>[] constructors = clazz.getConstructors();
|
||||
|
|
@ -334,49 +368,49 @@ public class ComponentLocator implements ComponentLocatorMBean {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (argTypes == null) {
|
||||
throw new CloudRuntimeException("Unable to find constructor to match parameters given: " + clazz.getName());
|
||||
}
|
||||
|
||||
|
||||
entity = new Singleton(factory.newInstance(argTypes, args, s_callbacks));
|
||||
} else {
|
||||
entity = new Singleton(factory.newInstance(s_callbacks));
|
||||
}
|
||||
|
||||
|
||||
if (inject) {
|
||||
inject(clazz, entity.singleton);
|
||||
entity.state = Singleton.State.Injected;
|
||||
}
|
||||
|
||||
|
||||
if (singleton) {
|
||||
synchronized(s_factories) {
|
||||
s_singletons.put(clazz, entity);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return entity.singleton;
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected ComponentInfo<GenericDao<?, ?>> getDao(String name) {
|
||||
ComponentInfo<GenericDao<?, ?>> info = _daoMap.get(name);
|
||||
if (info == null) {
|
||||
throw new CloudRuntimeException("Unable to find DAO " + name);
|
||||
}
|
||||
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
public static synchronized Object getComponent(String componentName) {
|
||||
synchronized(_hasCheckerRun) {
|
||||
/* System Integrity checker will run before all components really loaded */
|
||||
if (!_hasCheckerRun && !componentName.equalsIgnoreCase(SystemIntegrityChecker.Name)) {
|
||||
ComponentLocator.getComponent(SystemIntegrityChecker.Name);
|
||||
_hasCheckerRun = true;
|
||||
}
|
||||
}
|
||||
|
||||
synchronized(_hasCheckerRun) {
|
||||
/* System Integrity checker will run before all components really loaded */
|
||||
if (!_hasCheckerRun && !componentName.equalsIgnoreCase(SystemIntegrityChecker.Name)) {
|
||||
ComponentLocator.getComponent(SystemIntegrityChecker.Name);
|
||||
_hasCheckerRun = true;
|
||||
}
|
||||
}
|
||||
|
||||
ComponentLocator locator = s_locators.get(componentName);
|
||||
if (locator == null) {
|
||||
locator = ComponentLocator.getLocator(componentName);
|
||||
|
|
@ -441,10 +475,10 @@ public class ComponentLocator implements ComponentLocatorMBean {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected static void inject(Class<?> clazz, Object entity) {
|
||||
ComponentLocator locator = ComponentLocator.getCurrentLocator();
|
||||
|
||||
|
||||
do {
|
||||
Field[] fields = clazz.getDeclaredFields();
|
||||
for (Field field : fields) {
|
||||
|
|
@ -467,11 +501,11 @@ public class ComponentLocator implements ComponentLocatorMBean {
|
|||
s_logger.trace("Other:" + fc.getName());
|
||||
instance = locator.getManager(fc);
|
||||
}
|
||||
|
||||
|
||||
if (instance == null) {
|
||||
throw new CloudRuntimeException("Unable to inject " + fc.getSimpleName() + " in " + clazz.getSimpleName());
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
field.setAccessible(true);
|
||||
field.set(entity, instance);
|
||||
|
|
@ -545,7 +579,7 @@ public class ComponentLocator implements ComponentLocatorMBean {
|
|||
}
|
||||
return (T)info.instance;
|
||||
}
|
||||
|
||||
|
||||
protected void configureAdapters() {
|
||||
for (Adapters<? extends Adapter> adapters : _adapterMap.values()) {
|
||||
List<ComponentInfo<Adapter>> infos = adapters._infos;
|
||||
|
|
@ -597,7 +631,7 @@ public class ComponentLocator implements ComponentLocatorMBean {
|
|||
_adapterMap.put(entry.getKey(), adapters);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void instantiateAdapters(Map<String, List<ComponentInfo<Adapter>>> map) {
|
||||
Set<Map.Entry<String, List<ComponentInfo<Adapter>>>> entries = map.entrySet();
|
||||
for (Map.Entry<String, List<ComponentInfo<Adapter>>> entry : entries) {
|
||||
|
|
@ -641,18 +675,26 @@ public class ComponentLocator implements ComponentLocatorMBean {
|
|||
}
|
||||
|
||||
protected void instantiatePluggableServices() {
|
||||
Set<Map.Entry<String, ComponentInfo<PluggableService>>> entries = _pluggableServicesMap.entrySet();
|
||||
Set<Map.Entry<String, ComponentInfo<PluggableService>>> entries = _pluginsMap.entrySet();
|
||||
for (Map.Entry<String, ComponentInfo<PluggableService>> entry : entries) {
|
||||
ComponentInfo<PluggableService> info = entry.getValue();
|
||||
if (info.instance == null) {
|
||||
s_logger.info("Instantiating PluggableService: " + info.name);
|
||||
info.instance = (PluggableService)createInstance(info.clazz, false, info.singleton);
|
||||
|
||||
if (info.instance instanceof Plugin) {
|
||||
Plugin plugin = (Plugin)info.instance;
|
||||
|
||||
ComponentLibrary lib = plugin.getComponentLibrary();
|
||||
_managerMap.putAll(lib.getManagers());
|
||||
_daoMap.putAll(lib.getDaos());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected ComponentInfo<PluggableService> getPluggableService(String name) {
|
||||
ComponentInfo<PluggableService> mgr = _pluggableServicesMap.get(name);
|
||||
ComponentInfo<PluggableService> mgr = _pluginsMap.get(name);
|
||||
return mgr;
|
||||
}
|
||||
|
||||
|
|
@ -669,7 +711,7 @@ public class ComponentLocator implements ComponentLocatorMBean {
|
|||
|
||||
public <T> List<T> getAllPluggableServices() {
|
||||
List<T> services = new ArrayList<T>();
|
||||
Set<Map.Entry<String, ComponentInfo<PluggableService>>> entries = _pluggableServicesMap.entrySet();
|
||||
Set<Map.Entry<String, ComponentInfo<PluggableService>>> entries = _pluginsMap.entrySet();
|
||||
for (Map.Entry<String, ComponentInfo<PluggableService>> entry : entries) {
|
||||
ComponentInfo<PluggableService> info = entry.getValue();
|
||||
if (info.instance == null) {
|
||||
|
|
@ -680,11 +722,11 @@ public class ComponentLocator implements ComponentLocatorMBean {
|
|||
}
|
||||
return services;
|
||||
}
|
||||
|
||||
|
||||
public static <T> T inject(Class<T> clazz) {
|
||||
return (T)createInstance(clazz, true, false);
|
||||
}
|
||||
|
||||
|
||||
public <T> T createInstance(Class<T> clazz) {
|
||||
Class<? extends T> impl = (Class<? extends T>)_factories.get(clazz);
|
||||
if (impl == null) {
|
||||
|
|
@ -692,11 +734,11 @@ public class ComponentLocator implements ComponentLocatorMBean {
|
|||
}
|
||||
return inject(impl);
|
||||
}
|
||||
|
||||
|
||||
public static <T> T inject(Class<T> clazz, Object... args) {
|
||||
return (T)createInstance(clazz, true, false, args);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Map<String, List<String>> getAdapterNames() {
|
||||
HashMap<String, List<String>> result = new HashMap<String, List<String>>();
|
||||
|
|
@ -749,7 +791,7 @@ public class ComponentLocator implements ComponentLocatorMBean {
|
|||
}
|
||||
return new Adapters<Adapter>(key, new ArrayList<ComponentInfo<Adapter>>());
|
||||
}
|
||||
|
||||
|
||||
protected void resetInterceptors(InterceptorLibrary library) {
|
||||
library.addInterceptors(s_interceptors);
|
||||
if (s_interceptors.size() > 0) {
|
||||
|
|
@ -781,7 +823,7 @@ public class ComponentLocator implements ComponentLocatorMBean {
|
|||
s_once = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ComponentLocator locator;
|
||||
synchronized (s_locators) {
|
||||
locator = s_locators.get(server);
|
||||
|
|
@ -822,7 +864,7 @@ public class ComponentLocator implements ComponentLocatorMBean {
|
|||
} catch (IOException e) {
|
||||
s_logger.debug("environment.properties could not be loaded:" + e.toString());
|
||||
}
|
||||
|
||||
|
||||
if (configFile == null || PropertiesUtil.findConfigFile(configFile) == null) {
|
||||
configFile = "components.xml";
|
||||
if (PropertiesUtil.findConfigFile(configFile) == null){
|
||||
|
|
@ -843,31 +885,31 @@ public class ComponentLocator implements ComponentLocatorMBean {
|
|||
List<String> keys = new ArrayList<String>();
|
||||
T instance;
|
||||
boolean singleton = true;
|
||||
|
||||
|
||||
protected ComponentInfo() {
|
||||
}
|
||||
|
||||
|
||||
public List<String> getKeys() {
|
||||
return keys;
|
||||
}
|
||||
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
public ComponentInfo(String name, Class<? extends T> clazz) {
|
||||
this(name, clazz, new ArrayList<Pair<String, Object>>(0));
|
||||
}
|
||||
|
||||
|
||||
public ComponentInfo(String name, Class<? extends T> clazz, T instance) {
|
||||
this(name, clazz);
|
||||
this.instance = instance;
|
||||
}
|
||||
|
||||
|
||||
public ComponentInfo(String name, Class<? extends T> clazz, List<Pair<String, Object>> params) {
|
||||
this(name, clazz, params, true);
|
||||
}
|
||||
|
||||
|
||||
public ComponentInfo(String name, Class<? extends T> clazz, List<Pair<String, Object>> params, boolean singleton) {
|
||||
this.name = name;
|
||||
this.clazz = clazz;
|
||||
|
|
@ -877,10 +919,10 @@ public class ComponentLocator implements ComponentLocatorMBean {
|
|||
}
|
||||
fillInfo();
|
||||
}
|
||||
|
||||
|
||||
protected void fillInfo() {
|
||||
String clazzName = clazz.getName();
|
||||
|
||||
|
||||
Local local = clazz.getAnnotation(Local.class);
|
||||
if (local == null) {
|
||||
throw new CloudRuntimeException("Unable to find Local annotation for class " + clazzName);
|
||||
|
|
@ -900,7 +942,7 @@ public class ComponentLocator implements ComponentLocatorMBean {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void addParameter(String name, String value) {
|
||||
params.put(name, value);
|
||||
}
|
||||
|
|
@ -964,13 +1006,13 @@ public class ComponentLocator implements ComponentLocatorMBean {
|
|||
if (singleton != null) {
|
||||
info.singleton = Boolean.parseBoolean(singleton);
|
||||
}
|
||||
|
||||
|
||||
info.fillInfo();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void startElement(String namespaceURI, String localName, String qName, Attributes atts)
|
||||
throws SAXException {
|
||||
throws SAXException {
|
||||
if (qName.equals("interceptor") && s_interceptors.size() == 0) {
|
||||
synchronized(s_interceptors){
|
||||
if (s_interceptors.size() == 0) {
|
||||
|
|
@ -1001,7 +1043,7 @@ public class ComponentLocator implements ComponentLocatorMBean {
|
|||
throw new CloudRuntimeException("Unable to find " + implementationClass, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
library = getAttribute(atts, "library");
|
||||
}
|
||||
} else if (qName.equals("adapters")) {
|
||||
|
|
@ -1041,7 +1083,7 @@ public class ComponentLocator implements ComponentLocatorMBean {
|
|||
checkers.put(info.name, info);
|
||||
s_logger.info("Adding system integrity checker: " + info.name);
|
||||
currentInfo = info;
|
||||
} else if (qName.equals("pluggableservice")) {
|
||||
} else if (qName.equals("pluggableservice") || qName.equals("plugin")) {
|
||||
ComponentInfo<PluggableService> info = new ComponentInfo<PluggableService>();
|
||||
fillInfo(atts, PluggableService.class, info);
|
||||
s_logger.info("Adding PluggableService: " + info.name);
|
||||
|
|
@ -1096,17 +1138,17 @@ public class ComponentLocator implements ComponentLocatorMBean {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected static class InjectInfo {
|
||||
public Factory factory;
|
||||
public Enhancer enhancer;
|
||||
|
||||
|
||||
public InjectInfo(Enhancer enhancer, Factory factory) {
|
||||
this.factory = factory;
|
||||
this.enhancer = enhancer;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected static class CleanupThread extends Thread {
|
||||
@Override
|
||||
public void run() {
|
||||
|
|
@ -1133,7 +1175,7 @@ public class ComponentLocator implements ComponentLocatorMBean {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (ComponentLocator locator : s_locators.values()) {
|
||||
Iterator<ComponentInfo<Manager>> itManagers = locator._managerMap.values().iterator();
|
||||
while (itManagers.hasNext()) {
|
||||
|
|
@ -1154,7 +1196,7 @@ public class ComponentLocator implements ComponentLocatorMBean {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static class Singleton {
|
||||
public enum State {
|
||||
Instantiated,
|
||||
|
|
@ -1163,16 +1205,16 @@ public class ComponentLocator implements ComponentLocatorMBean {
|
|||
Started,
|
||||
Stopped
|
||||
}
|
||||
|
||||
|
||||
public Object singleton;
|
||||
public State state;
|
||||
|
||||
|
||||
public Singleton(Object singleton) {
|
||||
this.singleton = singleton;
|
||||
this.state = State.Instantiated;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected class InterceptorDispatcher implements MethodInterceptor {
|
||||
|
||||
@Override
|
||||
|
|
@ -1200,7 +1242,7 @@ public class ComponentLocator implements ComponentLocatorMBean {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected static class InterceptorFilter implements CallbackFilter {
|
||||
@Override
|
||||
public int accept(Method method) {
|
||||
|
|
@ -1215,7 +1257,7 @@ public class ComponentLocator implements ComponentLocatorMBean {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
package com.cloud.utils.component;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This interface defines methods for pluggable code within the Cloud Stack.
|
||||
*/
|
||||
|
|
@ -26,5 +27,5 @@ public interface PluggableService {
|
|||
* The config file name that lists API commands supported by this pluggable service
|
||||
*/
|
||||
String getPropertiesFile();
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,64 @@
|
|||
// 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
|
||||
// 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.utils.component;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.cloud.utils.Pair;
|
||||
|
||||
|
||||
/**
|
||||
* CloudStack uses Adapters to implement different capabilities.
|
||||
* There are different Adapters such as NetworkGuru, NetworkElement,
|
||||
* HypervisorGuru, DeploymentPlanner, etc. However, Adapters only
|
||||
* defines what CloudStack needs from the implementation. What about
|
||||
* what the Adapter itself needs, such as configurations and administrative
|
||||
* operations, and what if one implementation can
|
||||
* implement two different Adapters?
|
||||
*
|
||||
* Plugin is a CloudStack container for Adapters. It rolls the following
|
||||
* capabilities into the one package for CloudStack to load at runtime.
|
||||
* - REST API commands supported by the Plugin.
|
||||
* - Components needed by the Plugin.
|
||||
* - Adapters implemented by the Plugin.
|
||||
* - Database operations
|
||||
*
|
||||
*/
|
||||
public interface Plugin extends PluggableService {
|
||||
|
||||
/**
|
||||
* Retrieves the component libraries needed by this Plugin.
|
||||
* ComponentLocator put these components and add them to the startup
|
||||
* and shutdown processes of CloudStack. This is only needed if the
|
||||
* Plugin uses ComponentLocator to inject what it needs. If the
|
||||
* Plugin uses other mechanisms, then it can return null here.
|
||||
*
|
||||
* @return a component library that contains the components this Plugin
|
||||
* contains and needs.
|
||||
*/
|
||||
ComponentLibrary getComponentLibrary();
|
||||
|
||||
/**
|
||||
* Retrieves the list of Adapters and the interface they implement. It
|
||||
* can be an empty list if the Plugin does not implement any.
|
||||
*
|
||||
* @return list of pairs where the first is the interface and the second
|
||||
* is the adapter.
|
||||
*/
|
||||
List<Pair<Class<?>, Class<? extends Adapter>>> getAdapterImplementations();
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue