From 3f01b590f28bc6f02e4f3a34d909f29d73e805cb Mon Sep 17 00:00:00 2001 From: Mauro Mugnaini Date: Mon, 21 Dec 2020 18:10:16 +0100 Subject: [PATCH] Refactored/extracted event sender that uses OIDC token only and extended it for the UMA version --- .../HTTPWithOIDCAuthEventSender.java | 133 ++++++++++++++++++ .../publisher/HTTPWithUMAAuthEventSender.java | 117 ++------------- 2 files changed, 146 insertions(+), 104 deletions(-) create mode 100644 src/main/java/org/gcube/event/publisher/HTTPWithOIDCAuthEventSender.java diff --git a/src/main/java/org/gcube/event/publisher/HTTPWithOIDCAuthEventSender.java b/src/main/java/org/gcube/event/publisher/HTTPWithOIDCAuthEventSender.java new file mode 100644 index 0000000..0f48c97 --- /dev/null +++ b/src/main/java/org/gcube/event/publisher/HTTPWithOIDCAuthEventSender.java @@ -0,0 +1,133 @@ +package org.gcube.event.publisher; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; + +import org.gcube.oidc.rest.JWTToken; +import org.gcube.oidc.rest.OpenIdConnectRESTHelper; +import org.gcube.oidc.rest.OpenIdConnectRESTHelperException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class HTTPWithOIDCAuthEventSender implements EventSender { + + protected static final Logger log = LoggerFactory.getLogger(HTTPWithOIDCAuthEventSender.class); + + private URL baseEnndpointURL; + private String clientId; + private String clientSecret; + private URL tokenURL; + + public HTTPWithOIDCAuthEventSender(URL baseEnndpointURL, String clientId, String clientSecret, URL tokenURL) { + this.baseEnndpointURL = baseEnndpointURL; + this.clientId = clientId; + this.clientSecret = clientSecret; + this.tokenURL = tokenURL; + } + + @Override + public void send(Event event) { + log.debug("Starting HTTP POST thread to: {}", baseEnndpointURL); + try { + URL eventEndpoint = new URL(baseEnndpointURL, event.getName()); + new Thread(new HTTPost(eventEndpoint, event)).start(); + } catch (MalformedURLException e) { + log.error("Cannot compute event endpoint URL. Event name: " + event.getName() + ", base endpoint: " + + baseEnndpointURL, e); + } + } + + protected URL getTokenURL() { + return tokenURL; + } + + protected JWTToken getAuthorizationToken() throws OpenIdConnectRESTHelperException { + if (clientId != null && clientSecret != null && tokenURL != null) { + log.debug("Getting OIDC token for clientId '{}' from: {}", clientId, tokenURL); + return OpenIdConnectRESTHelper.queryClientToken(clientId, clientSecret, tokenURL); + } else { + log.debug("Can't get OIDC token since not all the required params were provied"); + return null; + } + } + + public class HTTPost implements Runnable { + + private static final int CONNECTION_TIMEOUT = 10000; + private static final int READ_TIMEOUT = 5000; + + private URL endpoint; + private Event event; + + public HTTPost(URL endpoint, Event event) { + this.endpoint = endpoint; + this.event = event; + } + + @Override + public void run() { + try { + log.debug("Getting auth token for client '{}' if needed", clientId); + JWTToken token = getAuthorizationToken(); + + log.debug("Performing HTTP POST to: {}", endpoint); + HttpURLConnection connection = (HttpURLConnection) endpoint.openConnection(); + connection.setRequestMethod("POST"); + connection.setConnectTimeout(CONNECTION_TIMEOUT); + log.trace("HTTP connection timeout set to: {}", connection.getConnectTimeout()); + connection.setReadTimeout(READ_TIMEOUT); + log.trace("HTTP connection Read timeout set to: {}", connection.getReadTimeout()); + connection.setRequestProperty("Content-Type", "application/json"); + // Commented out as per the Conductor issue: https://github.com/Netflix/conductor/issues/376 + // connection.setRequestProperty("Accept", "application/json"); + connection.setDoOutput(true); + if (token != null) { + log.debug("Setting authorization header as: {}", token.getAccessTokenAsBearer()); + connection.setRequestProperty("Authorization", token.getAccessTokenAsBearer()); + } else { + log.debug("Sending request without authorization header"); + } + OutputStream os = connection.getOutputStream(); + String jsonString = event.toJSONString(); + log.trace("Sending event JSON: {}", jsonString); + os.write(jsonString.getBytes("UTF-8")); + os.flush(); + os.close(); + + StringBuilder sb = new StringBuilder(); + int httpResultCode = connection.getResponseCode(); + log.trace("HTTP Response code: {}", httpResultCode); + + log.trace("Reading response"); + boolean ok = true; + InputStreamReader isr = null; + if (httpResultCode == HttpURLConnection.HTTP_OK) { + isr = new InputStreamReader(connection.getInputStream(), "UTF-8"); + } else { + ok = false; + isr = new InputStreamReader(connection.getErrorStream(), "UTF-8"); + } + BufferedReader br = new BufferedReader(isr); + String line = null; + while ((line = br.readLine()) != null) { + sb.append(line + "\n"); + } + br.close(); + isr.close(); + if (ok) { + log.info("[{}] Event publish for {} is OK", httpResultCode, event.getName()); + } else { + log.debug("[{}] Event publish for {} is not OK", httpResultCode, event.getName()); + } + log.trace("Response message from server: {}", sb.toString()); + } catch (Exception e) { + log.error("POSTing JSON to: " + endpoint, e); + } + } + } + +} \ No newline at end of file diff --git a/src/main/java/org/gcube/event/publisher/HTTPWithUMAAuthEventSender.java b/src/main/java/org/gcube/event/publisher/HTTPWithUMAAuthEventSender.java index 70daacf..e7ef242 100644 --- a/src/main/java/org/gcube/event/publisher/HTTPWithUMAAuthEventSender.java +++ b/src/main/java/org/gcube/event/publisher/HTTPWithUMAAuthEventSender.java @@ -1,130 +1,39 @@ package org.gcube.event.publisher; -import java.io.BufferedReader; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.net.HttpURLConnection; -import java.net.MalformedURLException; import java.net.URL; import org.gcube.oidc.rest.JWTToken; import org.gcube.oidc.rest.OpenIdConnectRESTHelper; +import org.gcube.oidc.rest.OpenIdConnectRESTHelperException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class HTTPWithUMAAuthEventSender implements EventSender { +public class HTTPWithUMAAuthEventSender extends HTTPWithOIDCAuthEventSender { protected static final Logger log = LoggerFactory.getLogger(HTTPWithUMAAuthEventSender.class); - private URL baseEnndpointURL; - private String clientId; - private String clientSecret; - private URL tokenURL; private String umaAudience; public HTTPWithUMAAuthEventSender(URL baseEnndpointURL, String clientId, String clientSecret, URL tokenURL, String umaAudience) { - this.baseEnndpointURL = baseEnndpointURL; - this.clientId = clientId; - this.clientSecret = clientSecret; - this.tokenURL = tokenURL; + super(baseEnndpointURL, clientId, clientSecret, tokenURL); this.umaAudience = umaAudience; } @Override - public void send(Event event) { - log.debug("Starting HTTP POST thread to: {}", baseEnndpointURL); - try { - URL eventEndpoint = new URL(baseEnndpointURL, event.getName()); - new Thread(new HTTPost(eventEndpoint, event)).start(); - } catch (MalformedURLException e) { - log.error("Cannot compute event endpoint URL. Event name: " + event.getName() + ", base endpoint: " - + baseEnndpointURL, e); - } - } - - public class HTTPost implements Runnable { - - private static final int CONNECTION_TIMEOUT = 10000; - private static final int READ_TIMEOUT = 5000; - - private URL endpoint; - private Event event; - - public HTTPost(URL endpoint, Event event) { - this.endpoint = endpoint; - this.event = event; - } - - @Override - public void run() { - try { - log.debug("Getting OIDC token for client: {}", clientId); - JWTToken umaToken = null; - if (clientId != null && clientSecret != null && tokenURL != null && umaAudience != null) { - log.debug("Getting OIDC token for clientId '{}' from: {}", clientId, tokenURL); - JWTToken oidcToken = OpenIdConnectRESTHelper.queryClientToken(clientId, clientSecret, tokenURL); - log.debug("Getting UMA token for audience '{}' from: {}", umaAudience, tokenURL); - umaToken = OpenIdConnectRESTHelper.queryUMAToken(tokenURL, oidcToken.getAccessTokenAsBearer(), - umaAudience, null); - } else { - log.debug("Can't get UMA token since not all the required params was provied"); - } - log.debug("Performing HTTP POST to: {}", endpoint); - HttpURLConnection connection = (HttpURLConnection) endpoint.openConnection(); - connection.setRequestMethod("POST"); - connection.setConnectTimeout(CONNECTION_TIMEOUT); - log.trace("HTTP connection timeout set to: {}", connection.getConnectTimeout()); - connection.setReadTimeout(READ_TIMEOUT); - log.trace("HTTP connection Read timeout set to: {}", connection.getReadTimeout()); - connection.setRequestProperty("Content-Type", "application/json"); - // Commented out as per the Conductor issue: https://github.com/Netflix/conductor/issues/376 - // connection.setRequestProperty("Accept", "application/json"); - connection.setDoOutput(true); - if (umaToken != null) { - log.debug("Setting authorization header as: {}", umaToken.getAccessTokenAsBearer()); - connection.setRequestProperty("Authorization", umaToken.getAccessTokenAsBearer()); - } else { - log.debug("Sending request without authorization header"); - } - OutputStream os = connection.getOutputStream(); - String jsonString = event.toJSONString(); - log.trace("Sending event JSON: {}", jsonString); - os.write(jsonString.getBytes("UTF-8")); - os.flush(); - os.close(); - - StringBuilder sb = new StringBuilder(); - int httpResultCode = connection.getResponseCode(); - log.trace("HTTP Response code: {}", httpResultCode); - - log.trace("Reading response"); - boolean ok = true; - InputStreamReader isr = null; - if (httpResultCode == HttpURLConnection.HTTP_OK) { - isr = new InputStreamReader(connection.getInputStream(), "UTF-8"); - } else { - ok = false; - isr = new InputStreamReader(connection.getErrorStream(), "UTF-8"); - } - BufferedReader br = new BufferedReader(isr); - String line = null; - while ((line = br.readLine()) != null) { - sb.append(line + "\n"); - } - br.close(); - isr.close(); - if (ok) { - log.info("[{}] Event publish for {} is OK", httpResultCode, event.getName()); - } else { - log.debug("[{}] Event publish for {} is not OK", httpResultCode, event.getName()); - } - log.trace("Response message from server: {}", sb.toString()); - } catch (Exception e) { - log.error("POSTing JSON to: " + endpoint, e); + protected JWTToken getAuthorizationToken() throws OpenIdConnectRESTHelperException { + JWTToken oidcToken = super.getAuthorizationToken(); + if (oidcToken != null) { + if (umaAudience != null) { + log.debug("Getting UMA token for audience '{}' from: {}", umaAudience, getTokenURL()); + return OpenIdConnectRESTHelper.queryUMAToken(getTokenURL(), oidcToken.getAccessTokenAsBearer(), + umaAudience, null); + } else { + log.debug("Can't get UMA token since the required param was not provied"); } } + return oidcToken; } } \ No newline at end of file