diff options
author | Instrumental <jonathan.gathman@att.com> | 2018-07-22 07:49:16 -0500 |
---|---|---|
committer | Instrumental <jonathan.gathman@att.com> | 2018-07-22 07:49:20 -0500 |
commit | cf52d77279f8d5a70429d45abad0ef3d1135070c (patch) | |
tree | f084fd660d3e201abc853df8f17542a044120070 | |
parent | 65c40b3bffb78a1a77d82fc74bbf633a6d0d906f (diff) |
Finish RESTful Client API
Issue-ID: AAF-361
Change-Id: I999cb419a79c5995baf3757fdbbe047528901597
Signed-off-by: Instrumental <jonathan.gathman@att.com>
10 files changed, 442 insertions, 47 deletions
diff --git a/auth/auth-cmd/src/test/java/org/onap/aaf/auth/cmd/test/HMangrStub.java b/auth/auth-cmd/src/test/java/org/onap/aaf/auth/cmd/test/HMangrStub.java index 7ceb1233..c1b87540 100644 --- a/auth/auth-cmd/src/test/java/org/onap/aaf/auth/cmd/test/HMangrStub.java +++ b/auth/auth-cmd/src/test/java/org/onap/aaf/auth/cmd/test/HMangrStub.java @@ -49,6 +49,10 @@ public class HMangrStub extends HMangr { return null; } @Override public<RET> RET oneOf(SecuritySetter<HttpURLConnection> ss, Retryable<RET> retryable, boolean notify, String host) { + try { + return retryable.code(clientMock); + } catch (Exception e) { + } return null; } } diff --git a/auth/auth-cmd/src/test/java/org/onap/aaf/auth/cmd/test/perm/JU_Create.java b/auth/auth-cmd/src/test/java/org/onap/aaf/auth/cmd/test/perm/JU_Create.java index 1fb27470..41295c79 100644 --- a/auth/auth-cmd/src/test/java/org/onap/aaf/auth/cmd/test/perm/JU_Create.java +++ b/auth/auth-cmd/src/test/java/org/onap/aaf/auth/cmd/test/perm/JU_Create.java @@ -60,7 +60,7 @@ public class JU_Create { @Mock private Locator<URI> locMock; @Mock private Writer wrtMock; @Mock private Rcli<HttpURLConnection> clientMock; - @Mock private Future<Object> futureMock; + @Mock private Future<String> futureMock; private static Create create; @@ -74,9 +74,9 @@ public class JU_Create { public void setUp () throws NoSuchFieldException, SecurityException, Exception, IllegalAccessException { MockitoAnnotations.initMocks(this); - when(clientMock.create(any(), any(), any())).thenReturn(futureMock); - when(clientMock.delete(any(), any(), any())).thenReturn(futureMock); - when(clientMock.update(any(), any(), any())).thenReturn(futureMock); + when(clientMock.create(any(), any(), any(String.class))).thenReturn(futureMock); + when(clientMock.delete(any(), any(), any(String.class))).thenReturn(futureMock); + when(clientMock.update(any(), any(), any(String.class))).thenReturn(futureMock); hman = new HMangrStub(access, locMock, clientMock); access = new PropAccess(new PrintStream(new ByteArrayOutputStream()), new String[0]); diff --git a/auth/auth-cmd/src/test/java/org/onap/aaf/auth/cmd/test/perm/JU_Delete.java b/auth/auth-cmd/src/test/java/org/onap/aaf/auth/cmd/test/perm/JU_Delete.java index 4fd7892a..19cacedb 100644 --- a/auth/auth-cmd/src/test/java/org/onap/aaf/auth/cmd/test/perm/JU_Delete.java +++ b/auth/auth-cmd/src/test/java/org/onap/aaf/auth/cmd/test/perm/JU_Delete.java @@ -24,7 +24,7 @@ package org.onap.aaf.auth.cmd.test.perm; import static org.mockito.Matchers.any; import static org.mockito.Mockito.when; - +import org.hamcrest.core.AnyOf; import org.junit.Before; import org.onap.aaf.auth.cmd.test.HMangrStub; @@ -62,7 +62,7 @@ public class JU_Delete { @Mock private Locator<URI> locMock; @Mock private Writer wrtMock; @Mock private Rcli<HttpURLConnection> clientMock; - @Mock private Future<Object> futureMock; + @Mock private Future<String> futureMock; private static Delete del; @@ -75,9 +75,9 @@ public class JU_Delete { public void setUp() throws NoSuchFieldException, SecurityException, Exception, IllegalAccessException { MockitoAnnotations.initMocks(this); - when(clientMock.create(any(), any(), any())).thenReturn(futureMock); - when(clientMock.delete(any(), any(), any())).thenReturn(futureMock); - when(clientMock.update(any(), any(), any())).thenReturn(futureMock); + when(clientMock.create(any(), any(), any(String.class))).thenReturn(futureMock); + when(clientMock.delete(any(), any(), any(String.class))).thenReturn(futureMock); + when(clientMock.update(any(), any(), any(String.class))).thenReturn(futureMock); hman = new HMangrStub(access, locMock, clientMock); access = new PropAccess(new PrintStream(new ByteArrayOutputStream()), new String[0]); diff --git a/auth/auth-cmd/src/test/java/org/onap/aaf/auth/cmd/test/perm/JU_Describe.java b/auth/auth-cmd/src/test/java/org/onap/aaf/auth/cmd/test/perm/JU_Describe.java index 224b5c75..9a5fc734 100644 --- a/auth/auth-cmd/src/test/java/org/onap/aaf/auth/cmd/test/perm/JU_Describe.java +++ b/auth/auth-cmd/src/test/java/org/onap/aaf/auth/cmd/test/perm/JU_Describe.java @@ -61,7 +61,7 @@ public class JU_Describe { @Mock private Locator<URI> locMock; @Mock private Writer wrtMock; @Mock private Rcli<HttpURLConnection> clientMock; - @Mock private Future<Object> futureMock; + @Mock private Future<String> futureMock; private PropAccess access; private HMangrStub hman; @@ -74,9 +74,9 @@ public class JU_Describe { public void setUp () throws NoSuchFieldException, SecurityException, Exception, IllegalAccessException { MockitoAnnotations.initMocks(this); - when(clientMock.create(any(), any(), any())).thenReturn(futureMock); - when(clientMock.delete(any(), any(), any())).thenReturn(futureMock); - when(clientMock.update(any(), any(), any())).thenReturn(futureMock); + when(clientMock.create(any(), any(), any(String.class))).thenReturn(futureMock); + when(clientMock.delete(any(), any(), any(String.class))).thenReturn(futureMock); + when(clientMock.update(any(), any(), any(String.class))).thenReturn(futureMock); hman = new HMangrStub(access, locMock, clientMock); access = new PropAccess(new PrintStream(new ByteArrayOutputStream()), new String[0]); diff --git a/auth/auth-cmd/src/test/java/org/onap/aaf/auth/cmd/test/perm/JU_Grant.java b/auth/auth-cmd/src/test/java/org/onap/aaf/auth/cmd/test/perm/JU_Grant.java index 17280c64..975b83d2 100644 --- a/auth/auth-cmd/src/test/java/org/onap/aaf/auth/cmd/test/perm/JU_Grant.java +++ b/auth/auth-cmd/src/test/java/org/onap/aaf/auth/cmd/test/perm/JU_Grant.java @@ -63,7 +63,7 @@ public class JU_Grant { @Mock private Locator<URI> locMock; @Mock private Writer wrtMock; @Mock private Rcli<HttpURLConnection> clientMock; - @Mock private Future<Object> futureMock; + @Mock private Future<String> futureMock; private PropAccess access; private HMangrStub hman; @@ -74,9 +74,9 @@ public class JU_Grant { public void setUp () throws NoSuchFieldException, SecurityException, Exception, IllegalAccessException { MockitoAnnotations.initMocks(this); - when(clientMock.create(any(), any(), any())).thenReturn(futureMock); - when(clientMock.delete(any(), any(), any())).thenReturn(futureMock); - when(clientMock.update(any(), any(), any())).thenReturn(futureMock); + when(clientMock.create(any(), any(), any(String.class))).thenReturn(futureMock); + when(clientMock.delete(any(), any(), any(String.class))).thenReturn(futureMock); + when(clientMock.update(any(), any(), any(String.class))).thenReturn(futureMock); hman = new HMangrStub(access, locMock, clientMock); access = new PropAccess(new PrintStream(new ByteArrayOutputStream()), new String[0]); diff --git a/auth/auth-hello/src/main/java/org/onap/aaf/auth/hello/API_Hello.java b/auth/auth-hello/src/main/java/org/onap/aaf/auth/hello/API_Hello.java index 2be162cc..030073a7 100644 --- a/auth/auth-hello/src/main/java/org/onap/aaf/auth/hello/API_Hello.java +++ b/auth/auth-hello/src/main/java/org/onap/aaf/auth/hello/API_Hello.java @@ -21,6 +21,9 @@ package org.onap.aaf.auth.hello; +import java.io.BufferedReader; +import java.io.InputStreamReader; + import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -40,6 +43,9 @@ import org.onap.aaf.misc.env.TimeTaken; public class API_Hello { + private static final String APPLICATION_JSON = "application/json"; + protected static final byte[] NOT_JSON = "Data does not look like JSON".getBytes(); + // Hide Public Constructor private API_Hello() {} @@ -85,10 +91,37 @@ public class API_Hello { } }); - //////// - // REST APIs - /////// - oauthHello.route(oauthHello.env,HttpMethods.GET,"/resthello/:perm*",new HttpCode<AuthzTrans, AAF_Hello>(oauthHello,"REST Hello OAuth") { +//////////////// +// REST APIs +//////////////// + + //////////////// + // CREATE/POST + //////////////// + oauthHello.route(oauthHello.env,HttpMethods.POST,"/resthello/:id",new HttpCode<AuthzTrans, AAF_Hello>(oauthHello,"REST Hello Create") { + @Override + public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception { + BufferedReader br = new BufferedReader(new InputStreamReader(req.getInputStream())); + StringBuilder sb = new StringBuilder(); + while(br.ready()) { + sb.append(br.readLine()); + } + String content = sb.toString(); + trans.info().printf("Content from %s: %s\n", pathParam(req, ":id"),content); + if(content.startsWith("{") && content.endsWith("}")) { + resp.setStatus(201 /* OK */); + } else { + resp.getOutputStream().write(NOT_JSON); + resp.setStatus(406); + } + } + },APPLICATION_JSON); + + + //////////////// + // READ/GET + //////////////// + oauthHello.route(oauthHello.env,HttpMethods.GET,"/resthello/:id/:perm*",new HttpCode<AuthzTrans, AAF_Hello>(oauthHello,"REST Hello Read") { @Override public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception { resp.setStatus(200 /* OK */); @@ -96,6 +129,7 @@ public class API_Hello { sb.append(req.getUserPrincipal().getName()); sb.append('"'); String perm = pathParam(req, "perm"); + trans.info().printf("Read request from %s: %s\n", pathParam(req, ":id"),perm); if(perm!=null && perm.length()>0) { TimeTaken tt = trans.start("Authorize perm", Env.REMOTE); try { @@ -113,9 +147,42 @@ public class API_Hello { os.println(sb.toString()); trans.info().printf("Said 'RESTful Hello' to %s, Authentication type: %s",trans.getUserPrincipal().getName(),trans.getUserPrincipal().getClass().getSimpleName()); } - },"application/json"); - - + },APPLICATION_JSON); + //////////////// + // UPDATE/PUT + //////////////// + oauthHello.route(oauthHello.env,HttpMethods.PUT,"/resthello/:id",new HttpCode<AuthzTrans, AAF_Hello>(oauthHello,"REST Hello Update") { + @Override + public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception { + BufferedReader br = new BufferedReader(new InputStreamReader(req.getInputStream())); + StringBuilder sb = new StringBuilder(); + while(br.ready()) { + sb.append(br.readLine()); + } + String content = sb.toString(); + trans.info().printf("Content from %s: %s\n", pathParam(req, ":id"),content); + if(content.startsWith("{") && content.endsWith("}")) { + resp.setStatus(200 /* OK */); + resp.getOutputStream().print(content); + } else { + resp.getOutputStream().write(NOT_JSON); + resp.setStatus(406); + } + } + },APPLICATION_JSON); + + + //////////////// + // DELETE + //////////////// + oauthHello.route(oauthHello.env,HttpMethods.DELETE,"/resthello/:id",new HttpCode<AuthzTrans, AAF_Hello>(oauthHello,"REST Hello Delete") { + @Override + public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception { + trans.info().printf("Delete requested on %s\n", pathParam(req, ":id")); + resp.setStatus(200 /* OK */); + } + },APPLICATION_JSON); + } } diff --git a/cadi/client/src/main/java/org/onap/aaf/cadi/client/Rcli.java b/cadi/client/src/main/java/org/onap/aaf/cadi/client/Rcli.java index 058bbd38..04075f29 100644 --- a/cadi/client/src/main/java/org/onap/aaf/cadi/client/Rcli.java +++ b/cadi/client/src/main/java/org/onap/aaf/cadi/client/Rcli.java @@ -217,6 +217,20 @@ public abstract class Rcli<CT> { return client.futureCreate(Void.class); } + public Future<Void> create(String pathinfo, String contentType, EClient.Transfer content) throws APIException, CadiException { + final ParsePath pp = new ParsePath(pathinfo); + + EClient<CT> client = client(); + client.setMethod(POST); + client.addHeader(CONTENT_TYPE,contentType); + client.setPathInfo(pp.path()); + client.setQueryParams(pp.query()); + client.setFragment(pp.frag()); + client.setPayload(content); + client.send(); + return client.futureCreate(Void.class); + } + /** * Post Data in WWW expected format, with the format tag1=value1&tag2=value2, etc @@ -462,6 +476,22 @@ public abstract class Rcli<CT> { client.send(); return client.futureReadString(); } + + public Future<String> update(String pathinfo, String contentType, EClient.Transfer content) throws APIException, CadiException { + final ParsePath pp = new ParsePath(pathinfo); + + EClient<CT> client = client(); + client.setMethod(PUT); + client.addHeader(CONTENT_TYPE,contentType); + client.setPathInfo(pp.path()); + client.setQueryParams(pp.query()); + client.setFragment(pp.frag()); + client.setPayload(content); + client.send(); + return client.futureReadString(); + } + + public<T> Future<T> update(String pathinfo, final RosettaDF<T> df, final T t) throws APIException, CadiException { @@ -503,6 +533,8 @@ public abstract class Rcli<CT> { client.send(); return client.future(t); } + + /** * A method to update with a VOID @@ -531,6 +563,7 @@ public abstract class Rcli<CT> { client.send(); return client.future(null); } + public<T> Future<T> delete(String pathinfo, String contentType, final RosettaDF<T> df, final T t) throws APIException, CadiException { final ParsePath pp = new ParsePath(pathinfo); diff --git a/cadi/client/src/main/java/org/onap/aaf/cadi/locator/SingleEndpointLocator.java b/cadi/client/src/main/java/org/onap/aaf/cadi/locator/SingleEndpointLocator.java index b0c830f6..23bcd4ad 100644 --- a/cadi/client/src/main/java/org/onap/aaf/cadi/locator/SingleEndpointLocator.java +++ b/cadi/client/src/main/java/org/onap/aaf/cadi/locator/SingleEndpointLocator.java @@ -22,6 +22,7 @@ package org.onap.aaf.cadi.locator; import java.net.URI; import java.net.URISyntaxException; +import java.util.Date; import org.onap.aaf.cadi.Locator; import org.onap.aaf.cadi.LocatorException; @@ -29,6 +30,7 @@ import org.onap.aaf.cadi.LocatorException; public class SingleEndpointLocator implements Locator<URI> { private final URI uri; private final static Item item = new Item() {}; + private Date noRetryUntil; public SingleEndpointLocator(final URI uri) { this.uri = uri; @@ -45,12 +47,20 @@ public class SingleEndpointLocator implements Locator<URI> { @Override public boolean hasItems() { + if(noRetryUntil!=null) { + if(new Date().after(noRetryUntil)) { + noRetryUntil = null; + } else { + return false; + } + } return true; } @Override public void invalidate(Item item) throws LocatorException { - // Endpoints cannot be invalidated + // one minute timeout, because there is no other item + noRetryUntil = new Date(System.currentTimeMillis()+60000); } @Override diff --git a/cadi/oauth-enduser/src/main/java/org/onap/aaf/cadi/enduser/SimpleRESTClient.java b/cadi/oauth-enduser/src/main/java/org/onap/aaf/cadi/enduser/SimpleRESTClient.java index 386d938c..30344de5 100644 --- a/cadi/oauth-enduser/src/main/java/org/onap/aaf/cadi/enduser/SimpleRESTClient.java +++ b/cadi/oauth-enduser/src/main/java/org/onap/aaf/cadi/enduser/SimpleRESTClient.java @@ -21,11 +21,14 @@ package org.onap.aaf.cadi.enduser; import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintWriter; import java.net.ConnectException; import java.security.Principal; import org.onap.aaf.cadi.CadiException; import org.onap.aaf.cadi.LocatorException; +import org.onap.aaf.cadi.client.EClient; import org.onap.aaf.cadi.client.Future; import org.onap.aaf.cadi.client.Rcli; import org.onap.aaf.cadi.client.Result; @@ -37,8 +40,10 @@ import org.onap.aaf.cadi.oauth.TokenClientFactory; import org.onap.aaf.cadi.oauth.TzClient; import org.onap.aaf.cadi.principal.TaggedPrincipal; import org.onap.aaf.misc.env.APIException; +import org.onap.aaf.misc.env.util.StringBuilderWriter; public class SimpleRESTClient { + private static final String APPLICATION_JSON = "application/json"; private static final String[] EMPTY = new String[0]; private final TokenClient tokenClient; private final TzClient restClient; @@ -93,13 +98,116 @@ public class SimpleRESTClient { } return this; } + + /** + * Single Threaded Class for building up content + * @author jg1555 + * + */ + public static class Input { + private static final byte[] EMPTY_STREAM_BYTES = "".getBytes(); + + private String content; + private StringBuilder sb; + + public Input() { + content = null; + sb = null; + } + + public Input(final String content) { + this.content = content; + } + + public void set(final String content) { + this.content = content; + } + + public PrintWriter writer() { + return new PrintWriter(new StringBuilderWriter(builder())); + } + + public StringBuilder builder() { + if(sb==null) { + sb = new StringBuilder(); + content = null; + } + return sb; + } + + /** + * Reuse StringBuilder object + */ + public void clear() { + content = null; + if(sb!=null) { + sb.setLength(0); + } + } + + @Override + public String toString() { + if(content!=null) { + return content; + } else if(sb!=null) { + return sb.toString(); + } else { + return ""; + } + } + + public byte[] getBytes() { + byte[] rv; + if(content==null) { + if(sb==null) { + rv = EMPTY_STREAM_BYTES; + } else { + rv = sb.toString().getBytes(); + } + } else { + rv = content.getBytes(); + } + content = null; + return rv; + } + } + + ///////////////////////////////////////////////////////////// + // + // CREATE + // + ///////////////////////////////////////////////////////////// + public void create(final String path, final Input input) throws RESTException, CadiException, LocatorException, APIException { + post(path,APPLICATION_JSON, input); + } + + public void post(final String path, final Input input) throws RESTException, CadiException, LocatorException, APIException { + post(path,APPLICATION_JSON, input); + } + + public void post(final String path, final String contentType, final Input input) throws RESTException, CadiException, LocatorException, APIException { + Future<Void> future = restClient.best(new Retryable<Future<Void>>() { + @Override + public Future<Void> code(Rcli<?> client) throws CadiException, ConnectException, APIException { + return client.create(path, contentType, new ETransfer(input)); + } + }); + if(!future.get(callTimeout)) { + throw new RESTException(future); + } + } + ///////////////////////////////////////////////////////////// + // + // READ + // + ///////////////////////////////////////////////////////////// public String read(final String path) throws RESTException, CadiException, LocatorException, APIException { - return get(path,"application/json"); + return get(path,APPLICATION_JSON); } public String get(final String path) throws RESTException, CadiException, LocatorException, APIException { - return get(path,"application/json"); + return get(path,APPLICATION_JSON); } public String get(final String path, final String accepts) throws RESTException, CadiException, LocatorException, APIException { @@ -116,6 +224,69 @@ public class SimpleRESTClient { } } + ///////////////////////////////////////////////////////////// + // + // UPDATE + // + ///////////////////////////////////////////////////////////// + + public String update(final String path, final Input input) throws RESTException, CadiException, LocatorException, APIException { + return put(path,APPLICATION_JSON, input); + } + + public String put(final String path, final Input input) throws RESTException, CadiException, LocatorException, APIException { + return put(path,APPLICATION_JSON, input); + } + + public String put(final String path, final String contentType, final Input input) throws RESTException, CadiException, LocatorException, APIException { + Future<String> future = restClient.best(new Retryable<Future<String>>() { + @Override + public Future<String> code(Rcli<?> client) throws CadiException, ConnectException, APIException { + return client.update(path, contentType, new ETransfer(input)); + } + }); + if(future.get(callTimeout)) { + return future.value; + } else { + throw new RESTException(future); + } + } + + ///////////////////////////////////////////////////////////// + // + // DELETE + // + ///////////////////////////////////////////////////////////// + public void delete(final String path) throws RESTException, CadiException, LocatorException, APIException { + delete(path,APPLICATION_JSON); + } + + public void delete(final String path, final String contentType) throws RESTException, CadiException, LocatorException, APIException { + Future<Void> future = restClient.best(new Retryable<Future<Void>>() { + @Override + public Future<Void> code(Rcli<?> client) throws CadiException, ConnectException, APIException { + return client.delete(path, contentType); + } + }); + if(!future.get(callTimeout)) { + throw new RESTException(future); + } + } + + ///////////////////////////////////////////////////////////// + + private static class ETransfer implements EClient.Transfer { + private Input input; + public ETransfer(final Input input) { + this.input = input; + } + + @Override + public void transfer(OutputStream os) throws IOException, APIException { + os.write(input.getBytes()); + } + } + public interface Headers { String[] headers(); } diff --git a/cadi/oauth-enduser/src/test/java/org/onap/aaf/cadi/enduser/test/SimpleRestClientExample.java b/cadi/oauth-enduser/src/test/java/org/onap/aaf/cadi/enduser/test/SimpleRestClientExample.java index 7d251bad..6cabc654 100644 --- a/cadi/oauth-enduser/src/test/java/org/onap/aaf/cadi/enduser/test/SimpleRestClientExample.java +++ b/cadi/oauth-enduser/src/test/java/org/onap/aaf/cadi/enduser/test/SimpleRestClientExample.java @@ -21,6 +21,7 @@ package org.onap.aaf.cadi.enduser.test; +import java.io.PrintWriter; import java.net.URISyntaxException; import java.security.Principal; @@ -29,6 +30,7 @@ import org.onap.aaf.cadi.LocatorException; import org.onap.aaf.cadi.enduser.ClientFactory; import org.onap.aaf.cadi.enduser.RESTException; import org.onap.aaf.cadi.enduser.SimpleRESTClient; +import org.onap.aaf.cadi.enduser.SimpleRESTClient.Input; import org.onap.aaf.misc.env.APIException; @@ -46,32 +48,93 @@ public class SimpleRestClientExample { + " add -Dmyurl=https://<aaf hello machine>:8130 to VM Args\n\t" + "where \"aaf hello machine\" is an aaf Installation you know about."); } else { - SimpleRESTClient restClient = cf.simpleRESTClient(urlString,"org.osaaf.aaf"); - - // Make some calls - // Call with no Queries - String rv = restClient.get("resthello"); - System.out.println(rv); - - // Same call with "read" style - rv = restClient.read("resthello"); - System.out.println(rv); + SimpleRESTClient restClient = cf.simpleRESTClient(urlString,"org.osaaf.aaf"); + + ///////////////////////////////////////////////////////////// + // + // Creating Content for CREATE/UPDATE + // + ///////////////////////////////////////////////////////////// + // Create an object that can be reusable IN THIS THREAD ONLY... Not Thread-safe on purpose + Input input = new SimpleRESTClient.Input(); + // Note: alternate use is to set the input object to an already created String + // Input input = new SimpleRESTClient.Input(aString); - // Call with Queries - rv = restClient.get("resthello?perm=org.osaaf.people|*|read"); - System.out.println(rv); + PrintWriter pw = input.writer(); + pw.print("{\"something\": ["); + for(int i=0;i<4;++i) { + if(i>0) { + pw.print(','); + } + pw.print("{\"myint\":"); + pw.print(i); + pw.print('}'); + } + pw.println("]}"); - // Call setting ID from principal coming from Trans - // Pretend Transaction - HRequest req = new HRequest("demo@people.osaaf.org"); // Pretend Trans has Jonathan as Identity + // You can check or log the content + String content = input.toString(); + System.out.println(content); - // Call with RESTException, which allows obtaining HTTPCode and any Error message sent - rv = restClient.endUser(req.userPrincipal()).get("resthello?perm=org.osaaf.people|*|read"); - System.out.println(rv); + // Good form for Writers is that you should close it... + pw.close(); + + ///////////////////////////////////////////////////////////// + // + // CREATE/POST + // + ///////////////////////////////////////////////////////////// + System.out.println("-------- START REST CREATE/UPDATE --------"); + try { + restClient.create("resthello/rest_id", input); + // No Error code, it worked. + System.out.println("No Error Code, Create worked..."); + } catch (RESTException e) { + System.out.println(e.getCode()); + System.out.println(e.getMsg()); + } finally { + System.out.println("-------- END REST CREATE/UPDATE --------"); + } + + ///////////////////////////////////////////////////////////// + // + // READ/GET + // + ///////////////////////////////////////////////////////////// + + // Make some calls. Note that RESTException is thrown if Call does not complete. + // RESTException has HTTP Code and any Message sent from Server + System.out.println("-------- START REST READ/GET --------"); + boolean expectException = false; try { + + // Call with no Queries + String rv = restClient.get("resthello/rest_id"); + System.out.println(rv); + + // Same call with "read" style + rv = restClient.read("resthello/rest_id"); + System.out.println(rv); + + + // Call with Queries + rv = restClient.get("resthello/rest_id?perm=org.osaaf.people|*|read"); + System.out.println(rv); + + // Call setting ID from principal coming from Trans + // Pretend Transaction + HRequest req = new HRequest("demo@people.osaaf.org"); // Pretend Trans has Jonathan as Identity + + // Call with RESTException, which allows obtaining HTTPCode and any Error message sent + rv = restClient.endUser(req.userPrincipal()).get("resthello/rest_id?perm=org.osaaf.people|*|read"); + System.out.println(rv); + + // Expect Exception here. + System.out.println("-------- START Expecting Exception starting here --------"); + expectException = true; restClient.get("notAnAPI"); } catch(RESTException e) { System.out.println(e.getCode()); @@ -79,10 +142,57 @@ public class SimpleRestClientExample { System.out.println(e.getMessage()); System.out.println(e.getLocalizedMessage()); System.out.println(e); + } finally { + if(expectException) { + System.out.println("-------- END Expecting Exception starting here --------"); + } + System.out.println("-------- END REST READ/GET --------"); } + ///////////////////////////////////////////////////////////// + // + // UPDATE/PUT + // + ///////////////////////////////////////////////////////////// + + + // If you use "input" object again as a writer, you can clear it on the same thread, and go again + input.clear(); + // Here we just set to a String, instead of Writing + input.set("{\"something\" : []}"); + + System.out.println("-------- END REST UPDATE/PUT --------"); + try { + String rv = restClient.update("resthello/rest_id", input); + // No Error code, it worked. REST Update will return the updated Data + System.out.println("Update worked"); + System.out.println(rv); + } catch (RESTException e) { + System.out.println(e.getCode()); + System.out.println(e.getMsg()); + } finally { + System.out.println("-------- END REST UPDATE/PUT --------"); + } + + ///////////////////////////////////////////////////////////// + // + // DELETE + // + ///////////////////////////////////////////////////////////// + + System.out.println("-------- START REST DELETE --------"); + try { + restClient.delete("resthello/rest_id"); + // No Error code, it worked. REST Update will return the updated Data + System.out.println("Delete worked"); + } catch (RESTException e) { + System.out.println(e.getCode()); + System.out.println(e.getMsg()); + } finally { + System.out.println("-------- END REST DELETE --------"); + } } - } catch (CadiException | APIException | RESTException e) { + } catch (CadiException | APIException e) { e.printStackTrace(); } } |