mirror of
https://github.com/apache/cloudstack.git
synced 2025-11-02 20:02:29 +01:00
Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/incubator-cloudstack
This commit is contained in:
commit
4ccbdbd23d
@ -47,6 +47,15 @@ public interface EntityManager {
|
||||
*/
|
||||
public <T> T findByUuid(Class<T> entityType, String uuid);
|
||||
|
||||
/**
|
||||
* Finds a unique entity by uuid string
|
||||
* @param <T> entity class
|
||||
* @param entityType type of entity you're looking for.
|
||||
* @param uuid the unique id
|
||||
* @return T if found, null if not.
|
||||
*/
|
||||
public <T> T findByUuidIncludingRemoved(Class<T> entityType, String uuid);
|
||||
|
||||
/**
|
||||
* Finds an entity by external id which is always String
|
||||
* @param <T> entity class
|
||||
|
||||
@ -18,7 +18,7 @@ package org.apache.cloudstack.api;
|
||||
|
||||
public abstract class BaseListAccountResourcesCmd extends BaseListDomainResourcesCmd {
|
||||
|
||||
@Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "List resources by account. Must be used with the domainId parameter.")
|
||||
@Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "list resources by account. Must be used with the domainId parameter.")
|
||||
private String accountName;
|
||||
|
||||
public String getAccountName() {
|
||||
|
||||
@ -47,7 +47,7 @@ public class AttachIsoCmd extends BaseAsyncCmd {
|
||||
required=true, description="the ID of the ISO file")
|
||||
private Long id;
|
||||
|
||||
@Parameter(name=ApiConstants.VIRTUAL_MACHINE_ID, type=CommandType.UUID, entityType = TemplateResponse.class,
|
||||
@Parameter(name=ApiConstants.VIRTUAL_MACHINE_ID, type=CommandType.UUID, entityType = UserVmResponse.class,
|
||||
required=true, description="the ID of the virtual machine")
|
||||
private Long virtualMachineId;
|
||||
|
||||
|
||||
@ -42,7 +42,7 @@ public class DetachIsoCmd extends BaseAsyncCmd {
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Parameter(name=ApiConstants.VIRTUAL_MACHINE_ID, type=CommandType.UUID, entityType = TemplateResponse.class,
|
||||
@Parameter(name=ApiConstants.VIRTUAL_MACHINE_ID, type=CommandType.UUID, entityType = UserVmResponse.class,
|
||||
required=true, description="The ID of the virtual machine")
|
||||
private Long virtualMachineId;
|
||||
|
||||
|
||||
@ -51,7 +51,7 @@ public class CopyTemplateCmd extends BaseAsyncCmd {
|
||||
required=true, description="ID of the zone the template is being copied to.")
|
||||
private Long destZoneId;
|
||||
|
||||
@Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType = UserVmResponse.class,
|
||||
@Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType = TemplateResponse.class,
|
||||
required=true, description="Template ID.")
|
||||
private Long id;
|
||||
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
package org.apache.cloudstack.api.command.user.template;
|
||||
|
||||
import org.apache.cloudstack.api.*;
|
||||
import org.apache.cloudstack.api.response.UserVmResponse;
|
||||
import org.apache.cloudstack.api.response.TemplateResponse;
|
||||
import org.apache.cloudstack.api.response.ZoneResponse;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
@ -38,7 +38,7 @@ public class DeleteTemplateCmd extends BaseAsyncCmd {
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType = UserVmResponse.class,
|
||||
@Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType = TemplateResponse.class,
|
||||
required=true, description="the ID of the template")
|
||||
private Long id;
|
||||
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
package org.apache.cloudstack.api.command.user.template;
|
||||
|
||||
import org.apache.cloudstack.api.*;
|
||||
import org.apache.cloudstack.api.response.UserVmResponse;
|
||||
import org.apache.cloudstack.api.response.TemplateResponse;
|
||||
import org.apache.cloudstack.api.response.ZoneResponse;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
@ -40,7 +40,7 @@ public class ExtractTemplateCmd extends BaseAsyncCmd {
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType = UserVmResponse.class,
|
||||
@Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType = TemplateResponse.class,
|
||||
required=true, description="the ID of the template")
|
||||
private Long id;
|
||||
|
||||
|
||||
@ -64,15 +64,6 @@ public class ListVPCsCmd extends BaseListTaggedResourcesCmd{
|
||||
, description="list by ID of the VPC offering")
|
||||
private Long VpcOffId;
|
||||
|
||||
@Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING, description="list by account associated with the VPC. " +
|
||||
"Must be used with the domainId parameter.")
|
||||
private String accountName;
|
||||
|
||||
@Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.UUID, entityType=DomainResponse.class,
|
||||
description="list by domain ID associated with the VPC. " +
|
||||
"If used with the account parameter returns the VPC associated with the account for the specified domain.")
|
||||
private Long domainId;
|
||||
|
||||
@Parameter(name=ApiConstants.SUPPORTED_SERVICES, type=CommandType.LIST, collectionType=CommandType.STRING,
|
||||
description="list VPC supporting certain services")
|
||||
private List<String> supportedServices;
|
||||
@ -87,14 +78,6 @@ public class ListVPCsCmd extends BaseListTaggedResourcesCmd{
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public String getAccountName() {
|
||||
return accountName;
|
||||
}
|
||||
|
||||
public Long getDomainId() {
|
||||
return domainId;
|
||||
}
|
||||
|
||||
public Long getZoneId() {
|
||||
return zoneId;
|
||||
}
|
||||
|
||||
@ -107,7 +107,7 @@ public class ApiDiscoveryServiceImpl implements ApiDiscoveryService {
|
||||
}
|
||||
}
|
||||
|
||||
Field[] fields = ReflectUtil.getAllFieldsForClass(cmdClass,
|
||||
Set<Field> fields = ReflectUtil.getAllFieldsForClass(cmdClass,
|
||||
new Class<?>[]{BaseCmd.class, BaseAsyncCmd.class, BaseAsyncCreateCmd.class});
|
||||
|
||||
boolean isAsync = ReflectUtil.isCmdClassAsync(cmdClass,
|
||||
|
||||
@ -27,6 +27,7 @@ import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
@ -157,8 +158,7 @@ public class ApiDispatcher {
|
||||
}
|
||||
|
||||
if (queueSizeLimit != null) {
|
||||
_asyncMgr
|
||||
.syncAsyncJobExecution(asyncCmd.getJob(), asyncCmd.getSyncObjType(), asyncCmd.getSyncObjId().longValue(), queueSizeLimit);
|
||||
_asyncMgr.syncAsyncJobExecution(asyncCmd.getJob(), asyncCmd.getSyncObjType(), asyncCmd.getSyncObjId().longValue(), queueSizeLimit);
|
||||
} else {
|
||||
s_logger.trace("The queue size is unlimited, skipping the synchronizing");
|
||||
}
|
||||
@ -190,8 +190,7 @@ public class ApiDispatcher {
|
||||
}
|
||||
}
|
||||
|
||||
Field[] fields = ReflectUtil.getAllFieldsForClass(cmd.getClass(),
|
||||
new Class<?>[] {BaseCmd.class});
|
||||
List<Field> fields = ReflectUtil.getAllFieldsForClass(cmd.getClass(), BaseCmd.class);
|
||||
|
||||
for (Field field : fields) {
|
||||
PlugService plugServiceAnnotation = field.getAnnotation(PlugService.class);
|
||||
@ -360,8 +359,9 @@ public class ApiDispatcher {
|
||||
// Go through each entity which is an interface to a VO class and get a VO object
|
||||
// Try to getId() for the object using reflection, break on first non-null value
|
||||
for (Class<?> entity: entities) {
|
||||
// findByUuid returns one VO object using uuid, use reflect to get the Id
|
||||
Object objVO = s_instance._entityMgr.findByUuid(entity, uuid);
|
||||
// For backward compatibility, we search within removed entities and let service layer deal
|
||||
// with removed ones, return empty response or error
|
||||
Object objVO = s_instance._entityMgr.findByUuidIncludingRemoved(entity, uuid);
|
||||
if (objVO == null) {
|
||||
continue;
|
||||
}
|
||||
@ -377,11 +377,10 @@ public class ApiDispatcher {
|
||||
break;
|
||||
}
|
||||
if (internalId == null) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Object entity with uuid=" + uuid + " does not exist in the database.");
|
||||
}
|
||||
if (s_logger.isDebugEnabled())
|
||||
s_logger.debug("Object entity uuid = " + uuid + " does not exist in the database.");
|
||||
throw new InvalidParameterValueException("Invalid parameter value=" + uuid
|
||||
+ " due to incorrect long value, entity not found, or an annotation bug.");
|
||||
+ " due to incorrect long value format, or entity was not found as it may have been deleted, or due to incorrect parameter annotation for the field in api cmd.");
|
||||
}
|
||||
return internalId;
|
||||
}
|
||||
|
||||
@ -28,6 +28,7 @@ import java.util.*;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
import com.cloud.utils.IteratorUtil;
|
||||
import com.cloud.utils.ReflectUtil;
|
||||
import org.apache.cloudstack.api.*;
|
||||
import org.apache.log4j.Logger;
|
||||
@ -135,7 +136,7 @@ public class ApiXmlDocWriter {
|
||||
String commandRoleMask = preProcessedCommand.substring(splitIndex + 1);
|
||||
Class<?> cmdClass = _apiNameCmdClassMap.get(key);
|
||||
if (cmdClass == null) {
|
||||
System.out.println("Check, Null Value for key: " + key + " preProcessedCommand=" + preProcessedCommand);
|
||||
System.out.println("Check, is this api part of another build profile? Null value for key: " + key + " preProcessedCommand=" + preProcessedCommand);
|
||||
continue;
|
||||
}
|
||||
String commandName = cmdClass.getName();
|
||||
@ -349,7 +350,7 @@ public class ApiXmlDocWriter {
|
||||
|
||||
apiCommand.setAsync(isAsync);
|
||||
|
||||
Field[] fields = ReflectUtil.getAllFieldsForClass(clas,
|
||||
Set<Field> fields = ReflectUtil.getAllFieldsForClass(clas,
|
||||
new Class<?>[] {BaseCmd.class, BaseAsyncCmd.class, BaseAsyncCreateCmd.class});
|
||||
|
||||
request = setRequestFields(fields);
|
||||
@ -422,10 +423,10 @@ public class ApiXmlDocWriter {
|
||||
out.writeObject(apiCommand);
|
||||
}
|
||||
|
||||
private static ArrayList<Argument> setRequestFields(Field[] fields) {
|
||||
private static ArrayList<Argument> setRequestFields(Set<Field> fields) {
|
||||
ArrayList<Argument> arguments = new ArrayList<Argument>();
|
||||
ArrayList<Argument> requiredArguments = new ArrayList<Argument>();
|
||||
ArrayList<Argument> optionalArguments = new ArrayList<Argument>();
|
||||
Set<Argument> requiredArguments = new HashSet<Argument>();
|
||||
Set<Argument> optionalArguments = new HashSet<Argument>();
|
||||
Argument id = null;
|
||||
for (Field f : fields) {
|
||||
Parameter parameterAnnotation = f.getAnnotation(Parameter.class);
|
||||
@ -444,7 +445,7 @@ public class ApiXmlDocWriter {
|
||||
reqArg.setSinceVersion(parameterAnnotation.since());
|
||||
}
|
||||
|
||||
if (reqArg.isRequired() == true) {
|
||||
if (reqArg.isRequired()) {
|
||||
if (parameterAnnotation.name().equals("id")) {
|
||||
id = reqArg;
|
||||
} else {
|
||||
@ -456,15 +457,12 @@ public class ApiXmlDocWriter {
|
||||
}
|
||||
}
|
||||
|
||||
Collections.sort(requiredArguments);
|
||||
Collections.sort(optionalArguments);
|
||||
|
||||
// sort required and optional arguments here
|
||||
if (id != null) {
|
||||
arguments.add(id);
|
||||
}
|
||||
arguments.addAll(requiredArguments);
|
||||
arguments.addAll(optionalArguments);
|
||||
arguments.addAll(IteratorUtil.asSortedList(requiredArguments));
|
||||
arguments.addAll(IteratorUtil.asSortedList(optionalArguments));
|
||||
|
||||
return arguments;
|
||||
}
|
||||
|
||||
@ -51,6 +51,13 @@ public class EntityManagerImpl implements EntityManager, Manager {
|
||||
return dao.findByUuid(uuid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T findByUuidIncludingRemoved(Class<T> entityType, String uuid) {
|
||||
// Finds and returns a unique VO using uuid, null if entity not found in db
|
||||
GenericDao<? extends T, String> dao = (GenericDao<? extends T, String>)GenericDaoBase.getDao(entityType);
|
||||
return dao.findByUuidIncludingRemoved(uuid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T findByXId(Class<T> entityType, String xid) {
|
||||
return null;
|
||||
|
||||
@ -75,7 +75,8 @@ class CloudMonkeyShell(cmd.Cmd, object):
|
||||
# datastructure {'verb': {cmd': ['api', [params], doc, required=[]]}}
|
||||
cache_verbs = precached_verbs
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self, pname):
|
||||
self.program_name = pname
|
||||
if os.path.exists(self.config_file):
|
||||
config = self.read_config()
|
||||
else:
|
||||
@ -262,8 +263,9 @@ class CloudMonkeyShell(cmd.Cmd, object):
|
||||
return
|
||||
|
||||
isAsync = isAsync and (self.asyncblock == "true")
|
||||
if isAsync and 'jobid' in response[response.keys()[0]]:
|
||||
jobId = response[response.keys()[0]]['jobid']
|
||||
responsekey = filter(lambda x: 'response' in x, response.keys())[0]
|
||||
if isAsync and 'jobid' in response[responsekey]:
|
||||
jobId = response[responsekey]['jobid']
|
||||
command = "queryAsyncJobResult"
|
||||
requests = {'jobid': jobId}
|
||||
timeout = int(self.timeout)
|
||||
@ -282,7 +284,7 @@ class CloudMonkeyShell(cmd.Cmd, object):
|
||||
jobstatus = result['jobstatus']
|
||||
if jobstatus == 2:
|
||||
jobresult = result["jobresult"]
|
||||
self.print_shell("Async query failed for jobid=",
|
||||
self.print_shell("\rAsync query failed for jobid",
|
||||
jobId, "\nError", jobresult["errorcode"],
|
||||
jobresult["errortext"])
|
||||
return
|
||||
@ -293,7 +295,7 @@ class CloudMonkeyShell(cmd.Cmd, object):
|
||||
timeout = timeout - pollperiod
|
||||
progress += 1
|
||||
logger.debug("job: %s to timeout in %ds" % (jobId, timeout))
|
||||
self.print_shell("Error:", "Async query timeout for jobid=", jobId)
|
||||
self.print_shell("Error:", "Async query timeout for jobid", jobId)
|
||||
|
||||
return response
|
||||
|
||||
@ -306,7 +308,19 @@ class CloudMonkeyShell(cmd.Cmd, object):
|
||||
return None
|
||||
return api_mod
|
||||
|
||||
def pipe_runner(self, args):
|
||||
if args.find(' |') > -1:
|
||||
pname = self.program_name
|
||||
if '.py' in pname:
|
||||
pname = "python " + pname
|
||||
self.do_shell("%s %s" % (pname, args))
|
||||
return True
|
||||
return False
|
||||
|
||||
def default(self, args):
|
||||
if self.pipe_runner(args):
|
||||
return
|
||||
|
||||
lexp = shlex.shlex(args.strip())
|
||||
lexp.whitespace = " "
|
||||
lexp.whitespace_split = True
|
||||
@ -387,7 +401,8 @@ class CloudMonkeyShell(cmd.Cmd, object):
|
||||
self.cache_verbs[verb][subject][1])
|
||||
search_string = text
|
||||
|
||||
autocompletions.append("filter=")
|
||||
if self.tabularize == "true":
|
||||
autocompletions.append("filter=")
|
||||
return [s for s in autocompletions if s.startswith(search_string)]
|
||||
|
||||
def do_api(self, args):
|
||||
@ -504,22 +519,21 @@ def main():
|
||||
for rule in grammar:
|
||||
def add_grammar(rule):
|
||||
def grammar_closure(self, args):
|
||||
if '|' in args: # FIXME: Consider parsing issues
|
||||
prog_name = sys.argv[0]
|
||||
if '.py' in prog_name:
|
||||
prog_name = "python " + prog_name
|
||||
self.do_shell("%s %s %s" % (prog_name, rule, args))
|
||||
if self.pipe_runner("%s %s" % (rule, args)):
|
||||
return
|
||||
try:
|
||||
args_partition = args.partition(" ")
|
||||
res = self.cache_verbs[rule][args_partition[0]]
|
||||
cmd = res[0]
|
||||
helpdoc = res[2]
|
||||
args = args_partition[2]
|
||||
except KeyError, e:
|
||||
self.print_shell("Error: invalid %s api arg" % rule, e)
|
||||
return
|
||||
if ' --help' in args or ' -h' in args:
|
||||
self.print_shell(res[2])
|
||||
self.print_shell(helpdoc)
|
||||
return
|
||||
self.default(res[0] + " " + args_partition[2])
|
||||
self.default("%s %s" % (cmd, args))
|
||||
return grammar_closure
|
||||
|
||||
grammar_handler = add_grammar(rule)
|
||||
@ -527,7 +541,7 @@ def main():
|
||||
grammar_handler.__name__ = 'do_' + rule
|
||||
setattr(self, grammar_handler.__name__, grammar_handler)
|
||||
|
||||
shell = CloudMonkeyShell()
|
||||
shell = CloudMonkeyShell(sys.argv[0])
|
||||
if len(sys.argv) > 1:
|
||||
shell.onecmd(' '.join(sys.argv[1:]))
|
||||
else:
|
||||
|
||||
@ -53,7 +53,7 @@ setup(
|
||||
include_package_data = True,
|
||||
zip_safe = False,
|
||||
classifiers = [
|
||||
"Development Status :: 4 - Beta",
|
||||
"Development Status :: 5 - Production/Stable",
|
||||
"Environment :: Console",
|
||||
"Intended Audience :: Developers",
|
||||
"Intended Audience :: End Users/Desktop",
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
// under the License.
|
||||
|
||||
(function($, cloudStack) {
|
||||
var zoneObjs, hypervisorObjs, featuredTemplateObjs, communityTemplateObjs, myTemplateObjs, featuredIsoObjs, community;
|
||||
var zoneObjs, hypervisorObjs, featuredTemplateObjs, communityTemplateObjs, myTemplateObjs, featuredIsoObjs, community, networkObjs;
|
||||
var selectedZoneObj, selectedTemplateObj, selectedHypervisor, selectedDiskOfferingObj;
|
||||
var step5ContainerType = 'nothing-to-select'; //'nothing-to-select', 'select-network', 'select-security-group'
|
||||
|
||||
@ -40,6 +40,33 @@
|
||||
!data.vpcid;
|
||||
},
|
||||
|
||||
// Runs when advanced SG-enabled zone is run, before
|
||||
// the security group step
|
||||
//
|
||||
// -- if it returns false, then 'Select Security Group' is skipped.
|
||||
//
|
||||
advSGFilter: function(args) {
|
||||
var selectedNetworks;
|
||||
|
||||
if ($.isArray(args.data['my-networks'])) {
|
||||
selectedNetworks = $(args.data['my-networks']).map(function(index, myNetwork) {
|
||||
return $.grep(networkObjs, function(networkObj) {
|
||||
return networkObj.id == myNetwork;
|
||||
});
|
||||
});
|
||||
} else {
|
||||
selectedNetworks = $.grep(networkObjs, function(networkObj) {
|
||||
return networkObj.id == args.data['my-networks'];
|
||||
});
|
||||
}
|
||||
|
||||
return $.grep(selectedNetworks, function(network) {
|
||||
return $.grep(network.service, function(service) {
|
||||
return service.name == 'SecurityGroup';
|
||||
}).length;
|
||||
}).length;
|
||||
},
|
||||
|
||||
// Data providers for each wizard step
|
||||
steps: [
|
||||
|
||||
@ -347,7 +374,7 @@
|
||||
networkData.account = g_account;
|
||||
}
|
||||
|
||||
var networkObjs, vpcObjs;
|
||||
var vpcObjs;
|
||||
|
||||
//listVPCs without account/domainid/listAll parameter will return only VPCs belonging to the current login. That's what should happen in Instances page's VM Wizard.
|
||||
//i.e. If the current login is root-admin, do not show VPCs belonging to regular-user/domain-admin in Instances page's VM Wizard.
|
||||
@ -365,7 +392,7 @@
|
||||
async: false,
|
||||
success: function(json) {
|
||||
networkObjs = json.listnetworksresponse.network ? json.listnetworksresponse.network : [];
|
||||
|
||||
|
||||
if(networkObjs.length > 0) {
|
||||
for(var i = 0; i < networkObjs.length; i++) {
|
||||
var networkObj = networkObjs[i];
|
||||
|
||||
@ -1026,7 +1026,7 @@
|
||||
createForm: {
|
||||
desc: 'message.enter.token',
|
||||
fields: {
|
||||
projectid: { label: 'label.project.id', validation: { required: true, docID: 'helpEnterTokenProjectID' }},
|
||||
projectid: { label: 'label.project.id', validation: { required: true}, docID: 'helpEnterTokenProjectID' },
|
||||
token: { label: 'label.token', docID: 'helpEnterTokenToken', validation: { required: true }}
|
||||
}
|
||||
},
|
||||
|
||||
@ -821,6 +821,16 @@
|
||||
cloudStack.dialog.notice({ message: 'message.step.4.continue' });
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($activeStep.hasClass('next-use-security-groups')) {
|
||||
var advSGFilter = args.advSGFilter({
|
||||
data: cloudStack.serializeForm($form)
|
||||
});
|
||||
|
||||
if (!advSGFilter) {
|
||||
showStep(6);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//step 6 - review (spcifiy displyname, group as well)
|
||||
|
||||
@ -16,8 +16,11 @@
|
||||
// under the License.
|
||||
package com.cloud.utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
public class IteratorUtil {
|
||||
public static <T> Iterable<T> enumerationAsIterable(final Enumeration<T> e) {
|
||||
@ -51,4 +54,11 @@ public class IteratorUtil {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static
|
||||
<T extends Comparable<? super T>> List<T> asSortedList(Collection<T> c) {
|
||||
List<T> list = new ArrayList<T>(c);
|
||||
java.util.Collections.sort(list);
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
@ -19,7 +19,10 @@ package com.cloud.utils;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
@ -87,26 +90,39 @@ public class ReflectUtil {
|
||||
return isAsync;
|
||||
}
|
||||
|
||||
// Returns all fields across the base class for a cmd
|
||||
public static Field[] getAllFieldsForClass(Class<?> cmdClass,
|
||||
Class<?>[] searchClasses) {
|
||||
Field[] fields = cmdClass.getDeclaredFields();
|
||||
// Returns all fields until a base class for a cmd class
|
||||
public static List<Field> getAllFieldsForClass(Class<?> cmdClass,
|
||||
Class<?> baseClass) {
|
||||
List<Field> fields = new ArrayList<Field>();
|
||||
Collections.addAll(fields, cmdClass.getDeclaredFields());
|
||||
Class<?> superClass = cmdClass.getSuperclass();
|
||||
while (baseClass.isAssignableFrom(superClass)) {
|
||||
Field[] superClassFields = superClass.getDeclaredFields();
|
||||
if (superClassFields != null)
|
||||
Collections.addAll(fields, superClassFields);
|
||||
superClass = superClass.getSuperclass();
|
||||
}
|
||||
return fields;
|
||||
}
|
||||
|
||||
// Returns all unique fields except excludeClasses for a cmd class
|
||||
public static Set<Field> getAllFieldsForClass(Class<?> cmdClass,
|
||||
Class<?>[] excludeClasses) {
|
||||
Set<Field> fields = new HashSet<Field>();
|
||||
Collections.addAll(fields, cmdClass.getDeclaredFields());
|
||||
Class<?> superClass = cmdClass.getSuperclass();
|
||||
|
||||
while (superClass != null && superClass != Object.class) {
|
||||
String superName = superClass.getName();
|
||||
for (Class<?> baseClass: searchClasses) {
|
||||
if(!baseClass.isAssignableFrom(superClass))
|
||||
continue;
|
||||
if (!superName.equals(baseClass.getName())) {
|
||||
Field[] superClassFields = superClass.getDeclaredFields();
|
||||
if (superClassFields != null) {
|
||||
Field[] tmpFields = new Field[fields.length + superClassFields.length];
|
||||
System.arraycopy(fields, 0, tmpFields, 0, fields.length);
|
||||
System.arraycopy(superClassFields, 0, tmpFields, fields.length, superClassFields.length);
|
||||
fields = tmpFields;
|
||||
}
|
||||
}
|
||||
boolean isNameEqualToSuperName = false;
|
||||
for (Class<?> baseClass: excludeClasses)
|
||||
if (superName.equals(baseClass.getName()))
|
||||
isNameEqualToSuperName = true;
|
||||
|
||||
if (!isNameEqualToSuperName) {
|
||||
Field[] superClassFields = superClass.getDeclaredFields();
|
||||
if (superClassFields != null)
|
||||
Collections.addAll(fields, superClassFields);
|
||||
}
|
||||
superClass = superClass.getSuperclass();
|
||||
}
|
||||
|
||||
@ -57,6 +57,9 @@ public interface GenericDao<T, ID extends Serializable> {
|
||||
|
||||
// Finds one unique VO using uuid
|
||||
T findByUuid(String uuid);
|
||||
|
||||
// Finds one unique VO using uuid including removed entities
|
||||
T findByUuidIncludingRemoved(String uuid);
|
||||
|
||||
/**
|
||||
* @return VO object ready to be used for update. It won't have any fields filled in.
|
||||
|
||||
@ -921,6 +921,14 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
|
||||
return findOneBy(sc);
|
||||
}
|
||||
|
||||
@Override @DB(txn=false)
|
||||
@SuppressWarnings("unchecked")
|
||||
public T findByUuidIncludingRemoved(final String uuid) {
|
||||
SearchCriteria<T> sc = createSearchCriteria();
|
||||
sc.addAnd("uuid", SearchCriteria.Op.EQ, uuid);
|
||||
return findOneIncludingRemovedBy(sc);
|
||||
}
|
||||
|
||||
@Override @DB(txn=false)
|
||||
public T findByIdIncludingRemoved(ID id) {
|
||||
return findById(id, true, null);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user