diff --git a/pom.xml b/pom.xml index a22d690..b9a4c7b 100644 --- a/pom.xml +++ b/pom.xml @@ -57,7 +57,7 @@ com.fasterxml.jackson.core jackson-databind - 2.9.10.5 + 2.9.10.8 jar @@ -70,11 +70,6 @@ gson 2.8.5 - - org.java-websocket - Java-WebSocket - 1.5.1 - diff --git a/src/main/java/com/oneidentity/safeguard/safeguardjava/IProgressCallback.java b/src/main/java/com/oneidentity/safeguard/safeguardjava/IProgressCallback.java new file mode 100644 index 0000000..15b2424 --- /dev/null +++ b/src/main/java/com/oneidentity/safeguard/safeguardjava/IProgressCallback.java @@ -0,0 +1,7 @@ +package com.oneidentity.safeguard.safeguardjava; + +import com.oneidentity.safeguard.safeguardjava.data.TransferProgress; + +public interface IProgressCallback { + public void checkProgress(TransferProgress transferProgress); +} diff --git a/src/main/java/com/oneidentity/safeguard/safeguardjava/ISafeguardConnection.java b/src/main/java/com/oneidentity/safeguard/safeguardjava/ISafeguardConnection.java index be055cb..c1c95e3 100644 --- a/src/main/java/com/oneidentity/safeguard/safeguardjava/ISafeguardConnection.java +++ b/src/main/java/com/oneidentity/safeguard/safeguardjava/ISafeguardConnection.java @@ -8,6 +8,7 @@ import com.oneidentity.safeguard.safeguardjava.exceptions.ArgumentException; import com.oneidentity.safeguard.safeguardjava.exceptions.ObjectDisposedException; import com.oneidentity.safeguard.safeguardjava.exceptions.SafeguardForJavaException; +import java.time.Duration; import java.util.Map; /** @@ -45,6 +46,7 @@ public interface ISafeguardConnection { * @param body Request body to pass to the method. * @param parameters Additional parameters to add to the URL. * @param additionalHeaders Additional headers to add to the request. + * @param timeout Per-request timeout in milliseconds (null for default) * @return Response body as a string. * @throws ObjectDisposedException Object has already been disposed. * @throws SafeguardForJavaException General Safeguard for Java exception. @@ -52,7 +54,7 @@ public interface ISafeguardConnection { */ String invokeMethod(Service service, Method method, String relativeUrl, String body, Map parameters, - Map additionalHeaders) + Map additionalHeaders, Integer timeout) throws ObjectDisposedException, SafeguardForJavaException, ArgumentException; /** @@ -65,6 +67,7 @@ String invokeMethod(Service service, Method method, String relativeUrl, * @param body Request body to pass to the method. * @param parameters Additional parameters to add to the URL. * @param additionalHeaders Additional headers to add to the request. + * @param timeout Per-request timeout in milliseconds (null for default) * @return Response with status code, headers, and body as string. * @throws ObjectDisposedException Object has already been disposed. * @throws SafeguardForJavaException General Safeguard for Java exception. @@ -72,7 +75,7 @@ String invokeMethod(Service service, Method method, String relativeUrl, */ FullResponse invokeMethodFull(Service service, Method method, String relativeUrl, String body, Map parameters, - Map additionalHeaders) + Map additionalHeaders, Integer timeout) throws ObjectDisposedException, SafeguardForJavaException, ArgumentException; /* @@ -86,6 +89,7 @@ FullResponse invokeMethodFull(Service service, Method method, String relativeUrl * @param body Request body to pass to the method. * @param parameters Additional parameters to add to the URL. * @param additionalHeaders Additional headers to add to the request. + * @param timeout Per-request timeout in milliseconds (null for default) * @returns Response body as a CSV string. * @throws ObjectDisposedException Object has already been disposed. * @throws SafeguardForJavaException General Safeguard for Java exception. @@ -93,9 +97,15 @@ FullResponse invokeMethodFull(Service service, Method method, String relativeUrl */ String invokeMethodCsv(Service service, Method method, String relativeUrl, String body, Map parameters, - Map additionalHeaders) + Map additionalHeaders, Integer timeout) throws ObjectDisposedException, SafeguardForJavaException, ArgumentException; + /** + * Provides support for HTTP streaming requests + * @return IStreamingRequest + */ + IStreamingRequest getStreamingRequest(); + /** * Gets a Safeguard event listener. You will need to call the RegisterEventHandler() * method to establish callbacks. Then, you just have to call Start(). Call Stop() diff --git a/src/main/java/com/oneidentity/safeguard/safeguardjava/IStreamingRequest.java b/src/main/java/com/oneidentity/safeguard/safeguardjava/IStreamingRequest.java new file mode 100644 index 0000000..6b3c1cc --- /dev/null +++ b/src/main/java/com/oneidentity/safeguard/safeguardjava/IStreamingRequest.java @@ -0,0 +1,41 @@ +package com.oneidentity.safeguard.safeguardjava; + +import com.oneidentity.safeguard.safeguardjava.data.Service; +import com.oneidentity.safeguard.safeguardjava.exceptions.ArgumentException; +import com.oneidentity.safeguard.safeguardjava.exceptions.ObjectDisposedException; +import com.oneidentity.safeguard.safeguardjava.exceptions.SafeguardForJavaException; +import java.util.Map; + +/** + * HTTP streaming request methods + */ +public interface IStreamingRequest { + + /** + * Call a Safeguard POST API providing a stream as request content. If there is a + * failure a SafeguardDotNetException will be thrown. + * + * @param service Safeguard service to call. + * @param relativeUrl Relative URL of the service to use. + * @param stream Stream to upload as request content. + * @param progressCallback Optionally report upload progress. + * @param parameters Additional parameters to add to the URL. + * @param additionalHeaders Additional headers to add to the request. + * @return Response body as a string. + */ + String uploadStream(Service service, String relativeUrl, byte[] stream, IProgressCallback progressCallback, Map parameters, Map additionalHeaders) throws SafeguardForJavaException, ArgumentException, ObjectDisposedException; + + /** + * Call a Safeguard GET API providing an output file path to which streaming download data will + * be written. If there is a failure a SafeguardDotNetException will be thrown. + * + * @param service Safeguard service to call. + * @param relativeUrl Relative URL of the service to use. + * @param outputFilePath Full path to the file where download will be written. + * @param body Optional request body + * @param progressCallback Optionally report upload progress. + * @param parameters Additional parameters to add to the URL. + * @param additionalHeaders Additional headers to add to the request. + */ + void downloadStream(Service service, String relativeUrl, String outputFilePath, IProgressCallback progressCallback, Map parameters, Map additionalHeaders) throws SafeguardForJavaException, ArgumentException, ObjectDisposedException; +} diff --git a/src/main/java/com/oneidentity/safeguard/safeguardjava/SafeguardA2AContext.java b/src/main/java/com/oneidentity/safeguard/safeguardjava/SafeguardA2AContext.java index ca0cd52..3c9093b 100644 --- a/src/main/java/com/oneidentity/safeguard/safeguardjava/SafeguardA2AContext.java +++ b/src/main/java/com/oneidentity/safeguard/safeguardjava/SafeguardA2AContext.java @@ -93,7 +93,7 @@ public List getRetrievableAccounts() throws ObjectDispos Map parameters = new HashMap<>(); - CloseableHttpResponse response = coreClient.execGET("A2ARegistrations", parameters, headers, clientCertificate); + CloseableHttpResponse response = coreClient.execGET("A2ARegistrations", parameters, headers, null, clientCertificate); if (response == null) { throw new SafeguardForJavaException(String.format("Unable to connect to web service %s", a2AClient.getBaseURL())); @@ -111,7 +111,7 @@ public List getRetrievableAccounts() throws ObjectDispos int registrationId = registration.getId(); response = coreClient.execGET(String.format("A2ARegistrations/%d/RetrievableAccounts", registrationId), - parameters, headers, clientCertificate); + parameters, headers, null, clientCertificate); if (response == null) { throw new SafeguardForJavaException(String.format("Unable to connect to web service %s", a2AClient.getBaseURL())); @@ -164,7 +164,7 @@ public char[] retrievePassword(char[] apiKey) throws ObjectDisposedException, Sa Map parameters = new HashMap<>(); parameters.put("type", "Password"); - CloseableHttpResponse response = a2AClient.execGET("Credentials", parameters, headers, clientCertificate); + CloseableHttpResponse response = a2AClient.execGET("Credentials", parameters, headers, null, clientCertificate); if (response == null) { throw new SafeguardForJavaException(String.format("Unable to connect to web service %s", a2AClient.getBaseURL())); @@ -200,7 +200,7 @@ public char[] retrievePrivateKey(char[] apiKey, KeyFormat keyFormat) throws Obje parameters.put("type", "PrivateKey"); parameters.put("keyFormat", keyFormat.name()); - CloseableHttpResponse response = a2AClient.execGET("Credentials", parameters, headers, clientCertificate); + CloseableHttpResponse response = a2AClient.execGET("Credentials", parameters, headers, null, clientCertificate); if (response == null) { throw new SafeguardForJavaException(String.format("Unable to connect to web service %s", a2AClient.getBaseURL())); @@ -308,7 +308,7 @@ public String brokerAccessRequest(char[] apiKey, BrokeredAccessRequest accessReq Map parameters = new HashMap<>(); - CloseableHttpResponse response = a2AClient.execPOST("AccessRequests", parameters, headers, accessRequest, clientCertificate); + CloseableHttpResponse response = a2AClient.execPOST("AccessRequests", parameters, headers, null, accessRequest, clientCertificate); if (response == null) { throw new SafeguardForJavaException(String.format("Unable to connect to web service %s", a2AClient.getBaseURL())); diff --git a/src/main/java/com/oneidentity/safeguard/safeguardjava/SafeguardConnection.java b/src/main/java/com/oneidentity/safeguard/safeguardjava/SafeguardConnection.java index b94d98f..ca12a49 100644 --- a/src/main/java/com/oneidentity/safeguard/safeguardjava/SafeguardConnection.java +++ b/src/main/java/com/oneidentity/safeguard/safeguardjava/SafeguardConnection.java @@ -32,7 +32,8 @@ class SafeguardConnection implements ISafeguardConnection { private final RestClient coreClient; private final RestClient applianceClient; private final RestClient notificationClient; - + private final IStreamingRequest streamingRequest; + public SafeguardConnection(IAuthenticationMechanism authenticationMechanism) { this.authenticationMechanism = authenticationMechanism; @@ -47,6 +48,8 @@ public SafeguardConnection(IAuthenticationMechanism authenticationMechanism) { String safeguardNotificationUrl = String.format("https://%s/service/notification/v%d", this.authenticationMechanism.getNetworkAddress(), this.authenticationMechanism.getApiVersion()); notificationClient = new RestClient(safeguardNotificationUrl, authenticationMechanism.isIgnoreSsl(), authenticationMechanism.getValidationCallback()); + + streamingRequest = new StreamingRequest(this); } @Override @@ -74,17 +77,17 @@ public void refreshAccessToken() throws ObjectDisposedException, SafeguardForJav @Override public String invokeMethod(Service service, Method method, String relativeUrl, String body, - Map parameters, Map additionalHeaders) + Map parameters, Map additionalHeaders, Integer timeout) throws ObjectDisposedException, SafeguardForJavaException, ArgumentException { if (disposed) { throw new ObjectDisposedException("SafeguardConnection"); } - return invokeMethodFull(service, method, relativeUrl, body, parameters, additionalHeaders).getBody(); + return invokeMethodFull(service, method, relativeUrl, body, parameters, additionalHeaders, timeout).getBody(); } @Override public FullResponse invokeMethodFull(Service service, Method method, String relativeUrl, - String body, Map parameters, Map additionalHeaders) + String body, Map parameters, Map additionalHeaders, Integer timeout) throws ObjectDisposedException, SafeguardForJavaException, ArgumentException { if (disposed) { @@ -101,25 +104,20 @@ public FullResponse invokeMethodFull(Service service, Method method, String rela Map headers = prepareHeaders(additionalHeaders, service); CloseableHttpResponse response = null; - String msg = String.format("Invoking method: %s %s", method.toString().toUpperCase(), client.getBaseURL() + "/" + relativeUrl); - Logger.getLogger(SafeguardConnection.class.getName()).log(Level.FINEST, msg); - msg = parameters == null ? "None" : parameters.keySet().stream().map(key -> key + "=" + parameters.get(key)).collect(Collectors.joining(", ", "{", "}")); - Logger.getLogger(SafeguardConnection.class.getName()).log(Level.FINEST, " Query parameters: {0}", msg); - msg = headers == null ? "None" : headers.keySet().stream().map(key -> key + "=" + headers.get(key)).collect(Collectors.joining(", ", "{", "}")); - Logger.getLogger(SafeguardConnection.class.getName()).log(Level.FINEST, " Additional headers: {0}", msg); + logRequestDetails(method, client.getBaseURL() + "/" + relativeUrl, parameters, additionalHeaders); switch (method) { case Get: - response = client.execGET(relativeUrl, parameters, headers); + response = client.execGET(relativeUrl, parameters, headers, timeout); break; case Post: - response = client.execPOST(relativeUrl, parameters, headers, new JsonBody(body)); + response = client.execPOST(relativeUrl, parameters, headers, timeout, new JsonBody(body)); break; case Put: - response = client.execPUT(relativeUrl, parameters, headers, new JsonBody(body)); + response = client.execPUT(relativeUrl, parameters, headers, timeout, new JsonBody(body)); break; case Delete: - response = client.execDELETE(relativeUrl, parameters, headers); + response = client.execDELETE(relativeUrl, parameters, headers, timeout); break; } @@ -136,18 +134,14 @@ public FullResponse invokeMethodFull(Service service, Method method, String rela FullResponse fullResponse = new FullResponse(response.getStatusLine().getStatusCode(), response.getAllHeaders(), reply); - Logger.getLogger(SafeguardConnection.class.getName()).log(Level.FINEST, "Reponse status code: {0}", fullResponse.getStatusCode()); - msg = fullResponse.getHeaders() == null ? "None" : fullResponse.getHeaders().stream().map(header -> header.getName() + "=" + header.getValue()).collect(Collectors.joining(", ", "{", "}")); - Logger.getLogger(SafeguardConnection.class.getName()).log(Level.FINEST, " Response headers: {0}", msg); - msg = fullResponse.getBody() == null ? "None" : String.format("%d",fullResponse.getBody().length()); - Logger.getLogger(SafeguardConnection.class.getName()).log(Level.FINEST, " Body size: {0}", msg); + logResponseDetails(fullResponse); return fullResponse; } @Override public String invokeMethodCsv(Service service, Method method, String relativeUrl, - String body, Map parameters, Map additionalHeaders) + String body, Map parameters, Map additionalHeaders, Integer timeout) throws ObjectDisposedException, SafeguardForJavaException, ArgumentException { if (disposed) { @@ -158,7 +152,7 @@ public String invokeMethodCsv(Service service, Method method, String relativeUrl } additionalHeaders.put(HttpHeaders.ACCEPT, "text/csv"); - return invokeMethodFull(service, method, relativeUrl, body, parameters, additionalHeaders).getBody(); + return invokeMethodFull(service, method, relativeUrl, body, parameters, additionalHeaders, timeout).getBody(); } @Override @@ -194,7 +188,7 @@ public void logOut() throws ObjectDisposedException { if (!authenticationMechanism.hasAccessToken()) return; try { - this.invokeMethodFull(Service.Core, Method.Post, "Token/Logout", null, null, null); + this.invokeMethodFull(Service.Core, Method.Post, "Token/Logout", null, null, null, null); Logger.getLogger(SafeguardConnection.class.getName()).log(Level.FINEST, "Successfully logged out"); } catch (Exception ex) { @@ -204,7 +198,26 @@ public void logOut() throws ObjectDisposedException { Logger.getLogger(SafeguardConnection.class.getName()).log(Level.FINEST, "Cleared access token"); } - private RestClient getClientForService(Service service) throws SafeguardForJavaException { + static void logRequestDetails(Method method, String uri, Map parameters, Map headers) + { + String msg = String.format("Invoking method: %s %s", method.toString().toUpperCase(), uri); + Logger.getLogger(SafeguardConnection.class.getName()).log(Level.FINEST, msg); + msg = parameters == null ? "None" : parameters.keySet().stream().map(key -> key + "=" + parameters.get(key)).collect(Collectors.joining(", ", "{", "}")); + Logger.getLogger(SafeguardConnection.class.getName()).log(Level.FINEST, " Query parameters: {0}", msg); + msg = headers == null ? "None" : headers.keySet().stream().map(key -> key + "=" + headers.get(key)).collect(Collectors.joining(", ", "{", "}")); + Logger.getLogger(SafeguardConnection.class.getName()).log(Level.FINEST, " Additional headers: {0}", msg); + } + + static void logResponseDetails(FullResponse fullResponse) + { + Logger.getLogger(SafeguardConnection.class.getName()).log(Level.FINEST, "Reponse status code: {0}", fullResponse.getStatusCode()); + String msg = fullResponse.getHeaders() == null ? "None" : fullResponse.getHeaders().stream().map(header -> header.getName() + "=" + header.getValue()).collect(Collectors.joining(", ", "{", "}")); + Logger.getLogger(SafeguardConnection.class.getName()).log(Level.FINEST, " Response headers: {0}", msg); + msg = fullResponse.getBody() == null ? "None" : String.format("%d",fullResponse.getBody().length()); + Logger.getLogger(SafeguardConnection.class.getName()).log(Level.FINEST, " Body size: {0}", msg); + } + + RestClient getClientForService(Service service) throws SafeguardForJavaException { switch (service) { case Core: return coreClient; @@ -220,7 +233,7 @@ private RestClient getClientForService(Service service) throws SafeguardForJavaE } } - private Map prepareHeaders(Map additionalHeaders, Service service) + Map prepareHeaders(Map additionalHeaders, Service service) throws ObjectDisposedException { Map headers = new HashMap<>(); @@ -235,6 +248,14 @@ private Map prepareHeaders(Map additionalHeaders, } return headers; } + + boolean isDisposed() { + return disposed; + } + + IAuthenticationMechanism getAuthenticationMechanism() { + return authenticationMechanism; + } @Override public void dispose() @@ -260,4 +281,9 @@ public Object cloneObject() throws SafeguardForJavaException return new SafeguardConnection((IAuthenticationMechanism)authenticationMechanism.cloneObject()); } + @Override + public IStreamingRequest getStreamingRequest() { + return this.streamingRequest; + } + } diff --git a/src/main/java/com/oneidentity/safeguard/safeguardjava/StreamingRequest.java b/src/main/java/com/oneidentity/safeguard/safeguardjava/StreamingRequest.java new file mode 100644 index 0000000..1045d53 --- /dev/null +++ b/src/main/java/com/oneidentity/safeguard/safeguardjava/StreamingRequest.java @@ -0,0 +1,122 @@ +package com.oneidentity.safeguard.safeguardjava; + +import com.oneidentity.safeguard.safeguardjava.authentication.IAuthenticationMechanism; +import com.oneidentity.safeguard.safeguardjava.data.FullResponse; +import com.oneidentity.safeguard.safeguardjava.data.Method; +import com.oneidentity.safeguard.safeguardjava.data.Service; +import com.oneidentity.safeguard.safeguardjava.exceptions.ArgumentException; +import com.oneidentity.safeguard.safeguardjava.exceptions.ObjectDisposedException; +import com.oneidentity.safeguard.safeguardjava.exceptions.SafeguardForJavaException; +import com.oneidentity.safeguard.safeguardjava.restclient.OutputStreamProgress; +import com.oneidentity.safeguard.safeguardjava.restclient.RestClient; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Map; +import org.apache.http.client.methods.CloseableHttpResponse; + +class StreamingRequest implements IStreamingRequest { + + private final Integer DefaultBufferSize = 81920; + private final SafeguardConnection safeguardConnection; + private final IAuthenticationMechanism authenticationMechanism; + + StreamingRequest(SafeguardConnection safeguardConnection) + { + this.safeguardConnection = safeguardConnection; + this.authenticationMechanism = safeguardConnection.getAuthenticationMechanism(); + } + + @Override + public String uploadStream(Service service, String relativeUrl, byte[] stream, IProgressCallback progressCallback, Map parameters, Map additionalHeaders) + throws SafeguardForJavaException, ArgumentException, ObjectDisposedException { + + if (safeguardConnection.isDisposed()) + throw new ObjectDisposedException("SafeguardConnection"); + if (Utils.isNullOrEmpty(relativeUrl)) + throw new ArgumentException("Parameter relativeUrl may not be null or empty"); + + RestClient client = safeguardConnection.getClientForService(service); + if (!authenticationMechanism.isAnonymous() && !authenticationMechanism.hasAccessToken()) { + throw new SafeguardForJavaException("Access token is missing due to log out, you must refresh the access token to invoke a method"); + } + + Map headers = safeguardConnection.prepareHeaders(additionalHeaders, service); + CloseableHttpResponse response = null; + + SafeguardConnection.logRequestDetails(Method.Post, client.getBaseURL() + "/" + relativeUrl, parameters, additionalHeaders); + + response = client.execPOSTBytes(relativeUrl, parameters, headers, null, stream, progressCallback); + + if (response == null) { + throw new SafeguardForJavaException(String.format("Unable to connect to web service %s", client.getBaseURL())); + } + + String reply = Utils.getResponse(response); + + if (!Utils.isSuccessful(response.getStatusLine().getStatusCode())) { + throw new SafeguardForJavaException("Error returned from Safeguard API, Error: " + + String.format("%d %s", response.getStatusLine().getStatusCode(), reply)); + } + + FullResponse fullResponse = new FullResponse(response.getStatusLine().getStatusCode(), response.getAllHeaders(), reply); + + SafeguardConnection.logResponseDetails(fullResponse); + + return fullResponse.getBody(); + } + + @Override + public void downloadStream(Service service, String relativeUrl, String outputFilePath, IProgressCallback progressCallback, Map parameters, Map additionalHeaders) + throws SafeguardForJavaException, ArgumentException, ObjectDisposedException { + + if (safeguardConnection.isDisposed()) + throw new ObjectDisposedException("SafeguardConnection"); + if (Utils.isNullOrEmpty(relativeUrl)) + throw new ArgumentException("Parameter relativeUrl may not be null or empty"); + + RestClient client = safeguardConnection.getClientForService(service); + if (!authenticationMechanism.isAnonymous() && !authenticationMechanism.hasAccessToken()) { + throw new SafeguardForJavaException("Access token is missing due to log out, you must refresh the access token to invoke a method"); + } + + Map headers = safeguardConnection.prepareHeaders(additionalHeaders, service); + + SafeguardConnection.logRequestDetails(Method.Get, client.getBaseURL() + "/" + relativeUrl, parameters, additionalHeaders); + + CloseableHttpResponse response = client.execGETBytes(relativeUrl, parameters, headers, null, progressCallback); + + if (response == null) { + throw new SafeguardForJavaException(String.format("Unable to connect to web service %s", client.getBaseURL())); + } + + if (!Utils.isSuccessful(response.getStatusLine().getStatusCode())) { + String reply = Utils.getResponse(response); + throw new SafeguardForJavaException("Error returned from Safeguard API, Error: " + + String.format("%d %s", response.getStatusLine().getStatusCode(), reply)); + } + + InputStream input = null; + OutputStream output = null; + byte[] buffer = new byte[DefaultBufferSize]; + + try { + input = response.getEntity().getContent(); + output = new OutputStreamProgress(new FileOutputStream(outputFilePath), progressCallback, response.getEntity().getContentLength()); + + for (int length; (length = input.read(buffer)) > 0;) { + output.write(buffer, 0, length); + } + } catch (Exception ex) { + throw new SafeguardForJavaException(String.format("Unable to download %s", outputFilePath), ex); + } finally { + if (output != null) try { output.close(); } catch (IOException logOrIgnore) {} + if (input != null) try { input.close(); } catch (IOException logOrIgnore) {} + } + + FullResponse fullResponse = new FullResponse(response.getStatusLine().getStatusCode(), response.getAllHeaders(), null); + + SafeguardConnection.logResponseDetails(fullResponse); + } +} diff --git a/src/main/java/com/oneidentity/safeguard/safeguardjava/authentication/AnonymousAuthenticator.java b/src/main/java/com/oneidentity/safeguard/safeguardjava/authentication/AnonymousAuthenticator.java index bd91782..3951f51 100644 --- a/src/main/java/com/oneidentity/safeguard/safeguardjava/authentication/AnonymousAuthenticator.java +++ b/src/main/java/com/oneidentity/safeguard/safeguardjava/authentication/AnonymousAuthenticator.java @@ -22,7 +22,7 @@ public AnonymousAuthenticator(String networkAddress, int apiVersion, boolean ign Map headers = new HashMap<>(); headers.put(HttpHeaders.ACCEPT, "application/json"); headers.put(HttpHeaders.CONTENT_TYPE, "application/json"); - CloseableHttpResponse response = notificationClient.execGET("Status", null, headers); + CloseableHttpResponse response = notificationClient.execGET("Status", null, headers, null); if (response == null) { throw new SafeguardForJavaException(String.format("Unable to anonymously connect to web service %s", notificationClient.getBaseURL())); diff --git a/src/main/java/com/oneidentity/safeguard/safeguardjava/authentication/AuthenticatorBase.java b/src/main/java/com/oneidentity/safeguard/safeguardjava/authentication/AuthenticatorBase.java index 2373512..91d8eb4 100644 --- a/src/main/java/com/oneidentity/safeguard/safeguardjava/authentication/AuthenticatorBase.java +++ b/src/main/java/com/oneidentity/safeguard/safeguardjava/authentication/AuthenticatorBase.java @@ -111,7 +111,7 @@ public int getAccessTokenLifetimeRemaining() throws ObjectDisposedException, Saf headers.put(HttpHeaders.AUTHORIZATION, String.format("Bearer %s", new String(accessToken))); headers.put("X-TokenLifetimeRemaining", ""); - CloseableHttpResponse response = coreClient.execGET("LoginMessage", null, headers); + CloseableHttpResponse response = coreClient.execGET("LoginMessage", null, headers, null); if (response == null) { throw new SafeguardForJavaException(String.format("Unable to connect to web service %s", coreClient.getBaseURL())); @@ -145,7 +145,7 @@ public void refreshAccessToken() throws ObjectDisposedException, SafeguardForJav char[] rStsToken = getRstsTokenInternal(); AccessTokenBody body = new AccessTokenBody(rStsToken); - CloseableHttpResponse response = coreClient.execPOST("Token/LoginResponse", null, null, body); + CloseableHttpResponse response = coreClient.execPOST("Token/LoginResponse", null, null, null, body); if (response == null) { throw new SafeguardForJavaException(String.format("Unable to connect to web service %s", coreClient.getBaseURL())); @@ -180,10 +180,10 @@ public String resolveProviderToScope(String provider) throws SafeguardForJavaExc parameters.put("redirect_uri", "urn:InstalledApplication"); parameters.put("loginRequestStep", "1"); - response = rstsClient.execPOST("UserLogin/LoginController", parameters, headers, new JsonBody("RelayState=")); + response = rstsClient.execPOST("UserLogin/LoginController", parameters, headers, null, new JsonBody("RelayState=")); if (response == null || (!Utils.isSuccessful(response.getStatusLine().getStatusCode()))) - response = rstsClient.execGET("UserLogin/LoginController", parameters, headers); + response = rstsClient.execGET("UserLogin/LoginController", parameters, headers, null); if (response == null) throw new SafeguardForJavaException("Unable to connect to RSTS to find identity provider scopes"); diff --git a/src/main/java/com/oneidentity/safeguard/safeguardjava/authentication/CertificateAuthenticator.java b/src/main/java/com/oneidentity/safeguard/safeguardjava/authentication/CertificateAuthenticator.java index a469d7b..17d03fc 100644 --- a/src/main/java/com/oneidentity/safeguard/safeguardjava/authentication/CertificateAuthenticator.java +++ b/src/main/java/com/oneidentity/safeguard/safeguardjava/authentication/CertificateAuthenticator.java @@ -111,7 +111,7 @@ protected char[] getRstsTokenInternal() throws ObjectDisposedException, Safeguar CloseableHttpResponse response = null; OauthBody body = new OauthBody("client_credentials", providerScope); - response = rstsClient.execPOST("oauth2/token", null, null, body, clientCertificate); + response = rstsClient.execPOST("oauth2/token", null, null, null, body, clientCertificate); if (response == null) throw new SafeguardForJavaException(String.format("Unable to connect to RSTS service %s", rstsClient.getBaseURL())); diff --git a/src/main/java/com/oneidentity/safeguard/safeguardjava/authentication/PasswordAuthenticator.java b/src/main/java/com/oneidentity/safeguard/safeguardjava/authentication/PasswordAuthenticator.java index 802702c..76d04db 100644 --- a/src/main/java/com/oneidentity/safeguard/safeguardjava/authentication/PasswordAuthenticator.java +++ b/src/main/java/com/oneidentity/safeguard/safeguardjava/authentication/PasswordAuthenticator.java @@ -51,7 +51,7 @@ protected char[] getRstsTokenInternal() throws ObjectDisposedException, Safeguar providerScope = resolveProviderToScope(provider); OauthBody body = new OauthBody("password", username, password, providerScope); - CloseableHttpResponse response = rstsClient.execPOST("oauth2/token", null, null, body); + CloseableHttpResponse response = rstsClient.execPOST("oauth2/token", null, null, null, body); if (response == null) throw new SafeguardForJavaException(String.format("Unable to connect to RSTS service %s", rstsClient.getBaseURL())); diff --git a/src/main/java/com/oneidentity/safeguard/safeguardjava/data/TransferProgress.java b/src/main/java/com/oneidentity/safeguard/safeguardjava/data/TransferProgress.java new file mode 100644 index 0000000..6d909a1 --- /dev/null +++ b/src/main/java/com/oneidentity/safeguard/safeguardjava/data/TransferProgress.java @@ -0,0 +1,26 @@ +package com.oneidentity.safeguard.safeguardjava.data; + +public class TransferProgress { + private long BytesTransferred; + private long BytesTotal; + + public long getBytesTransferred() { + return BytesTransferred; + } + + public void setBytesTransferred(long BytesTransferred) { + this.BytesTransferred = BytesTransferred; + } + + public long getBytesTotal() { + return BytesTotal; + } + + public void setBytesTotal(long BytesTotal) { + this.BytesTotal = BytesTotal; + } + + public int getPercentComplete() { + return BytesTotal == 0 ? 0 : (int)((double)BytesTransferred / BytesTotal * 100); + } +} diff --git a/src/main/java/com/oneidentity/safeguard/safeguardjava/restclient/ByteArrayEntity.java b/src/main/java/com/oneidentity/safeguard/safeguardjava/restclient/ByteArrayEntity.java new file mode 100644 index 0000000..8d8cbda --- /dev/null +++ b/src/main/java/com/oneidentity/safeguard/safeguardjava/restclient/ByteArrayEntity.java @@ -0,0 +1,39 @@ +package com.oneidentity.safeguard.safeguardjava.restclient; + +import com.oneidentity.safeguard.safeguardjava.IProgressCallback; +import java.io.IOException; +import java.io.OutputStream; + +public class ByteArrayEntity extends org.apache.http.entity.ByteArrayEntity { + + private OutputStreamProgress outstream; + private final IProgressCallback progressCallback; + private final long totalBytes; + + public ByteArrayEntity(byte[] b, IProgressCallback progressCallback) { + super(b); + this.progressCallback = progressCallback; + this.totalBytes = b.length; + } + + @Override + public void writeTo(OutputStream outstream) throws IOException { + this.outstream = new OutputStreamProgress(outstream, this.progressCallback, totalBytes); + super.writeTo(this.outstream); + } + + /** + * Progress: 0-100 + */ + public int getProgress() { + if (outstream == null) { + return 0; + } + long contentLength = getContentLength(); + if (contentLength <= 0) { // Prevent division by zero and negative values + return 0; + } + long writtenLength = outstream.getWrittenLength(); + return (int) (100*writtenLength/contentLength); + } +} diff --git a/src/main/java/com/oneidentity/safeguard/safeguardjava/restclient/OutputStreamProgress.java b/src/main/java/com/oneidentity/safeguard/safeguardjava/restclient/OutputStreamProgress.java new file mode 100644 index 0000000..ebb0989 --- /dev/null +++ b/src/main/java/com/oneidentity/safeguard/safeguardjava/restclient/OutputStreamProgress.java @@ -0,0 +1,71 @@ +package com.oneidentity.safeguard.safeguardjava.restclient; + +import com.oneidentity.safeguard.safeguardjava.IProgressCallback; +import com.oneidentity.safeguard.safeguardjava.data.TransferProgress; +import java.io.IOException; +import java.io.OutputStream; + +public class OutputStreamProgress extends OutputStream { + + private final OutputStream outstream; + private final IProgressCallback progressCallback; + private final TransferProgress transferProgress = new TransferProgress(); + private int lastSentPercent = 5; + private volatile long bytesWritten=0; + + public OutputStreamProgress(OutputStream outstream, IProgressCallback progressCallback, long totalBytes) { + this.outstream = outstream; + this.progressCallback = progressCallback; + this.transferProgress.setBytesTotal(totalBytes); + this.transferProgress.setBytesTransferred(bytesWritten); + } + + private void sendProgress() { + transferProgress.setBytesTransferred(bytesWritten); + if (transferProgress.getPercentComplete() >= lastSentPercent) { + lastSentPercent += 5; + progressCallback.checkProgress(transferProgress); + } + } + + @Override + public void write(int b) throws IOException { + outstream.write(b); + bytesWritten++; + if (progressCallback != null) { + sendProgress(); + } + } + + @Override + public void write(byte[] b) throws IOException { + outstream.write(b); + bytesWritten += b.length; + if (progressCallback != null) { + sendProgress(); + } + } + + @Override + public void write(byte[] b, int off, int len) throws IOException { + outstream.write(b, off, len); + bytesWritten += len; + if (progressCallback != null) { + sendProgress(); + } + } + + @Override + public void flush() throws IOException { + outstream.flush(); + } + + @Override + public void close() throws IOException { + outstream.close(); + } + + public long getWrittenLength() { + return bytesWritten; + } +} \ No newline at end of file diff --git a/src/main/java/com/oneidentity/safeguard/safeguardjava/restclient/RestClient.java b/src/main/java/com/oneidentity/safeguard/safeguardjava/restclient/RestClient.java index 1d0dd54..5dd948a 100644 --- a/src/main/java/com/oneidentity/safeguard/safeguardjava/restclient/RestClient.java +++ b/src/main/java/com/oneidentity/safeguard/safeguardjava/restclient/RestClient.java @@ -1,7 +1,7 @@ package com.oneidentity.safeguard.safeguardjava.restclient; -import com.oneidentity.safeguard.safeguardjava.CertificateUtilities; import static com.oneidentity.safeguard.safeguardjava.CertificateUtilities.WINDOWSKEYSTORE; +import com.oneidentity.safeguard.safeguardjava.IProgressCallback; import com.oneidentity.safeguard.safeguardjava.data.CertificateContext; import com.oneidentity.safeguard.safeguardjava.data.JsonObject; import java.io.ByteArrayInputStream; @@ -22,6 +22,7 @@ import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.logging.ConsoleHandler; @@ -38,6 +39,7 @@ import javax.net.ssl.X509KeyManager; import javax.net.ssl.X509TrustManager; import org.apache.http.HttpHeaders; +import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.RequestBuilder; import org.apache.http.config.Registry; @@ -101,9 +103,9 @@ public String getBaseURL() { return serverUrl; } - public CloseableHttpResponse execGET(String path, Map queryParams, Map headers) { + public CloseableHttpResponse execGET(String path, Map queryParams, Map headers, Integer timeout) { - RequestBuilder rb = prepareRequest (RequestBuilder.get(getBaseURI(path)), queryParams, headers); + RequestBuilder rb = prepareRequest (RequestBuilder.get(getBaseURI(path)), queryParams, headers, timeout); try { CloseableHttpResponse r = client.execute(rb.build()); @@ -113,12 +115,12 @@ public CloseableHttpResponse execGET(String path, Map queryParam } } - public CloseableHttpResponse execGET(String path, Map queryParams, Map headers, CertificateContext certificateContext) { + public CloseableHttpResponse execGET(String path, Map queryParams, Map headers, Integer timeout, CertificateContext certificateContext) { CloseableHttpClient certClient = getClientWithCertificate(certificateContext); if (certClient != null) { - RequestBuilder rb = prepareRequest(RequestBuilder.get(getBaseURI(path)), queryParams, headers); + RequestBuilder rb = prepareRequest(RequestBuilder.get(getBaseURI(path)), queryParams, headers, timeout); try { CloseableHttpResponse r = certClient.execute(rb.build()); @@ -129,10 +131,49 @@ public CloseableHttpResponse execGET(String path, Map queryParam } return null; } + + public CloseableHttpResponse execGETBytes(String path, Map queryParams, Map headers, + Integer timeout, IProgressCallback progressCallback) { - public CloseableHttpResponse execPUT(String path, Map queryParams, Map headers, JsonObject requestEntity) { + if (headers == null || !headers.containsKey(HttpHeaders.ACCEPT)) { + headers = headers == null ? new HashMap() : headers; + headers.put(HttpHeaders.ACCEPT, "application/octet-stream"); + } + RequestBuilder rb = prepareRequest(RequestBuilder.get(getBaseURI(path)), queryParams, headers, timeout); - RequestBuilder rb = prepareRequest(RequestBuilder.put(getBaseURI(path)), queryParams, headers); + try { + CloseableHttpResponse r = client.execute(rb.build()); + return r; + } catch (IOException ex) { + return null; + } + } + + public CloseableHttpResponse execGETBytes(String path, Map queryParams, Map headers, + Integer timeout, CertificateContext certificateContext, IProgressCallback progressCallback) { + + CloseableHttpClient certClient = getClientWithCertificate(certificateContext); + + if (certClient != null) { + if (headers == null || !headers.containsKey(HttpHeaders.ACCEPT)) { + headers = headers == null ? new HashMap() : headers; + headers.put(HttpHeaders.ACCEPT, "application/octet-stream"); + } + RequestBuilder rb = prepareRequest(RequestBuilder.get(getBaseURI(path)), queryParams, headers, timeout); + + try { + CloseableHttpResponse r = client.execute(rb.build()); + return r; + } catch (IOException ex) { + return null; + } + } + return null; + } + + public CloseableHttpResponse execPUT(String path, Map queryParams, Map headers, Integer timeout, JsonObject requestEntity) { + + RequestBuilder rb = prepareRequest(RequestBuilder.put(getBaseURI(path)), queryParams, headers, timeout); try { rb.setEntity(new StringEntity(requestEntity.toJson())); @@ -143,9 +184,9 @@ public CloseableHttpResponse execPUT(String path, Map queryParam } } - public CloseableHttpResponse execPOST(String path, Map queryParams, Map headers, JsonObject requestEntity) { + public CloseableHttpResponse execPOST(String path, Map queryParams, Map headers, Integer timeout, JsonObject requestEntity) { - RequestBuilder rb = prepareRequest(RequestBuilder.post(getBaseURI(path)), queryParams, headers); + RequestBuilder rb = prepareRequest(RequestBuilder.post(getBaseURI(path)), queryParams, headers, timeout); try { rb.setEntity(new StringEntity(requestEntity.toJson())); @@ -156,29 +197,70 @@ public CloseableHttpResponse execPOST(String path, Map queryPara } } - public CloseableHttpResponse execPOST(String path, Map queryParams, Map headers, JsonObject requestEntity, - CertificateContext certificateContext) { + public CloseableHttpResponse execPOST(String path, Map queryParams, Map headers, Integer timeout, + JsonObject requestEntity, CertificateContext certificateContext) { CloseableHttpClient certClient = getClientWithCertificate(certificateContext); if (certClient != null) { - RequestBuilder rb = prepareRequest(RequestBuilder.post(getBaseURI(path)), queryParams, headers); + RequestBuilder rb = prepareRequest(RequestBuilder.post(getBaseURI(path)), queryParams, headers, timeout); try { rb.setEntity(new StringEntity(requestEntity.toJson())); CloseableHttpResponse r = certClient.execute(rb.build()); return r; - } catch (Exception ex) { + } catch (IOException ex) { return null; } } return null; } + + public CloseableHttpResponse execPOSTBytes(String path, Map queryParams, Map headers, Integer timeout, + byte[] requestEntity, IProgressCallback progressCallback) { - public CloseableHttpResponse execDELETE(String path, Map queryParams, Map headers) { + if (headers == null || !headers.containsKey(HttpHeaders.CONTENT_TYPE)) { + headers = headers == null ? new HashMap() : headers; + headers.put(HttpHeaders.CONTENT_TYPE, "application/octet-stream"); + } + RequestBuilder rb = prepareRequest(RequestBuilder.post(getBaseURI(path)), queryParams, headers, timeout); - RequestBuilder rb = prepareRequest(RequestBuilder.delete(getBaseURI(path)), queryParams, headers); + try { + rb.setEntity(new ByteArrayEntity(requestEntity, progressCallback)); + CloseableHttpResponse r = client.execute(rb.build()); + return r; + } catch (IOException ex) { + return null; + } + } + + public CloseableHttpResponse execPOSTBytes(String path, Map queryParams, Map headers, Integer timeout, + byte[] requestEntity, CertificateContext certificateContext, IProgressCallback progressCallback) { + + CloseableHttpClient certClient = getClientWithCertificate(certificateContext); + + if (certClient != null) { + if (headers == null || !headers.containsKey(HttpHeaders.CONTENT_TYPE)) { + headers = headers == null ? new HashMap() : headers; + headers.put(HttpHeaders.CONTENT_TYPE, "application/octet-stream"); + } + RequestBuilder rb = prepareRequest(RequestBuilder.post(getBaseURI(path)), queryParams, headers, timeout); + + try { + rb.setEntity(new ByteArrayEntity(requestEntity, progressCallback)); + CloseableHttpResponse r = client.execute(rb.build()); + return r; + } catch (IOException ex) { + return null; + } + } + return null; + } + + public CloseableHttpResponse execDELETE(String path, Map queryParams, Map headers, Integer timeout) { + + RequestBuilder rb = prepareRequest(RequestBuilder.delete(getBaseURI(path)), queryParams, headers, timeout); try { CloseableHttpResponse r = client.execute(rb.build()); @@ -241,7 +323,7 @@ private CloseableHttpClient getClientWithCertificate(CertificateContext certific return certClient; } - private RequestBuilder prepareRequest(RequestBuilder rb, Map queryParams, Map headers) { + private RequestBuilder prepareRequest(RequestBuilder rb, Map queryParams, Map headers, Integer timeout) { if (headers == null || !headers.containsKey(HttpHeaders.ACCEPT)) rb.addHeader(HttpHeaders.ACCEPT, "application/json"); @@ -258,6 +340,13 @@ private RequestBuilder prepareRequest(RequestBuilder rb, Map que rb.addParameter(entry.getKey(), entry.getValue()); } } + if (timeout != null) { + RequestConfig rconfig = RequestConfig.custom() + .setConnectTimeout(timeout) + .setConnectionRequestTimeout(timeout) + .setSocketTimeout(timeout).build(); + rb.setConfig(rconfig); + } return rb; } diff --git a/tests/safeguardjavaclient/pom.xml b/tests/safeguardjavaclient/pom.xml index 936ded7..9f4e1d1 100644 --- a/tests/safeguardjavaclient/pom.xml +++ b/tests/safeguardjavaclient/pom.xml @@ -23,7 +23,7 @@ com.oneidentity.safeguard safeguardjava - 6.8.0-SNAPSHOT + 6.9.0-SNAPSHOT diff --git a/tests/safeguardjavaclient/src/main/java/com/oneidentity/safeguard/safeguardclient/ProgressNotification.java b/tests/safeguardjavaclient/src/main/java/com/oneidentity/safeguard/safeguardclient/ProgressNotification.java new file mode 100644 index 0000000..4024d67 --- /dev/null +++ b/tests/safeguardjavaclient/src/main/java/com/oneidentity/safeguard/safeguardclient/ProgressNotification.java @@ -0,0 +1,13 @@ +package com.oneidentity.safeguard.safeguardclient; + +import com.oneidentity.safeguard.safeguardjava.IProgressCallback; +import com.oneidentity.safeguard.safeguardjava.data.TransferProgress; + +public class ProgressNotification implements IProgressCallback { + + @Override + public void checkProgress(TransferProgress transferProgress) { + System.out.println(String.format("\tBytes transfered %d done", transferProgress.getPercentComplete())); + } + +} diff --git a/tests/safeguardjavaclient/src/main/java/com/oneidentity/safeguard/safeguardclient/SafeguardJavaClient.java b/tests/safeguardjavaclient/src/main/java/com/oneidentity/safeguard/safeguardclient/SafeguardJavaClient.java index 46c9901..6e57b0e 100644 --- a/tests/safeguardjavaclient/src/main/java/com/oneidentity/safeguard/safeguardclient/SafeguardJavaClient.java +++ b/tests/safeguardjavaclient/src/main/java/com/oneidentity/safeguard/safeguardclient/SafeguardJavaClient.java @@ -86,6 +86,12 @@ public static void main(String[] args) { case 19: eventListener = tests.safeguardDisconnectEventListener(eventListener); break; + case 20: + tests.safeguardTestBackupDownload(connection); + break; + case 21: + tests.safeguardTestBackupUpload(connection); + break; default: done = true; break; @@ -117,6 +123,8 @@ private static Integer displayMenu() { System.out.println ("\t17. Event Listener by thumbprint"); System.out.println ("\t18. Test Event Listener"); System.out.println ("\t19. Disconnect Event Listener"); + System.out.println ("\t20. Test Download Backup File"); + System.out.println ("\t21. Test Upload Backup File"); System.out.println ("\t99. Exit"); diff --git a/tests/safeguardjavaclient/src/main/java/com/oneidentity/safeguard/safeguardclient/SafeguardTests.java b/tests/safeguardjavaclient/src/main/java/com/oneidentity/safeguard/safeguardclient/SafeguardTests.java index 1b6a200..0a0959f 100644 --- a/tests/safeguardjavaclient/src/main/java/com/oneidentity/safeguard/safeguardclient/SafeguardTests.java +++ b/tests/safeguardjavaclient/src/main/java/com/oneidentity/safeguard/safeguardclient/SafeguardTests.java @@ -1,6 +1,7 @@ package com.oneidentity.safeguard.safeguardclient; import static com.oneidentity.safeguard.safeguardclient.SafeguardJavaClient.readLine; +import com.oneidentity.safeguard.safeguardjava.IProgressCallback; import com.oneidentity.safeguard.safeguardjava.ISafeguardA2AContext; import com.oneidentity.safeguard.safeguardjava.ISafeguardConnection; import com.oneidentity.safeguard.safeguardjava.Safeguard; @@ -15,6 +16,9 @@ import com.oneidentity.safeguard.safeguardjava.exceptions.ArgumentException; import com.oneidentity.safeguard.safeguardjava.exceptions.ObjectDisposedException; import com.oneidentity.safeguard.safeguardjava.exceptions.SafeguardForJavaException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.List; public class SafeguardTests { @@ -183,15 +187,15 @@ public void safeguardTestConnection(ISafeguardConnection connection) { int remaining = connection.getAccessTokenLifetimeRemaining(); System.out.println(String.format("\tTime remaining: %d", remaining)); - String response = connection.invokeMethod(Service.Core, Method.Get, "Users", null, null, null); + String response = connection.invokeMethod(Service.Core, Method.Get, "Users", null, null, null, null); System.out.println(String.format("\t\\Users response:")); System.out.println(response); - FullResponse fullResponse = connection.invokeMethodFull(Service.Core, Method.Get, "Users", null, null, null); + FullResponse fullResponse = connection.invokeMethodFull(Service.Core, Method.Get, "Users", null, null, null, null); System.out.println(String.format("\t\\Users full response:")); System.out.println(fullResponse.toString()); - response = connection.invokeMethod(Service.Notification, Method.Get, "Status", null, null, null); + response = connection.invokeMethod(Service.Notification, Method.Get, "Status", null, null, null, null); System.out.println(String.format("\t\\Appliance status:")); System.out.println(response); @@ -487,4 +491,62 @@ public ISafeguardEventListener safeguardDisconnectEventListener(ISafeguardEventL return null; } + public void safeguardTestBackupDownload(ISafeguardConnection connection) { + + if (connection == null) { + System.out.println(String.format("Safeguard not connected")); + return; + } + + String backupId = readLine("Backup Id: ", null); + String backupFileName = readLine("Backup File Name: ", null); + boolean withProgress = readLine("With Progress Notification(y/n): ", "n").equalsIgnoreCase("y"); + + if (backupId == null || backupFileName == null) { + System.out.println(String.format("Missing id or file name")); + return; + } + + try { + String filePath = Paths.get(".", backupFileName).toAbsolutePath().toString(); + IProgressCallback progressCallback = withProgress ? new ProgressNotification() : null; + System.out.println(String.format("\tFile path: %s", filePath)); + connection.getStreamingRequest().downloadStream(Service.Appliance, String.format("Backups/%s/Download", backupId), filePath, progressCallback, null, null); + System.out.println(String.format("\tDownloaded file: %s", backupFileName)); + } catch (ObjectDisposedException | SafeguardForJavaException ex) { + System.out.println("\t[ERROR]Test backup download failed: " + ex.getMessage()); + } catch (Exception ex) { + System.out.println("\t[ERROR]Test backup download failed: " + ex.getMessage()); + } + } + + public void safeguardTestBackupUpload(ISafeguardConnection connection) { + + if (connection == null) { + System.out.println(String.format("Safeguard not connected")); + return; + } + + String backupFileName = readLine("Backup File Name: ", null); + boolean withProgress = readLine("With Progress Notification(y/n): ", "n").equalsIgnoreCase("y"); + + if (backupFileName == null) { + System.out.println(String.format("Missing id or file name")); + return; + } + + try { + Path filePath = Paths.get(".", backupFileName).toAbsolutePath(); + IProgressCallback progressCallback = withProgress ? new ProgressNotification() : null; + byte[] fileContent = Files.readAllBytes(filePath); + System.out.println(String.format("\tFile path: %s", filePath.toAbsolutePath())); + connection.getStreamingRequest().uploadStream(Service.Appliance, "Backups/Upload", fileContent, progressCallback, null, null); + System.out.println(String.format("\tUploaded file: %s", backupFileName)); + } catch (ObjectDisposedException | SafeguardForJavaException ex) { + System.out.println("\t[ERROR]Test backup download failed: " + ex.getMessage()); + } catch (Exception ex) { + System.out.println("\t[ERROR]Test backup download failed: " + ex.getMessage()); + } + } + }