Skip to content

Commit d15243e

Browse files
author
Craig Squire
committed
Discover tags field on superclass of API responses
1 parent c6e53f6 commit d15243e

File tree

4 files changed

+95
-54
lines changed

4 files changed

+95
-54
lines changed

plugins/api/discovery/src/org/apache/cloudstack/api/response/ApiDiscoveryResponse.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,13 @@
1616
// under the License.
1717
package org.apache.cloudstack.api.response;
1818

19-
import java.util.HashSet;
20-
import java.util.Set;
21-
19+
import com.cloud.serializer.Param;
2220
import com.google.gson.annotations.SerializedName;
23-
2421
import org.apache.cloudstack.api.ApiConstants;
2522
import org.apache.cloudstack.api.BaseResponse;
2623

27-
import com.cloud.serializer.Param;
24+
import java.util.HashSet;
25+
import java.util.Set;
2826

2927
@SuppressWarnings("unused")
3028
public class ApiDiscoveryResponse extends BaseResponse {
@@ -121,4 +119,8 @@ public void addParam(ApiParameterResponse param) {
121119
public void addApiResponse(ApiResponseResponse apiResponse) {
122120
this.apiResponse.add(apiResponse);
123121
}
122+
123+
public Set<ApiResponseResponse> getApiResponse() {
124+
return apiResponse;
125+
}
124126
}

plugins/api/discovery/src/org/apache/cloudstack/api/response/ApiResponseResponse.java

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,13 @@
1616
// under the License.
1717
package org.apache.cloudstack.api.response;
1818

19-
import java.util.HashSet;
20-
import java.util.Set;
21-
19+
import com.cloud.serializer.Param;
2220
import com.google.gson.annotations.SerializedName;
23-
2421
import org.apache.cloudstack.api.ApiConstants;
2522
import org.apache.cloudstack.api.BaseResponse;
2623

27-
import com.cloud.serializer.Param;
24+
import java.util.HashSet;
25+
import java.util.Set;
2826

2927
public class ApiResponseResponse extends BaseResponse {
3028
@SerializedName(ApiConstants.NAME)
@@ -61,4 +59,20 @@ public void addApiResponse(ApiResponseResponse childApiResponse) {
6159
}
6260
this.apiResponse.add(childApiResponse);
6361
}
62+
63+
public String getName() {
64+
return name;
65+
}
66+
67+
public String getDescription() {
68+
return description;
69+
}
70+
71+
public String getType() {
72+
return type;
73+
}
74+
75+
public Set<ApiResponseResponse> getApiResponse() {
76+
return apiResponse;
77+
}
6478
}

plugins/api/discovery/src/org/apache/cloudstack/discovery/ApiDiscoveryServiceImpl.java

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,13 @@
1616
// under the License.
1717
package org.apache.cloudstack.discovery;
1818

19-
import java.lang.reflect.Field;
20-
import java.util.ArrayList;
21-
import java.util.HashMap;
22-
import java.util.HashSet;
23-
import java.util.List;
24-
import java.util.Map;
25-
import java.util.Set;
26-
27-
import javax.inject.Inject;
28-
29-
import org.apache.log4j.Logger;
30-
import org.springframework.stereotype.Component;
31-
19+
import com.cloud.serializer.Param;
20+
import com.cloud.user.User;
21+
import com.cloud.utils.ReflectUtil;
22+
import com.cloud.utils.StringUtils;
23+
import com.cloud.utils.component.ComponentLifecycleBase;
24+
import com.cloud.utils.component.PluggableService;
3225
import com.google.gson.annotations.SerializedName;
33-
3426
import org.apache.cloudstack.acl.APIChecker;
3527
import org.apache.cloudstack.api.APICommand;
3628
import org.apache.cloudstack.api.BaseAsyncCmd;
@@ -43,13 +35,18 @@
4335
import org.apache.cloudstack.api.response.ApiParameterResponse;
4436
import org.apache.cloudstack.api.response.ApiResponseResponse;
4537
import org.apache.cloudstack.api.response.ListResponse;
38+
import org.apache.log4j.Logger;
39+
import org.springframework.stereotype.Component;
4640

47-
import com.cloud.serializer.Param;
48-
import com.cloud.user.User;
49-
import com.cloud.utils.ReflectUtil;
50-
import com.cloud.utils.StringUtils;
51-
import com.cloud.utils.component.ComponentLifecycleBase;
52-
import com.cloud.utils.component.PluggableService;
41+
import javax.inject.Inject;
42+
import java.lang.reflect.Field;
43+
import java.util.ArrayList;
44+
import java.util.Arrays;
45+
import java.util.HashMap;
46+
import java.util.HashSet;
47+
import java.util.List;
48+
import java.util.Map;
49+
import java.util.Set;
5350

5451
@Component
5552
public class ApiDiscoveryServiceImpl extends ComponentLifecycleBase implements ApiDiscoveryService {
@@ -100,7 +97,8 @@ protected Map<String, List<String>> cacheResponseMap(Set<Class<?>> cmdClasses) {
10097
}
10198
ApiDiscoveryResponse response = getCmdRequestMap(cmdClass, apiCmdAnnotation);
10299

103-
String responseName = apiCmdAnnotation.responseObject().getName();
100+
Class<? extends BaseResponse> responseClass = apiCmdAnnotation.responseObject();
101+
String responseName = responseClass.getName();
104102
if (!responseName.contains("SuccessResponse")) {
105103
if (!responseApiNameListMap.containsKey(responseName)) {
106104
responseApiNameListMap.put(responseName, new ArrayList<String>());
@@ -109,7 +107,12 @@ protected Map<String, List<String>> cacheResponseMap(Set<Class<?>> cmdClasses) {
109107
}
110108
response.setRelated(responseName);
111109

112-
Field[] responseFields = apiCmdAnnotation.responseObject().getDeclaredFields();
110+
List<Field> responseFields = new ArrayList<>(Arrays.asList(responseClass.getDeclaredFields()));
111+
Class superClass = responseClass.getSuperclass();
112+
while(superClass != null) {
113+
responseFields.addAll(Arrays.asList(superClass.getDeclaredFields()));
114+
superClass = superClass.getSuperclass();
115+
}
113116
for (Field responseField : responseFields) {
114117
ApiResponseResponse responseResponse = getFieldResponseMap(responseField);
115118
response.addApiResponse(responseResponse);

plugins/api/discovery/test/org/apache/cloudstack/discovery/ApiDiscoveryTest.java

Lines changed: 44 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -16,49 +16,56 @@
1616
// under the License.
1717
package org.apache.cloudstack.discovery;
1818

19-
import static org.junit.Assert.assertEquals;
20-
import static org.junit.Assert.assertFalse;
21-
import static org.junit.Assert.assertTrue;
22-
import static org.mockito.Matchers.any;
23-
import static org.mockito.Matchers.anyString;
24-
import static org.mockito.Mockito.mock;
25-
import static org.mockito.Mockito.when;
19+
import com.cloud.user.User;
20+
import com.cloud.user.UserVO;
21+
import com.cloud.utils.component.PluggableService;
22+
import org.apache.cloudstack.acl.APIChecker;
23+
import org.apache.cloudstack.api.APICommand;
24+
import org.apache.cloudstack.api.command.user.discovery.ListApisCmd;
25+
import org.apache.cloudstack.api.command.user.vm.ListVMsCmd;
26+
import org.apache.cloudstack.api.response.ApiDiscoveryResponse;
27+
import org.apache.cloudstack.api.response.ApiResponseResponse;
28+
import org.apache.cloudstack.api.response.ListResponse;
29+
import org.apache.commons.lang.StringUtils;
30+
import org.junit.BeforeClass;
31+
import org.junit.Test;
2632

33+
import javax.naming.ConfigurationException;
2734
import java.util.ArrayList;
2835
import java.util.Arrays;
2936
import java.util.HashSet;
3037
import java.util.List;
3138
import java.util.Set;
39+
import java.util.stream.Collectors;
3240

33-
import javax.naming.ConfigurationException;
34-
35-
import org.junit.BeforeClass;
36-
import org.junit.Test;
37-
38-
import org.apache.cloudstack.acl.APIChecker;
39-
import org.apache.cloudstack.api.APICommand;
40-
import org.apache.cloudstack.api.command.user.discovery.ListApisCmd;
41-
import org.apache.cloudstack.api.response.ApiDiscoveryResponse;
42-
import org.apache.cloudstack.api.response.ListResponse;
43-
44-
import com.cloud.user.User;
45-
import com.cloud.user.UserVO;
46-
import com.cloud.utils.component.PluggableService;
41+
import static org.junit.Assert.assertEquals;
42+
import static org.junit.Assert.assertFalse;
43+
import static org.junit.Assert.assertNotNull;
44+
import static org.junit.Assert.assertTrue;
45+
import static org.mockito.Matchers.any;
46+
import static org.mockito.Matchers.anyString;
47+
import static org.mockito.Mockito.mock;
48+
import static org.mockito.Mockito.when;
4749

4850
public class ApiDiscoveryTest {
4951
private static APIChecker s_apiChecker = mock(APIChecker.class);
5052
private static PluggableService s_pluggableService = mock(PluggableService.class);
5153
private static ApiDiscoveryServiceImpl s_discoveryService = new ApiDiscoveryServiceImpl();
5254

5355
private static Class<?> testCmdClass = ListApisCmd.class;
56+
private static Class<?> listVMsCmdClass = ListVMsCmd.class;
5457
private static User testUser;
5558
private static String testApiName;
59+
private static String listVmsCmdName;
5660
private static String testApiDescription;
5761
private static String testApiSince;
5862
private static boolean testApiAsync;
5963

6064
@BeforeClass
6165
public static void setUp() throws ConfigurationException {
66+
67+
listVmsCmdName = listVMsCmdClass.getAnnotation(APICommand.class).name();
68+
6269
testApiName = testCmdClass.getAnnotation(APICommand.class).name();
6370
testApiDescription = testCmdClass.getAnnotation(APICommand.class).description();
6471
testApiSince = testCmdClass.getAnnotation(APICommand.class).since();
@@ -75,13 +82,15 @@ public static void setUp() throws ConfigurationException {
7582

7683
Set<Class<?>> cmdClasses = new HashSet<Class<?>>();
7784
cmdClasses.add(ListApisCmd.class);
85+
cmdClasses.add(ListVMsCmd.class);
7886
s_discoveryService.start();
7987
s_discoveryService.cacheResponseMap(cmdClasses);
8088
}
8189

8290
@Test
8391
public void verifyListSingleApi() throws Exception {
8492
ListResponse<ApiDiscoveryResponse> responses = (ListResponse<ApiDiscoveryResponse>)s_discoveryService.listApis(testUser, testApiName);
93+
assertNotNull("Responses should not be null", responses);
8594
if (responses != null) {
8695
ApiDiscoveryResponse response = responses.getResponses().get(0);
8796
assertTrue("No. of response items should be one", responses.getCount() == 1);
@@ -95,12 +104,25 @@ public void verifyListSingleApi() throws Exception {
95104
@Test
96105
public void verifyListApis() throws Exception {
97106
ListResponse<ApiDiscoveryResponse> responses = (ListResponse<ApiDiscoveryResponse>)s_discoveryService.listApis(testUser, null);
107+
assertNotNull("Responses should not be null", responses);
98108
if (responses != null) {
99-
assertTrue("No. of response items > 1", responses.getCount().intValue() == 1);
109+
assertTrue("No. of response items > 2", responses.getCount().intValue() == 2);
100110
for (ApiDiscoveryResponse response : responses.getResponses()) {
101111
assertFalse("API name is empty", response.getName().isEmpty());
102112
assertFalse("API description is empty", response.getDescription().isEmpty());
103113
}
104114
}
105115
}
116+
117+
@Test
118+
public void verifyListVirtualMachinesTagsField() throws Exception {
119+
ListResponse<ApiDiscoveryResponse> responses = (ListResponse<ApiDiscoveryResponse>)s_discoveryService.listApis(testUser, listVmsCmdName);
120+
assertNotNull("Response should not be null", responses);
121+
if (responses != null) {
122+
assertEquals("No. of response items should be one", 1, (int) responses.getCount());
123+
ApiDiscoveryResponse response = responses.getResponses().get(0);
124+
List<ApiResponseResponse> tagsResponse = response.getApiResponse().stream().filter(resp -> StringUtils.equals(resp.getName(), "tags")).collect(Collectors.toList());
125+
assertEquals("Tags field should be present in listVirtualMachines response fields", tagsResponse.size(), 1);
126+
}
127+
}
106128
}

0 commit comments

Comments
 (0)