CLOUDSTACK-6784: Expose data types via API so consumers of API can validate data

This commit is contained in:
Marcus Sorensen 2014-05-27 11:31:46 -06:00
parent 96055058b0
commit 20a31b43d6
5 changed files with 46 additions and 2 deletions

View File

@ -232,6 +232,10 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager,
return;
}
if (resultObject != null) {
job.setResult(resultObject);
}
publishOnEventBus(job, "complete"); // publish before the instance type and ID are wiped out
List<Long> wakeupList = Transaction.execute(new TransactionCallback<List<Long>>() {
@Override

View File

@ -279,15 +279,19 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
eventDescription.put("account", jobOwner.getUuid());
eventDescription.put("processStatus", "" + job.getProcessStatus());
eventDescription.put("resultCode", "" + job.getResultCode());
eventDescription.put("instanceUuid", ApiDBUtils.findJobInstanceUuid(job));
eventDescription.put("instanceUuid", (job.getInstanceId() != null ? ApiDBUtils.findJobInstanceUuid(job) : "" ) );
eventDescription.put("instanceType", (job.getInstanceType() != null ? job.getInstanceType().toString() : "unknown"));
eventDescription.put("commandEventType", cmdEventType);
eventDescription.put("jobId", job.getUuid());
eventDescription.put("jobResult", job.getResult());
eventDescription.put("cmdInfo", job.getCmdInfo());
eventDescription.put("status", "" + job.getStatus() );
// If the event.accountinfo boolean value is set, get the human readable value for the username / domainname
Map<String, String> configs = _configDao.getConfiguration("management-server", new HashMap<String, String>());
if (Boolean.valueOf(configs.get("event.accountinfo"))) {
DomainVO domain = _domainDao.findById(jobOwner.getDomainId());
eventDescription.put("username", userJobOwner.getUsername());
eventDescription.put("accountname", jobOwner.getAccountName());
eventDescription.put("domainname", domain.getName());
}
event.setDescription(eventDescription);

View File

@ -471,6 +471,8 @@ public class ApiXmlDocWriter {
reqArg.setType(parameterAnnotation.type().toString().toLowerCase());
}
reqArg.setDataType(parameterAnnotation.type().toString().toLowerCase());
if (!parameterAnnotation.since().isEmpty()) {
reqArg.setSinceVersion(parameterAnnotation.since());
}
@ -518,6 +520,8 @@ public class ApiXmlDocWriter {
respArg.setDescription(description);
}
respArg.setDataType(responseField.getType().getSimpleName().toLowerCase());
if (!paramAnnotation.since().isEmpty()) {
respArg.setSinceVersion(paramAnnotation.since());
}
@ -648,4 +652,4 @@ public class ApiXmlDocWriter {
}
}
}
}

View File

@ -25,6 +25,7 @@ public class Argument implements Comparable {
private String type;
private String sinceVersion = null;
private List<Argument> arguments;
private String dataType;
public Argument(String name) {
this.name = name;
@ -49,6 +50,14 @@ public class Argument implements Comparable {
this.type = type;
}
public void setDataType(String dataType) {
this.dataType = dataType;
}
public String getDataType() {
return this.dataType;
}
public String getName() {
return name;
}
@ -100,4 +109,9 @@ public class Argument implements Comparable {
public boolean hasArguments() {
return (arguments != null && !arguments.isEmpty());
}
@Override
public String toString() {
return "name=" + this.name + ", description=" + description + ", required=" + required + ", type=" + this.type + ", sinceVersion=" + this.sinceVersion + ", arguments=" + this.arguments + ", dataType=" + this.dataType;
}
}

View File

@ -32,6 +32,7 @@ class cmdParameterProperty(object):
self.desc = ""
self.type = "planObject"
self.subProperties = []
self.dataType = ""
class cloudStackCmd(object):
@ -123,6 +124,8 @@ class CodeGenerator(object):
self.code += 'from baseCmd import *\n'
self.code += 'from baseResponse import *\n'
self.code += "class %sCmd (baseCmd):\n" % self.cmd.name
self.code += self.space
self.code += 'typeInfo = {}\n'
self.code += self.space + "def __init__(self):\n"
self.code += self.space + self.space
@ -142,6 +145,8 @@ class CodeGenerator(object):
self.code += 'self.%s = %s\n' % (req.name, value)
if req.required == "true":
self.required.append(req.name)
self.code += self.space + self.space
self.code += "self.typeInfo['%s'] = '%s'\n" % ( req.name, req.dataType )
self.code += self.space + self.space + "self.required = ["
for require in self.required:
@ -153,6 +158,8 @@ class CodeGenerator(object):
subItems = {}
self.code += self.newline
self.code += 'class %sResponse (baseResponse):\n' % self.cmd.name
self.code += self.space
self.code += 'typeInfo = {}\n'
self.code += self.space + "def __init__(self):\n"
if len(self.cmd.response) == 0:
self.code += self.space + self.space + "pass"
@ -169,6 +176,10 @@ class CodeGenerator(object):
else:
self.code += self.space + self.space
self.code += 'self.%s = None\n' % res.name
if res.dataType is not None:
self.code += self.space + self.space
self.code += "self.typeInfo['%s'] = '%s'\n" % ( res.name, res.dataType )
self.code += self.newline
for subclass in self.subclass:
@ -267,6 +278,9 @@ class CodeGenerator(object):
paramProperty.name = getText(response.getElementsByTagName('name'))
paramProperty.desc = getText(response.
getElementsByTagName('description'))
dataType = response.getElementsByTagName('dataType')
if dataType:
paramProperty.dataType = getText(dataType)
if paramProperty.name.find('(*)') != -1:
'''This is a list'''
paramProperty.name = paramProperty.name.split('(*)')[0]
@ -313,6 +327,10 @@ class CodeGenerator(object):
if type:
paramProperty.type = getText(type)
dataType = param.getElementsByTagName('dataType')
if dataType:
paramProperty.dataType = getText(dataType)
csCmd.request.append(paramProperty)
responseEle = cmd.getElementsByTagName("response")[0]