From a789d43dedf3c2c70d81901d61b5fc8f58ea7360 Mon Sep 17 00:00:00 2001 From: Prasanna Santhanam Date: Tue, 28 May 2013 12:13:55 +0530 Subject: [PATCH] marvin_refactor: Derive the entity from the responseObject The API discovery service is enhanced to include the entity that an API will act upon. Also included are the changes for API doc generation. For APIs that don't provide a direct relationship to their entities we use the related parameter to derive the entity. Signed-off-by: Prasanna Santhanam --- .../discovery/ApiDiscoveryServiceImpl.java | 27 ++++++-- .../com/cloud/api/doc/ApiXmlDocWriter.java | 62 +++++++++---------- server/src/com/cloud/api/doc/Command.java | 13 +++- 3 files changed, 64 insertions(+), 38 deletions(-) diff --git a/plugins/api/discovery/src/org/apache/cloudstack/discovery/ApiDiscoveryServiceImpl.java b/plugins/api/discovery/src/org/apache/cloudstack/discovery/ApiDiscoveryServiceImpl.java index 83cc8c2006c..47b9d581bf1 100755 --- a/plugins/api/discovery/src/org/apache/cloudstack/discovery/ApiDiscoveryServiceImpl.java +++ b/plugins/api/discovery/src/org/apache/cloudstack/discovery/ApiDiscoveryServiceImpl.java @@ -101,17 +101,19 @@ public class ApiDiscoveryServiceImpl extends ComponentLifecycleBase implements A s_logger.trace("Found api: " + apiName); } ApiDiscoveryResponse response = getCmdRequestMap(cmdClass, apiCmdAnnotation); - String responseName = apiCmdAnnotation.responseObject().getName(); if (!responseName.contains("SuccessResponse")) { if (!responseApiNameListMap.containsKey(responseName)) { responseApiNameListMap.put(responseName, new ArrayList()); } + //Identify entities for those with a direct response responseApiNameListMap.get(responseName).add(apiName); + String entity = apiCmdAnnotation.responseObject().getSimpleName().replace("Response", ""); + response.setEntity(entity); + } else { + String entity = deriveRelatedEntity(apiName, response).replace("Response", ""); + response.setEntity(entity); } - response.setRelated(responseName); - String entity = apiCmdAnnotation.responseObject().getSimpleName(); - response.setEntity(entity.replaceAll("Response", "")); Field[] responseFields = apiCmdAnnotation.responseObject().getDeclaredFields(); for(Field responseField: responseFields) { @@ -144,11 +146,26 @@ public class ApiDiscoveryServiceImpl extends ComponentLifecycleBase implements A } else { response.setRelated(null); } + s_apiNameDiscoveryResponseMap.put(apiName, response); } return responseApiNameListMap; } + private String deriveRelatedEntity(String currentApi, ApiDiscoveryResponse response) { + //Guess the entity from the related APIs + String entity = ""; + for (ApiParameterResponse param : response.getParams()) { + if (param.getRelated() != null) { + entity = param.getRelated(); + } + } + if (entity.isEmpty()) { + s_logger.warn("Couldn't find entity for API: " + currentApi + " from related APIs"); + } + return entity; + } + private ApiResponseResponse getFieldResponseMap(Field responseField) { ApiResponseResponse responseResponse = new ApiResponseResponse(); SerializedName serializedName = responseField.getAnnotation(SerializedName.class); @@ -211,7 +228,7 @@ public class ApiDiscoveryServiceImpl extends ComponentLifecycleBase implements A if (!parameterAnnotation.since().isEmpty()) { paramResponse.setSince(parameterAnnotation.since()); } - paramResponse.setRelated(parameterAnnotation.entityType()[0].getName()); + paramResponse.setRelated(parameterAnnotation.entityType()[0].getSimpleName()); response.addParam(paramResponse); } } diff --git a/server/src/com/cloud/api/doc/ApiXmlDocWriter.java b/server/src/com/cloud/api/doc/ApiXmlDocWriter.java index b7d526d94d9..b981abbc9e6 100644 --- a/server/src/com/cloud/api/doc/ApiXmlDocWriter.java +++ b/server/src/com/cloud/api/doc/ApiXmlDocWriter.java @@ -16,6 +16,29 @@ // under the License. package com.cloud.api.doc; +import com.cloud.alert.AlertManager; +import com.cloud.serializer.Param; +import com.cloud.utils.IteratorUtil; +import com.cloud.utils.ReflectUtil; +import com.google.gson.annotations.SerializedName; +import com.thoughtworks.xstream.XStream; +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.BaseAsyncCmd; +import org.apache.cloudstack.api.BaseAsyncCreateCmd; +import org.apache.cloudstack.api.BaseCmd; +import org.apache.cloudstack.api.BaseResponse; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.response.AsyncJobResponse; +import org.apache.cloudstack.api.response.HostResponse; +import org.apache.cloudstack.api.response.IPAddressResponse; +import org.apache.cloudstack.api.response.SecurityGroupResponse; +import org.apache.cloudstack.api.response.SnapshotResponse; +import org.apache.cloudstack.api.response.StoragePoolResponse; +import org.apache.cloudstack.api.response.TemplateResponse; +import org.apache.cloudstack.api.response.UserVmResponse; +import org.apache.cloudstack.api.response.VolumeResponse; +import org.apache.log4j.Logger; + import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; @@ -41,32 +64,6 @@ import java.util.TreeMap; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; -import org.apache.log4j.Logger; - -import com.google.gson.annotations.SerializedName; -import com.thoughtworks.xstream.XStream; - -import org.apache.cloudstack.api.APICommand; -import org.apache.cloudstack.api.BaseAsyncCmd; -import org.apache.cloudstack.api.BaseAsyncCreateCmd; -import org.apache.cloudstack.api.BaseCmd; -import org.apache.cloudstack.api.BaseResponse; -import org.apache.cloudstack.api.Parameter; -import org.apache.cloudstack.api.response.AsyncJobResponse; -import org.apache.cloudstack.api.response.HostResponse; -import org.apache.cloudstack.api.response.IPAddressResponse; -import org.apache.cloudstack.api.response.SecurityGroupResponse; -import org.apache.cloudstack.api.response.SnapshotResponse; -import org.apache.cloudstack.api.response.StoragePoolResponse; -import org.apache.cloudstack.api.response.TemplateResponse; -import org.apache.cloudstack.api.response.UserVmResponse; -import org.apache.cloudstack.api.response.VolumeResponse; - -import com.cloud.alert.AlertManager; -import com.cloud.serializer.Param; -import com.cloud.utils.IteratorUtil; -import com.cloud.utils.ReflectUtil; - public class ApiXmlDocWriter { public static final Logger s_logger = Logger.getLogger(ApiXmlDocWriter.class.getName()); @@ -357,6 +354,11 @@ public class ApiXmlDocWriter { if (commandUsage != null && !commandUsage.isEmpty()) { apiCommand.setUsage(commandUsage); } + + String entity = impl.responseObject().getSimpleName(); + if (entity != null && !entity.isEmpty()) { + apiCommand.setEntity(entity.replaceAll("Response", "")); + } //Set version when the API is added if(!impl.since().isEmpty()){ @@ -606,11 +608,9 @@ public class ApiXmlDocWriter { try { ObjectOutputStream out = xs.createObjectOutputStream(new FileWriter(dirName + "/alert_types.xml"), "alerts"); for (Field f : AlertManager.class.getFields()) { - if (f.getClass().isAssignableFrom(Number.class)) { - String name = f.getName().substring(11); - Alert alert = new Alert(name, f.getInt(null)); - out.writeObject(alert); - } + String name = f.getName().substring(11); + Alert alert = new Alert(name, f.getInt(null)); + out.writeObject(alert); } out.close(); } catch (IOException e) { diff --git a/server/src/com/cloud/api/doc/Command.java b/server/src/com/cloud/api/doc/Command.java index a267605216e..db7a395ad0a 100644 --- a/server/src/com/cloud/api/doc/Command.java +++ b/server/src/com/cloud/api/doc/Command.java @@ -27,8 +27,9 @@ public class Command { private String sinceVersion = null; private ArrayList request; private ArrayList response; - - public Command(String name, String description) { + private String entity; + + public Command(String name, String description) { this.name = name; this.description = description; } @@ -108,4 +109,12 @@ public class Command { public void setUsage(String usage) { this.usage = usage; } + + public void setEntity(String entity) { + this.entity = entity; + } + + public String getEntity() { + return this.entity; + } }