Skip to content

Commit 1e6ea34

Browse files
a LOT of groundwork for fancier testing of api calls
1 parent bb92e07 commit 1e6ea34

File tree

7 files changed

+373
-81
lines changed

7 files changed

+373
-81
lines changed

src/main/java/com/softlayer/api/RestApiClient.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -225,10 +225,11 @@ class ServiceProxy<S extends Service> implements InvocationHandler {
225225

226226
final Class<S> serviceClass;
227227
final String id;
228-
Mask mask;
228+
public Mask mask;
229229
String maskString;
230230
ResultLimit resultLimit;
231231
Integer lastResponseTotalItemCount;
232+
232233

233234
public ServiceProxy(Class<S> serviceClass, String id) {
234235
this.serviceClass = serviceClass;
@@ -304,7 +305,7 @@ public Object logAndHandleResponse(HttpResponse response, String url,
304305
}
305306

306307
public Object invokeService(Method method, final Object[] args) throws Throwable {
307-
System.out.print("invokeService: " + method + "\n");
308+
308309
ApiMethod methodInfo = method.getAnnotation(ApiMethod.class);
309310
// Must have ID if instance is required
310311
if (methodInfo.instanceRequired() && id == null) {
@@ -441,7 +442,6 @@ public boolean isDone() {
441442
@Override
442443
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
443444
boolean noParams = args == null || args.length == 0;
444-
System.out.print("Invoking: " + method.getName() + "\n");
445445
if ("asAsync".equals(method.getName()) && noParams) {
446446
ServiceProxy<S> asyncProxy = new ServiceProxy<>(serviceClass, id);
447447
asyncProxy.mask = mask;

src/main/java/com/softlayer/api/TestApiClient.java

Lines changed: 0 additions & 61 deletions
This file was deleted.

src/test/java/com/softlayer/api/MaskTest.java

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ public void testMaskRemoval() {
106106
}
107107

108108
@Test
109-
public void testRecursiveMaskandLocal() {
109+
public void testRecursiveMaskAndLocal() {
110110
RestApiClient client = new RestApiClient("http://example.com/");
111111
TestEntity.Service service = TestEntity.service(client);
112112
service.withMask().recursiveProperty().recursiveProperty().baz();
@@ -137,16 +137,37 @@ public void testMultiLevelMask() {
137137

138138
service.withMask().moreChildren().recursiveProperty().baz();
139139
service.withMask().moreChildren().date();
140+
String result = service.getRecursiveProperty();
140141

141142
assertEquals("moreChildren[date,recursiveProperty.baz],recursiveProperty[foo,baz]",
142143
service.withMask().toString());
143144
}
144145

146+
@Test
147+
public void testNoChangeMaskScope() {
148+
149+
150+
TestApiClient client = new TestApiClient("http://example.com/");
151+
152+
client.setLoggingEnabled(true);
153+
154+
TestEntity.Service service = TestEntity.service(client);
155+
service.withMask().testThing().id();
156+
service.withMask().testThing().first();
157+
158+
TestEntity result = service.getObject();
159+
assertEquals("testThing[id,first]", service.withMask().toString());
160+
String expected = "http://example.com/SoftLayer_TestEntity.json?objectMask=mask%5BtestThing%5Bid%2Cfirst%5D%5D";
161+
assertEquals(expected, client.httpClientFactory.fullUrl);
162+
163+
164+
}
165+
145166
@Test
146167
public void testChangeMaskScope() {
147-
RestApiClient client = new TestApiClient("http://example.com/");
168+
TestApiClient client = new TestApiClient("http://example.com/");
148169
client.setLoggingEnabled(true);
149-
System.out.print("Hello");
170+
150171
TestEntity.Service service = TestEntity.service(client);
151172
service.withMask().recursiveProperty().baz();
152173
service.withMask().recursiveProperty().foo();
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
package com.softlayer.api;
2+
3+
import com.softlayer.api.annotation.ApiMethod;
4+
import com.softlayer.api.annotation.ApiService;
5+
import com.softlayer.api.http.*;
6+
import com.softlayer.api.json.GsonJsonMarshallerFactoryTest;
7+
8+
import java.io.ByteArrayOutputStream;
9+
import java.io.OutputStream;
10+
import java.lang.reflect.InvocationHandler;
11+
import java.lang.reflect.Method;
12+
import java.lang.reflect.Proxy;
13+
import java.util.Collections;
14+
15+
import org.mockito.Mockito;
16+
17+
public class TestApiClient extends RestApiClient{
18+
19+
20+
private HttpBasicAuthCredentials credentials;
21+
public HttpBasicAuthCredentials getCredentials() {
22+
return credentials;
23+
}
24+
public FakeHttpClientFactory httpClientFactory;
25+
public TestApiClient(String baseUrl) {
26+
super(baseUrl);
27+
}
28+
29+
public FakeHttpClientFactory getHttpClientFactory() {
30+
if (httpClientFactory == null) {
31+
httpClientFactory = new FakeHttpClientFactory(200,
32+
Collections.emptyMap(), "");
33+
}
34+
return httpClientFactory;
35+
}
36+
public void setHttpClientFactory(FakeHttpClientFactory httpClientFactory) {
37+
this.httpClientFactory = httpClientFactory;
38+
}
39+
40+
public <S extends Service> S createService(Class<S> serviceClass, String id) {
41+
return (S) Proxy.newProxyInstance(getClass().getClassLoader(),
42+
new Class<?>[] { serviceClass }, new TestServiceProxy<>(serviceClass, id));
43+
}
44+
45+
class TestServiceProxy<S extends Service> extends ServiceProxy {
46+
47+
final Class<S> serviceClass;
48+
final String id;
49+
50+
public Mask mask;
51+
public String url;
52+
String maskString;
53+
ResultLimit resultLimit;
54+
Integer lastResponseTotalItemCount;
55+
56+
57+
public TestServiceProxy(Class<S> serviceClass, String id) {
58+
super(serviceClass, id);
59+
Class c = serviceClass;
60+
try {
61+
c = Class.forName("com.softlayer.api.service.TestEntity$ServiceTester");
62+
}catch (ClassNotFoundException x) {
63+
x.printStackTrace();
64+
}
65+
66+
this.serviceClass = c;
67+
this.id = id;
68+
}
69+
70+
@Override
71+
public Object invokeService(Method method, final Object[] args) throws Throwable {
72+
this.mask = super.mask;
73+
this.maskString = super.maskString;
74+
75+
ApiMethod methodInfo = method.getAnnotation(ApiMethod.class);
76+
// Must have ID if instance is required
77+
78+
if (methodInfo.instanceRequired() && id == null) {
79+
throw new IllegalStateException("ID is required to invoke " + method);
80+
}
81+
String methodName = methodInfo.value().isEmpty() ? method.getName() : methodInfo.value();
82+
final String httpMethod = getHttpMethodFromMethodName(methodName);
83+
String methodId = methodInfo.instanceRequired() ? this.id : null;
84+
final String url = getFullUrl(serviceClass.getAnnotation(ApiService.class).value(),
85+
methodName, methodId, resultLimit, mask == null ? maskString : mask.getMask());
86+
87+
this.url = url;
88+
89+
Method toCall = serviceClass.getDeclaredMethod(method.getName());
90+
Object resultInvoke = toCall.invoke(serviceClass.newInstance());
91+
OutputStream output = new ByteArrayOutputStream();
92+
getJsonMarshallerFactory().getJsonMarshaller().toJson(
93+
resultInvoke, output);
94+
FakeHttpClientFactory faketory = new FakeHttpClientFactory(200,
95+
Collections.emptyMap(), output.toString());
96+
setHttpClientFactory(faketory);
97+
98+
final HttpClient client = getHttpClientFactory().getHttpClient(credentials, httpMethod, url, HEADERS);
99+
HttpResponse response = client.invokeSync(() -> {
100+
logRequestAndWriteBody(client, httpMethod, url, args);
101+
return null;
102+
});
103+
return logAndHandleResponse(response, url, method.getGenericReturnType());
104+
}
105+
}
106+
107+
108+
}

src/test/java/com/softlayer/api/http/FakeHttpClientFactory.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,11 @@ public OutputStream getBodyStream() {
8181
@Override
8282
public HttpResponse invokeSync(Callable<?> setupBody) {
8383
invokeSyncCalled = true;
84-
try {
85-
setupBody.call();
86-
} catch (Exception e) {
87-
throw new RuntimeException(e);
88-
}
84+
// try {
85+
// setupBody.call();
86+
// } catch (Exception e) {
87+
// throw new RuntimeException(e);
88+
// }
8989
return this;
9090
}
9191

src/test/java/com/softlayer/api/service/TestEntity.java

Lines changed: 48 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import java.util.concurrent.Future;
77

88
import com.softlayer.api.ApiClient;
9-
import com.softlayer.api.Mask;
109
import com.softlayer.api.ResponseHandler;
1110
import com.softlayer.api.ResultLimit;
1211
import com.softlayer.api.annotation.ApiMethod;
@@ -118,12 +117,23 @@ public List<TestEntity> getMoreChildren() {
118117
@ApiProperty
119118
protected List<TestEntity> recursiveProperty;
120119

121-
public List<TestEntity> getrecursiveProperty() {
120+
public List<TestEntity> getRecursiveProperty() {
122121
if (recursiveProperty == null) {
123122
recursiveProperty = new ArrayList<TestEntity>();
124123
}
125124
return recursiveProperty;
126125
}
126+
127+
@ApiProperty
128+
protected TestThing testThing;
129+
130+
public TestThing getTestThing() {
131+
if (testThing == null) {
132+
testThing = new TestThing();
133+
}
134+
return testThing;
135+
}
136+
127137
public Service asService(ApiClient client) {
128138
return service(client, id);
129139
}
@@ -155,6 +165,12 @@ public static interface Service extends com.softlayer.api.Service {
155165

156166
@ApiMethod("getRecursiveProperty")
157167
public String getRecursiveProperty();
168+
169+
@ApiMethod("getObject")
170+
public TestEntity getObject();
171+
172+
@ApiMethod("getTestThing")
173+
public TestThing getTestThing();
158174
}
159175

160176
public static interface ServiceAsync extends com.softlayer.api.ServiceAsync {
@@ -174,7 +190,7 @@ public static interface ServiceAsync extends com.softlayer.api.ServiceAsync {
174190
}
175191

176192
public static class Mask extends Entity.Mask {
177-
193+
178194
public Mask foo() {
179195
withLocalProperty("foo");
180196
return this;
@@ -199,11 +215,15 @@ public Mask moreChildren() {
199215
}
200216

201217
public Mask recursiveProperty() {
202-
return withSubMask("recursiveProperty", Mask.class);
218+
return withSubMask("recursiveProperty", com.softlayer.api.service.TestEntity.Mask.class);
219+
}
220+
public TestThing.Mask testThing() {
221+
return withSubMask("testThing", com.softlayer.api.service.TestThing.Mask.class);
203222
}
204223
}
205224

206-
public class TestService implements Service {
225+
@ApiService("SoftLayer_TestEntity")
226+
public static class ServiceTester implements Service {
207227

208228
@Override
209229
public ServiceAsync asAsync() {
@@ -212,12 +232,13 @@ public ServiceAsync asAsync() {
212232

213233
@Override
214234
public Mask withNewMask() {
215-
return null;
235+
return new Mask();
216236
}
217237

218238
@Override
219239
public Mask withMask() {
220-
return null;
240+
241+
return new Mask();
221242
}
222243

223244
@Override
@@ -257,10 +278,28 @@ public Void doSomethingNonStatic(GregorianCalendar param1) {
257278

258279
@Override
259280
public String getRecursiveProperty() {
260-
System.out.print("This is playing");
261-
return "Thats playing to win";
281+
System.out.print("getRecursiveProperty\n");
282+
System.out.print("MASK: " + withMask().toString() +"\n");
283+
284+
return "Hello World";
262285
}
263286

287+
@Override
288+
public TestEntity getObject() {
289+
TestEntity toReturn = new TestEntity();
290+
toReturn.id = Long.valueOf(12345);
291+
toReturn.baz = "GotBaz";
292+
return toReturn;
293+
294+
}
295+
296+
@Override
297+
public TestThing getTestThing() {
298+
TestThing toReturn = new TestThing();
299+
toReturn.id = Long.valueOf(5555);
300+
toReturn.first = "First Test Thing";
301+
return toReturn;
302+
}
264303
@Override
265304
public ResultLimit getResultLimit() {
266305
return null;

0 commit comments

Comments
 (0)