From 5adc2e1908b834cad1d953dd5103a6f3c42e620d Mon Sep 17 00:00:00 2001 From: Fernando Ojeda Date: Fri, 8 Jun 2018 15:39:17 -0400 Subject: [PATCH 01/45] Fixed the object mask to work with result limit. --- src/main/java/com/softlayer/api/Mask.java | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/softlayer/api/Mask.java b/src/main/java/com/softlayer/api/Mask.java index 3c35061..cabf6de 100644 --- a/src/main/java/com/softlayer/api/Mask.java +++ b/src/main/java/com/softlayer/api/Mask.java @@ -4,6 +4,7 @@ import java.util.HashSet; import java.util.Map; import java.util.Set; +import java.util.regex.Pattern; /** Object mask parameter. See http://sldn.softlayer.com/article/Object-Masks */ public class Mask { @@ -44,7 +45,26 @@ protected String getMask() { @Override public String toString() { - return toString(new StringBuilder()).toString(); + String objectMask = new String(); + String builtedMask = toString(new StringBuilder()).toString(); + if(builtedMask.contains("[")){ + String [] mask = builtedMask.split(Pattern.quote("[")); + for (int count = 0; count < mask.length; count ++ ) { + if (count != 0){ + objectMask = new StringBuilder().append(objectMask).append(mask[count]).toString(); + } + } + } + else { + String [] mask = builtedMask.split(Pattern.quote(".")); + for (int count = 0; count < mask.length; count ++ ) { + if (count != 0){ + objectMask = new StringBuilder().append(objectMask).append(mask[count]).append(".").toString(); + } + } + } + String resultMask = objectMask.substring(0, objectMask.length()-1); + return resultMask; } /** Append this mask's string representation to the given builder and return it */ From f7f3f915025fdd934a372075358d5007d21a0fb8 Mon Sep 17 00:00:00 2001 From: albert camacho Date: Mon, 11 Jun 2018 16:59:36 -0400 Subject: [PATCH 02/45] Fix for issue #53 --- gen/src/main/java/com/softlayer/api/gen/ClassWriter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gen/src/main/java/com/softlayer/api/gen/ClassWriter.java b/gen/src/main/java/com/softlayer/api/gen/ClassWriter.java index 6e318c8..671c04f 100644 --- a/gen/src/main/java/com/softlayer/api/gen/ClassWriter.java +++ b/gen/src/main/java/com/softlayer/api/gen/ClassWriter.java @@ -272,7 +272,7 @@ public ClassWriter emitServiceMethod(TypeClass.Method method, boolean async) thr if (!method.name.equals(method.meta.name)) { params.put("value", stringLiteral(method.meta.name)); } - if (!method.meta.isstatic) { + if (!method.meta.isstatic && !"SoftLayer_Resource_Metadata".equals(type.meta.name)) { params.put("instanceRequired", true); } emitAnnotation(TYPE_API_METHOD, params); From 16571b82e6934e3640061a5c71c91849991454bc Mon Sep 17 00:00:00 2001 From: Fernando Ojeda Date: Thu, 14 Jun 2018 09:54:28 -0400 Subject: [PATCH 03/45] Fixed the object mask to work with result limit. --- src/main/java/com/softlayer/api/Mask.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/softlayer/api/Mask.java b/src/main/java/com/softlayer/api/Mask.java index cabf6de..2839bb1 100644 --- a/src/main/java/com/softlayer/api/Mask.java +++ b/src/main/java/com/softlayer/api/Mask.java @@ -56,11 +56,15 @@ public String toString() { } } else { - String [] mask = builtedMask.split(Pattern.quote(".")); - for (int count = 0; count < mask.length; count ++ ) { - if (count != 0){ - objectMask = new StringBuilder().append(objectMask).append(mask[count]).append(".").toString(); + if(builtedMask.contains(".")){ + String [] mask = builtedMask.split(Pattern.quote(".")); + for (int count = 0; count < mask.length; count ++ ) { + if (count != 0){ + objectMask = new StringBuilder().append(objectMask).append(mask[count]).append(".").toString(); + } } + }else { + objectMask = builtedMask + "."; } } String resultMask = objectMask.substring(0, objectMask.length()-1); From be56b0da04656d5f769230a50f1937ecc9c8e39c Mon Sep 17 00:00:00 2001 From: Fernando Ojeda Date: Thu, 14 Jun 2018 16:23:06 -0400 Subject: [PATCH 04/45] Fixed the object mask to work with result limit. --- src/main/java/com/softlayer/api/Mask.java | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/softlayer/api/Mask.java b/src/main/java/com/softlayer/api/Mask.java index 2839bb1..d457c82 100644 --- a/src/main/java/com/softlayer/api/Mask.java +++ b/src/main/java/com/softlayer/api/Mask.java @@ -45,26 +45,28 @@ protected String getMask() { @Override public String toString() { + String subMask = new String(); String objectMask = new String(); - String builtedMask = toString(new StringBuilder()).toString(); - if(builtedMask.contains("[")){ - String [] mask = builtedMask.split(Pattern.quote("[")); + String builtMask = toString(new StringBuilder()).toString(); + if(builtMask.contains("[")){ + String [] mask = builtMask.split(Pattern.quote("[")); for (int count = 0; count < mask.length; count ++ ) { if (count != 0){ - objectMask = new StringBuilder().append(objectMask).append(mask[count]).toString(); + subMask = new StringBuilder().append(subMask).append("[").append(mask[count]).toString(); } } + objectMask = subMask.substring(1, subMask.length()); } else { - if(builtedMask.contains(".")){ - String [] mask = builtedMask.split(Pattern.quote(".")); + if(builtMask.contains(".")){ + String [] mask = builtMask.split(Pattern.quote(".")); for (int count = 0; count < mask.length; count ++ ) { if (count != 0){ objectMask = new StringBuilder().append(objectMask).append(mask[count]).append(".").toString(); } } }else { - objectMask = builtedMask + "."; + objectMask = builtMask + "."; } } String resultMask = objectMask.substring(0, objectMask.length()-1); From 18ff77919ff34c46dd4d8dfb3c8ae80a980cd43d Mon Sep 17 00:00:00 2001 From: allmightyspiff Date: Thu, 14 Jun 2018 15:42:47 -0500 Subject: [PATCH 05/45] Splitting out Mask tests to a new file. --- src/test/java/com/softlayer/api/MaskTest.java | 108 ++++++++++++++++++ .../com/softlayer/api/RestApiClientTest.java | 78 +------------ 2 files changed, 109 insertions(+), 77 deletions(-) create mode 100644 src/test/java/com/softlayer/api/MaskTest.java diff --git a/src/test/java/com/softlayer/api/MaskTest.java b/src/test/java/com/softlayer/api/MaskTest.java new file mode 100644 index 0000000..b55a193 --- /dev/null +++ b/src/test/java/com/softlayer/api/MaskTest.java @@ -0,0 +1,108 @@ +package com.softlayer.api; + +import static org.junit.Assert.*; + + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.lang.reflect.Proxy; +import java.net.URLEncoder; +import java.util.Collections; +import java.util.GregorianCalendar; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.junit.Test; + +import com.softlayer.api.http.FakeHttpClientFactory; +import com.softlayer.api.http.HttpBasicAuthCredentials; +import com.softlayer.api.json.GsonJsonMarshallerFactoryTest; +import com.softlayer.api.service.TestEntity; + + + +public class MaskTest { + static { + GsonJsonMarshallerFactoryTest.addTestEntityToGson(); + } + @Test + public void testWithMask() throws Exception { + FakeHttpClientFactory http = new FakeHttpClientFactory(200, + Collections.emptyMap(), "\"some response\""); + RestApiClient client = new RestApiClient("http://example.com/") + .withCredentials("user", "key"); + client.setHttpClientFactory(http); + + TestEntity entity = new TestEntity(); + entity.setFoo("blah"); + TestEntity.Service service = TestEntity.service(client); + service.withMask().foo().child().date(); + service.withMask().child().baz(); + + assertEquals("some response", service.doSomethingStatic(123L, entity)); + assertEquals("http://example.com/SoftLayer_TestEntity/doSomethingStatic.json" + + "?objectMask=" + URLEncoder.encode(service.withMask().getMask(), "UTF-8"), http.fullUrl); + assertTrue(http.invokeSyncCalled); + } + + @Test + public void testSetObjectMask() throws Exception { + FakeHttpClientFactory http = new FakeHttpClientFactory(200, + Collections.emptyMap(), "\"some response\""); + RestApiClient client = new RestApiClient("http://example.com/") + .withCredentials("user", "key"); + client.setHttpClientFactory(http); + + TestEntity entity = new TestEntity(); + entity.setFoo("blah"); + TestEntity.Service service = TestEntity.service(client); + TestEntity.Mask mask = new TestEntity.Mask(); + mask.foo().child().date(); + mask.child().baz(); + service.setMask(mask); + + assertEquals("some response", service.doSomethingStatic(123L, entity)); + assertEquals("http://example.com/SoftLayer_TestEntity/doSomethingStatic.json" + + "?objectMask=" + URLEncoder.encode(mask.getMask(), "UTF-8"), http.fullUrl); + assertTrue(http.invokeSyncCalled); + } + + @Test + public void testSetStringMask() throws Exception { + FakeHttpClientFactory http = new FakeHttpClientFactory(200, + Collections.emptyMap(), "\"some response\""); + RestApiClient client = new RestApiClient("http://example.com/") + .withCredentials("user", "key"); + client.setHttpClientFactory(http); + + TestEntity entity = new TestEntity(); + entity.setFoo("blah"); + TestEntity.Service service = TestEntity.service(client); + service.setMask("yay-a-mask"); + + assertEquals("some response", service.doSomethingStatic(123L, entity)); + assertEquals("http://example.com/SoftLayer_TestEntity/doSomethingStatic.json" + + "?objectMask=yay-a-mask", http.fullUrl); + assertTrue(http.invokeSyncCalled); + } + + @Test(expected = IllegalArgumentException.class) + public void testMaskMustNotBeNull() { + RestApiClient client = new RestApiClient("http://example.com/"); + TestEntity.Service service = TestEntity.service(client); + service.setMask((Mask) null); + } + + @Test + public void testMaskRemoval() { + RestApiClient client = new RestApiClient("http://example.com/"); + TestEntity.Service service = TestEntity.service(client); + service.withMask().baz(); + assertEquals("baz", service.withMask().toString()); + service.clearMask(); + assertEquals("", service.withMask().toString()); + } +} + diff --git a/src/test/java/com/softlayer/api/RestApiClientTest.java b/src/test/java/com/softlayer/api/RestApiClientTest.java index 481d030..1a0b565 100644 --- a/src/test/java/com/softlayer/api/RestApiClientTest.java +++ b/src/test/java/com/softlayer/api/RestApiClientTest.java @@ -313,68 +313,7 @@ public void testDifferentMethodName() throws Exception { assertEquals(RestApiClient.HEADERS, http.headers); assertTrue(http.invokeSyncCalled); } - - @Test - public void testWithMask() throws Exception { - FakeHttpClientFactory http = new FakeHttpClientFactory(200, - Collections.emptyMap(), "\"some response\""); - RestApiClient client = new RestApiClient("http://example.com/") - .withCredentials("user", "key"); - client.setHttpClientFactory(http); - TestEntity entity = new TestEntity(); - entity.setFoo("blah"); - TestEntity.Service service = TestEntity.service(client); - service.withMask().foo().child().date(); - service.withMask().child().baz(); - - assertEquals("some response", service.doSomethingStatic(123L, entity)); - assertEquals("http://example.com/SoftLayer_TestEntity/doSomethingStatic.json" - + "?objectMask=" + URLEncoder.encode(service.withMask().getMask(), "UTF-8"), http.fullUrl); - assertTrue(http.invokeSyncCalled); - } - - @Test - public void testSetObjectMask() throws Exception { - FakeHttpClientFactory http = new FakeHttpClientFactory(200, - Collections.emptyMap(), "\"some response\""); - RestApiClient client = new RestApiClient("http://example.com/") - .withCredentials("user", "key"); - client.setHttpClientFactory(http); - - TestEntity entity = new TestEntity(); - entity.setFoo("blah"); - TestEntity.Service service = TestEntity.service(client); - TestEntity.Mask mask = new TestEntity.Mask(); - mask.foo().child().date(); - mask.child().baz(); - service.setMask(mask); - - assertEquals("some response", service.doSomethingStatic(123L, entity)); - assertEquals("http://example.com/SoftLayer_TestEntity/doSomethingStatic.json" - + "?objectMask=" + URLEncoder.encode(mask.getMask(), "UTF-8"), http.fullUrl); - assertTrue(http.invokeSyncCalled); - } - - @Test - public void testSetStringMask() throws Exception { - FakeHttpClientFactory http = new FakeHttpClientFactory(200, - Collections.emptyMap(), "\"some response\""); - RestApiClient client = new RestApiClient("http://example.com/") - .withCredentials("user", "key"); - client.setHttpClientFactory(http); - - TestEntity entity = new TestEntity(); - entity.setFoo("blah"); - TestEntity.Service service = TestEntity.service(client); - service.setMask("yay-a-mask"); - - assertEquals("some response", service.doSomethingStatic(123L, entity)); - assertEquals("http://example.com/SoftLayer_TestEntity/doSomethingStatic.json" - + "?objectMask=yay-a-mask", http.fullUrl); - assertTrue(http.invokeSyncCalled); - } - @Test public void testWithResultLimit() throws Exception { FakeHttpClientFactory http = new FakeHttpClientFactory(200, @@ -461,22 +400,7 @@ public void onSuccess(String value) { assertTrue(successCalled.get()); } - @Test(expected = IllegalArgumentException.class) - public void testMaskMustNotBeNull() { - RestApiClient client = new RestApiClient("http://example.com/"); - TestEntity.Service service = TestEntity.service(client); - service.setMask((Mask) null); - } - - @Test - public void testMaskRemoval() { - RestApiClient client = new RestApiClient("http://example.com/"); - TestEntity.Service service = TestEntity.service(client); - service.withMask().baz(); - assertEquals("baz", service.withMask().toString()); - service.clearMask(); - assertEquals("", service.withMask().toString()); - } + @Test public void testNormalObjectMethodsOnService() { From bb92e07dc8ae23f3007d5a897f5a41a15ae6a475 Mon Sep 17 00:00:00 2001 From: allmightyspiff Date: Mon, 18 Jun 2018 18:19:15 -0500 Subject: [PATCH 06/45] #52 some unit tests around objectMasks, groundwork for withMask() improvements --- .gitignore | 1 + src/main/java/com/softlayer/api/Mask.java | 28 +----- .../java/com/softlayer/api/RestApiClient.java | 3 +- .../java/com/softlayer/api/TestApiClient.java | 61 ++++++++++++ src/test/java/com/softlayer/api/MaskTest.java | 57 ++++++++++- .../com/softlayer/api/service/TestEntity.java | 94 ++++++++++++++++++- 6 files changed, 214 insertions(+), 30 deletions(-) create mode 100644 src/main/java/com/softlayer/api/TestApiClient.java diff --git a/.gitignore b/.gitignore index 2c04155..05900eb 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ /gen/build.log /examples/target settings.xml +.DS_Store diff --git a/src/main/java/com/softlayer/api/Mask.java b/src/main/java/com/softlayer/api/Mask.java index d457c82..3c35061 100644 --- a/src/main/java/com/softlayer/api/Mask.java +++ b/src/main/java/com/softlayer/api/Mask.java @@ -4,7 +4,6 @@ import java.util.HashSet; import java.util.Map; import java.util.Set; -import java.util.regex.Pattern; /** Object mask parameter. See http://sldn.softlayer.com/article/Object-Masks */ public class Mask { @@ -45,32 +44,7 @@ protected String getMask() { @Override public String toString() { - String subMask = new String(); - String objectMask = new String(); - String builtMask = toString(new StringBuilder()).toString(); - if(builtMask.contains("[")){ - String [] mask = builtMask.split(Pattern.quote("[")); - for (int count = 0; count < mask.length; count ++ ) { - if (count != 0){ - subMask = new StringBuilder().append(subMask).append("[").append(mask[count]).toString(); - } - } - objectMask = subMask.substring(1, subMask.length()); - } - else { - if(builtMask.contains(".")){ - String [] mask = builtMask.split(Pattern.quote(".")); - for (int count = 0; count < mask.length; count ++ ) { - if (count != 0){ - objectMask = new StringBuilder().append(objectMask).append(mask[count]).append(".").toString(); - } - } - }else { - objectMask = builtMask + "."; - } - } - String resultMask = objectMask.substring(0, objectMask.length()-1); - return resultMask; + return toString(new StringBuilder()).toString(); } /** Append this mask's string representation to the given builder and return it */ diff --git a/src/main/java/com/softlayer/api/RestApiClient.java b/src/main/java/com/softlayer/api/RestApiClient.java index 46afa0e..4bbdf6b 100644 --- a/src/main/java/com/softlayer/api/RestApiClient.java +++ b/src/main/java/com/softlayer/api/RestApiClient.java @@ -304,6 +304,7 @@ public Object logAndHandleResponse(HttpResponse response, String url, } public Object invokeService(Method method, final Object[] args) throws Throwable { + System.out.print("invokeService: " + method + "\n"); ApiMethod methodInfo = method.getAnnotation(ApiMethod.class); // Must have ID if instance is required if (methodInfo.instanceRequired() && id == null) { @@ -440,7 +441,7 @@ public boolean isDone() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { boolean noParams = args == null || args.length == 0; - + System.out.print("Invoking: " + method.getName() + "\n"); if ("asAsync".equals(method.getName()) && noParams) { ServiceProxy asyncProxy = new ServiceProxy<>(serviceClass, id); asyncProxy.mask = mask; diff --git a/src/main/java/com/softlayer/api/TestApiClient.java b/src/main/java/com/softlayer/api/TestApiClient.java new file mode 100644 index 0000000..cfc0dca --- /dev/null +++ b/src/main/java/com/softlayer/api/TestApiClient.java @@ -0,0 +1,61 @@ +package com.softlayer.api; + +import com.softlayer.api.annotation.ApiMethod; +import com.softlayer.api.annotation.ApiService; +import com.softlayer.api.http.HttpBasicAuthCredentials; +import com.softlayer.api.http.HttpClient; +import com.softlayer.api.http.HttpResponse; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; + +public class TestApiClient extends RestApiClient{ + + + private HttpBasicAuthCredentials credentials; + public HttpBasicAuthCredentials getCredentials() { + return credentials; + } + + public TestApiClient(String baseUrl) { + super(baseUrl); + } + + public S createService(Class serviceClass, String id) { + return (S) Proxy.newProxyInstance(getClass().getClassLoader(), + new Class[] { serviceClass }, new TestServiceProxy<>(serviceClass, id)); + } + + class TestServiceProxy extends ServiceProxy { + + final Class serviceClass; + final String id; + Mask mask; + String maskString; + ResultLimit resultLimit; + Integer lastResponseTotalItemCount; + + public TestServiceProxy(Class serviceClass, String id) { + super(serviceClass, id); + this.serviceClass = serviceClass; + this.id = id; + + } + + public String invokeService(Method method, final Object[] args) throws Throwable { + System.out.print("invokeTESTService: " + method + "\n"); + ApiMethod methodInfo = method.getAnnotation(ApiMethod.class); + // Must have ID if instance is required + if (methodInfo.instanceRequired() && id == null) { + throw new IllegalStateException("ID is required to invoke " + method); + } + String methodName = methodInfo.value().isEmpty() ? method.getName() : methodInfo.value(); + final String httpMethod = getHttpMethodFromMethodName(methodName); + String methodId = methodInfo.instanceRequired() ? this.id : null; + final String url = getFullUrl(serviceClass.getAnnotation(ApiService.class).value(), + methodName, methodId, resultLimit, mask == null ? maskString : mask.getMask()); + return url; + } + } +} diff --git a/src/test/java/com/softlayer/api/MaskTest.java b/src/test/java/com/softlayer/api/MaskTest.java index b55a193..1c90d42 100644 --- a/src/test/java/com/softlayer/api/MaskTest.java +++ b/src/test/java/com/softlayer/api/MaskTest.java @@ -70,7 +70,7 @@ public void testSetObjectMask() throws Exception { } @Test - public void testSetStringMask() throws Exception { + public void testSetStringMask() { FakeHttpClientFactory http = new FakeHttpClientFactory(200, Collections.emptyMap(), "\"some response\""); RestApiClient client = new RestApiClient("http://example.com/") @@ -104,5 +104,60 @@ public void testMaskRemoval() { service.clearMask(); assertEquals("", service.withMask().toString()); } + + @Test + public void testRecursiveMaskandLocal() { + RestApiClient client = new RestApiClient("http://example.com/"); + TestEntity.Service service = TestEntity.service(client); + service.withMask().recursiveProperty().recursiveProperty().baz(); + service.withMask().recursiveProperty().recursiveProperty().foo(); + service.withMask().recursiveProperty().date(); + assertEquals("recursiveProperty[date,recursiveProperty[foo,baz]]", + service.withMask().toString()); + } + + @Test + public void testRecursiveMask() { + RestApiClient client = new RestApiClient("http://example.com/"); + TestEntity.Service service = TestEntity.service(client); + service.withMask().recursiveProperty().baz(); + service.withMask().recursiveProperty().foo(); + service.withMask().recursiveProperty().date(); + + assertEquals("recursiveProperty[date,foo,baz]", + service.withMask().toString()); + } + + @Test + public void testMultiLevelMask() { + RestApiClient client = new RestApiClient("http://example.com/"); + TestEntity.Service service = TestEntity.service(client); + service.withMask().recursiveProperty().baz(); + service.withMask().recursiveProperty().foo(); + + service.withMask().moreChildren().recursiveProperty().baz(); + service.withMask().moreChildren().date(); + + assertEquals("moreChildren[date,recursiveProperty.baz],recursiveProperty[foo,baz]", + service.withMask().toString()); + } + + @Test + public void testChangeMaskScope() { + RestApiClient client = new TestApiClient("http://example.com/"); + client.setLoggingEnabled(true); + System.out.print("Hello"); + TestEntity.Service service = TestEntity.service(client); + service.withMask().recursiveProperty().baz(); + service.withMask().recursiveProperty().foo(); + + String result = service.getRecursiveProperty(); + System.out.print(result); +// RestApiClient.ServiceProxy serviceProxy = client.createService(TestEntity, 1234); +// serviceProxy.invoke(service, service.getRecursiveProperty(),null); +// assertEquals("http://example.com/SomeService/1234/someMethod.json?objectMask=someMask%26%26", +// client.ServiceProxy. +// ) + } } diff --git a/src/test/java/com/softlayer/api/service/TestEntity.java b/src/test/java/com/softlayer/api/service/TestEntity.java index 66411e2..e852c96 100644 --- a/src/test/java/com/softlayer/api/service/TestEntity.java +++ b/src/test/java/com/softlayer/api/service/TestEntity.java @@ -6,7 +6,9 @@ import java.util.concurrent.Future; import com.softlayer.api.ApiClient; +import com.softlayer.api.Mask; import com.softlayer.api.ResponseHandler; +import com.softlayer.api.ResultLimit; import com.softlayer.api.annotation.ApiMethod; import com.softlayer.api.annotation.ApiProperty; import com.softlayer.api.annotation.ApiService; @@ -113,6 +115,15 @@ public List getMoreChildren() { return moreChildren; } + @ApiProperty + protected List recursiveProperty; + + public List getrecursiveProperty() { + if (recursiveProperty == null) { + recursiveProperty = new ArrayList(); + } + return recursiveProperty; + } public Service asService(ApiClient client) { return service(client, id); } @@ -141,6 +152,9 @@ public static interface Service extends com.softlayer.api.Service { @ApiMethod(instanceRequired = true) public Void doSomethingNonStatic(GregorianCalendar param1); + + @ApiMethod("getRecursiveProperty") + public String getRecursiveProperty(); } public static interface ServiceAsync extends com.softlayer.api.ServiceAsync { @@ -162,7 +176,7 @@ public static interface ServiceAsync extends com.softlayer.api.ServiceAsync { public static class Mask extends Entity.Mask { public Mask foo() { - withLocalProperty("bar"); + withLocalProperty("foo"); return this; } @@ -183,5 +197,83 @@ public Mask child() { public Mask moreChildren() { return withSubMask("moreChildren", Mask.class); } + + public Mask recursiveProperty() { + return withSubMask("recursiveProperty", Mask.class); + } + } + + public class TestService implements Service { + + @Override + public ServiceAsync asAsync() { + return null; + } + + @Override + public Mask withNewMask() { + return null; + } + + @Override + public Mask withMask() { + return null; + } + + @Override + public void setMask(com.softlayer.api.Mask mask) { + + } + + @Override + public void setMask(String mask) { + + } + + @Override + public void clearMask() { + + } + + @Override + public void setMask(Mask mask) { + + } + + @Override + public String doSomethingStatic(Long param1, TestEntity param2) { + return null; + } + + @Override + public List fakeName() { + return null; + } + + @Override + public Void doSomethingNonStatic(GregorianCalendar param1) { + return null; + } + + @Override + public String getRecursiveProperty() { + System.out.print("This is playing"); + return "Thats playing to win"; + } + + @Override + public ResultLimit getResultLimit() { + return null; + } + + @Override + public ResultLimit setResultLimit(ResultLimit limit) { + return null; + } + + @Override + public Integer getLastResponseTotalItemCount() { + return null; + } } } \ No newline at end of file From 1e6ea3483723cb389f9fa8ffafaf195004d1b2c6 Mon Sep 17 00:00:00 2001 From: allmightyspiff Date: Wed, 20 Jun 2018 17:43:25 -0500 Subject: [PATCH 07/45] a LOT of groundwork for fancier testing of api calls --- .../java/com/softlayer/api/RestApiClient.java | 6 +- .../java/com/softlayer/api/TestApiClient.java | 61 ------ src/test/java/com/softlayer/api/MaskTest.java | 27 ++- .../java/com/softlayer/api/TestApiClient.java | 108 ++++++++++ .../api/http/FakeHttpClientFactory.java | 10 +- .../com/softlayer/api/service/TestEntity.java | 57 +++++- .../com/softlayer/api/service/TestThing.java | 185 ++++++++++++++++++ 7 files changed, 373 insertions(+), 81 deletions(-) delete mode 100644 src/main/java/com/softlayer/api/TestApiClient.java create mode 100644 src/test/java/com/softlayer/api/TestApiClient.java create mode 100644 src/test/java/com/softlayer/api/service/TestThing.java diff --git a/src/main/java/com/softlayer/api/RestApiClient.java b/src/main/java/com/softlayer/api/RestApiClient.java index 4bbdf6b..8a85e8d 100644 --- a/src/main/java/com/softlayer/api/RestApiClient.java +++ b/src/main/java/com/softlayer/api/RestApiClient.java @@ -225,10 +225,11 @@ class ServiceProxy implements InvocationHandler { final Class serviceClass; final String id; - Mask mask; + public Mask mask; String maskString; ResultLimit resultLimit; Integer lastResponseTotalItemCount; + public ServiceProxy(Class serviceClass, String id) { this.serviceClass = serviceClass; @@ -304,7 +305,7 @@ public Object logAndHandleResponse(HttpResponse response, String url, } public Object invokeService(Method method, final Object[] args) throws Throwable { - System.out.print("invokeService: " + method + "\n"); + ApiMethod methodInfo = method.getAnnotation(ApiMethod.class); // Must have ID if instance is required if (methodInfo.instanceRequired() && id == null) { @@ -441,7 +442,6 @@ public boolean isDone() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { boolean noParams = args == null || args.length == 0; - System.out.print("Invoking: " + method.getName() + "\n"); if ("asAsync".equals(method.getName()) && noParams) { ServiceProxy asyncProxy = new ServiceProxy<>(serviceClass, id); asyncProxy.mask = mask; diff --git a/src/main/java/com/softlayer/api/TestApiClient.java b/src/main/java/com/softlayer/api/TestApiClient.java deleted file mode 100644 index cfc0dca..0000000 --- a/src/main/java/com/softlayer/api/TestApiClient.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.softlayer.api; - -import com.softlayer.api.annotation.ApiMethod; -import com.softlayer.api.annotation.ApiService; -import com.softlayer.api.http.HttpBasicAuthCredentials; -import com.softlayer.api.http.HttpClient; -import com.softlayer.api.http.HttpResponse; - -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; - -public class TestApiClient extends RestApiClient{ - - - private HttpBasicAuthCredentials credentials; - public HttpBasicAuthCredentials getCredentials() { - return credentials; - } - - public TestApiClient(String baseUrl) { - super(baseUrl); - } - - public S createService(Class serviceClass, String id) { - return (S) Proxy.newProxyInstance(getClass().getClassLoader(), - new Class[] { serviceClass }, new TestServiceProxy<>(serviceClass, id)); - } - - class TestServiceProxy extends ServiceProxy { - - final Class serviceClass; - final String id; - Mask mask; - String maskString; - ResultLimit resultLimit; - Integer lastResponseTotalItemCount; - - public TestServiceProxy(Class serviceClass, String id) { - super(serviceClass, id); - this.serviceClass = serviceClass; - this.id = id; - - } - - public String invokeService(Method method, final Object[] args) throws Throwable { - System.out.print("invokeTESTService: " + method + "\n"); - ApiMethod methodInfo = method.getAnnotation(ApiMethod.class); - // Must have ID if instance is required - if (methodInfo.instanceRequired() && id == null) { - throw new IllegalStateException("ID is required to invoke " + method); - } - String methodName = methodInfo.value().isEmpty() ? method.getName() : methodInfo.value(); - final String httpMethod = getHttpMethodFromMethodName(methodName); - String methodId = methodInfo.instanceRequired() ? this.id : null; - final String url = getFullUrl(serviceClass.getAnnotation(ApiService.class).value(), - methodName, methodId, resultLimit, mask == null ? maskString : mask.getMask()); - return url; - } - } -} diff --git a/src/test/java/com/softlayer/api/MaskTest.java b/src/test/java/com/softlayer/api/MaskTest.java index 1c90d42..5ac60bd 100644 --- a/src/test/java/com/softlayer/api/MaskTest.java +++ b/src/test/java/com/softlayer/api/MaskTest.java @@ -106,7 +106,7 @@ public void testMaskRemoval() { } @Test - public void testRecursiveMaskandLocal() { + public void testRecursiveMaskAndLocal() { RestApiClient client = new RestApiClient("http://example.com/"); TestEntity.Service service = TestEntity.service(client); service.withMask().recursiveProperty().recursiveProperty().baz(); @@ -137,16 +137,37 @@ public void testMultiLevelMask() { service.withMask().moreChildren().recursiveProperty().baz(); service.withMask().moreChildren().date(); + String result = service.getRecursiveProperty(); assertEquals("moreChildren[date,recursiveProperty.baz],recursiveProperty[foo,baz]", service.withMask().toString()); } + @Test + public void testNoChangeMaskScope() { + + + TestApiClient client = new TestApiClient("http://example.com/"); + + client.setLoggingEnabled(true); + + TestEntity.Service service = TestEntity.service(client); + service.withMask().testThing().id(); + service.withMask().testThing().first(); + + TestEntity result = service.getObject(); + assertEquals("testThing[id,first]", service.withMask().toString()); + String expected = "http://example.com/SoftLayer_TestEntity.json?objectMask=mask%5BtestThing%5Bid%2Cfirst%5D%5D"; + assertEquals(expected, client.httpClientFactory.fullUrl); + + + } + @Test public void testChangeMaskScope() { - RestApiClient client = new TestApiClient("http://example.com/"); + TestApiClient client = new TestApiClient("http://example.com/"); client.setLoggingEnabled(true); - System.out.print("Hello"); + TestEntity.Service service = TestEntity.service(client); service.withMask().recursiveProperty().baz(); service.withMask().recursiveProperty().foo(); diff --git a/src/test/java/com/softlayer/api/TestApiClient.java b/src/test/java/com/softlayer/api/TestApiClient.java new file mode 100644 index 0000000..1dc7caf --- /dev/null +++ b/src/test/java/com/softlayer/api/TestApiClient.java @@ -0,0 +1,108 @@ +package com.softlayer.api; + +import com.softlayer.api.annotation.ApiMethod; +import com.softlayer.api.annotation.ApiService; +import com.softlayer.api.http.*; +import com.softlayer.api.json.GsonJsonMarshallerFactoryTest; + +import java.io.ByteArrayOutputStream; +import java.io.OutputStream; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.Collections; + +import org.mockito.Mockito; + +public class TestApiClient extends RestApiClient{ + + + private HttpBasicAuthCredentials credentials; + public HttpBasicAuthCredentials getCredentials() { + return credentials; + } + public FakeHttpClientFactory httpClientFactory; + public TestApiClient(String baseUrl) { + super(baseUrl); + } + + public FakeHttpClientFactory getHttpClientFactory() { + if (httpClientFactory == null) { + httpClientFactory = new FakeHttpClientFactory(200, + Collections.emptyMap(), ""); + } + return httpClientFactory; + } + public void setHttpClientFactory(FakeHttpClientFactory httpClientFactory) { + this.httpClientFactory = httpClientFactory; + } + + public S createService(Class serviceClass, String id) { + return (S) Proxy.newProxyInstance(getClass().getClassLoader(), + new Class[] { serviceClass }, new TestServiceProxy<>(serviceClass, id)); + } + + class TestServiceProxy extends ServiceProxy { + + final Class serviceClass; + final String id; + + public Mask mask; + public String url; + String maskString; + ResultLimit resultLimit; + Integer lastResponseTotalItemCount; + + + public TestServiceProxy(Class serviceClass, String id) { + super(serviceClass, id); + Class c = serviceClass; + try { + c = Class.forName("com.softlayer.api.service.TestEntity$ServiceTester"); + }catch (ClassNotFoundException x) { + x.printStackTrace(); + } + + this.serviceClass = c; + this.id = id; + } + + @Override + public Object invokeService(Method method, final Object[] args) throws Throwable { + this.mask = super.mask; + this.maskString = super.maskString; + + ApiMethod methodInfo = method.getAnnotation(ApiMethod.class); + // Must have ID if instance is required + + if (methodInfo.instanceRequired() && id == null) { + throw new IllegalStateException("ID is required to invoke " + method); + } + String methodName = methodInfo.value().isEmpty() ? method.getName() : methodInfo.value(); + final String httpMethod = getHttpMethodFromMethodName(methodName); + String methodId = methodInfo.instanceRequired() ? this.id : null; + final String url = getFullUrl(serviceClass.getAnnotation(ApiService.class).value(), + methodName, methodId, resultLimit, mask == null ? maskString : mask.getMask()); + + this.url = url; + + Method toCall = serviceClass.getDeclaredMethod(method.getName()); + Object resultInvoke = toCall.invoke(serviceClass.newInstance()); + OutputStream output = new ByteArrayOutputStream(); + getJsonMarshallerFactory().getJsonMarshaller().toJson( + resultInvoke, output); + FakeHttpClientFactory faketory = new FakeHttpClientFactory(200, + Collections.emptyMap(), output.toString()); + setHttpClientFactory(faketory); + + final HttpClient client = getHttpClientFactory().getHttpClient(credentials, httpMethod, url, HEADERS); + HttpResponse response = client.invokeSync(() -> { + logRequestAndWriteBody(client, httpMethod, url, args); + return null; + }); + return logAndHandleResponse(response, url, method.getGenericReturnType()); + } + } + + +} diff --git a/src/test/java/com/softlayer/api/http/FakeHttpClientFactory.java b/src/test/java/com/softlayer/api/http/FakeHttpClientFactory.java index 4f78ac0..85bb91b 100644 --- a/src/test/java/com/softlayer/api/http/FakeHttpClientFactory.java +++ b/src/test/java/com/softlayer/api/http/FakeHttpClientFactory.java @@ -81,11 +81,11 @@ public OutputStream getBodyStream() { @Override public HttpResponse invokeSync(Callable setupBody) { invokeSyncCalled = true; - try { - setupBody.call(); - } catch (Exception e) { - throw new RuntimeException(e); - } +// try { +// setupBody.call(); +// } catch (Exception e) { +// throw new RuntimeException(e); +// } return this; } diff --git a/src/test/java/com/softlayer/api/service/TestEntity.java b/src/test/java/com/softlayer/api/service/TestEntity.java index e852c96..909bc17 100644 --- a/src/test/java/com/softlayer/api/service/TestEntity.java +++ b/src/test/java/com/softlayer/api/service/TestEntity.java @@ -6,7 +6,6 @@ import java.util.concurrent.Future; import com.softlayer.api.ApiClient; -import com.softlayer.api.Mask; import com.softlayer.api.ResponseHandler; import com.softlayer.api.ResultLimit; import com.softlayer.api.annotation.ApiMethod; @@ -118,12 +117,23 @@ public List getMoreChildren() { @ApiProperty protected List recursiveProperty; - public List getrecursiveProperty() { + public List getRecursiveProperty() { if (recursiveProperty == null) { recursiveProperty = new ArrayList(); } return recursiveProperty; } + + @ApiProperty + protected TestThing testThing; + + public TestThing getTestThing() { + if (testThing == null) { + testThing = new TestThing(); + } + return testThing; + } + public Service asService(ApiClient client) { return service(client, id); } @@ -155,6 +165,12 @@ public static interface Service extends com.softlayer.api.Service { @ApiMethod("getRecursiveProperty") public String getRecursiveProperty(); + + @ApiMethod("getObject") + public TestEntity getObject(); + + @ApiMethod("getTestThing") + public TestThing getTestThing(); } public static interface ServiceAsync extends com.softlayer.api.ServiceAsync { @@ -174,7 +190,7 @@ public static interface ServiceAsync extends com.softlayer.api.ServiceAsync { } public static class Mask extends Entity.Mask { - + public Mask foo() { withLocalProperty("foo"); return this; @@ -199,11 +215,15 @@ public Mask moreChildren() { } public Mask recursiveProperty() { - return withSubMask("recursiveProperty", Mask.class); + return withSubMask("recursiveProperty", com.softlayer.api.service.TestEntity.Mask.class); + } + public TestThing.Mask testThing() { + return withSubMask("testThing", com.softlayer.api.service.TestThing.Mask.class); } } - public class TestService implements Service { + @ApiService("SoftLayer_TestEntity") + public static class ServiceTester implements Service { @Override public ServiceAsync asAsync() { @@ -212,12 +232,13 @@ public ServiceAsync asAsync() { @Override public Mask withNewMask() { - return null; + return new Mask(); } @Override public Mask withMask() { - return null; + + return new Mask(); } @Override @@ -257,10 +278,28 @@ public Void doSomethingNonStatic(GregorianCalendar param1) { @Override public String getRecursiveProperty() { - System.out.print("This is playing"); - return "Thats playing to win"; + System.out.print("getRecursiveProperty\n"); + System.out.print("MASK: " + withMask().toString() +"\n"); + + return "Hello World"; } + @Override + public TestEntity getObject() { + TestEntity toReturn = new TestEntity(); + toReturn.id = Long.valueOf(12345); + toReturn.baz = "GotBaz"; + return toReturn; + + } + + @Override + public TestThing getTestThing() { + TestThing toReturn = new TestThing(); + toReturn.id = Long.valueOf(5555); + toReturn.first = "First Test Thing"; + return toReturn; + } @Override public ResultLimit getResultLimit() { return null; diff --git a/src/test/java/com/softlayer/api/service/TestThing.java b/src/test/java/com/softlayer/api/service/TestThing.java new file mode 100644 index 0000000..ca7f5ae --- /dev/null +++ b/src/test/java/com/softlayer/api/service/TestThing.java @@ -0,0 +1,185 @@ +package com.softlayer.api.service; + +import java.util.ArrayList; +import java.util.GregorianCalendar; +import java.util.List; +import java.util.concurrent.Future; + + +import com.softlayer.api.ApiClient; +import com.softlayer.api.Mask; +import com.softlayer.api.ResponseHandler; +import com.softlayer.api.ResultLimit; +import com.softlayer.api.annotation.ApiMethod; +import com.softlayer.api.annotation.ApiProperty; +import com.softlayer.api.annotation.ApiService; +import com.softlayer.api.annotation.ApiType; +import com.softlayer.api.service.TestEntity; +import org.junit.Test; + + +public class TestThing extends Entity { + + @ApiProperty(canBeNullOrNotSet = true) + protected Long id; + + public Long getId() { + return id; + } + + public void setId(Long id) { + idSpecified = true; + this.id = id; + } + + protected boolean idSpecified; + + public boolean isIdSpecified() { + return idSpecified; + } + + public void unsetId() { + id = null; + idSpecified = false; + } + + @ApiProperty("first") + protected String first; + + public String getFirst() { return first; } + + public void setFirst(String first) { + this.first = first; + } + + @ApiProperty("second") + protected String second; + + public String getSecond() { return second; } + + public void setSecond(String second) { + this.second = second; + } + + @ApiProperty("testEntity") + protected List testEntity; + + public List getTestEntity() { + if (testEntity == null) { + testEntity = new ArrayList(); + } + return testEntity; + } + public Service asService(ApiClient client) { + return service(client, id); + } + + public static Service service(ApiClient client) { + return client.createService(Service.class, null); + } + + public static Service service(ApiClient client, Long id) { + return client.createService(Service.class, id == null ? null : id.toString()); + } + + @ApiService("SoftLayer_TestThing") + public static interface Service extends com.softlayer.api.Service { + public ServiceAsync asAsync(); + public Mask withNewMask(); + public Mask withMask(); + public void setMask(Mask mask); + + @ApiMethod("getObject") + public TestThing getObject(); + + @ApiMethod("getTestEntity") + public List getTestEntity(); + } + + public static interface ServiceAsync extends com.softlayer.api.ServiceAsync { + public Mask withNewMask(); + public Mask withMask(); + public void setMask(Mask mask); + + public Future getObject(); + public Future getObject(ResponseHandler handler); + + public Future> getTestEntity(); + public Future getTestEntity(ResponseHandler> handler); + } + + public static class Mask extends Entity.Mask { + + public Mask id() { + withLocalProperty("id"); + return this; + } + public Mask first() { + withLocalProperty("first"); + return this; + } + public Mask second() { + withLocalProperty("second"); + return this; + } + public Mask testEntity() { + return withSubMask("testEntity", Mask.class); + } + + } + + @ApiService("SoftLayer_TestThing") + public static class ServiceTester implements Service { + + @Override + public ServiceAsync asAsync() { return null; } + + @Override + public Mask withNewMask() { return new Mask(); } + + @Override + public Mask withMask() { return new Mask(); } + + @Override + public void setMask(com.softlayer.api.Mask mask) { + + } + + @Override + public void setMask(String mask) { + + } + + @Override + public void clearMask() { + + } + + @Override + public void setMask(Mask mask) { + + } + + @Override + public TestThing getObject() { + TestThing toReturn = new TestThing(); + toReturn.id = Long.valueOf(1234); + toReturn.first = "First Property"; + + return toReturn; + } + + @Override + public List getTestEntity() { return null; } + + @Override + public ResultLimit getResultLimit() { return null; } + + @Override + public ResultLimit setResultLimit(ResultLimit limit) { return null; } + + @Override + public Integer getLastResponseTotalItemCount() { return null; } + } +} + From 21494f74e06745928436316ca149dea0c87355bf Mon Sep 17 00:00:00 2001 From: allmightyspiff Date: Wed, 20 Jun 2018 18:08:02 -0500 Subject: [PATCH 08/45] fixed some unit tests --- .../java/com/softlayer/api/RestApiClient.java | 5 ++-- src/test/java/com/softlayer/api/MaskTest.java | 24 +++++++++---------- .../api/http/FakeHttpClientFactory.java | 10 ++++---- .../com/softlayer/api/service/TestEntity.java | 3 --- 4 files changed, 18 insertions(+), 24 deletions(-) diff --git a/src/main/java/com/softlayer/api/RestApiClient.java b/src/main/java/com/softlayer/api/RestApiClient.java index 8a85e8d..46afa0e 100644 --- a/src/main/java/com/softlayer/api/RestApiClient.java +++ b/src/main/java/com/softlayer/api/RestApiClient.java @@ -225,11 +225,10 @@ class ServiceProxy implements InvocationHandler { final Class serviceClass; final String id; - public Mask mask; + Mask mask; String maskString; ResultLimit resultLimit; Integer lastResponseTotalItemCount; - public ServiceProxy(Class serviceClass, String id) { this.serviceClass = serviceClass; @@ -305,7 +304,6 @@ public Object logAndHandleResponse(HttpResponse response, String url, } public Object invokeService(Method method, final Object[] args) throws Throwable { - ApiMethod methodInfo = method.getAnnotation(ApiMethod.class); // Must have ID if instance is required if (methodInfo.instanceRequired() && id == null) { @@ -442,6 +440,7 @@ public boolean isDone() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { boolean noParams = args == null || args.length == 0; + if ("asAsync".equals(method.getName()) && noParams) { ServiceProxy asyncProxy = new ServiceProxy<>(serviceClass, id); asyncProxy.mask = mask; diff --git a/src/test/java/com/softlayer/api/MaskTest.java b/src/test/java/com/softlayer/api/MaskTest.java index 5ac60bd..4b8f766 100644 --- a/src/test/java/com/softlayer/api/MaskTest.java +++ b/src/test/java/com/softlayer/api/MaskTest.java @@ -90,14 +90,14 @@ public void testSetStringMask() { @Test(expected = IllegalArgumentException.class) public void testMaskMustNotBeNull() { - RestApiClient client = new RestApiClient("http://example.com/"); + RestApiClient client = new TestApiClient("http://example.com/"); TestEntity.Service service = TestEntity.service(client); service.setMask((Mask) null); } @Test public void testMaskRemoval() { - RestApiClient client = new RestApiClient("http://example.com/"); + RestApiClient client = new TestApiClient("http://example.com/"); TestEntity.Service service = TestEntity.service(client); service.withMask().baz(); assertEquals("baz", service.withMask().toString()); @@ -107,7 +107,7 @@ public void testMaskRemoval() { @Test public void testRecursiveMaskAndLocal() { - RestApiClient client = new RestApiClient("http://example.com/"); + RestApiClient client = new TestApiClient("http://example.com/"); TestEntity.Service service = TestEntity.service(client); service.withMask().recursiveProperty().recursiveProperty().baz(); service.withMask().recursiveProperty().recursiveProperty().foo(); @@ -118,7 +118,7 @@ public void testRecursiveMaskAndLocal() { @Test public void testRecursiveMask() { - RestApiClient client = new RestApiClient("http://example.com/"); + RestApiClient client = new TestApiClient("http://example.com/"); TestEntity.Service service = TestEntity.service(client); service.withMask().recursiveProperty().baz(); service.withMask().recursiveProperty().foo(); @@ -130,7 +130,7 @@ public void testRecursiveMask() { @Test public void testMultiLevelMask() { - RestApiClient client = new RestApiClient("http://example.com/"); + RestApiClient client = new TestApiClient("http://example.com/"); TestEntity.Service service = TestEntity.service(client); service.withMask().recursiveProperty().baz(); service.withMask().recursiveProperty().foo(); @@ -149,12 +149,13 @@ public void testNoChangeMaskScope() { TestApiClient client = new TestApiClient("http://example.com/"); - client.setLoggingEnabled(true); +// client.setLoggingEnabled(true); TestEntity.Service service = TestEntity.service(client); service.withMask().testThing().id(); service.withMask().testThing().first(); + TestEntity result = service.getObject(); assertEquals("testThing[id,first]", service.withMask().toString()); String expected = "http://example.com/SoftLayer_TestEntity.json?objectMask=mask%5BtestThing%5Bid%2Cfirst%5D%5D"; @@ -165,20 +166,17 @@ public void testNoChangeMaskScope() { @Test public void testChangeMaskScope() { +// https://github.com/softlayer/softlayer-java/issues/19 + TestApiClient client = new TestApiClient("http://example.com/"); - client.setLoggingEnabled(true); +// client.setLoggingEnabled(true); TestEntity.Service service = TestEntity.service(client); service.withMask().recursiveProperty().baz(); service.withMask().recursiveProperty().foo(); String result = service.getRecursiveProperty(); - System.out.print(result); -// RestApiClient.ServiceProxy serviceProxy = client.createService(TestEntity, 1234); -// serviceProxy.invoke(service, service.getRecursiveProperty(),null); -// assertEquals("http://example.com/SomeService/1234/someMethod.json?objectMask=someMask%26%26", -// client.ServiceProxy. -// ) +// assertEquals("baz,foo", service.withMask()); } } diff --git a/src/test/java/com/softlayer/api/http/FakeHttpClientFactory.java b/src/test/java/com/softlayer/api/http/FakeHttpClientFactory.java index 85bb91b..4f78ac0 100644 --- a/src/test/java/com/softlayer/api/http/FakeHttpClientFactory.java +++ b/src/test/java/com/softlayer/api/http/FakeHttpClientFactory.java @@ -81,11 +81,11 @@ public OutputStream getBodyStream() { @Override public HttpResponse invokeSync(Callable setupBody) { invokeSyncCalled = true; -// try { -// setupBody.call(); -// } catch (Exception e) { -// throw new RuntimeException(e); -// } + try { + setupBody.call(); + } catch (Exception e) { + throw new RuntimeException(e); + } return this; } diff --git a/src/test/java/com/softlayer/api/service/TestEntity.java b/src/test/java/com/softlayer/api/service/TestEntity.java index 909bc17..db3ac7f 100644 --- a/src/test/java/com/softlayer/api/service/TestEntity.java +++ b/src/test/java/com/softlayer/api/service/TestEntity.java @@ -278,9 +278,6 @@ public Void doSomethingNonStatic(GregorianCalendar param1) { @Override public String getRecursiveProperty() { - System.out.print("getRecursiveProperty\n"); - System.out.print("MASK: " + withMask().toString() +"\n"); - return "Hello World"; } From 7c67c40b0172abdb817d8b0054c46136c34cdc9f Mon Sep 17 00:00:00 2001 From: Cameron Porter Date: Tue, 4 Dec 2018 11:31:41 -0600 Subject: [PATCH 09/45] Release version 0.2.6 --- README.md | 2 +- examples/pom.xml | 11 ++++------- gen/pom.xml | 12 ++++++------ pom.xml | 25 ++++++++++++------------- 4 files changed, 23 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index eed2cf1..ec3e9fe 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ To add the project you your Maven project, add the dependency: com.softlayer.api softlayer-api-client - 0.2.5 + 0.2.6 ``` diff --git a/examples/pom.xml b/examples/pom.xml index de92d47..6c9becd 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -5,7 +5,7 @@ softlayer-api-client-examples jar - 0.2.5 + 0.2.6 softlayer-api-client-examples http://sldn.softlayer.com @@ -28,18 +28,15 @@ - org.apache.maven.plugins maven-resources-plugin - 2.6 + 3.1.0 org.codehaus.mojo exec-maven-plugin - 1.2.1 + 1.6.0 @@ -54,7 +51,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.7.0 + 3.8.0 ${java.version} ${java.version} diff --git a/gen/pom.xml b/gen/pom.xml index 78f41fb..a69cfe9 100644 --- a/gen/pom.xml +++ b/gen/pom.xml @@ -5,7 +5,7 @@ softlayer-api-client-gen jar - 0.2.5 + 0.2.6 softlayer-api-client-gen http://sldn.softlayer.com @@ -29,12 +29,12 @@ com.google.code.gson gson - 2.3 + 2.8.5 junit junit - 4.11 + 4.12 test @@ -43,7 +43,7 @@ org.codehaus.mojo exec-maven-plugin - 1.2.1 + 1.6.0 @@ -58,12 +58,12 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.0.0-M1 + 3.0.1 org.apache.maven.plugins maven-compiler-plugin - 3.7.0 + 3.8.0 ${java.version} ${java.version} diff --git a/pom.xml b/pom.xml index 46c6aca..b6dee25 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ softlayer-api-client jar - 0.2.5 + 0.2.6 SoftLayer API Client for Java API client for accessing the SoftLayer API http://sldn.softlayer.com @@ -41,7 +41,7 @@ scm:git:git@github.com:softlayer/softlayer-java.git scm:git:git@github.com:softlayer/softlayer-java.git git@github.com:softlayer/softlayer-java.git - 0.2.5 + 0.2.6 UTF-8 @@ -67,7 +67,7 @@ com.google.code.gson gson - 2.6 + 2.8.5 junit @@ -78,7 +78,7 @@ org.mockito mockito-core - 2.8.47 + 2.23.4 test @@ -87,7 +87,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.7.0 + 3.8.0 ${java.version} ${java.version} @@ -109,18 +109,18 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.0.0-M1 + 3.0.1 + + + + none + attach-javadocs jar - - - - -Xdoclint:none - @@ -141,8 +141,7 @@ maven-invoker-plugin - - 2.0.0 + 3.1.0 generate-services From 6c018a2c5f3677b32988afff013c7f26ea825256 Mon Sep 17 00:00:00 2001 From: Cameron Porter Date: Tue, 4 Dec 2018 12:19:36 -0600 Subject: [PATCH 10/45] Update travis configuration to test on java 10 and 11 where available and supported by OpenJDK and Oracle. --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index 342a614..53b61d0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,8 @@ language: java jdk: - oraclejdk8 + - oraclejdk11 - openjdk8 + - openjdk10 + - openjdk11 install: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -Dgpg.skip=true \ No newline at end of file From c3d535488b16ccd1cfd59c0a590ffee20d3670aa Mon Sep 17 00:00:00 2001 From: Cameron Porter Date: Tue, 19 Mar 2019 12:54:12 -0500 Subject: [PATCH 11/45] Code cleanup. The ServiceTester classes don't really work the way the client expects, so they've been removed in favor of using the FakeHttpClientFactory in place where it is needed. Additionally the TestApiClient duplicates a lot of the same code as the RestApiClient and is not flexible for service types other than the TestEntity ServiceTester class. --- src/test/java/com/softlayer/api/MaskTest.java | 77 ++++---- .../com/softlayer/api/RestApiClientTest.java | 4 - .../java/com/softlayer/api/TestApiClient.java | 108 ----------- .../com/softlayer/api/service/TestEntity.java | 174 +++++------------- .../com/softlayer/api/service/TestThing.java | 82 ++------- 5 files changed, 97 insertions(+), 348 deletions(-) delete mode 100644 src/test/java/com/softlayer/api/TestApiClient.java diff --git a/src/test/java/com/softlayer/api/MaskTest.java b/src/test/java/com/softlayer/api/MaskTest.java index 4b8f766..928b0be 100644 --- a/src/test/java/com/softlayer/api/MaskTest.java +++ b/src/test/java/com/softlayer/api/MaskTest.java @@ -2,37 +2,27 @@ import static org.junit.Assert.*; - -import java.io.ByteArrayOutputStream; -import java.io.PrintStream; -import java.lang.reflect.Proxy; import java.net.URLEncoder; import java.util.Collections; -import java.util.GregorianCalendar; -import java.util.List; -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.atomic.AtomicBoolean; +import org.junit.Ignore; import org.junit.Test; import com.softlayer.api.http.FakeHttpClientFactory; -import com.softlayer.api.http.HttpBasicAuthCredentials; import com.softlayer.api.json.GsonJsonMarshallerFactoryTest; import com.softlayer.api.service.TestEntity; - - public class MaskTest { static { GsonJsonMarshallerFactoryTest.addTestEntityToGson(); } + @Test public void testWithMask() throws Exception { FakeHttpClientFactory http = new FakeHttpClientFactory(200, - Collections.emptyMap(), "\"some response\""); + Collections.emptyMap(), "\"some response\""); RestApiClient client = new RestApiClient("http://example.com/") - .withCredentials("user", "key"); + .withCredentials("user", "key"); client.setHttpClientFactory(http); TestEntity entity = new TestEntity(); @@ -43,16 +33,16 @@ public void testWithMask() throws Exception { assertEquals("some response", service.doSomethingStatic(123L, entity)); assertEquals("http://example.com/SoftLayer_TestEntity/doSomethingStatic.json" - + "?objectMask=" + URLEncoder.encode(service.withMask().getMask(), "UTF-8"), http.fullUrl); + + "?objectMask=" + URLEncoder.encode(service.withMask().getMask(), "UTF-8"), http.fullUrl); assertTrue(http.invokeSyncCalled); } @Test public void testSetObjectMask() throws Exception { FakeHttpClientFactory http = new FakeHttpClientFactory(200, - Collections.emptyMap(), "\"some response\""); + Collections.emptyMap(), "\"some response\""); RestApiClient client = new RestApiClient("http://example.com/") - .withCredentials("user", "key"); + .withCredentials("user", "key"); client.setHttpClientFactory(http); TestEntity entity = new TestEntity(); @@ -65,16 +55,16 @@ public void testSetObjectMask() throws Exception { assertEquals("some response", service.doSomethingStatic(123L, entity)); assertEquals("http://example.com/SoftLayer_TestEntity/doSomethingStatic.json" - + "?objectMask=" + URLEncoder.encode(mask.getMask(), "UTF-8"), http.fullUrl); + + "?objectMask=" + URLEncoder.encode(mask.getMask(), "UTF-8"), http.fullUrl); assertTrue(http.invokeSyncCalled); } @Test public void testSetStringMask() { FakeHttpClientFactory http = new FakeHttpClientFactory(200, - Collections.emptyMap(), "\"some response\""); + Collections.emptyMap(), "\"some response\""); RestApiClient client = new RestApiClient("http://example.com/") - .withCredentials("user", "key"); + .withCredentials("user", "key"); client.setHttpClientFactory(http); TestEntity entity = new TestEntity(); @@ -84,20 +74,20 @@ public void testSetStringMask() { assertEquals("some response", service.doSomethingStatic(123L, entity)); assertEquals("http://example.com/SoftLayer_TestEntity/doSomethingStatic.json" - + "?objectMask=yay-a-mask", http.fullUrl); + + "?objectMask=yay-a-mask", http.fullUrl); assertTrue(http.invokeSyncCalled); } @Test(expected = IllegalArgumentException.class) public void testMaskMustNotBeNull() { - RestApiClient client = new TestApiClient("http://example.com/"); + RestApiClient client = new RestApiClient("http://example.com/"); TestEntity.Service service = TestEntity.service(client); service.setMask((Mask) null); } @Test public void testMaskRemoval() { - RestApiClient client = new TestApiClient("http://example.com/"); + RestApiClient client = new RestApiClient("http://example.com/"); TestEntity.Service service = TestEntity.service(client); service.withMask().baz(); assertEquals("baz", service.withMask().toString()); @@ -107,30 +97,34 @@ public void testMaskRemoval() { @Test public void testRecursiveMaskAndLocal() { - RestApiClient client = new TestApiClient("http://example.com/"); + RestApiClient client = new RestApiClient("http://example.com/"); TestEntity.Service service = TestEntity.service(client); service.withMask().recursiveProperty().recursiveProperty().baz(); service.withMask().recursiveProperty().recursiveProperty().foo(); service.withMask().recursiveProperty().date(); assertEquals("recursiveProperty[date,recursiveProperty[foo,baz]]", - service.withMask().toString()); + service.withMask().toString()); } @Test public void testRecursiveMask() { - RestApiClient client = new TestApiClient("http://example.com/"); + RestApiClient client = new RestApiClient("http://example.com/"); TestEntity.Service service = TestEntity.service(client); service.withMask().recursiveProperty().baz(); service.withMask().recursiveProperty().foo(); service.withMask().recursiveProperty().date(); assertEquals("recursiveProperty[date,foo,baz]", - service.withMask().toString()); + service.withMask().toString()); } @Test public void testMultiLevelMask() { - RestApiClient client = new TestApiClient("http://example.com/"); + FakeHttpClientFactory http = new FakeHttpClientFactory(200, + Collections.emptyMap(),""); + RestApiClient client = new RestApiClient("http://example.com/"); + client.setHttpClientFactory(http); + TestEntity.Service service = TestEntity.service(client); service.withMask().recursiveProperty().baz(); service.withMask().recursiveProperty().foo(); @@ -140,43 +134,40 @@ public void testMultiLevelMask() { String result = service.getRecursiveProperty(); assertEquals("moreChildren[date,recursiveProperty.baz],recursiveProperty[foo,baz]", - service.withMask().toString()); + service.withMask().toString()); } @Test public void testNoChangeMaskScope() { - - - TestApiClient client = new TestApiClient("http://example.com/"); - -// client.setLoggingEnabled(true); + FakeHttpClientFactory http = new FakeHttpClientFactory(200, + Collections.emptyMap(),""); + RestApiClient client = new RestApiClient("http://example.com/"); + client.setHttpClientFactory(http); TestEntity.Service service = TestEntity.service(client); service.withMask().testThing().id(); service.withMask().testThing().first(); - TestEntity result = service.getObject(); assertEquals("testThing[id,first]", service.withMask().toString()); String expected = "http://example.com/SoftLayer_TestEntity.json?objectMask=mask%5BtestThing%5Bid%2Cfirst%5D%5D"; - assertEquals(expected, client.httpClientFactory.fullUrl); - - + assertEquals(expected, http.fullUrl); } + /** + * This doesn't work due to the issues mentioned in https://github.com/softlayer/softlayer-java/issues/19 + */ @Test + @Ignore public void testChangeMaskScope() { -// https://github.com/softlayer/softlayer-java/issues/19 - - TestApiClient client = new TestApiClient("http://example.com/"); -// client.setLoggingEnabled(true); + RestApiClient client = new RestApiClient("http://example.com/"); TestEntity.Service service = TestEntity.service(client); service.withMask().recursiveProperty().baz(); service.withMask().recursiveProperty().foo(); String result = service.getRecursiveProperty(); -// assertEquals("baz,foo", service.withMask()); + assertEquals("baz,foo", service.withMask().toString()); } } diff --git a/src/test/java/com/softlayer/api/RestApiClientTest.java b/src/test/java/com/softlayer/api/RestApiClientTest.java index 1a0b565..e44b7e5 100644 --- a/src/test/java/com/softlayer/api/RestApiClientTest.java +++ b/src/test/java/com/softlayer/api/RestApiClientTest.java @@ -5,10 +5,8 @@ import java.io.ByteArrayOutputStream; import java.io.PrintStream; import java.lang.reflect.Proxy; -import java.net.URLEncoder; import java.util.Collections; import java.util.GregorianCalendar; -import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.atomic.AtomicBoolean; @@ -400,8 +398,6 @@ public void onSuccess(String value) { assertTrue(successCalled.get()); } - - @Test public void testNormalObjectMethodsOnService() { RestApiClient client = new RestApiClient("http://example.com/"); diff --git a/src/test/java/com/softlayer/api/TestApiClient.java b/src/test/java/com/softlayer/api/TestApiClient.java deleted file mode 100644 index 1dc7caf..0000000 --- a/src/test/java/com/softlayer/api/TestApiClient.java +++ /dev/null @@ -1,108 +0,0 @@ -package com.softlayer.api; - -import com.softlayer.api.annotation.ApiMethod; -import com.softlayer.api.annotation.ApiService; -import com.softlayer.api.http.*; -import com.softlayer.api.json.GsonJsonMarshallerFactoryTest; - -import java.io.ByteArrayOutputStream; -import java.io.OutputStream; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; -import java.util.Collections; - -import org.mockito.Mockito; - -public class TestApiClient extends RestApiClient{ - - - private HttpBasicAuthCredentials credentials; - public HttpBasicAuthCredentials getCredentials() { - return credentials; - } - public FakeHttpClientFactory httpClientFactory; - public TestApiClient(String baseUrl) { - super(baseUrl); - } - - public FakeHttpClientFactory getHttpClientFactory() { - if (httpClientFactory == null) { - httpClientFactory = new FakeHttpClientFactory(200, - Collections.emptyMap(), ""); - } - return httpClientFactory; - } - public void setHttpClientFactory(FakeHttpClientFactory httpClientFactory) { - this.httpClientFactory = httpClientFactory; - } - - public S createService(Class serviceClass, String id) { - return (S) Proxy.newProxyInstance(getClass().getClassLoader(), - new Class[] { serviceClass }, new TestServiceProxy<>(serviceClass, id)); - } - - class TestServiceProxy extends ServiceProxy { - - final Class serviceClass; - final String id; - - public Mask mask; - public String url; - String maskString; - ResultLimit resultLimit; - Integer lastResponseTotalItemCount; - - - public TestServiceProxy(Class serviceClass, String id) { - super(serviceClass, id); - Class c = serviceClass; - try { - c = Class.forName("com.softlayer.api.service.TestEntity$ServiceTester"); - }catch (ClassNotFoundException x) { - x.printStackTrace(); - } - - this.serviceClass = c; - this.id = id; - } - - @Override - public Object invokeService(Method method, final Object[] args) throws Throwable { - this.mask = super.mask; - this.maskString = super.maskString; - - ApiMethod methodInfo = method.getAnnotation(ApiMethod.class); - // Must have ID if instance is required - - if (methodInfo.instanceRequired() && id == null) { - throw new IllegalStateException("ID is required to invoke " + method); - } - String methodName = methodInfo.value().isEmpty() ? method.getName() : methodInfo.value(); - final String httpMethod = getHttpMethodFromMethodName(methodName); - String methodId = methodInfo.instanceRequired() ? this.id : null; - final String url = getFullUrl(serviceClass.getAnnotation(ApiService.class).value(), - methodName, methodId, resultLimit, mask == null ? maskString : mask.getMask()); - - this.url = url; - - Method toCall = serviceClass.getDeclaredMethod(method.getName()); - Object resultInvoke = toCall.invoke(serviceClass.newInstance()); - OutputStream output = new ByteArrayOutputStream(); - getJsonMarshallerFactory().getJsonMarshaller().toJson( - resultInvoke, output); - FakeHttpClientFactory faketory = new FakeHttpClientFactory(200, - Collections.emptyMap(), output.toString()); - setHttpClientFactory(faketory); - - final HttpClient client = getHttpClientFactory().getHttpClient(credentials, httpMethod, url, HEADERS); - HttpResponse response = client.invokeSync(() -> { - logRequestAndWriteBody(client, httpMethod, url, args); - return null; - }); - return logAndHandleResponse(response, url, method.getGenericReturnType()); - } - } - - -} diff --git a/src/test/java/com/softlayer/api/service/TestEntity.java b/src/test/java/com/softlayer/api/service/TestEntity.java index db3ac7f..ce85bf6 100644 --- a/src/test/java/com/softlayer/api/service/TestEntity.java +++ b/src/test/java/com/softlayer/api/service/TestEntity.java @@ -5,17 +5,17 @@ import java.util.List; import java.util.concurrent.Future; -import com.softlayer.api.ApiClient; -import com.softlayer.api.ResponseHandler; -import com.softlayer.api.ResultLimit; import com.softlayer.api.annotation.ApiMethod; import com.softlayer.api.annotation.ApiProperty; import com.softlayer.api.annotation.ApiService; import com.softlayer.api.annotation.ApiType; +import com.softlayer.api.ApiClient; +import com.softlayer.api.ResponseHandler; +import com.softlayer.api.ResultLimit; @ApiType("SoftLayer_TestEntity") public class TestEntity extends Entity { - + @ApiProperty(canBeNullOrNotSet = true) protected Long id; @@ -38,75 +38,75 @@ public void unsetId() { id = null; idSpecified = false; } - + @ApiProperty("bar") protected String foo; - + public String getFoo() { return foo; } - + public void setFoo(String foo) { this.foo = foo; } - + @ApiProperty(canBeNullOrNotSet = true) protected String baz; protected boolean bazSpecified; - + public String getBaz() { return baz; } - + public void setBaz(String baz) { bazSpecified = true; this.baz = baz; } - + public boolean isBazSpecified() { return bazSpecified; } - + public void unsetBaz() { baz = null; bazSpecified = false; } - + @ApiProperty protected GregorianCalendar date; - + public GregorianCalendar getDate() { return date; } - + public void setDate(GregorianCalendar date) { this.date = date; } - + protected String notApiProperty; - + public String getNotApiProperty() { return notApiProperty; } - + public void setNotApiProperty(String notApiProperty) { this.notApiProperty = notApiProperty; } - + @ApiProperty protected TestEntity child; - + public TestEntity getChild() { return child; } - + public void setChild(TestEntity child) { this.child = child; } - + @ApiProperty protected List moreChildren; - + public List getMoreChildren() { if (moreChildren == null) { moreChildren = new ArrayList(); @@ -145,21 +145,24 @@ public static Service service(ApiClient client) { public static Service service(ApiClient client, Long id) { return client.createService(Service.class, id == null ? null : id.toString()); } - + @ApiService("SoftLayer_TestEntity") public static interface Service extends com.softlayer.api.Service { public ServiceAsync asAsync(); + public Mask withNewMask(); + public Mask withMask(); + public void setMask(Mask mask); - + @ApiMethod public String doSomethingStatic(Long param1, TestEntity param2); - + @ApiMethod("actualName") public List fakeName(); - + @ApiMethod(instanceRequired = true) public Void doSomethingNonStatic(GregorianCalendar param1); @@ -172,44 +175,49 @@ public static interface Service extends com.softlayer.api.Service { @ApiMethod("getTestThing") public TestThing getTestThing(); } - + public static interface ServiceAsync extends com.softlayer.api.ServiceAsync { public Mask withNewMask(); + public Mask withMask(); + public void setMask(Mask mask); - + public Future doSomethingStatic(Long param1, TestEntity param2); + public Future doSomethingStatic(Long param1, TestEntity param2, ResponseHandler handler); - + public Future fakeName(); + public Future fakeName(ResponseHandler handler); - + public Future doSomethingNonStatic(GregorianCalendar param1); + public Future doSomethingNonStatic(GregorianCalendar param1, ResponseHandler handler); } - + public static class Mask extends Entity.Mask { public Mask foo() { withLocalProperty("foo"); return this; } - + public Mask baz() { withLocalProperty("baz"); return this; } - + public Mask date() { withLocalProperty("date"); return this; } - + public Mask child() { return withSubMask("child", Mask.class); } - + public Mask moreChildren() { return withSubMask("moreChildren", Mask.class); } @@ -217,99 +225,9 @@ public Mask moreChildren() { public Mask recursiveProperty() { return withSubMask("recursiveProperty", com.softlayer.api.service.TestEntity.Mask.class); } + public TestThing.Mask testThing() { return withSubMask("testThing", com.softlayer.api.service.TestThing.Mask.class); } } - - @ApiService("SoftLayer_TestEntity") - public static class ServiceTester implements Service { - - @Override - public ServiceAsync asAsync() { - return null; - } - - @Override - public Mask withNewMask() { - return new Mask(); - } - - @Override - public Mask withMask() { - - return new Mask(); - } - - @Override - public void setMask(com.softlayer.api.Mask mask) { - - } - - @Override - public void setMask(String mask) { - - } - - @Override - public void clearMask() { - - } - - @Override - public void setMask(Mask mask) { - - } - - @Override - public String doSomethingStatic(Long param1, TestEntity param2) { - return null; - } - - @Override - public List fakeName() { - return null; - } - - @Override - public Void doSomethingNonStatic(GregorianCalendar param1) { - return null; - } - - @Override - public String getRecursiveProperty() { - return "Hello World"; - } - - @Override - public TestEntity getObject() { - TestEntity toReturn = new TestEntity(); - toReturn.id = Long.valueOf(12345); - toReturn.baz = "GotBaz"; - return toReturn; - - } - - @Override - public TestThing getTestThing() { - TestThing toReturn = new TestThing(); - toReturn.id = Long.valueOf(5555); - toReturn.first = "First Test Thing"; - return toReturn; - } - @Override - public ResultLimit getResultLimit() { - return null; - } - - @Override - public ResultLimit setResultLimit(ResultLimit limit) { - return null; - } - - @Override - public Integer getLastResponseTotalItemCount() { - return null; - } - } -} \ No newline at end of file +} diff --git a/src/test/java/com/softlayer/api/service/TestThing.java b/src/test/java/com/softlayer/api/service/TestThing.java index ca7f5ae..2eac363 100644 --- a/src/test/java/com/softlayer/api/service/TestThing.java +++ b/src/test/java/com/softlayer/api/service/TestThing.java @@ -1,22 +1,15 @@ package com.softlayer.api.service; import java.util.ArrayList; -import java.util.GregorianCalendar; import java.util.List; import java.util.concurrent.Future; - import com.softlayer.api.ApiClient; -import com.softlayer.api.Mask; import com.softlayer.api.ResponseHandler; import com.softlayer.api.ResultLimit; import com.softlayer.api.annotation.ApiMethod; import com.softlayer.api.annotation.ApiProperty; import com.softlayer.api.annotation.ApiService; -import com.softlayer.api.annotation.ApiType; -import com.softlayer.api.service.TestEntity; -import org.junit.Test; - public class TestThing extends Entity { @@ -46,7 +39,9 @@ public void unsetId() { @ApiProperty("first") protected String first; - public String getFirst() { return first; } + public String getFirst() { + return first; + } public void setFirst(String first) { this.first = first; @@ -55,7 +50,9 @@ public void setFirst(String first) { @ApiProperty("second") protected String second; - public String getSecond() { return second; } + public String getSecond() { + return second; + } public void setSecond(String second) { this.second = second; @@ -70,6 +67,7 @@ public List getTestEntity() { } return testEntity; } + public Service asService(ApiClient client) { return service(client, id); } @@ -85,8 +83,11 @@ public static Service service(ApiClient client, Long id) { @ApiService("SoftLayer_TestThing") public static interface Service extends com.softlayer.api.Service { public ServiceAsync asAsync(); + public Mask withNewMask(); + public Mask withMask(); + public void setMask(Mask mask); @ApiMethod("getObject") @@ -98,13 +99,17 @@ public static interface Service extends com.softlayer.api.Service { public static interface ServiceAsync extends com.softlayer.api.ServiceAsync { public Mask withNewMask(); + public Mask withMask(); + public void setMask(Mask mask); public Future getObject(); + public Future getObject(ResponseHandler handler); public Future> getTestEntity(); + public Future getTestEntity(ResponseHandler> handler); } @@ -114,72 +119,19 @@ public Mask id() { withLocalProperty("id"); return this; } + public Mask first() { withLocalProperty("first"); return this; } + public Mask second() { withLocalProperty("second"); return this; } + public Mask testEntity() { return withSubMask("testEntity", Mask.class); } - - } - - @ApiService("SoftLayer_TestThing") - public static class ServiceTester implements Service { - - @Override - public ServiceAsync asAsync() { return null; } - - @Override - public Mask withNewMask() { return new Mask(); } - - @Override - public Mask withMask() { return new Mask(); } - - @Override - public void setMask(com.softlayer.api.Mask mask) { - - } - - @Override - public void setMask(String mask) { - - } - - @Override - public void clearMask() { - - } - - @Override - public void setMask(Mask mask) { - - } - - @Override - public TestThing getObject() { - TestThing toReturn = new TestThing(); - toReturn.id = Long.valueOf(1234); - toReturn.first = "First Property"; - - return toReturn; - } - - @Override - public List getTestEntity() { return null; } - - @Override - public ResultLimit getResultLimit() { return null; } - - @Override - public ResultLimit setResultLimit(ResultLimit limit) { return null; } - - @Override - public Integer getLastResponseTotalItemCount() { return null; } } } - From 0bb17f4b520aae0d0878f3dcaad0d9ee96472363 Mon Sep 17 00:00:00 2001 From: Cameron Porter Date: Thu, 21 Mar 2019 15:56:22 -0500 Subject: [PATCH 12/45] Release version 0.2.7 --- README.md | 25 ++++++++++++++++++++----- examples/pom.xml | 2 +- gen/pom.xml | 2 +- pom.xml | 4 ++-- 4 files changed, 24 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index ec3e9fe..eea475a 100644 --- a/README.md +++ b/README.md @@ -27,19 +27,34 @@ servers and may charge your account. ## Using -To add the project you your Maven project, add the dependency: +Add the library as a dependency using your favorite build tooling. + +Note that the published client library is built upon the state of the API at the time of the version's release. +It will contain the generated artifacts as of that time only. +See "Building" for more information on how to regenerate the artifacts to get regular +additions to the SoftLayer API. + +### Maven ```xml com.softlayer.api softlayer-api-client - 0.2.6 + 0.2.7 ``` -Note, the client published to Maven is built upon version change of this project. It will contain the generated -artifacts as of that time only. See "Building" for more information on how to regenerate the artifacts to get regular -additions to the SoftLayer API. +### Gradle + +```groovy +implementation 'com.softlayer.api:softlayer-api-client:0.2.7' +``` + +### Kotlin + +```kotlin +compile("com.softlayer.api:softlayer-api-client:0.2.7") +``` ### Creating a Client diff --git a/examples/pom.xml b/examples/pom.xml index 6c9becd..bf99322 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -5,7 +5,7 @@ softlayer-api-client-examples jar - 0.2.6 + 0.2.7 softlayer-api-client-examples http://sldn.softlayer.com diff --git a/gen/pom.xml b/gen/pom.xml index a69cfe9..7582733 100644 --- a/gen/pom.xml +++ b/gen/pom.xml @@ -5,7 +5,7 @@ softlayer-api-client-gen jar - 0.2.6 + 0.2.7 softlayer-api-client-gen http://sldn.softlayer.com diff --git a/pom.xml b/pom.xml index b6dee25..62e9be7 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ softlayer-api-client jar - 0.2.6 + 0.2.7 SoftLayer API Client for Java API client for accessing the SoftLayer API http://sldn.softlayer.com @@ -41,7 +41,7 @@ scm:git:git@github.com:softlayer/softlayer-java.git scm:git:git@github.com:softlayer/softlayer-java.git git@github.com:softlayer/softlayer-java.git - 0.2.6 + 0.2.7 UTF-8 From 6a94e4615776e1eb26ace554c211ed7ecdf7ae18 Mon Sep 17 00:00:00 2001 From: Cameron Porter Date: Fri, 13 Sep 2019 15:04:32 -0500 Subject: [PATCH 13/45] Update travis java versions. --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 53b61d0..0343321 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,9 @@ language: java jdk: - - oraclejdk8 + - oraclejdk9 - oraclejdk11 - openjdk8 - openjdk10 - openjdk11 + - openjdk12 install: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -Dgpg.skip=true \ No newline at end of file From b9c7bf3c20e2fc5782fee397d9a13287277068d9 Mon Sep 17 00:00:00 2001 From: Cameron Porter Date: Mon, 16 Sep 2019 09:25:45 -0500 Subject: [PATCH 14/45] Fix building under java 11 and 12, and remove oracle java 9. --- .travis.yml | 2 +- examples/pom.xml | 2 +- gen/pom.xml | 7 +++++-- pom.xml | 9 +++++---- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0343321..0bb046d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,8 @@ language: java jdk: - - oraclejdk9 - oraclejdk11 - openjdk8 + - openjdk9 - openjdk10 - openjdk11 - openjdk12 diff --git a/examples/pom.xml b/examples/pom.xml index bf99322..87c864c 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -51,7 +51,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.8.0 + 3.8.1 ${java.version} ${java.version} diff --git a/gen/pom.xml b/gen/pom.xml index 7582733..ba022cc 100644 --- a/gen/pom.xml +++ b/gen/pom.xml @@ -58,12 +58,15 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.0.1 + 3.1.1 + + ${java.version} + org.apache.maven.plugins maven-compiler-plugin - 3.8.0 + 3.8.1 ${java.version} ${java.version} diff --git a/pom.xml b/pom.xml index 62e9be7..0cde3bd 100644 --- a/pom.xml +++ b/pom.xml @@ -87,7 +87,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.8.0 + 3.8.1 ${java.version} ${java.version} @@ -96,7 +96,7 @@ org.apache.maven.plugins maven-source-plugin - 3.0.1 + 3.1.0 attach-sources @@ -109,11 +109,12 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.0.1 + 3.1.1 none + ${java.version} @@ -141,7 +142,7 @@ maven-invoker-plugin - 3.1.0 + 3.2.1 generate-services From d709a2912f388df834d55794109642e4a1fa4dfb Mon Sep 17 00:00:00 2001 From: Cameron Porter Date: Mon, 16 Sep 2019 10:03:56 -0500 Subject: [PATCH 15/45] Release version 0.2.8 --- README.md | 6 +++--- examples/pom.xml | 2 +- gen/pom.xml | 2 +- pom.xml | 6 +++--- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index eea475a..3157553 100644 --- a/README.md +++ b/README.md @@ -40,20 +40,20 @@ additions to the SoftLayer API. com.softlayer.api softlayer-api-client - 0.2.7 + 0.2.8 ``` ### Gradle ```groovy -implementation 'com.softlayer.api:softlayer-api-client:0.2.7' +implementation 'com.softlayer.api:softlayer-api-client:0.2.8' ``` ### Kotlin ```kotlin -compile("com.softlayer.api:softlayer-api-client:0.2.7") +compile("com.softlayer.api:softlayer-api-client:0.2.8") ``` ### Creating a Client diff --git a/examples/pom.xml b/examples/pom.xml index 87c864c..94fb261 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -5,7 +5,7 @@ softlayer-api-client-examples jar - 0.2.7 + 0.2.8 softlayer-api-client-examples http://sldn.softlayer.com diff --git a/gen/pom.xml b/gen/pom.xml index ba022cc..d775d66 100644 --- a/gen/pom.xml +++ b/gen/pom.xml @@ -5,7 +5,7 @@ softlayer-api-client-gen jar - 0.2.7 + 0.2.8 softlayer-api-client-gen http://sldn.softlayer.com diff --git a/pom.xml b/pom.xml index 0cde3bd..9e9cfdd 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ softlayer-api-client jar - 0.2.7 + 0.2.8 SoftLayer API Client for Java API client for accessing the SoftLayer API http://sldn.softlayer.com @@ -41,7 +41,7 @@ scm:git:git@github.com:softlayer/softlayer-java.git scm:git:git@github.com:softlayer/softlayer-java.git git@github.com:softlayer/softlayer-java.git - 0.2.7 + 0.2.8 UTF-8 @@ -78,7 +78,7 @@ org.mockito mockito-core - 2.23.4 + 2.28.2 test From a679c9a18fdd41fe8845c2877c1ab2a4bbf8532d Mon Sep 17 00:00:00 2001 From: Cameron Porter Date: Mon, 30 Dec 2019 13:27:48 -0600 Subject: [PATCH 16/45] Update dates. Use pandoc in travis to update the github pages. --- .travis.yml | 24 +++++++++++++++++++++++- LICENSE | 2 +- README.md | 2 +- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0bb046d..47fc8c1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,11 @@ language: java + +addons: + apt: + update: true + packages: + - pandoc + jdk: - oraclejdk11 - openjdk8 @@ -6,4 +13,19 @@ jdk: - openjdk10 - openjdk11 - openjdk12 -install: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -Dgpg.skip=true \ No newline at end of file + +install: + - mvn install -DskipTests=true -Dmaven.javadoc.skip=true -Dgpg.skip=true + - mkdir ghpages + - pandoc -o ghpages/index.html README.md + - printf "%s" "$GH_PAGES_DEPLOYMENT_KEY" > gh_pages_deployment_key + +deploy: + provider: pages:git + edge: true + skip_cleanup: true + local_dir: ghpages + deploy_key: gh_pages_deployment_key + keep_history: true + on: + branch: master diff --git a/LICENSE b/LICENSE index f1d9742..d8f5d64 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2018 The SoftLayer Developer Network +Copyright (c) 2020 The SoftLayer Developer Network Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 3157553..398738e 100644 --- a/README.md +++ b/README.md @@ -289,4 +289,4 @@ fully qualified class name of your implementation on a single line in a file in ## Copyright -This software is Copyright (c) 2018 The SoftLayer Developer Network. See the bundled LICENSE file for more information. +This software is Copyright (c) 2020 The SoftLayer Developer Network. See the bundled LICENSE file for more information. From b9e21e0dc692abbb7df59557fd31c786f4f0c994 Mon Sep 17 00:00:00 2001 From: Cameron Porter Date: Thu, 2 Jan 2020 18:41:58 -0600 Subject: [PATCH 17/45] Temporary fix for the metadata API issues. --- .travis.yml | 2 +- gen/src/main/java/com/softlayer/api/gen/Main.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 47fc8c1..a6ce414 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,7 +18,7 @@ install: - mvn install -DskipTests=true -Dmaven.javadoc.skip=true -Dgpg.skip=true - mkdir ghpages - pandoc -o ghpages/index.html README.md - - printf "%s" "$GH_PAGES_DEPLOYMENT_KEY" > gh_pages_deployment_key + - printf "$GH_PAGES_DEPLOYMENT_KEY" > gh_pages_deployment_key deploy: provider: pages:git diff --git a/gen/src/main/java/com/softlayer/api/gen/Main.java b/gen/src/main/java/com/softlayer/api/gen/Main.java index ee75d34..3fa541a 100644 --- a/gen/src/main/java/com/softlayer/api/gen/Main.java +++ b/gen/src/main/java/com/softlayer/api/gen/Main.java @@ -14,7 +14,7 @@ /** Entry point for the code generator */ public class Main { - protected static final String METADATA_URL = "https://api.softlayer.com/metadata/v3.1"; + protected static final String METADATA_URL = "https://api.softlayer.com/metadata/v3.1/"; protected static final String DEFAULT_SOURCE_PATH = "../src/main/java"; public static final String USAGE = @@ -23,7 +23,7 @@ public class Main { " --src DIR - Optional directory to generate source into. The com.softlayer.api.service package\n" + " underneath this directory will be cleaned before code is generated. If not given,\n" + " ../src/main/java is used\n" + - " --url URL - Optional metadata URL. If not given, http://api.softlayer.com/metadata is used.\n" + + " --url URL - Optional metadata URL. If not given, http://api.softlayer.com/metadata/v3.1/ is used.\n" + " --whitelist FILENAME - Optional set of types, properties, and methods to whitelist. It is one\n" + " entry per line and anything not entered will not be included in the generated client. Simply\n" + " give the type name, the property as type_name.propertyName, or the method as type_name::methodName.\n" + From cf2d6b8196bbad9dbaacb826311d830ca9611cd2 Mon Sep 17 00:00:00 2001 From: Cameron Porter Date: Thu, 2 Jan 2020 19:00:15 -0600 Subject: [PATCH 18/45] Remove gh-pages updating for now --- .travis.yml | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/.travis.yml b/.travis.yml index a6ce414..d7cbd69 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,16 +16,3 @@ jdk: install: - mvn install -DskipTests=true -Dmaven.javadoc.skip=true -Dgpg.skip=true - - mkdir ghpages - - pandoc -o ghpages/index.html README.md - - printf "$GH_PAGES_DEPLOYMENT_KEY" > gh_pages_deployment_key - -deploy: - provider: pages:git - edge: true - skip_cleanup: true - local_dir: ghpages - deploy_key: gh_pages_deployment_key - keep_history: true - on: - branch: master From 073d3532cc423b64fe18db09811adfa4c16e1138 Mon Sep 17 00:00:00 2001 From: Cameron Porter Date: Thu, 2 Jan 2020 19:23:43 -0600 Subject: [PATCH 19/45] Set the maven compiler plugin release config to version 8. Replace usages of Class.newInstance(), which is deprecated in Java 9. --- examples/pom.xml | 3 ++- gen/pom.xml | 3 ++- pom.xml | 3 ++- src/main/java/com/softlayer/api/Mask.java | 2 +- src/main/java/com/softlayer/api/RestApiClient.java | 4 ++-- .../com/softlayer/api/json/GsonJsonMarshallerFactory.java | 4 ++-- 6 files changed, 11 insertions(+), 8 deletions(-) diff --git a/examples/pom.xml b/examples/pom.xml index 94fb261..1e2ec67 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -17,7 +17,7 @@ UTF-8 - 1.8 + 8 @@ -55,6 +55,7 @@ ${java.version} ${java.version} + ${java.version} diff --git a/gen/pom.xml b/gen/pom.xml index d775d66..f7b8a1f 100644 --- a/gen/pom.xml +++ b/gen/pom.xml @@ -17,7 +17,7 @@ UTF-8 - 1.8 + 8 com.softlayer.api.gen.Main @@ -70,6 +70,7 @@ ${java.version} ${java.version} + ${java.version} diff --git a/pom.xml b/pom.xml index 9e9cfdd..8ab09d3 100644 --- a/pom.xml +++ b/pom.xml @@ -45,7 +45,7 @@ UTF-8 - 1.8 + 8 @@ -91,6 +91,7 @@ ${java.version} ${java.version} + ${java.version} diff --git a/src/main/java/com/softlayer/api/Mask.java b/src/main/java/com/softlayer/api/Mask.java index 3c35061..9fae4d8 100644 --- a/src/main/java/com/softlayer/api/Mask.java +++ b/src/main/java/com/softlayer/api/Mask.java @@ -29,7 +29,7 @@ protected T withSubMask(String name, Class maskClass) { T subMask = (T) subMasks.get(name); if (subMask == null) { try { - subMask = maskClass.newInstance(); + subMask = maskClass.getDeclaredConstructor().newInstance(); } catch (Exception e) { throw new RuntimeException(); } diff --git a/src/main/java/com/softlayer/api/RestApiClient.java b/src/main/java/com/softlayer/api/RestApiClient.java index 46afa0e..5c11e2e 100644 --- a/src/main/java/com/softlayer/api/RestApiClient.java +++ b/src/main/java/com/softlayer/api/RestApiClient.java @@ -449,12 +449,12 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl return Proxy.newProxyInstance(getClass().getClassLoader(), new Class[] { method.getReturnType() }, asyncProxy); } else if ("withNewMask".equals(method.getName()) && noParams) { - mask = (Mask) method.getReturnType().newInstance(); + mask = (Mask) method.getReturnType().getDeclaredConstructor().newInstance(); maskString = null; return mask; } else if ("withMask".equals(method.getName()) && noParams) { if (mask == null) { - mask = (Mask) method.getReturnType().newInstance(); + mask = (Mask) method.getReturnType().getDeclaredConstructor().newInstance(); maskString = null; } return mask; diff --git a/src/main/java/com/softlayer/api/json/GsonJsonMarshallerFactory.java b/src/main/java/com/softlayer/api/json/GsonJsonMarshallerFactory.java index 87bac33..f77eb2b 100644 --- a/src/main/java/com/softlayer/api/json/GsonJsonMarshallerFactory.java +++ b/src/main/java/com/softlayer/api/json/GsonJsonMarshallerFactory.java @@ -208,8 +208,8 @@ private Entity readForThisType(JsonReader in) throws IOException { // Begin/end object (and the first "complexType" property) are done outside of here Entity entity; try { - entity = typeClass.newInstance(); - } catch (InstantiationException | IllegalAccessException e) { + entity = typeClass.getDeclaredConstructor().newInstance(); + } catch (ReflectiveOperationException e) { throw new RuntimeException(e); } Map unknownProperties = new HashMap<>(); From 86df33d80313420051ef06d026ef8ab668867572 Mon Sep 17 00:00:00 2001 From: Cameron Porter Date: Wed, 8 Jan 2020 10:11:54 -0600 Subject: [PATCH 20/45] Readd doc generation since an issue with travis-ci/dpl has been addressed. --- .travis.yml | 13 +++++++++++++ examples/pom.xml | 1 - gen/pom.xml | 1 - pom.xml | 1 - 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index d7cbd69..a6ce414 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,3 +16,16 @@ jdk: install: - mvn install -DskipTests=true -Dmaven.javadoc.skip=true -Dgpg.skip=true + - mkdir ghpages + - pandoc -o ghpages/index.html README.md + - printf "$GH_PAGES_DEPLOYMENT_KEY" > gh_pages_deployment_key + +deploy: + provider: pages:git + edge: true + skip_cleanup: true + local_dir: ghpages + deploy_key: gh_pages_deployment_key + keep_history: true + on: + branch: master diff --git a/examples/pom.xml b/examples/pom.xml index 1e2ec67..38b3175 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -55,7 +55,6 @@ ${java.version} ${java.version} - ${java.version} diff --git a/gen/pom.xml b/gen/pom.xml index f7b8a1f..08bed14 100644 --- a/gen/pom.xml +++ b/gen/pom.xml @@ -70,7 +70,6 @@ ${java.version} ${java.version} - ${java.version} diff --git a/pom.xml b/pom.xml index 8ab09d3..aca1da3 100644 --- a/pom.xml +++ b/pom.xml @@ -91,7 +91,6 @@ ${java.version} ${java.version} - ${java.version} From 580f8bcef1e950de551a1ab555307e5517e8c8aa Mon Sep 17 00:00:00 2001 From: Cameron Porter Date: Thu, 9 Jan 2020 10:10:51 -0600 Subject: [PATCH 21/45] Use a different deployment method instead. --- .travis.yml | 4 ++-- ghpages_secret.enc | Bin 0 -> 1680 bytes 2 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 ghpages_secret.enc diff --git a/.travis.yml b/.travis.yml index a6ce414..6a06ba8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,14 +18,14 @@ install: - mvn install -DskipTests=true -Dmaven.javadoc.skip=true -Dgpg.skip=true - mkdir ghpages - pandoc -o ghpages/index.html README.md - - printf "$GH_PAGES_DEPLOYMENT_KEY" > gh_pages_deployment_key + - openssl aes-256-cbc -K $encrypted_60afd10366bc_key -iv $encrypted_60afd10366bc_iv -in ghpages_secret.enc -out ghpages_secret -d deploy: provider: pages:git edge: true skip_cleanup: true local_dir: ghpages - deploy_key: gh_pages_deployment_key + deploy_key: ghpages_secret keep_history: true on: branch: master diff --git a/ghpages_secret.enc b/ghpages_secret.enc new file mode 100644 index 0000000000000000000000000000000000000000..00f2d2dd1621942d5fd86858ba6e2dd70a7e21cf GIT binary patch literal 1680 zcmV;B25a!HSY;t5VW`I zj6X`@zbB5p)CeOBuJ%$+ShwS zYkCh)e1&w4!u5TLrI)`IoV-ddzk~@oxTVIPO=2SiEh)#g{*5VoT9bspE*6U3&#NSs~*XnCBQLB-BlKgQl)F} z9wf4yghr3;d8z?_lxHUF^mAVTR7vDOCofyKqNd;*eY@#Rn7THUF1fV>jRHu}3_v zYoXRgB9(ybXVB=JpGRBaa%V4Ku>_+Sl?Ka@W8oyb42zf{=j~noMFdS0rT(0V`HeGd zje(1e2YL5liZ*X{iLoH;|2jrN{T+x?uWv$=xjB=k8?Y{m2P$FdBI_Yqc(8Bd3!+Mv zXW59n0NdrT90Oz>8i%7p+N>Xwq&=U+M5HKR(jL>Kr=MmU1$0_ujCIZFOo(*nTx7CC z7pTJY0;L0!X)m@gz{(xQJGM5@o*Q2cDx{LXl=if}O8QG=#!Xh$c(?_`!a<~)BvGgb z(c;hUsjZW^X%c1!4*k7Xgdqa*SO=;{I2u62%Vcd#PVPt%d=R{|S zzQ{7vbeXBSBQ!3?PVhk{OTQp~_p?bv*Fu{xtrN&bbc)oAlswcZv%Y4es8|tbP$w{A^KQov6K3@2E#yi%0L8KA>p)bk1G$>x zsWbvy8bA(HB`@5aM_(|`4nnU?T}W}Z{^WsbCi~J}t%zC$L5!Bz%bI^nO}AQI4m(l+ zP!G;NoquANSytz;aj*_u_`j@Pgzx;1u=*J2YWHEDFs<}a46lb$kB6)xO;eep!~Jo3 z&h*as7yA<%)c`%E%50MzBT=zRPIxZp5yo=7WV8>bh@uaQ^CxycvBpcVt3=q|&L49C zLNrPJ6%K8XDi_PW7d6!(>astWJ(Xd{b5wx9ywPhNJQRKhBm>y3Io?!gud)FEFBh#* zkRjQWyUL{QOS4?hOL=WkvOp=4A=PC(s{BEk(5|F z;8O)SDofHf|5J;5gAtXe4gzw+Ll!6DYfCpQY`DA=S z``}??k({vhbx?dBgXm^NoGy47nK$b-kyTkg8N}-j9Ct(lW1Br^Ds(wF)|oZ7W+-kF zW27J?o@IHuCK3!63(CDK1&qDk2o)ySEYka3v@ Date: Tue, 21 Jan 2020 13:43:39 -0600 Subject: [PATCH 22/45] Release 0.2.9 --- README.md | 6 +++--- examples/pom.xml | 2 +- gen/pom.xml | 4 ++-- pom.xml | 7 ++++--- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 398738e..6c79ee7 100644 --- a/README.md +++ b/README.md @@ -40,20 +40,20 @@ additions to the SoftLayer API. com.softlayer.api softlayer-api-client - 0.2.8 + 0.2.9 ``` ### Gradle ```groovy -implementation 'com.softlayer.api:softlayer-api-client:0.2.8' +implementation 'com.softlayer.api:softlayer-api-client:0.2.9' ``` ### Kotlin ```kotlin -compile("com.softlayer.api:softlayer-api-client:0.2.8") +compile("com.softlayer.api:softlayer-api-client:0.2.9") ``` ### Creating a Client diff --git a/examples/pom.xml b/examples/pom.xml index 38b3175..b9d43ba 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -5,7 +5,7 @@ softlayer-api-client-examples jar - 0.2.8 + 0.2.9 softlayer-api-client-examples http://sldn.softlayer.com diff --git a/gen/pom.xml b/gen/pom.xml index 08bed14..005927a 100644 --- a/gen/pom.xml +++ b/gen/pom.xml @@ -5,7 +5,7 @@ softlayer-api-client-gen jar - 0.2.8 + 0.2.9 softlayer-api-client-gen http://sldn.softlayer.com @@ -34,7 +34,7 @@ junit junit - 4.12 + 4.13 test diff --git a/pom.xml b/pom.xml index aca1da3..b1854bf 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ softlayer-api-client jar - 0.2.8 + 0.2.9 SoftLayer API Client for Java API client for accessing the SoftLayer API http://sldn.softlayer.com @@ -41,7 +41,7 @@ scm:git:git@github.com:softlayer/softlayer-java.git scm:git:git@github.com:softlayer/softlayer-java.git git@github.com:softlayer/softlayer-java.git - 0.2.8 + 0.2.9 UTF-8 @@ -72,7 +72,7 @@ junit junit - 4.12 + 4.13 test @@ -115,6 +115,7 @@ none ${java.version} + --allow-script-in-comments From dd5d0232524db013d8d2d00284008b086d873fcf Mon Sep 17 00:00:00 2001 From: Cameron Porter Date: Mon, 23 Mar 2020 18:01:24 -0500 Subject: [PATCH 23/45] Allow type coercion when determining APi types When we read objects from the API, we want to ensure the type matches either the type class that the client is aware of, or whatever the complexType property on the object tells us. In some cases, the API returns a type for a property that is not the same or a subtype of the type defined by the API. The API should not do this, however the previous behavior was to throw an exception in these cases, which is quite annoying. Instead, we will now coerce the object we get into the type that the definition says. If properties are missing, they will remain unset, and any extra properties will be added to the unknown properties. --- .../api/json/GsonJsonMarshallerFactory.java | 14 +-- .../json/GsonJsonMarshallerFactoryTest.java | 95 ++++++++++++++++--- .../com/softlayer/api/service/TestEntity.java | 1 - .../com/softlayer/api/service/TestThing.java | 2 + 4 files changed, 87 insertions(+), 25 deletions(-) diff --git a/src/main/java/com/softlayer/api/json/GsonJsonMarshallerFactory.java b/src/main/java/com/softlayer/api/json/GsonJsonMarshallerFactory.java index f77eb2b..e47d558 100644 --- a/src/main/java/com/softlayer/api/json/GsonJsonMarshallerFactory.java +++ b/src/main/java/com/softlayer/api/json/GsonJsonMarshallerFactory.java @@ -14,12 +14,8 @@ import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Base64; -import java.util.GregorianCalendar; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; +import java.util.function.Supplier; import com.google.gson.Gson; import com.google.gson.GsonBuilder; @@ -191,12 +187,12 @@ public Entity read(JsonReader in) throws IOException { // we're an adapter for. So if we have SoftLayer_Something and a newer release of the // API has a type extending it but we don't have a generated class for it, it will get // properly serialized to a SoftLayer_Something. + // If the API returns a type that isn't the same or a subtype of the type class, + // try as best we can to fit the data within the type class. Class clazz = typeClasses.get(apiTypeName); Entity result; - if (clazz == null) { + if (clazz == null || !typeClass.isAssignableFrom(clazz)) { result = readForThisType(in); - } else if (!typeClass.isAssignableFrom(clazz)) { - throw new RuntimeException("Expecting " + typeClass + " to be super type of " + clazz); } else { result = ((EntityTypeAdapter) gson.getAdapter(clazz)).readForThisType(in); } diff --git a/src/test/java/com/softlayer/api/json/GsonJsonMarshallerFactoryTest.java b/src/test/java/com/softlayer/api/json/GsonJsonMarshallerFactoryTest.java index 06ea291..5233db7 100644 --- a/src/test/java/com/softlayer/api/json/GsonJsonMarshallerFactoryTest.java +++ b/src/test/java/com/softlayer/api/json/GsonJsonMarshallerFactoryTest.java @@ -21,6 +21,7 @@ import com.google.gson.reflect.TypeToken; import com.softlayer.api.service.Entity; import com.softlayer.api.service.TestEntity; +import com.softlayer.api.service.TestThing; public class GsonJsonMarshallerFactoryTest { @@ -51,21 +52,22 @@ private String toJson(Object obj) throws Exception { public void testRead() throws Exception { Entity entity = fromJson(Entity.class, "{" - + "\"complexType\": \"SoftLayer_TestEntity\"," - + "\"bar\": \"some string\"," - + "\"foo\": \"another string\"," - + "\"baz\": null," - + "\"date\": \"1984-02-25T20:15:25-06:00\"," - + "\"notApiProperty\": \"bad value\"," - + "\"child\": {" - + " \"complexType\": \"SoftLayer_TestEntity\"," - + " \"bar\": \"child string\"" - + "}," - + "\"moreChildren\": [" - + " { \"complexType\": \"SoftLayer_TestEntity\", \"bar\": \"child 1\" }," - + " { \"complexType\": \"SoftLayer_TestEntity\", \"bar\": \"child 2\" }" - + "]" - + "}"); + + "\"complexType\": \"SoftLayer_TestEntity\"," + + "\"bar\": \"some string\"," + + "\"foo\": \"another string\"," + + "\"baz\": null," + + "\"date\": \"1984-02-25T20:15:25-06:00\"," + + "\"notApiProperty\": \"bad value\"," + + "\"child\": {" + + " \"complexType\": \"SoftLayer_TestEntity\"," + + " \"bar\": \"child string\"" + + "}," + + "\"moreChildren\": [" + + " { \"complexType\": \"SoftLayer_TestEntity\", \"bar\": \"child 1\" }," + + " { \"complexType\": \"SoftLayer_TestEntity\", \"bar\": \"child 2\" }" + + "]," + + "\"testThing\": {\"complexType\": \"SoftLayer_TestThing\", \"id\": 123}" + + "}"); assertEquals(TestEntity.class, entity.getClass()); TestEntity obj = (TestEntity) entity; assertEquals("some string", obj.getFoo()); @@ -85,6 +87,69 @@ public void testRead() throws Exception { assertEquals(2, obj.getMoreChildren().size()); assertEquals("child 1", obj.getMoreChildren().get(0).getFoo()); assertEquals("child 2", obj.getMoreChildren().get(1).getFoo()); + assertEquals(TestThing.class, obj.getTestThing().getClass()); + assertEquals(123, obj.getTestThing().getId().intValue()); + } + + @Test + public void testReadPropertyWithIncorrectComplexTypeCoercesTheType() throws Exception { + Entity entity = fromJson(Entity.class, + "{" + + "\"complexType\": \"SoftLayer_TestEntity\"," + + "\"testThing\": {\"complexType\": \"SoftLayer_TestEntity\", \"id\": 123, \"foo\": \"unknown!\"}" + + "}"); + assertEquals(TestEntity.class, entity.getClass()); + TestEntity obj = (TestEntity) entity; + assertEquals(0, obj.getUnknownProperties().size()); + assertEquals(TestThing.class, obj.getTestThing().getClass()); + assertEquals(123, obj.getTestThing().getId().intValue()); + assertEquals(1, obj.getTestThing().getUnknownProperties().size()); + assertEquals("unknown!", obj.getTestThing().getUnknownProperties().get("foo")); + } + + + @Test + public void testReadPropertyWithUnknownComplexTypeCoercesTheType() throws Exception { + Entity entity = fromJson(Entity.class, + "{" + + "\"complexType\": \"SoftLayer_TestEntity\"," + + "\"testThing\": {\"complexType\": \"WhoKnows\", \"id\": 123, \"foo\": \"unknown!\"}" + + "}"); + assertEquals(TestEntity.class, entity.getClass()); + TestEntity obj = (TestEntity) entity; + assertEquals(0, obj.getUnknownProperties().size()); + assertEquals(TestThing.class, obj.getTestThing().getClass()); + assertEquals(123, obj.getTestThing().getId().intValue()); + assertEquals(1, obj.getTestThing().getUnknownProperties().size()); + assertEquals("unknown!", obj.getTestThing().getUnknownProperties().get("foo")); + } + + @Test + public void testReadPropertyThrowsExceptionWithoutComplexType() { + + Exception e = assertThrows(RuntimeException.class, () -> { + Entity entity = fromJson(Entity.class, + "{" + + "\"complexType\": \"SoftLayer_TestEntity\"," + + "\"testThing\": {\"id\": 123}" + + "}"); + }); + + assertEquals("Expected 'complexType' as first property", e.getMessage()); + } + + @Test + public void testReadPropertyThrowsExceptioWithComplexTypeNotFirst() { + + Exception e = assertThrows(RuntimeException.class, () -> { + Entity entity = fromJson(Entity.class, + "{" + + "\"testThing\": {\"id\": 123}," + + "\"complexType\": \"SoftLayer_TestEntity\"" + + "}"); + }); + + assertEquals("Expected 'complexType' as first property", e.getMessage()); } @Test diff --git a/src/test/java/com/softlayer/api/service/TestEntity.java b/src/test/java/com/softlayer/api/service/TestEntity.java index ce85bf6..df3f7d8 100644 --- a/src/test/java/com/softlayer/api/service/TestEntity.java +++ b/src/test/java/com/softlayer/api/service/TestEntity.java @@ -11,7 +11,6 @@ import com.softlayer.api.annotation.ApiType; import com.softlayer.api.ApiClient; import com.softlayer.api.ResponseHandler; -import com.softlayer.api.ResultLimit; @ApiType("SoftLayer_TestEntity") public class TestEntity extends Entity { diff --git a/src/test/java/com/softlayer/api/service/TestThing.java b/src/test/java/com/softlayer/api/service/TestThing.java index 2eac363..548b87c 100644 --- a/src/test/java/com/softlayer/api/service/TestThing.java +++ b/src/test/java/com/softlayer/api/service/TestThing.java @@ -10,7 +10,9 @@ import com.softlayer.api.annotation.ApiMethod; import com.softlayer.api.annotation.ApiProperty; import com.softlayer.api.annotation.ApiService; +import com.softlayer.api.annotation.ApiType; +@ApiType("SoftLayer_TestThing") public class TestThing extends Entity { @ApiProperty(canBeNullOrNotSet = true) From 5c1a5a1b112af06530ca94cd9bb6ed01704ad0dc Mon Sep 17 00:00:00 2001 From: Cameron Porter Date: Wed, 25 Mar 2020 10:06:23 -0500 Subject: [PATCH 24/45] Update RestApiClient docs and add a BASE_SERVICE_URL constant. --- src/main/java/com/softlayer/api/RestApiClient.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/main/java/com/softlayer/api/RestApiClient.java b/src/main/java/com/softlayer/api/RestApiClient.java index 5c11e2e..f587b33 100644 --- a/src/main/java/com/softlayer/api/RestApiClient.java +++ b/src/main/java/com/softlayer/api/RestApiClient.java @@ -30,7 +30,15 @@ */ public class RestApiClient implements ApiClient { + /** + * The publically available API URL. + */ public static final String BASE_URL = "https://api.softlayer.com/rest/v3.1/"; + + /** + * The API URL that should be used when connecting via the softlayer/classic infrastructure private network. + */ + public static final String BASE_SERVICE_URL = "https://api.service.softlayer.com/rest/v3.1/"; static final String BASE_PKG = Entity.class.getPackage().getName(); @@ -58,6 +66,9 @@ public class RestApiClient implements ApiClient { private boolean loggingEnabled = false; private HttpBasicAuthCredentials credentials; + /** + * Create a Rest client that uses the publically available API. + */ public RestApiClient() { this(BASE_URL); } From 4b6df6f494464437374d0bc2c3f9906de3005086 Mon Sep 17 00:00:00 2001 From: Cameron Porter Date: Wed, 25 Mar 2020 10:13:02 -0500 Subject: [PATCH 25/45] Update README with service API information. --- README.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6c79ee7..e963476 100644 --- a/README.md +++ b/README.md @@ -68,7 +68,14 @@ ApiClient client = new RestApiClient().withCredentials("my user", "my api key"); ``` If the end point isn't at the normal SoftLayer API, you can provide the prefix to the constructor of the -`RestApiClient`. By default it is set to `https://api.softlayer.com/rest/v3.1/`. +`RestApiClient`. By default it is set to the public API endpoint, `https://api.softlayer.com/rest/v3.1/`. + +If you are using the classic infrastructure private network, you can communicate with the API over that network by using the service URL instead: + +```java +ApiClient client = new RestApiClient(RestApiClient.BASE_SERVICE_URL) + .withCredentials("my user", "my api key"); +``` ### Making API Calls From 5eace401e1a1954760d32ddafc33cf77bfb5059f Mon Sep 17 00:00:00 2001 From: Cameron Porter Date: Wed, 25 Mar 2020 12:15:00 -0500 Subject: [PATCH 26/45] Release version 0.3.0 --- README.md | 6 +++--- examples/pom.xml | 2 +- gen/pom.xml | 2 +- pom.xml | 6 +++--- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index e963476..95261b2 100644 --- a/README.md +++ b/README.md @@ -40,20 +40,20 @@ additions to the SoftLayer API. com.softlayer.api softlayer-api-client - 0.2.9 + 0.3.0 ``` ### Gradle ```groovy -implementation 'com.softlayer.api:softlayer-api-client:0.2.9' +implementation 'com.softlayer.api:softlayer-api-client:0.3.0' ``` ### Kotlin ```kotlin -compile("com.softlayer.api:softlayer-api-client:0.2.9") +compile("com.softlayer.api:softlayer-api-client:0.3.0") ``` ### Creating a Client diff --git a/examples/pom.xml b/examples/pom.xml index b9d43ba..9cf4371 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -5,7 +5,7 @@ softlayer-api-client-examples jar - 0.2.9 + 0.3.0 softlayer-api-client-examples http://sldn.softlayer.com diff --git a/gen/pom.xml b/gen/pom.xml index 005927a..58a5eb2 100644 --- a/gen/pom.xml +++ b/gen/pom.xml @@ -5,7 +5,7 @@ softlayer-api-client-gen jar - 0.2.9 + 0.3.0 softlayer-api-client-gen http://sldn.softlayer.com diff --git a/pom.xml b/pom.xml index b1854bf..f003f80 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ softlayer-api-client jar - 0.2.9 + 0.3.0 SoftLayer API Client for Java API client for accessing the SoftLayer API http://sldn.softlayer.com @@ -41,7 +41,7 @@ scm:git:git@github.com:softlayer/softlayer-java.git scm:git:git@github.com:softlayer/softlayer-java.git git@github.com:softlayer/softlayer-java.git - 0.2.9 + 0.3.0 UTF-8 @@ -78,7 +78,7 @@ org.mockito mockito-core - 2.28.2 + 3.3.3 test From 8a0e0d36ee7c7c7563c572e18f7866612c90f2a7 Mon Sep 17 00:00:00 2001 From: Cameron Porter Date: Wed, 25 Mar 2020 14:59:41 -0500 Subject: [PATCH 27/45] Use shields.io for maven badge. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 95261b2..6612f93 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # SoftLayer API Client for Java [![Build Status](https://travis-ci.org/softlayer/softlayer-java.svg)](https://travis-ci.org/softlayer/softlayer-java) -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.softlayer.api/softlayer-api-client/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.softlayer.api/softlayer-api-client) +[![Maven Central](https://img.shields.io/maven-central/v/com.softlayer.api/softlayer-api-client)](https://search.maven.org/artifact/com.softlayer.api/softlayer-api-client) [![Javadocs](https://www.javadoc.io/badge/com.softlayer.api/softlayer-api-client.svg)](https://www.javadoc.io/doc/com.softlayer.api/softlayer-api-client) ## Introduction From 961e406f2f51394681e674e35fa52b57e7c587e2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Oct 2020 02:47:46 +0000 Subject: [PATCH 28/45] Bump junit from 4.13 to 4.13.1 Bumps [junit](https://github.com/junit-team/junit4) from 4.13 to 4.13.1. - [Release notes](https://github.com/junit-team/junit4/releases) - [Changelog](https://github.com/junit-team/junit4/blob/main/doc/ReleaseNotes4.13.1.md) - [Commits](https://github.com/junit-team/junit4/compare/r4.13...r4.13.1) Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f003f80..8bb7ed9 100644 --- a/pom.xml +++ b/pom.xml @@ -72,7 +72,7 @@ junit junit - 4.13 + 4.13.1 test From 280931d170b2ff1a8c34ebc990cd9094270259e1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Oct 2020 02:51:11 +0000 Subject: [PATCH 29/45] Bump junit from 4.13 to 4.13.1 in /gen Bumps [junit](https://github.com/junit-team/junit4) from 4.13 to 4.13.1. - [Release notes](https://github.com/junit-team/junit4/releases) - [Changelog](https://github.com/junit-team/junit4/blob/main/doc/ReleaseNotes4.13.1.md) - [Commits](https://github.com/junit-team/junit4/compare/r4.13...r4.13.1) Signed-off-by: dependabot[bot] --- gen/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gen/pom.xml b/gen/pom.xml index 58a5eb2..c646e34 100644 --- a/gen/pom.xml +++ b/gen/pom.xml @@ -34,7 +34,7 @@ junit junit - 4.13 + 4.13.1 test From b70f9535dc1dea23a084a360aea0ae0ffb1e1dea Mon Sep 17 00:00:00 2001 From: Cameron Porter Date: Mon, 9 Nov 2020 15:34:30 -0600 Subject: [PATCH 30/45] Release 0.3.1 --- README.md | 6 +++--- examples/pom.xml | 2 +- gen/pom.xml | 4 ++-- pom.xml | 15 +++++++-------- 4 files changed, 13 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 6612f93..2563f68 100644 --- a/README.md +++ b/README.md @@ -40,20 +40,20 @@ additions to the SoftLayer API. com.softlayer.api softlayer-api-client - 0.3.0 + 0.3.1 ``` ### Gradle ```groovy -implementation 'com.softlayer.api:softlayer-api-client:0.3.0' +implementation 'com.softlayer.api:softlayer-api-client:0.3.1' ``` ### Kotlin ```kotlin -compile("com.softlayer.api:softlayer-api-client:0.3.0") +compile("com.softlayer.api:softlayer-api-client:0.3.1") ``` ### Creating a Client diff --git a/examples/pom.xml b/examples/pom.xml index 9cf4371..21d766c 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -5,7 +5,7 @@ softlayer-api-client-examples jar - 0.3.0 + 0.3.1 softlayer-api-client-examples http://sldn.softlayer.com diff --git a/gen/pom.xml b/gen/pom.xml index c646e34..f1becb3 100644 --- a/gen/pom.xml +++ b/gen/pom.xml @@ -5,7 +5,7 @@ softlayer-api-client-gen jar - 0.3.0 + 0.3.1 softlayer-api-client-gen http://sldn.softlayer.com @@ -29,7 +29,7 @@ com.google.code.gson gson - 2.8.5 + 2.8.6 junit diff --git a/pom.xml b/pom.xml index 8bb7ed9..ac69f4e 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ softlayer-api-client jar - 0.3.0 + 0.3.1 SoftLayer API Client for Java API client for accessing the SoftLayer API http://sldn.softlayer.com @@ -27,9 +27,8 @@ camporter Cameron Porter - cmporter@softlayer.com - SoftLayer - http://softlayer.com + IBM + http://ibm.com/cloud owner developer @@ -41,7 +40,7 @@ scm:git:git@github.com:softlayer/softlayer-java.git scm:git:git@github.com:softlayer/softlayer-java.git git@github.com:softlayer/softlayer-java.git - 0.3.0 + 0.3.1 UTF-8 @@ -50,7 +49,7 @@ jcenter - http://jcenter.bintray.com/ + https://jcenter.bintray.com/ @@ -67,7 +66,7 @@ com.google.code.gson gson - 2.8.5 + 2.8.6 junit @@ -78,7 +77,7 @@ org.mockito mockito-core - 3.3.3 + 3.6.0 test From 94db1a6eeaf4fca2ec44263b25f66d93d086d460 Mon Sep 17 00:00:00 2001 From: cmp Date: Thu, 19 Nov 2020 19:22:52 -0600 Subject: [PATCH 31/45] Add maven workflow action --- .github/workflows/maven.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 .github/workflows/maven.yml diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml new file mode 100644 index 0000000..6f18e58 --- /dev/null +++ b/.github/workflows/maven.yml @@ -0,0 +1,20 @@ +name: Java CI + +on: + push: + branches: [ master ] + pull_request: +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + java: [8, 11, 15] + steps: + - uses: actions/checkout@v2 + - name: Set up JDK + uses: actions/setup-java@v1 + with: + java-version: ${{matrix.java}} + - name: Build with Maven + run: mvn -B package --file pom.xml From d51f8a17a2e63690ce6bf1328634877b75e34315 Mon Sep 17 00:00:00 2001 From: cmp Date: Tue, 8 Dec 2020 17:28:11 -0600 Subject: [PATCH 32/45] Replace travisci badge with github actions --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2563f68..34b8046 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # SoftLayer API Client for Java -[![Build Status](https://travis-ci.org/softlayer/softlayer-java.svg)](https://travis-ci.org/softlayer/softlayer-java) +![Java CI](https://github.com/softlayer/softlayer-java/workflows/Java%20CI/badge.svg) [![Maven Central](https://img.shields.io/maven-central/v/com.softlayer.api/softlayer-api-client)](https://search.maven.org/artifact/com.softlayer.api/softlayer-api-client) [![Javadocs](https://www.javadoc.io/badge/com.softlayer.api/softlayer-api-client.svg)](https://www.javadoc.io/doc/com.softlayer.api/softlayer-api-client) From c0cf8e9107fa521f45c9b7da37639990992e4fbc Mon Sep 17 00:00:00 2001 From: Christopher Gallo Date: Mon, 4 Jan 2021 16:41:23 -0600 Subject: [PATCH 33/45] #70 examples for Bearer Authentication --- .../com/softlayer/api/example/Example.java | 9 +++++- .../com/softlayer/api/example/QuickTest.java | 28 +++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 examples/src/main/java/com/softlayer/api/example/QuickTest.java diff --git a/examples/src/main/java/com/softlayer/api/example/Example.java b/examples/src/main/java/com/softlayer/api/example/Example.java index db2d386..32566fc 100644 --- a/examples/src/main/java/com/softlayer/api/example/Example.java +++ b/examples/src/main/java/com/softlayer/api/example/Example.java @@ -17,7 +17,14 @@ public void start(String[] args) throws Exception { baseUrl += '/'; } - run(new RestApiClient(baseUrl).withCredentials(args[0], args[1])); + RestApiClient client; + // mvn -e -q compile exec:java -Dexec.args="QuickTest Bearer eyJraWQ..... + if (args[0].trim().equals("Bearer")) { + client = new RestApiClient(baseUrl).withBearerToken(args[1]); + } else { + client = new RestApiClient(baseUrl).withCredentials(args[0], args[1]); + } + run(client); } /** Run the example with the given client */ diff --git a/examples/src/main/java/com/softlayer/api/example/QuickTest.java b/examples/src/main/java/com/softlayer/api/example/QuickTest.java new file mode 100644 index 0000000..24701da --- /dev/null +++ b/examples/src/main/java/com/softlayer/api/example/QuickTest.java @@ -0,0 +1,28 @@ +package com.softlayer.api.example; + +import com.softlayer.api.ApiClient; +import com.softlayer.api.RestApiClient; +import com.softlayer.api.service.Account; + + +/** A quick example for testing if authentication works. + +cd softlayer-java/examples +mvn -e -q compile exec:java -Dexec.args="QuickTest Bearer eyJraWQ..... +*/ +public class QuickTest extends Example { + + @Override + public void run(ApiClient client) throws Exception { + client.withLoggingEnabled(); + System.out.format("Authorization: %s\n", client.getCredentials()); + Account.Service service = Account.service(client); + + Account account = service.getObject(); + System.out.format("Account Name: %s\n", account.getCompanyName()); + } + + public static void main(String[] args) throws Exception { + new QuickTest().start(args); + } +} From 0cdfb8d1c3845ad77569df8e66977595c5f8dacb Mon Sep 17 00:00:00 2001 From: Christopher Gallo Date: Mon, 4 Jan 2021 16:42:50 -0600 Subject: [PATCH 34/45] #70 support for Bearer HTTP authorization --- .../java/com/softlayer/api/ApiClient.java | 25 ++++++++++++++++++- .../java/com/softlayer/api/RestApiClient.java | 14 +++++++++-- .../api/http/BuiltInHttpClientFactory.java | 8 ++---- .../api/http/HttpBearerCredentials.java | 20 +++++++++++++++ .../softlayer/api/http/HttpCredentials.java | 1 + .../http/BuiltInHttpClientFactoryTest.java | 15 ----------- .../api/http/HttpBearerCredentialsTest.java | 22 ++++++++++++++++ 7 files changed, 81 insertions(+), 24 deletions(-) create mode 100644 src/main/java/com/softlayer/api/http/HttpBearerCredentials.java create mode 100644 src/test/java/com/softlayer/api/http/HttpBearerCredentialsTest.java diff --git a/src/main/java/com/softlayer/api/ApiClient.java b/src/main/java/com/softlayer/api/ApiClient.java index 092d686..a637995 100644 --- a/src/main/java/com/softlayer/api/ApiClient.java +++ b/src/main/java/com/softlayer/api/ApiClient.java @@ -1,5 +1,7 @@ package com.softlayer.api; +import com.softlayer.api.http.HttpCredentials; + /** Common interface for all API clients. {@link RestApiClient} is the preferred implementation */ public interface ApiClient { @@ -9,7 +11,28 @@ public interface ApiClient { * @return This instance */ ApiClient withCredentials(String username, String apiKey); - + + /** + * Uses a HTTP Bearer token for authentication instead of API key. + * + * @return This instance + */ + ApiClient withBearerToken(String token); + + /** + * Enables logging for client API calls + * + * @return This instance + */ + ApiClient withLoggingEnabled(); + + /** + * Returns the HTTP Authorization header + * + * @return This instance + */ + HttpCredentials getCredentials(); + /** * Get a service for the given sets of classes and optional ID. It is not recommended to call this * directly, but rather invoke the service method on the type class. diff --git a/src/main/java/com/softlayer/api/RestApiClient.java b/src/main/java/com/softlayer/api/RestApiClient.java index f587b33..43450c8 100644 --- a/src/main/java/com/softlayer/api/RestApiClient.java +++ b/src/main/java/com/softlayer/api/RestApiClient.java @@ -18,7 +18,9 @@ import com.softlayer.api.annotation.ApiMethod; import com.softlayer.api.annotation.ApiService; +import com.softlayer.api.http.HttpCredentials; import com.softlayer.api.http.HttpBasicAuthCredentials; +import com.softlayer.api.http.HttpBearerCredentials; import com.softlayer.api.http.HttpClient; import com.softlayer.api.http.HttpClientFactory; import com.softlayer.api.http.HttpResponse; @@ -64,7 +66,7 @@ public class RestApiClient implements ApiClient { private HttpClientFactory httpClientFactory; private JsonMarshallerFactory jsonMarshallerFactory; private boolean loggingEnabled = false; - private HttpBasicAuthCredentials credentials; + private HttpCredentials credentials; /** * Create a Rest client that uses the publically available API. @@ -114,6 +116,7 @@ public void setLoggingEnabled(boolean loggingEnabled) { this.loggingEnabled = loggingEnabled; } + @Override public RestApiClient withLoggingEnabled() { this.loggingEnabled = true; return this; @@ -141,7 +144,14 @@ public RestApiClient withCredentials(String username, String apiKey) { return this; } - public HttpBasicAuthCredentials getCredentials() { + @Override + public RestApiClient withBearerToken(String token) { + credentials = new HttpBearerCredentials(token); + return this; + } + + @Override + public HttpCredentials getCredentials() { return credentials; } diff --git a/src/main/java/com/softlayer/api/http/BuiltInHttpClientFactory.java b/src/main/java/com/softlayer/api/http/BuiltInHttpClientFactory.java index 5cf49f0..2d96b32 100644 --- a/src/main/java/com/softlayer/api/http/BuiltInHttpClientFactory.java +++ b/src/main/java/com/softlayer/api/http/BuiltInHttpClientFactory.java @@ -89,7 +89,7 @@ public void setThreadPool(ExecutorService threadPool) { class BuiltInHttpClient implements HttpClient, HttpResponse { - final HttpBasicAuthCredentials credentials; + final HttpCredentials credentials; final String method; final String fullUrl; final Map> headers; @@ -101,11 +101,7 @@ public BuiltInHttpClient( String fullUrl, Map> headers ) { - // We only support basic auth - if (credentials != null && !(credentials instanceof HttpBasicAuthCredentials)) { - throw new UnsupportedOperationException("Only basic auth is supported, not " + credentials.getClass()); - } - this.credentials = (HttpBasicAuthCredentials) credentials; + this.credentials = credentials; this.method = method; this.fullUrl = fullUrl; this.headers = headers; diff --git a/src/main/java/com/softlayer/api/http/HttpBearerCredentials.java b/src/main/java/com/softlayer/api/http/HttpBearerCredentials.java new file mode 100644 index 0000000..fd80aa1 --- /dev/null +++ b/src/main/java/com/softlayer/api/http/HttpBearerCredentials.java @@ -0,0 +1,20 @@ +package com.softlayer.api.http; + +/** HTTP bearer authorization support for bearer token fromhttps://iam.cloud.ibm.com/identity/token */ +public class HttpBearerCredentials implements HttpCredentials { + + public final String token; + + public HttpBearerCredentials(String token) { + this.token = token; + } + + /** + * Formats the token into a HTTP Authorization header. + * + * @return String + */ + public String getHeader() { + return "Bearer " + token; + } +} diff --git a/src/main/java/com/softlayer/api/http/HttpCredentials.java b/src/main/java/com/softlayer/api/http/HttpCredentials.java index a0ae093..a588f83 100644 --- a/src/main/java/com/softlayer/api/http/HttpCredentials.java +++ b/src/main/java/com/softlayer/api/http/HttpCredentials.java @@ -2,4 +2,5 @@ /** Base interface for all accepted HTTP credentials */ public interface HttpCredentials { + public String getHeader(); } diff --git a/src/test/java/com/softlayer/api/http/BuiltInHttpClientFactoryTest.java b/src/test/java/com/softlayer/api/http/BuiltInHttpClientFactoryTest.java index ee40c56..75ff90f 100644 --- a/src/test/java/com/softlayer/api/http/BuiltInHttpClientFactoryTest.java +++ b/src/test/java/com/softlayer/api/http/BuiltInHttpClientFactoryTest.java @@ -15,21 +15,6 @@ public class BuiltInHttpClientFactoryTest { - @Test - public void testGetHttpClientWithoutBasicAuth() { - try { - new BuiltInHttpClientFactory().getHttpClient( - new HttpCredentials() { }, - "GET", - "http://example.com", - Collections.emptyMap() - ); - fail(); - } catch (UnsupportedOperationException e) { - assertTrue(e.getMessage().contains("basic auth")); - } - } - @Test public void testGetThreadPoolDefaultsToDaemonThreads() throws Exception { boolean daemon = new BuiltInHttpClientFactory().getThreadPool().submit( diff --git a/src/test/java/com/softlayer/api/http/HttpBearerCredentialsTest.java b/src/test/java/com/softlayer/api/http/HttpBearerCredentialsTest.java new file mode 100644 index 0000000..0a1d67d --- /dev/null +++ b/src/test/java/com/softlayer/api/http/HttpBearerCredentialsTest.java @@ -0,0 +1,22 @@ +package com.softlayer.api.http; + +import static org.junit.Assert.*; + +import org.junit.Test; + +public class HttpBearerCredentialsTest { + + public final String bearerToken = "qqqqwwwweeerrttyyuuiiooppasddfgfgjghjkjklZXxcvcvbvbnnbm"; + @Test + public void testConstructor() { + HttpBearerCredentials authCredentials = new HttpBearerCredentials(bearerToken); + assertEquals(bearerToken, authCredentials.token); + } + + @Test + public void testGetHeader() { + HttpBearerCredentials authCredentials = new HttpBearerCredentials(bearerToken); + String header = "Bearer " + bearerToken; + assertEquals(header, authCredentials.getHeader()); + } +} From 194e7166f667622fa858f208f404b92eb5e45ce5 Mon Sep 17 00:00:00 2001 From: Christopher Gallo Date: Tue, 5 Jan 2021 16:37:02 -0600 Subject: [PATCH 35/45] #70 added code coverage tool to pom.xml, and a BuiltinHttpClientFactoryTest test --- README.md | 20 ++++++++++--- pom.xml | 28 +++++++++++++++++-- .../http/BuiltInHttpClientFactoryTest.java | 8 ++++++ 3 files changed, 50 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 34b8046..ca73258 100644 --- a/README.md +++ b/README.md @@ -40,20 +40,20 @@ additions to the SoftLayer API. com.softlayer.api softlayer-api-client - 0.3.1 + 0.3.2 ``` ### Gradle ```groovy -implementation 'com.softlayer.api:softlayer-api-client:0.3.1' +implementation 'com.softlayer.api:softlayer-api-client:0.3.2' ``` ### Kotlin ```kotlin -compile("com.softlayer.api:softlayer-api-client:0.3.1") +compile("com.softlayer.api:softlayer-api-client:0.3.2") ``` ### Creating a Client @@ -61,12 +61,24 @@ compile("com.softlayer.api:softlayer-api-client:0.3.1") All clients are instances of `ApiClient`. Currently there is only one implementation, the `RestApiClient`. Simply instantiate it and provide your credentials: + +#### Username and API Key +For using a Classic Infrastructure or IBM Cloud API key. When using the IBM Cloud Api key, your username is litterally `apikey`, more information about that can be found on the SLDN [Authenticating to the SoftLayer API](https://sldn.softlayer.com/article/authenticating-softlayer-api/#cloud-api) article. + ```java import com.softlayer.api.*; ApiClient client = new RestApiClient().withCredentials("my user", "my api key"); ``` +#### Acesses Token +Information on how to get a temoprary api token can be found on the SLDN [Authenticating to the SoftLayer API](https://sldn.softlayer.com/article/authenticating-softlayer-api/#temp-token) article. + +```java +import com.softlayer.api.*; +ApiClient client = new RestApiClient().withBearerToken("qqqqwwwweeeaaassddd...."); +``` + If the end point isn't at the normal SoftLayer API, you can provide the prefix to the constructor of the `RestApiClient`. By default it is set to the public API endpoint, `https://api.softlayer.com/rest/v3.1/`. @@ -296,4 +308,4 @@ fully qualified class name of your implementation on a single line in a file in ## Copyright -This software is Copyright (c) 2020 The SoftLayer Developer Network. See the bundled LICENSE file for more information. +This software is Copyright (c) 2021 The SoftLayer Developer Network. See the bundled LICENSE file for more information. diff --git a/pom.xml b/pom.xml index ac69f4e..32ae219 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ softlayer-api-client jar - 0.3.1 + 0.3.2 SoftLayer API Client for Java API client for accessing the SoftLayer API http://sldn.softlayer.com @@ -40,7 +40,7 @@ scm:git:git@github.com:softlayer/softlayer-java.git scm:git:git@github.com:softlayer/softlayer-java.git git@github.com:softlayer/softlayer-java.git - 0.3.1 + 0.3.2 UTF-8 @@ -161,6 +161,30 @@ + + org.jacoco + jacoco-maven-plugin + 0.8.6 + + + **/*com/softlayer/api/service/**/* + + + + + + prepare-agent + + + + report + prepare-package + + report + + + + diff --git a/src/test/java/com/softlayer/api/http/BuiltInHttpClientFactoryTest.java b/src/test/java/com/softlayer/api/http/BuiltInHttpClientFactoryTest.java index 75ff90f..15a355c 100644 --- a/src/test/java/com/softlayer/api/http/BuiltInHttpClientFactoryTest.java +++ b/src/test/java/com/softlayer/api/http/BuiltInHttpClientFactoryTest.java @@ -23,6 +23,14 @@ public void testGetThreadPoolDefaultsToDaemonThreads() throws Exception { assertTrue(daemon); } + @Test + public void testGetThreadPoolLazyLoading() { + BuiltInHttpClientFactory factory = new BuiltInHttpClientFactory(); + ExecutorService threadPool = factory.getThreadPool(); + assertNotNull(threadPool); + assertEquals(threadPool, factory.getThreadPool()); + } + @Test public void testSetThreadPoolShutsDownNonUserDefined() { BuiltInHttpClientFactory factory = new BuiltInHttpClientFactory(); From 80ed0e74cb3286d4b530934ed7f43dbf0b80aa66 Mon Sep 17 00:00:00 2001 From: Christopher Gallo Date: Thu, 7 Jan 2021 13:03:32 -0600 Subject: [PATCH 36/45] cleared up some documentation for BearerAuthorization --- README.md | 2 +- .../com/softlayer/api/http/HttpBearerCredentials.java | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index ca73258..1944b81 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ instantiate it and provide your credentials: #### Username and API Key -For using a Classic Infrastructure or IBM Cloud API key. When using the IBM Cloud Api key, your username is litterally `apikey`, more information about that can be found on the SLDN [Authenticating to the SoftLayer API](https://sldn.softlayer.com/article/authenticating-softlayer-api/#cloud-api) article. +For using a Classic Infrastructure or IBM Cloud API key. When using the IBM Cloud Api key, your username is the literal string `apikey`, more information about that can be found on the SLDN [Authenticating to the SoftLayer API](https://sldn.softlayer.com/article/authenticating-softlayer-api/#cloud-api) article. ```java import com.softlayer.api.*; diff --git a/src/main/java/com/softlayer/api/http/HttpBearerCredentials.java b/src/main/java/com/softlayer/api/http/HttpBearerCredentials.java index fd80aa1..951f4f2 100644 --- a/src/main/java/com/softlayer/api/http/HttpBearerCredentials.java +++ b/src/main/java/com/softlayer/api/http/HttpBearerCredentials.java @@ -1,9 +1,13 @@ package com.softlayer.api.http; -/** HTTP bearer authorization support for bearer token fromhttps://iam.cloud.ibm.com/identity/token */ +/** HTTP Bearer authorization support for IBM IAM Tokens. + * + * @see IAM Tokens + * @see Authenticating SoftLayer API + */ public class HttpBearerCredentials implements HttpCredentials { - public final String token; + protected final String token; public HttpBearerCredentials(String token) { this.token = token; From 1e82fa35d5cca13b11ff2be045fde93ac9ef098a Mon Sep 17 00:00:00 2001 From: Christopher Gallo Date: Thu, 14 Jan 2021 14:45:18 -0600 Subject: [PATCH 37/45] fixed pull request feedback --- LICENSE | 2 +- README.md | 2 +- examples/pom.xml | 2 +- gen/pom.xml | 2 +- src/main/java/com/softlayer/api/http/HttpCredentials.java | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/LICENSE b/LICENSE index d8f5d64..213959f 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2020 The SoftLayer Developer Network +Copyright (c) 2021 The SoftLayer Developer Network Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 1944b81..c99f64f 100644 --- a/README.md +++ b/README.md @@ -71,7 +71,7 @@ import com.softlayer.api.*; ApiClient client = new RestApiClient().withCredentials("my user", "my api key"); ``` -#### Acesses Token +#### Access Token Information on how to get a temoprary api token can be found on the SLDN [Authenticating to the SoftLayer API](https://sldn.softlayer.com/article/authenticating-softlayer-api/#temp-token) article. ```java diff --git a/examples/pom.xml b/examples/pom.xml index 21d766c..7a988fc 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -5,7 +5,7 @@ softlayer-api-client-examples jar - 0.3.1 + 0.3.2 softlayer-api-client-examples http://sldn.softlayer.com diff --git a/gen/pom.xml b/gen/pom.xml index f1becb3..c62354f 100644 --- a/gen/pom.xml +++ b/gen/pom.xml @@ -5,7 +5,7 @@ softlayer-api-client-gen jar - 0.3.1 + 0.3.2 softlayer-api-client-gen http://sldn.softlayer.com diff --git a/src/main/java/com/softlayer/api/http/HttpCredentials.java b/src/main/java/com/softlayer/api/http/HttpCredentials.java index a588f83..a751a46 100644 --- a/src/main/java/com/softlayer/api/http/HttpCredentials.java +++ b/src/main/java/com/softlayer/api/http/HttpCredentials.java @@ -2,5 +2,5 @@ /** Base interface for all accepted HTTP credentials */ public interface HttpCredentials { - public String getHeader(); + String getHeader(); } From 7492c132e5930c0964af1f7ab952fca896e4e26a Mon Sep 17 00:00:00 2001 From: cmp Date: Thu, 21 Jan 2021 10:49:02 -0600 Subject: [PATCH 38/45] Add credential usage warning --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c99f64f..363c06f 100644 --- a/README.md +++ b/README.md @@ -65,10 +65,12 @@ instantiate it and provide your credentials: #### Username and API Key For using a Classic Infrastructure or IBM Cloud API key. When using the IBM Cloud Api key, your username is the literal string `apikey`, more information about that can be found on the SLDN [Authenticating to the SoftLayer API](https://sldn.softlayer.com/article/authenticating-softlayer-api/#cloud-api) article. +:warning: Make sure to avoid hard coding your username and API key when using the client! Always pull credentials from the environment, secure config, or other source. + ```java import com.softlayer.api.*; -ApiClient client = new RestApiClient().withCredentials("my user", "my api key"); +ApiClient client = new RestApiClient().withCredentials(myUser, myApiKey); ``` #### Access Token From 76029c8040c709cc98b95fd1806047bae259a2f8 Mon Sep 17 00:00:00 2001 From: Cameron Porter Date: Tue, 14 Sep 2021 21:41:04 -0500 Subject: [PATCH 39/45] Remove Travis CI config. Prep version 0.3.3. * Update maven workflow and add github pages workflow. * Update dependencies. * Fix links in README and credential misuse examples. --- .github/workflows/maven.yml | 18 ++++++++++-------- .github/workflows/pages.yml | 23 +++++++++++++++++++++++ .travis.yml | 31 ------------------------------- README.md | 26 ++++++++++++++------------ examples/pom.xml | 4 ++-- gen/pom.xml | 10 +++++----- ghpages_secret.enc | Bin 1680 -> 0 bytes pom.xml | 22 +++++++++++----------- 8 files changed, 65 insertions(+), 69 deletions(-) create mode 100644 .github/workflows/pages.yml delete mode 100644 .travis.yml delete mode 100644 ghpages_secret.enc diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 6f18e58..67b51dc 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -9,12 +9,14 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - java: [8, 11, 15] + java: [8, 11, 16] steps: - - uses: actions/checkout@v2 - - name: Set up JDK - uses: actions/setup-java@v1 - with: - java-version: ${{matrix.java}} - - name: Build with Maven - run: mvn -B package --file pom.xml + - name: Checkout + uses: actions/checkout@v2 + - name: Set up JDK + uses: actions/setup-java@v2.3.0 + with: + distribution: 'temurin' + java-version: ${{matrix.java}} + - name: Build with Maven + run: mvn verify -B -e -V --file pom.xml diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml new file mode 100644 index 0000000..3e50206 --- /dev/null +++ b/.github/workflows/pages.yml @@ -0,0 +1,23 @@ +name: Publish Pages +on: + push: + branches: + - master +jobs: + build-and-deploy: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Build + run: | + apt-get update && apt-get install -y pandoc + mkdir ghpages + pandoc -o ghpages/index.html README.md + + - name: Deploy + uses: JamesIves/github-pages-deploy-action@4.1.5 + with: + branch: gh-pages + folder: ghpages diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 6a06ba8..0000000 --- a/.travis.yml +++ /dev/null @@ -1,31 +0,0 @@ -language: java - -addons: - apt: - update: true - packages: - - pandoc - -jdk: - - oraclejdk11 - - openjdk8 - - openjdk9 - - openjdk10 - - openjdk11 - - openjdk12 - -install: - - mvn install -DskipTests=true -Dmaven.javadoc.skip=true -Dgpg.skip=true - - mkdir ghpages - - pandoc -o ghpages/index.html README.md - - openssl aes-256-cbc -K $encrypted_60afd10366bc_key -iv $encrypted_60afd10366bc_iv -in ghpages_secret.enc -out ghpages_secret -d - -deploy: - provider: pages:git - edge: true - skip_cleanup: true - local_dir: ghpages - deploy_key: ghpages_secret - keep_history: true - on: - branch: master diff --git a/README.md b/README.md index 363c06f..2baff25 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,19 @@ # SoftLayer API Client for Java -![Java CI](https://github.com/softlayer/softlayer-java/workflows/Java%20CI/badge.svg) +[![Java CI](https://github.com/softlayer/softlayer-java/actions/workflows/maven.yml/badge.svg)](https://github.com/softlayer/softlayer-java/actions/workflows/maven.yml) [![Maven Central](https://img.shields.io/maven-central/v/com.softlayer.api/softlayer-api-client)](https://search.maven.org/artifact/com.softlayer.api/softlayer-api-client) [![Javadocs](https://www.javadoc.io/badge/com.softlayer.api/softlayer-api-client.svg)](https://www.javadoc.io/doc/com.softlayer.api/softlayer-api-client) ## Introduction -This library provides a JVM client for the [SoftLayer API](http://sldn.softlayer.com/article/SoftLayer-API-Overview). It +This library provides a JVM client for the [SoftLayer API](https://sldn.softlayer.com/article/getting-started/). It has code generated and compiled via Maven. The client can work with any Java 8+ runtime. It uses the code generation project in `gen/` to generate the service and type related code. Although likely to work in resource-constrained environments (i.e. Android, J2ME, etc), using this is not recommended; Use the -[REST](http://sldn.softlayer.com/article/REST) API instead. +[REST](https://sldn.softlayer.com/article/rest/) API instead. By default the HTTP client is the Java `HttpUrlConnection` and the JSON marshalling is done by -[Gson](https://code.google.com/p/google-gson/). Both of these pieces can be exchanged for alternative implementations +[Gson](https://github.com/google/gson). Both of these pieces can be exchanged for alternative implementations (see below). The `examples/` project has sample uses of the API. It can be executed from Maven while inside the `examples/` folder @@ -40,20 +40,20 @@ additions to the SoftLayer API. com.softlayer.api softlayer-api-client - 0.3.2 + 0.3.3 ``` ### Gradle ```groovy -implementation 'com.softlayer.api:softlayer-api-client:0.3.2' +implementation 'com.softlayer.api:softlayer-api-client:0.3.3' ``` ### Kotlin ```kotlin -compile("com.softlayer.api:softlayer-api-client:0.3.2") +compile("com.softlayer.api:softlayer-api-client:0.3.3") ``` ### Creating a Client @@ -74,21 +74,23 @@ ApiClient client = new RestApiClient().withCredentials(myUser, myApiKey); ``` #### Access Token -Information on how to get a temoprary api token can be found on the SLDN [Authenticating to the SoftLayer API](https://sldn.softlayer.com/article/authenticating-softlayer-api/#temp-token) article. +Information on how to get a temoprary api token can be found on the SLDN +[Authenticating to the SoftLayer API](https://sldn.softlayer.com/article/authenticating-softlayer-api/#temp-token) +article. ```java import com.softlayer.api.*; -ApiClient client = new RestApiClient().withBearerToken("qqqqwwwweeeaaassddd...."); +ApiClient client = new RestApiClient().withBearerToken(myBearerToken); ``` If the end point isn't at the normal SoftLayer API, you can provide the prefix to the constructor of the -`RestApiClient`. By default it is set to the public API endpoint, `https://api.softlayer.com/rest/v3.1/`. +`RestApiClient`. By default, it is set to the public API endpoint, `https://api.softlayer.com/rest/v3.1/`. If you are using the classic infrastructure private network, you can communicate with the API over that network by using the service URL instead: ```java ApiClient client = new RestApiClient(RestApiClient.BASE_SERVICE_URL) - .withCredentials("my user", "my api key"); + .withCredentials(myUser, myApiKey); ``` ### Making API Calls @@ -170,7 +172,7 @@ for (Vlan vlan : service.getObject().getNetworkVlans()) { All values of a type can be masked upon. If a value represents a primitive or collection of primitives, the same mask it is called on is returned. Otherwise the mask of the other type is given. These translate into SoftLayer's -[string-based object mask format](http://sldn.softlayer.com/article/Object-Masks). A string or an instance of a mask +[string-based object mask format](https://sldn.softlayer.com/article/object-masks/). A string or an instance of a mask can be given directly by calling `setMask` on the service. Note, when object masks are added on a service object, they will be sent with every service call unless removed via `clearMask` or overwritten via `withNewMask` or `setMask`. diff --git a/examples/pom.xml b/examples/pom.xml index 7a988fc..ca8db44 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -5,7 +5,7 @@ softlayer-api-client-examples jar - 0.3.2 + 0.3.3 softlayer-api-client-examples http://sldn.softlayer.com @@ -36,7 +36,7 @@ org.codehaus.mojo exec-maven-plugin - 1.6.0 + 3.0.0 diff --git a/gen/pom.xml b/gen/pom.xml index c62354f..9a7961f 100644 --- a/gen/pom.xml +++ b/gen/pom.xml @@ -5,7 +5,7 @@ softlayer-api-client-gen jar - 0.3.2 + 0.3.3 softlayer-api-client-gen http://sldn.softlayer.com @@ -29,12 +29,12 @@ com.google.code.gson gson - 2.8.6 + 2.8.8 junit junit - 4.13.1 + 4.13.2 test @@ -43,7 +43,7 @@ org.codehaus.mojo exec-maven-plugin - 1.6.0 + 3.0.0 @@ -58,7 +58,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.1.1 + 3.3.1 ${java.version} diff --git a/ghpages_secret.enc b/ghpages_secret.enc deleted file mode 100644 index 00f2d2dd1621942d5fd86858ba6e2dd70a7e21cf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1680 zcmV;B25a!HSY;t5VW`I zj6X`@zbB5p)CeOBuJ%$+ShwS zYkCh)e1&w4!u5TLrI)`IoV-ddzk~@oxTVIPO=2SiEh)#g{*5VoT9bspE*6U3&#NSs~*XnCBQLB-BlKgQl)F} z9wf4yghr3;d8z?_lxHUF^mAVTR7vDOCofyKqNd;*eY@#Rn7THUF1fV>jRHu}3_v zYoXRgB9(ybXVB=JpGRBaa%V4Ku>_+Sl?Ka@W8oyb42zf{=j~noMFdS0rT(0V`HeGd zje(1e2YL5liZ*X{iLoH;|2jrN{T+x?uWv$=xjB=k8?Y{m2P$FdBI_Yqc(8Bd3!+Mv zXW59n0NdrT90Oz>8i%7p+N>Xwq&=U+M5HKR(jL>Kr=MmU1$0_ujCIZFOo(*nTx7CC z7pTJY0;L0!X)m@gz{(xQJGM5@o*Q2cDx{LXl=if}O8QG=#!Xh$c(?_`!a<~)BvGgb z(c;hUsjZW^X%c1!4*k7Xgdqa*SO=;{I2u62%Vcd#PVPt%d=R{|S zzQ{7vbeXBSBQ!3?PVhk{OTQp~_p?bv*Fu{xtrN&bbc)oAlswcZv%Y4es8|tbP$w{A^KQov6K3@2E#yi%0L8KA>p)bk1G$>x zsWbvy8bA(HB`@5aM_(|`4nnU?T}W}Z{^WsbCi~J}t%zC$L5!Bz%bI^nO}AQI4m(l+ zP!G;NoquANSytz;aj*_u_`j@Pgzx;1u=*J2YWHEDFs<}a46lb$kB6)xO;eep!~Jo3 z&h*as7yA<%)c`%E%50MzBT=zRPIxZp5yo=7WV8>bh@uaQ^CxycvBpcVt3=q|&L49C zLNrPJ6%K8XDi_PW7d6!(>astWJ(Xd{b5wx9ywPhNJQRKhBm>y3Io?!gud)FEFBh#* zkRjQWyUL{QOS4?hOL=WkvOp=4A=PC(s{BEk(5|F z;8O)SDofHf|5J;5gAtXe4gzw+Ll!6DYfCpQY`DA=S z``}??k({vhbx?dBgXm^NoGy47nK$b-kyTkg8N}-j9Ct(lW1Br^Ds(wF)|oZ7W+-kF zW27J?o@IHuCK3!63(CDK1&qDk2o)ySEYka3v@softlayer-api-client jar - 0.3.2 + 0.3.3 SoftLayer API Client for Java API client for accessing the SoftLayer API - http://sldn.softlayer.com + https://sldn.softlayer.com The MIT License (MIT) - http://opensource.org/licenses/MIT + https://opensource.org/licenses/MIT repo @@ -28,7 +28,7 @@ camporter Cameron Porter IBM - http://ibm.com/cloud + https://ibm.com/cloud owner developer @@ -40,7 +40,7 @@ scm:git:git@github.com:softlayer/softlayer-java.git scm:git:git@github.com:softlayer/softlayer-java.git git@github.com:softlayer/softlayer-java.git - 0.3.2 + 0.3.3 UTF-8 @@ -66,12 +66,12 @@ com.google.code.gson gson - 2.8.6 + 2.8.8 junit junit - 4.13.1 + 4.13.2 test @@ -108,7 +108,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.1.1 + 3.3.1 @@ -128,7 +128,7 @@ org.apache.maven.plugins maven-gpg-plugin - 1.6 + 3.0.1 sign-artifacts @@ -142,7 +142,7 @@ maven-invoker-plugin - 3.2.1 + 3.2.2 generate-services @@ -164,7 +164,7 @@ org.jacoco jacoco-maven-plugin - 0.8.6 + 0.8.7 **/*com/softlayer/api/service/**/* From d2e3ddad640186f42c79a166a1bd87b59a75fe98 Mon Sep 17 00:00:00 2001 From: Cameron Porter Date: Wed, 15 Sep 2021 12:41:26 -0500 Subject: [PATCH 40/45] Skip gpg signing for the maven workflow. --- .github/workflows/maven.yml | 2 +- pom.xml | 6 ------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 67b51dc..5a48c50 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -19,4 +19,4 @@ jobs: distribution: 'temurin' java-version: ${{matrix.java}} - name: Build with Maven - run: mvn verify -B -e -V --file pom.xml + run: mvn verify -B -e -V --file pom.xml -Dgpg.skip=true diff --git a/pom.xml b/pom.xml index 7612382..32b563f 100644 --- a/pom.xml +++ b/pom.xml @@ -46,12 +46,6 @@ UTF-8 8 - - - jcenter - https://jcenter.bintray.com/ - - ossrh From a1e38e9fa97b771797a9546ae751f7f4635ed6f1 Mon Sep 17 00:00:00 2001 From: Cameron Porter Date: Wed, 15 Sep 2021 12:50:01 -0500 Subject: [PATCH 41/45] Use maven cache for java setup. --- .github/workflows/maven.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 5a48c50..36a45c6 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -18,5 +18,6 @@ jobs: with: distribution: 'temurin' java-version: ${{matrix.java}} + cache: 'maven' - name: Build with Maven run: mvn verify -B -e -V --file pom.xml -Dgpg.skip=true From 7a337d9d8a72a6bb517105ce9c4e986e84ce9502 Mon Sep 17 00:00:00 2001 From: Cameron Porter Date: Wed, 15 Sep 2021 13:46:35 -0500 Subject: [PATCH 42/45] Publishing requires using passwordless sudo to install pandoc. --- .github/workflows/pages.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index 3e50206..fb9fbe9 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -12,7 +12,7 @@ jobs: - name: Build run: | - apt-get update && apt-get install -y pandoc + sudo apt-get update && sudo apt-get install -y pandoc mkdir ghpages pandoc -o ghpages/index.html README.md From 7b1a5a0bec48d2753e8445ae53c6ee802c4e6839 Mon Sep 17 00:00:00 2001 From: Cameron Porter Date: Thu, 16 Dec 2021 16:57:28 -0600 Subject: [PATCH 43/45] Process deprecations from the API metadata and annotate types, methods, and properties if they are deprecated. --- .github/workflows/maven.yml | 4 +- examples/pom.xml | 7 ++- gen/pom.xml | 7 ++- .../com/softlayer/api/gen/ClassWriter.java | 50 +++++++++++++++---- .../main/java/com/softlayer/api/gen/Meta.java | 3 ++ pom.xml | 25 +++++++++- 6 files changed, 78 insertions(+), 18 deletions(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 36a45c6..2581fba 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -9,12 +9,12 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - java: [8, 11, 16] + java: [8, 11, 16, 17] steps: - name: Checkout uses: actions/checkout@v2 - name: Set up JDK - uses: actions/setup-java@v2.3.0 + uses: actions/setup-java@v2.4.0 with: distribution: 'temurin' java-version: ${{matrix.java}} diff --git a/examples/pom.xml b/examples/pom.xml index ca8db44..09cd982 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -1,17 +1,20 @@ 4.0.0 + + 3.3.9 + com.softlayer.api softlayer-api-client-examples jar 0.3.3 softlayer-api-client-examples - http://sldn.softlayer.com + https://sldn.softlayer.com/ The MIT License (MIT) - http://opensource.org/licenses/MIT + https://opensource.org/licenses/MIT repo diff --git a/gen/pom.xml b/gen/pom.xml index 9a7961f..0181564 100644 --- a/gen/pom.xml +++ b/gen/pom.xml @@ -1,13 +1,16 @@ 4.0.0 + + 3.3.9 + com.softlayer.api softlayer-api-client-gen jar 0.3.3 softlayer-api-client-gen - http://sldn.softlayer.com + https://sldn.softlayer.com/ The MIT License (MIT) @@ -29,7 +32,7 @@ com.google.code.gson gson - 2.8.8 + 2.8.9 junit diff --git a/gen/src/main/java/com/softlayer/api/gen/ClassWriter.java b/gen/src/main/java/com/softlayer/api/gen/ClassWriter.java index 671c04f..2d4ef46 100644 --- a/gen/src/main/java/com/softlayer/api/gen/ClassWriter.java +++ b/gen/src/main/java/com/softlayer/api/gen/ClassWriter.java @@ -134,6 +134,10 @@ public ClassWriter emitProperty(TypeClass.Property property) throws IOException if (property.meta.doc != null) { emitJavadoc(property.meta.doc.replace("\n", "
\n")); } + + if (property.meta.deprecated) { + emitAnnotation("Deprecated"); + } Map params = new HashMap<>(2); if (!property.name.equals(property.meta.name)) { @@ -267,6 +271,10 @@ public ClassWriter emitServiceMethod(TypeClass.Method method, boolean async) thr javadoc += "@see " + type.meta.name + "::" + method.meta.name + ""; emitJavadoc(javadoc); + + if (method.meta.deprecated) { + emitAnnotation("Deprecated"); + } Map params = new HashMap<>(2); if (!method.name.equals(method.meta.name)) { @@ -279,6 +287,10 @@ public ClassWriter emitServiceMethod(TypeClass.Method method, boolean async) thr } else { // Otherwise, just a javadoc link emitJavadoc("Async version of {@link Service#" + method.name + "}"); + + if (method.meta.deprecated) { + emitAnnotation("Deprecated"); + } } String[] parameters = new String[method.parameters.size() * 2]; @@ -296,6 +308,9 @@ public ClassWriter emitServiceMethod(TypeClass.Method method, boolean async) thr // Async has an extra callback method if (async) { + if (method.meta.deprecated) { + emitAnnotation("Deprecated"); + } parameters = Arrays.copyOf(parameters, parameters.length + 2); parameters[parameters.length - 2] = TYPE_RESPONSE_HANDLER + '<' + method.javaType + '>'; parameters[parameters.length - 1] = "callback"; @@ -324,6 +339,10 @@ public ClassWriter emitServiceMethod(TypeClass.Property property, boolean async) javadoc += "@see " + type.meta.name + "::" + name + ""; emitJavadoc(javadoc); + + if (property.meta.deprecated) { + emitAnnotation("Deprecated"); + } // Instance is only required if it's not an account property if ("SoftLayer_Account".equals(type.meta.name)) { @@ -334,6 +353,10 @@ public ClassWriter emitServiceMethod(TypeClass.Property property, boolean async) } else { // Otherwise, just a javadoc link emitJavadoc("Async version of {@link Service#" + name + "}"); + + if (property.meta.deprecated) { + emitAnnotation("Deprecated"); + } } String returnType = property.javaType; @@ -355,17 +378,12 @@ public ClassWriter emitType() throws IOException { emitPackage(type.packageName); emitTypeImports(); - - // Javadoc - String javadoc = type.meta.typeDoc != null ? type.meta.typeDoc : type.meta.serviceDoc; - if (javadoc == null) { - javadoc = ""; - } else { - javadoc = javadoc.replace("\n", "
\n") + "\n\n"; + + emitJavadoc(getTypeJavadoc()); + + if (type.meta.deprecated) { + emitAnnotation("Deprecated"); } - javadoc += "@see " + type.meta.name + ""; - emitJavadoc(javadoc); // Each type has a type attribute emitAnnotation("ApiType", stringLiteral(type.meta.name)); @@ -432,6 +450,18 @@ public ClassWriter emitType() throws IOException { emitMask().endType(); return this; } + + protected String getTypeJavadoc() { + String javadoc = type.meta.typeDoc != null ? type.meta.typeDoc : type.meta.serviceDoc; + if (javadoc == null) { + javadoc = ""; + } else { + javadoc = javadoc.replace("\n", "
\n") + "\n\n"; + } + javadoc += "@see " + type.meta.name + ""; + return javadoc; + } public ClassWriter emitTypeImports() throws IOException { Map imports = new HashMap<>(type.imports); diff --git a/gen/src/main/java/com/softlayer/api/gen/Meta.java b/gen/src/main/java/com/softlayer/api/gen/Meta.java index 7a9ad8d..838af47 100644 --- a/gen/src/main/java/com/softlayer/api/gen/Meta.java +++ b/gen/src/main/java/com/softlayer/api/gen/Meta.java @@ -75,6 +75,7 @@ public static class Type { public String serviceDoc; public Map methods = Collections.emptyMap(); public boolean noservice; + public boolean deprecated; } /** @@ -86,6 +87,7 @@ public static class Property { public boolean typeArray; public PropertyForm form; public String doc; + public boolean deprecated; } public enum PropertyForm { @@ -109,6 +111,7 @@ public static class Method { public boolean filterable; public boolean maskable; public List parameters = Collections.emptyList(); + public boolean deprecated; } /** diff --git a/pom.xml b/pom.xml index 32b563f..314cd06 100644 --- a/pom.xml +++ b/pom.xml @@ -1,5 +1,8 @@ 4.0.0 + + 3.3.9 + com.softlayer.api softlayer-api-client jar @@ -60,7 +63,7 @@ com.google.code.gson gson - 2.8.8 + 2.8.9 junit @@ -71,7 +74,7 @@ org.mockito mockito-core - 3.6.0 + 4.2.0 test @@ -181,4 +184,22 @@
+ + + + org.codehaus.mojo + versions-maven-plugin + 2.8.1 + + + + dependency-updates-report + plugin-updates-report + property-updates-report + + + + + + From ecc49545c1d487ae1261d3b4e6e30ce0817d1c28 Mon Sep 17 00:00:00 2001 From: Cameron Porter Date: Fri, 17 Dec 2021 12:08:09 -0600 Subject: [PATCH 44/45] Release version 0.3.4 --- CHANGELOG.md | 56 ++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 8 +++---- examples/pom.xml | 2 +- gen/pom.xml | 2 +- pom.xml | 4 ++-- 5 files changed, 64 insertions(+), 8 deletions(-) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..e123418 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,56 @@ +# Changelog + +Note that new releases update the API types and services and may change or remove classes, methods, and types without +notice. + +## [Unreleased] + +## [0.3.4] - 2021-12-17 + +### Changed +* Add deprecation annotations to types, properties, and methods. Deprecations may be removed in future changes to the + API. + +### Changed +* New service definitions. + +## [0.3.3] - 2021-09-15 + +### Changed +* Updated services and types. +* Updated dependencies. + +## [0.3.2] - 2021-01-20 + +### Added +* Added support for Bearer Authentication Token Support. + +```java +import com.softlayer.api.*; +ApiClient client = new RestApiClient().withBearerToken("qqqqwwwweeeaaassddd...."); +``` + +### Changed +* Updated services and types. + +## [0.3.1] - 2021-11-09 + +### Changed +* Updated services and types. + +## [0.3.0] - 2021-03-25 + +### Added +* Added a new `RestApiClient.BASE_SERVICE_URL` constant to use the client with the classic infrastructure private + network. + +### Changed +* A breaking change has been made. Coerce return types to whatever the API metadata says should be returned, even if + the type returned by the API does not match (#64). + +* Updated services and types. + +## [0.2.9] - 2020-01-21 + +### Changed +* Updated generated services and types. diff --git a/README.md b/README.md index 2baff25..a771bf3 100644 --- a/README.md +++ b/README.md @@ -40,20 +40,20 @@ additions to the SoftLayer API. com.softlayer.api softlayer-api-client - 0.3.3 + 0.3.4 ``` ### Gradle ```groovy -implementation 'com.softlayer.api:softlayer-api-client:0.3.3' +implementation 'com.softlayer.api:softlayer-api-client:0.3.4' ``` ### Kotlin ```kotlin -compile("com.softlayer.api:softlayer-api-client:0.3.3") +compile("com.softlayer.api:softlayer-api-client:0.3.4") ``` ### Creating a Client @@ -74,7 +74,7 @@ ApiClient client = new RestApiClient().withCredentials(myUser, myApiKey); ``` #### Access Token -Information on how to get a temoprary api token can be found on the SLDN +Information on how to get a temporary api token can be found on the SLDN [Authenticating to the SoftLayer API](https://sldn.softlayer.com/article/authenticating-softlayer-api/#temp-token) article. diff --git a/examples/pom.xml b/examples/pom.xml index 09cd982..f90f564 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -8,7 +8,7 @@ softlayer-api-client-examples jar - 0.3.3 + 0.3.4 softlayer-api-client-examples https://sldn.softlayer.com/ diff --git a/gen/pom.xml b/gen/pom.xml index 0181564..768a3a5 100644 --- a/gen/pom.xml +++ b/gen/pom.xml @@ -8,7 +8,7 @@ softlayer-api-client-gen jar - 0.3.3 + 0.3.4 softlayer-api-client-gen https://sldn.softlayer.com/ diff --git a/pom.xml b/pom.xml index 314cd06..23bd176 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ softlayer-api-client jar - 0.3.3 + 0.3.4 SoftLayer API Client for Java API client for accessing the SoftLayer API https://sldn.softlayer.com @@ -43,7 +43,7 @@ scm:git:git@github.com:softlayer/softlayer-java.git scm:git:git@github.com:softlayer/softlayer-java.git git@github.com:softlayer/softlayer-java.git - 0.3.3 + 0.3.4 UTF-8 From 6185d58b1d7c34146a66922c0bbe440df8ca6941 Mon Sep 17 00:00:00 2001 From: Cameron Porter Date: Fri, 17 Dec 2021 12:17:52 -0600 Subject: [PATCH 45/45] Correct some changelog release dates --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e123418..b8b5301 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,12 +33,12 @@ ApiClient client = new RestApiClient().withBearerToken("qqqqwwwweeeaaassddd...." ### Changed * Updated services and types. -## [0.3.1] - 2021-11-09 +## [0.3.1] - 2020-11-09 ### Changed * Updated services and types. -## [0.3.0] - 2021-03-25 +## [0.3.0] - 2020-03-25 ### Added * Added a new `RestApiClient.BASE_SERVICE_URL` constant to use the client with the classic infrastructure private