From c5a6edd0b19e4fb78020967b0cc80bc3474b2c7f Mon Sep 17 00:00:00 2001 From: georgweiss Date: Mon, 20 Jan 2025 16:08:47 +0100 Subject: [PATCH] Switch to native HttpClient for legacy Olog client --- app/logbook/elog/pom.xml | 4 - app/logbook/olog/client/pom.xml | 14 - .../applications/logbook/OlogLogbook.java | 10 +- .../main/java/org/phoebus/olog/api/Olog.java | 31 - .../java/org/phoebus/olog/api/OlogClient.java | 697 ++++++++++-------- .../org/phoebus/olog/api/OlogException.java | 29 +- .../org/phoebus/olog/api/OlogProperties.java | 23 - .../org/phoebus/olog/api/Preferences.java | 31 + .../phoebus/olog/api/RawLoggingFilter.java | 282 ------- dependencies/phoebus-target/.classpath | 4 - dependencies/phoebus-target/pom.xml | 22 +- 11 files changed, 431 insertions(+), 716 deletions(-) delete mode 100644 app/logbook/olog/client/src/main/java/org/phoebus/olog/api/Olog.java delete mode 100644 app/logbook/olog/client/src/main/java/org/phoebus/olog/api/OlogProperties.java create mode 100644 app/logbook/olog/client/src/main/java/org/phoebus/olog/api/Preferences.java delete mode 100644 app/logbook/olog/client/src/main/java/org/phoebus/olog/api/RawLoggingFilter.java diff --git a/app/logbook/elog/pom.xml b/app/logbook/elog/pom.xml index 3042b44be7..ae14ea243f 100644 --- a/app/logbook/elog/pom.xml +++ b/app/logbook/elog/pom.xml @@ -7,10 +7,6 @@ app-logbook-elog - - - - org.phoebus core-logbook diff --git a/app/logbook/olog/client/pom.xml b/app/logbook/olog/client/pom.xml index b63ed3093f..7eb5316825 100644 --- a/app/logbook/olog/client/pom.xml +++ b/app/logbook/olog/client/pom.xml @@ -10,10 +10,6 @@ app-logbook-olog-client - - - - org.phoebus core-logbook @@ -46,16 +42,6 @@ jackson-databind ${jackson.version} - - com.sun.jersey - jersey-client - 1.19 - - - com.sun.jersey.contribs - jersey-multipart - 1.19 - javax.xml.bind jaxb-api diff --git a/app/logbook/olog/client/src/main/java/org/phoebus/applications/logbook/OlogLogbook.java b/app/logbook/olog/client/src/main/java/org/phoebus/applications/logbook/OlogLogbook.java index d062084199..e3ba94347e 100644 --- a/app/logbook/olog/client/src/main/java/org/phoebus/applications/logbook/OlogLogbook.java +++ b/app/logbook/olog/client/src/main/java/org/phoebus/applications/logbook/OlogLogbook.java @@ -5,6 +5,7 @@ import org.phoebus.logbook.LogClient; import org.phoebus.logbook.LogFactory; +import org.phoebus.olog.api.OlogClient; import org.phoebus.olog.api.OlogClient.OlogClientBuilder; import org.phoebus.security.tokens.SimpleAuthenticationToken; @@ -23,7 +24,7 @@ public String getId() { public LogClient getLogClient() { if (oLogClient == null) { try { - oLogClient = OlogClientBuilder.serviceURL().create(); + oLogClient = OlogClient.builder().build(); } catch (Exception e) { logger.log(Level.SEVERE, "Failed to create olog client", e); } @@ -36,11 +37,10 @@ public LogClient getLogClient(Object authToken) { try { if (authToken instanceof SimpleAuthenticationToken) { SimpleAuthenticationToken token = (SimpleAuthenticationToken) authToken; - return OlogClientBuilder.serviceURL().withHTTPAuthentication(true).username(token.getUsername()).password(token.getPassword()) - .create(); + return OlogClient.builder().username(token.getUsername()).password(token.getPassword()) + .build(); } else if (oLogClient == null) { - oLogClient = OlogClientBuilder.serviceURL().create(); - + oLogClient = OlogClient.builder().build(); } } catch (Exception e) { logger.log(Level.SEVERE, "Failed to create olog client", e); diff --git a/app/logbook/olog/client/src/main/java/org/phoebus/olog/api/Olog.java b/app/logbook/olog/client/src/main/java/org/phoebus/olog/api/Olog.java deleted file mode 100644 index dd675eced6..0000000000 --- a/app/logbook/olog/client/src/main/java/org/phoebus/olog/api/Olog.java +++ /dev/null @@ -1,31 +0,0 @@ -package org.phoebus.olog.api; - -import static org.phoebus.olog.api.OlogClient.OlogClientBuilder.*; - -import org.phoebus.logbook.LogClient; - -public class Olog { - private static volatile LogClient client; - - private Olog() { - - } - - public static void setClient(LogClient client) { - Olog.client = client; - } - - /** - * Returns the default {@link LogClient}. - * - * @return - * @throws Exception - */ - public static LogClient getClient() throws Exception { - if (client == null) { - Olog.client = serviceURL().withHTTPAuthentication(false).create(); - } - return client; - } - -} diff --git a/app/logbook/olog/client/src/main/java/org/phoebus/olog/api/OlogClient.java b/app/logbook/olog/client/src/main/java/org/phoebus/olog/api/OlogClient.java index 65997f2c4f..0d3dd02ffd 100644 --- a/app/logbook/olog/client/src/main/java/org/phoebus/olog/api/OlogClient.java +++ b/app/logbook/olog/client/src/main/java/org/phoebus/olog/api/OlogClient.java @@ -1,40 +1,52 @@ package org.phoebus.olog.api; -import com.sun.jersey.api.client.Client; -import com.sun.jersey.api.client.ClientResponse; -import com.sun.jersey.api.client.UniformInterfaceException; -import com.sun.jersey.api.client.WebResource; -import com.sun.jersey.api.client.config.ClientConfig; -import com.sun.jersey.api.client.config.DefaultClientConfig; -import com.sun.jersey.api.client.filter.HTTPBasicAuthFilter; -import com.sun.jersey.client.urlconnection.HTTPSProperties; -import com.sun.jersey.core.util.MultivaluedMapImpl; -import com.sun.jersey.multipart.FormDataMultiPart; -import com.sun.jersey.multipart.file.FileDataBodyPart; -import com.sun.jersey.multipart.impl.MultiPartWriter; -import org.phoebus.logbook.*; -import org.phoebus.security.managers.DummyX509TrustManager; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.phoebus.logbook.Attachment; +import org.phoebus.logbook.LogClient; +import org.phoebus.logbook.LogEntry; +import org.phoebus.logbook.Logbook; +import org.phoebus.logbook.LogbookException; +import org.phoebus.logbook.Messages; +import org.phoebus.logbook.Property; +import org.phoebus.logbook.SearchResult; +import org.phoebus.logbook.Tag; +import org.phoebus.security.store.SecureStore; +import org.phoebus.security.tokens.AuthenticationScope; +import org.phoebus.security.tokens.ScopedAuthenticationToken; +import org.phoebus.util.http.HttpRequestMultipartBody; +import org.phoebus.util.http.QueryParamsHelper; import org.phoebus.util.time.TimeParser; -import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLSession; -import javax.net.ssl.TrustManager; +import javax.net.ssl.SSLEngine; +import javax.net.ssl.X509ExtendedTrustManager; import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.MultivaluedHashMap; import javax.ws.rs.core.MultivaluedMap; -import javax.ws.rs.core.UriBuilder; import java.io.IOException; import java.io.InputStream; +import java.net.CookieManager; +import java.net.CookiePolicy; +import java.net.Socket; import java.net.URI; +import java.net.URLEncoder; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardCopyOption; -import java.security.KeyManagementException; -import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.security.cert.X509Certificate; +import java.time.Duration; import java.time.Instant; import java.time.temporal.TemporalAmount; import java.util.ArrayList; import java.util.Arrays; +import java.util.Base64; import java.util.Collection; import java.util.Collections; import java.util.HashSet; @@ -42,10 +54,8 @@ import java.util.List; import java.util.Map; import java.util.concurrent.Callable; -import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; @@ -58,95 +68,39 @@ public class OlogClient implements LogClient { private static final Logger logger = Logger.getLogger(OlogClient.class.getName()); - - private final WebResource service; + private final HttpClient httpClient; private final ExecutorService executor; + private final String basicAuthenticationHeader; + + private static final Logger LOGGER = Logger.getLogger(OlogClient.class.getName()); + + private static final ObjectMapper OBJECT_MAPPER; + + static { + OBJECT_MAPPER = new ObjectMapper(); + OBJECT_MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + OBJECT_MAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL); + } /** * Builder Class to help create a olog client. - * + * * @author shroffk - * */ public static class OlogClientBuilder { - // required - private URI ologURI = null; - // optional - private boolean withHTTPAuthentication = false; - private boolean withRawFilter; - - private ClientConfig clientConfig = null; - private TrustManager[] trustManager = new TrustManager[] { new DummyX509TrustManager() };; - @SuppressWarnings("unused") - private SSLContext sslContext = null; - - private String protocol = null; private String username = null; private String password = null; - private String connectTimeoutAsString = null; - - private ExecutorService executor = Executors.newSingleThreadExecutor(); - - private OlogProperties properties = new OlogProperties(); - + private final URI uri; private OlogClientBuilder() { - this.ologURI = URI.create(this.properties.getPreferenceValue("olog_url")); - this.protocol = this.ologURI.getScheme(); - } - - private OlogClientBuilder(URI uri) { - this.ologURI = uri; - this.protocol = this.ologURI.getScheme(); - } - - /** - * Creates a {@link OlogClientBuilder} for a CF client to Default URL in the - * channelfinder.properties. - * - * @return - */ - public static OlogClientBuilder serviceURL() { - return new OlogClientBuilder(); - } - - /** - * Creates a {@link OlogClientBuilder} for a CF client to URI uri. - * - * @param uri - * @return {@link OlogClientBuilder} - */ - public static OlogClientBuilder serviceURL(String uri) { - return new OlogClientBuilder(URI.create(uri)); - } - - /** - * Creates a {@link OlogClientBuilder} for a CF client to {@link URI} - * uri. - * - * @param uri - * @return {@link OlogClientBuilder} - */ - public static OlogClientBuilder serviceURL(URI uri) { - return new OlogClientBuilder(uri); - } - - /** - * Enable of Disable the HTTP authentication on the client connection. - * - * @param withHTTPAuthentication - * @return {@link OlogClientBuilder} - */ - public OlogClientBuilder withHTTPAuthentication(boolean withHTTPAuthentication) { - this.withHTTPAuthentication = withHTTPAuthentication; - return this; + this.uri = URI.create(Preferences.olog_url); } /** * Set the username to be used for HTTP Authentication. - * - * @param username + * + * @param username User account name * @return {@link OlogClientBuilder} */ public OlogClientBuilder username(String username) { @@ -156,8 +110,8 @@ public OlogClientBuilder username(String username) { /** * Set the password to be used for the HTTP Authentication. - * - * @param password + * + * @param password User's password * @return {@link OlogClientBuilder} */ public OlogClientBuilder password(String password) { @@ -165,119 +119,85 @@ public OlogClientBuilder password(String password) { return this; } - /** - * set the {@link ClientConfig} to be used while creating the channelfinder - * client connection. - * - * @param clientConfig - * @return {@link OlogClientBuilder} - */ - public OlogClientBuilder withClientConfig(ClientConfig clientConfig) { - this.clientConfig = clientConfig; - return this; - } - - @SuppressWarnings("unused") - private OlogClientBuilder withSSLContext(SSLContext sslContext) { - this.sslContext = sslContext; - return this; - } - - /** - * Set the trustManager that should be used for authentication. - * - * @param trustManager - * @return {@link OlogClientBuilder} - */ - public OlogClientBuilder withTrustManager(TrustManager[] trustManager) { - this.trustManager = trustManager; - return this; - } - - /** - * Provide your own executor on which the queries are to be made.
- * By default a single threaded executor is used. - * - * @param executor - * @return {@link OlogClientBuilder} - */ - public OlogClientBuilder withExecutor(ExecutorService executor) { - this.executor = executor; - return this; + private ScopedAuthenticationToken getCredentialsFromSecureStore() { + try { + SecureStore secureStore = new SecureStore(); + return secureStore.getScopedAuthenticationToken(AuthenticationScope.LOGBOOK); + } catch (Exception e) { + Logger.getLogger(OlogClient.class.getName()).log(Level.WARNING, "Unable to instantiate SecureStore", e); + return null; + } } - public OlogClient create() throws Exception { - if (this.protocol.equalsIgnoreCase("http")) { //$NON-NLS-1$ - this.clientConfig = new DefaultClientConfig(); - } else if (this.protocol.equalsIgnoreCase("https")) { //$NON-NLS-1$ - if (this.clientConfig == null) { - SSLContext sslContext = null; - try { - sslContext = SSLContext.getInstance("SSL"); //$NON-NLS-1$ - sslContext.init(null, this.trustManager, null); - } catch (NoSuchAlgorithmException e) { - throw new OlogException(); - } catch (KeyManagementException e) { - throw new OlogException(); - } - this.clientConfig = new DefaultClientConfig(); - this.clientConfig.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES, - new HTTPSProperties(new HostnameVerifier() { - @Override - public boolean verify(String hostname, SSLSession session) { - return true; - } - }, sslContext)); + public OlogClient build() { + if (this.username == null || this.password == null) { + ScopedAuthenticationToken scopedAuthenticationToken = getCredentialsFromSecureStore(); + if (scopedAuthenticationToken != null) { + this.username = scopedAuthenticationToken.getUsername(); + this.password = scopedAuthenticationToken.getPassword(); } } - this.username = ifNullReturnPreferenceValue(this.username, "username"); - this.password = ifNullReturnPreferenceValue(this.password, "password"); - this.connectTimeoutAsString = ifNullReturnPreferenceValue(this.connectTimeoutAsString, "connectTimeout"); - Integer connectTimeout = 0; - try { - connectTimeout = Integer.parseInt(connectTimeoutAsString); - } catch (NumberFormatException e) { - Logger.getLogger(OlogClientBuilder.class.getPackageName()) - .warning("connectTimeout preference not set or invalid, using 0 (=infinite)"); - } - this.clientConfig.getProperties().put(ClientConfig.PROPERTY_CONNECT_TIMEOUT, connectTimeout); - - this.withRawFilter = Boolean.valueOf(this.properties.getPreferenceValue("debug")); - return new OlogClient(this.ologURI, - this.clientConfig, - this.withHTTPAuthentication, - this.username, - this.password, - this.executor, - this.withRawFilter); - } - - private String ifNullReturnPreferenceValue(String value, String key) { - if (value == null) { - return this.properties.getPreferenceValue(key); + HttpClient httpClient; + + if (uri.getScheme().equalsIgnoreCase("https")) { + try { + SSLContext sslContext = SSLContext.getInstance("SSL"); // OR TLS + sslContext.init(null, new PromiscuousTrustManager[]{new PromiscuousTrustManager()}, new SecureRandom()); + if (Preferences.connectTimeout > 0) { + httpClient = HttpClient.newBuilder() + .cookieHandler(new CookieManager(null, CookiePolicy.ACCEPT_ALL)) + .followRedirects(HttpClient.Redirect.ALWAYS) + .connectTimeout(Duration.ofMillis(Preferences.connectTimeout)) + .sslContext(sslContext) + .build(); + } else { + httpClient = HttpClient.newBuilder() + .cookieHandler(new CookieManager(null, CookiePolicy.ACCEPT_ALL)) + .followRedirects(HttpClient.Redirect.ALWAYS) + .connectTimeout(Duration.ofMillis(Preferences.connectTimeout)) + .sslContext(sslContext) + .build(); + } + } catch (Exception e) { + LOGGER.log(Level.WARNING, + "Failed to properly create the olog rest client to: " + Preferences.olog_url + , e); + throw new RuntimeException(e); + } } else { - return value; + if (Preferences.connectTimeout > 0) { + httpClient = HttpClient.newBuilder() + .cookieHandler(new CookieManager(null, CookiePolicy.ACCEPT_ALL)) + .followRedirects(HttpClient.Redirect.ALWAYS) + .connectTimeout(Duration.ofMillis(Preferences.connectTimeout)) + .build(); + } else { + httpClient = HttpClient.newBuilder() + .cookieHandler(new CookieManager(null, CookiePolicy.ACCEPT_ALL)) + .followRedirects(HttpClient.Redirect.ALWAYS) + .connectTimeout(Duration.ofMillis(Preferences.connectTimeout)) + .build(); + } } + + return new OlogClient(httpClient, this.username, this.password); } + } + public static OlogClientBuilder builder() { + return new OlogClientBuilder(); } - private OlogClient(URI ologURI, ClientConfig config, boolean withHTTPBasicAuthFilter, String username, - String password, ExecutorService executor, boolean withRawFilter) { - this.executor = executor; - config.getClasses().add(MultiPartWriter.class); - Client client = Client.create(config); - if (withHTTPBasicAuthFilter) { - client.addFilter(new HTTPBasicAuthFilter(username, password)); - } - if (withRawFilter) { - client.addFilter(new RawLoggingFilter(Logger.getLogger(OlogClient.class.getName()))); - } - client.setFollowRedirects(true); - service = client.resource(UriBuilder.fromUri(ologURI).build()); + private OlogClient(HttpClient httpClient, String userName, String password) { + this.httpClient = httpClient; + executor = Executors.newSingleThreadExecutor(); + basicAuthenticationHeader = "Basic " + Base64.getEncoder().encodeToString((userName != null ? userName : Preferences.username + ":" + + password != null ? password : Preferences.password).getBytes()); + } + // A predefined set of levels supported by olog private final List levels = Arrays.asList("Urgent", "Suggestion", "Info", "Request", "Problem"); @@ -285,34 +205,58 @@ private OlogClient(URI ologURI, ClientConfig config, boolean withHTTPBasicAuthFi public Collection listLevels() { return levels; } - + @Override public Collection listLogbooks() { - return wrappedSubmit(new Callable>() { + return wrappedSubmit(new Callable<>() { @Override public Collection call() throws Exception { - Collection allLogbooks = new HashSet(); - XmlLogbooks allXmlLogbooks = service.path("logbooks").accept(MediaType.APPLICATION_XML) - .get(XmlLogbooks.class); + Collection allLogbooks = new HashSet<>(); + + HttpRequest httpRequest = HttpRequest.newBuilder() + .uri(URI.create(Preferences.olog_url + "/logbooks")) + .header("Accept", MediaType.APPLICATION_XML) + .GET() + .build(); + HttpResponse httpResponse = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString()); + + if (httpResponse.statusCode() < 300) { + LOGGER.log(Level.WARNING, "Failed to retrieve logbooks list: " + httpResponse.body()); + throw new OlogException(httpResponse.statusCode(), httpResponse.body()); + } + + XmlLogbooks allXmlLogbooks = OBJECT_MAPPER.readValue(httpResponse.body(), XmlLogbooks.class); for (XmlLogbook xmlLogbook : allXmlLogbooks.getLogbooks()) { allLogbooks.add(new OlogLogbook(xmlLogbook)); } return allLogbooks; } - }); } @Override public Collection listTags() { - return wrappedSubmit(new Callable>() { + return wrappedSubmit(new Callable<>() { @Override public Collection call() throws Exception { - Collection allTags = new HashSet(); - XmlTags allXmlTags = service.path("tags").accept(MediaType.APPLICATION_XML).get(XmlTags.class); + + HttpRequest httpRequest = HttpRequest.newBuilder() + .uri(URI.create(Preferences.olog_url + "/tags")) + .header("Accept", MediaType.APPLICATION_XML) + .GET() + .build(); + HttpResponse httpResponse = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString()); + + if (httpResponse.statusCode() != 200) { + LOGGER.log(Level.WARNING, "Failed to retrieve tags list: " + httpResponse.body()); + throw new OlogException(httpResponse.statusCode(), httpResponse.body()); + } + + Collection allTags = new HashSet<>(); + XmlTags allXmlTags = OBJECT_MAPPER.readValue(httpResponse.body(), XmlTags.class); for (XmlTag xmlTag : allXmlTags.getTags()) { allTags.add(new OlogTag(xmlTag)); } @@ -324,12 +268,25 @@ public Collection call() throws Exception { @Override public Collection listProperties() { - return wrappedSubmit(new Callable>() { + return wrappedSubmit(new Callable<>() { @Override public Collection call() throws Exception { - Collection allProperties = new HashSet(); - XmlProperties xmlProperties = service.path("properties").accept(MediaType.APPLICATION_XML) - .accept(MediaType.APPLICATION_JSON).get(XmlProperties.class); + + HttpRequest httpRequest = HttpRequest.newBuilder() + .uri(URI.create(Preferences.olog_url + "/properties")) + .header("Accept", MediaType.APPLICATION_XML) + .header("Accept", MediaType.APPLICATION_JSON) + .GET() + .build(); + HttpResponse httpResponse = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString()); + + if (httpResponse.statusCode() != 200) { + LOGGER.log(Level.WARNING, "Failed to retrieve properties list: " + httpResponse.body()); + throw new OlogException(httpResponse.statusCode(), httpResponse.body()); + } + + Collection allProperties = new HashSet<>(); + XmlProperties xmlProperties = OBJECT_MAPPER.readValue(httpResponse.body(), XmlProperties.class); for (XmlProperty xmlProperty : xmlProperties.getProperties()) { allProperties.add(new OlogProperty(xmlProperty)); } @@ -345,11 +302,25 @@ public Collection listAttributes(String propertyName) { @Override public Collection listLogs() { - return wrappedSubmit(new Callable>() { + return wrappedSubmit(new Callable<>() { @Override public Collection call() throws Exception { - XmlLogs xmlLogs = service.path("logs").accept(MediaType.APPLICATION_XML) - .accept(MediaType.APPLICATION_JSON).get(XmlLogs.class); + + + HttpRequest httpRequest = HttpRequest.newBuilder() + .uri(URI.create(Preferences.olog_url + "/logs")) + .header("Accept", MediaType.APPLICATION_XML) + .header("Accept", MediaType.APPLICATION_JSON) + .GET() + .build(); + HttpResponse httpResponse = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString()); + + if (httpResponse.statusCode() != 200) { + LOGGER.log(Level.WARNING, "Failed to retrieve log entries: " + httpResponse.body()); + throw new OlogException(httpResponse.statusCode(), httpResponse.body()); + } + + XmlLogs xmlLogs = OBJECT_MAPPER.readValue(httpResponse.body(), XmlLogs.class); return LogUtil.toLogs(xmlLogs); } @@ -363,13 +334,26 @@ public LogEntry getLog(Long logId) { @Override public Collection listAttachments(Long logId) { - return wrappedSubmit(new Callable>() { + return wrappedSubmit(new Callable<>() { @Override public Collection call() throws Exception { - Collection allAttachments = new HashSet(); - XmlAttachments allXmlAttachments = service.path("attachments").path(logId.toString()) - .accept(MediaType.APPLICATION_XML).get(XmlAttachments.class); + + + HttpRequest httpRequest = HttpRequest.newBuilder() + .uri(URI.create(Preferences.olog_url + "/attachments")) + .header("Accept", MediaType.APPLICATION_XML) + .GET() + .build(); + HttpResponse httpResponse = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString()); + + if (httpResponse.statusCode() != 200) { + LOGGER.log(Level.WARNING, "Failed to retrieve attachments list: " + httpResponse.body()); + throw new OlogException(httpResponse.statusCode(), httpResponse.body()); + } + Collection allAttachments = new HashSet<>(); + + XmlAttachments allXmlAttachments = OBJECT_MAPPER.readValue(httpResponse.body(), XmlAttachments.class); for (XmlAttachment xmlAttachment : allXmlAttachments.getAttachments()) { allAttachments.add(new OlogAttachment(xmlAttachment)); } @@ -382,11 +366,18 @@ public Collection call() throws Exception { @Override public InputStream getAttachment(Long logId, Attachment attachment) { try { - ClientResponse response = service.path("attachments") - .path(logId.toString()) - .path(attachment.getName()) - .get(ClientResponse.class); - return response.getEntity(InputStream.class); + HttpRequest httpRequest = HttpRequest.newBuilder() + .uri(URI.create(Preferences.olog_url + "/attachments/" + + URLEncoder.encode(attachment.getName(), StandardCharsets.UTF_8).replace("+", "%20"))) + .header("Accept", MediaType.APPLICATION_XML) + .GET() + .build(); + HttpResponse httpResponse = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofInputStream()); + + if (httpResponse.statusCode() < 300){ + LOGGER.log(Level.WARNING, "Failed to get attachment"); + throw new OlogException("Failed to get attachment"); + } } catch (Exception e) { } return null; @@ -395,12 +386,18 @@ public InputStream getAttachment(Long logId, Attachment attachment) { @Override public InputStream getAttachment(Long logId, String attachmentName) { try { - ClientResponse response = service - .path("attachments") - .path(logId.toString()) - .path(attachmentName) - .get(ClientResponse.class); - return response.getEntity(InputStream.class); + HttpRequest httpRequest = HttpRequest.newBuilder() + .uri(URI.create(Preferences.olog_url + "/attachments/" + logId.toString() + "/" + + URLEncoder.encode(attachmentName, StandardCharsets.UTF_8).replace("+", "%20"))) + .header("Accept", MediaType.APPLICATION_XML) + .GET() + .build(); + HttpResponse httpResponse = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofInputStream()); + + if (httpResponse.statusCode() < 300){ + LOGGER.log(Level.WARNING, "Failed to get attachment"); + throw new OlogException("Failed to get attachment"); + } } catch (Exception e) { } return null; @@ -408,15 +405,23 @@ public InputStream getAttachment(Long logId, String attachmentName) { @Override public Property getProperty(String property) { - final String propertyName = property; - return wrappedSubmit(new Callable() { + return wrappedSubmit(new Callable<>() { @Override public Property call() throws Exception { - return new OlogProperty(service.path("properties") - .path(propertyName).accept(MediaType.APPLICATION_XML) - .accept(MediaType.APPLICATION_JSON) - .get(XmlProperty.class)); + HttpRequest httpRequest = HttpRequest.newBuilder() + .uri(URI.create(Preferences.olog_url + "/properties/" + + URLEncoder.encode(property, StandardCharsets.UTF_8).replace("+", "%20"))) + .header("Accept", MediaType.APPLICATION_XML) + .header("Accept", MediaType.APPLICATION_XML) + .GET() + .build(); + HttpResponse httpResponse = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString()); + if(httpResponse.statusCode() < 300){ + LOGGER.log(Level.WARNING, "Failed to get property " + property); + throw new OlogException(httpResponse.statusCode(), httpResponse.body()); + } + return new OlogProperty(OBJECT_MAPPER.readValue(httpResponse.body(), XmlProperty.class)); } }); } @@ -436,48 +441,75 @@ public LogEntry set(LogEntry log) throws LogbookException { } private class SetLogs implements Callable> { - private Collection logs; + private final Collection logs; public SetLogs(LogEntry log) { - this.logs = new ArrayList(); + this.logs = new ArrayList<>(); this.logs.add(log); } @Override public Collection call() { - Collection returnLogs = new HashSet(); + Collection returnLogs = new HashSet<>(); for (LogEntry log : logs) { XmlLogs xmlLogs = new XmlLogs(); XmlLog xmlLog = new XmlLog(log); xmlLog.setLevel("Info"); xmlLogs.getLogs().add(xmlLog); - ClientResponse clientResponse = service.path("logs") - .accept(MediaType.APPLICATION_XML) - .accept(MediaType.APPLICATION_JSON) - .post(ClientResponse.class, xmlLogs); - - if (clientResponse.getStatus() < 300) { + try { + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(Preferences.olog_url + "/logs")) + .header("Accept", MediaType.APPLICATION_JSON) + .header("Accept", MediaType.APPLICATION_XML) + .header("Content-Type", MediaType.APPLICATION_JSON) + .header("Authorization", basicAuthenticationHeader) + .POST(HttpRequest.BodyPublishers.ofString(OBJECT_MAPPER.writeValueAsString(xmlLogs))) + .build(); + + HttpResponse response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); + + if (response.statusCode() < 300) { + LOGGER.log(Level.WARNING, "Failed to create log entry"); + throw new OlogException(response.statusCode(), response.body()); + } // XXX there is an assumption that the result without an error status will consist of a single created log entry - XmlLog createdLog = clientResponse.getEntity(XmlLogs.class).getLogs().iterator().next(); + XmlLog createdLog = OBJECT_MAPPER.readValue(response.body(), XmlLogs.class).getLogs().iterator().next(); + //XmlLog createdLog = clientResponse.getEntity(XmlLogs.class).getLogs().iterator().next(); log.getAttachments().forEach(attachment -> { - FormDataMultiPart form = new FormDataMultiPart(); - form.bodyPart(new FileDataBodyPart("file", attachment.getFile())); - XmlAttachment createdAttachment = service.path("attachments").path(createdLog.getId().toString()) - .type(MediaType.MULTIPART_FORM_DATA).accept(MediaType.APPLICATION_XML) - .post(XmlAttachment.class, form); - createdLog.addXmlAttachment(createdAttachment); + + HttpRequestMultipartBody httpRequestMultipartBody = new HttpRequestMultipartBody(); + httpRequestMultipartBody.addFilePart(attachment.getFile()); + + HttpRequest attachmentRequest = HttpRequest.newBuilder() + .uri(URI.create(Preferences.olog_url + "/attachments/" + createdLog.getId())) + .header("Accept", MediaType.APPLICATION_XML) + .header("Content-Type", httpRequestMultipartBody.getContentType()) + .header("Authorization", basicAuthenticationHeader) + .POST(HttpRequest.BodyPublishers.ofByteArray(httpRequestMultipartBody.getBytes())) + .build(); + + try { + HttpResponse attachmentResponse = httpClient.send(attachmentRequest, HttpResponse.BodyHandlers.ofString()); + + if (attachmentResponse.statusCode() < 300) { + LOGGER.log(Level.WARNING, "Failed to create attachment"); + throw new OlogException(attachmentResponse.statusCode(), attachmentResponse.body()); + } + + createdLog.addXmlAttachment(OBJECT_MAPPER.readValue(attachmentResponse.body(), + XmlAttachment.class)); + } catch (Exception e) { + throw new RuntimeException(e); + } }); returnLogs.add(new OlogLog(createdLog)); - - } else - throw new UniformInterfaceException(clientResponse); - + } catch (Exception e) { + throw new RuntimeException(e); + } } - return Collections.unmodifiableCollection(returnLogs); - } } @@ -495,15 +527,22 @@ public UpdateLog(LogEntry log) { @Override public LogEntry call() throws Exception { - ClientResponse clientResponse = service.path("logs") - .path(String.valueOf(log.getId())) - .accept(MediaType.APPLICATION_XML) - .accept(MediaType.APPLICATION_JSON) - .post(ClientResponse.class, log); - if (clientResponse.getStatus() < 300) - return new OlogLog(clientResponse.getEntity(XmlLog.class)); + + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(Preferences.olog_url + "/logs/" + log.getId())) + .header("Accept", MediaType.APPLICATION_JSON) + .header("Accept", MediaType.APPLICATION_XML) + .header("Content-Type", MediaType.APPLICATION_JSON) + .header("Authorization", basicAuthenticationHeader) + .POST(HttpRequest.BodyPublishers.ofString(OBJECT_MAPPER.writeValueAsString(log))) + .build(); + + HttpResponse httpResponse = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); + + if (httpResponse.statusCode() < 300) + return new OlogLog(OBJECT_MAPPER.readValue(httpResponse.body(), XmlLog.class)); else - throw new UniformInterfaceException(clientResponse); + throw new OlogException(httpResponse.statusCode(), httpResponse.body()); } } @@ -517,7 +556,7 @@ private class UpdateLogs implements Callable> { public UpdateLogs(Collection logs) { this.logs = new XmlLogs(); - Collection xmlLogs = new ArrayList(); + Collection xmlLogs = new ArrayList<>(); for (LogEntry log : logs) { xmlLogs.add(new XmlLog(log)); } @@ -526,34 +565,51 @@ public UpdateLogs(Collection logs) { @Override public Collection call() throws Exception { - ClientResponse clientResponse = service.path("logs").accept(MediaType.APPLICATION_XML) - .accept(MediaType.APPLICATION_JSON).post(ClientResponse.class, logs); - if (clientResponse.getStatus() < 300) { - // return new Log(clientResponse.getEntity(XmlLog.class)); - Collection logs = new HashSet(); - for (XmlLog xmlLog : clientResponse.getEntity(XmlLogs.class).getLogs()) { + + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(Preferences.olog_url + "/logs")) + .header("Accept", MediaType.APPLICATION_JSON) + .header("Accept", MediaType.APPLICATION_XML) + .header("Content-Type", MediaType.APPLICATION_JSON) + .header("Authorization", basicAuthenticationHeader) + .POST(HttpRequest.BodyPublishers.ofString(OBJECT_MAPPER.writeValueAsString(logs))) + .build(); + + HttpResponse httpResponse = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); + + if (httpResponse.statusCode() < 300) { + Collection logs = new HashSet<>(); + for (XmlLog xmlLog : OBJECT_MAPPER.readValue(httpResponse.body(), XmlLogs.class).getLogs()) { logs.add(new OlogLog(xmlLog)); } - ; return Collections.unmodifiableCollection(logs); } else { - throw new UniformInterfaceException(clientResponse); + throw new OlogException(httpResponse.statusCode(), httpResponse.body()); } } } @Override public LogEntry findLogById(Long logId) { - return wrappedSubmit(new Callable() { + return wrappedSubmit(new Callable<>() { @Override public LogEntry call() throws Exception { - XmlLog xmlLog = service.path("logs").path(logId.toString()) - .accept(MediaType.APPLICATION_XML) - .accept(MediaType.APPLICATION_JSON).get(XmlLog.class); - return new OlogLog(xmlLog); - } + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(Preferences.olog_url + "/logs/" + logId)) + .header("Accept", MediaType.APPLICATION_JSON) + .header("Accept", MediaType.APPLICATION_XML) + .GET() + .build(); + + HttpResponse httpResponse = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); + if (httpResponse.statusCode() < 300) { + LOGGER.log(Level.WARNING, "Failed to get log id " + logId + ": " + httpResponse.body()); + throw new OlogException(httpResponse.statusCode(), httpResponse.body()); + } + return new OlogLog(OBJECT_MAPPER.readValue(httpResponse.body(), XmlLog.class)); + } }); } @@ -574,7 +630,7 @@ public List findLogsByLogbook(String logbook) { @Override public List findLogsByProperty(String propertyName, String attributeName, String attributeValue) { - MultivaluedMap mMap = new MultivaluedMapImpl(); + MultivaluedMap mMap = new MultivaluedHashMap<>(); mMap.putSingle(propertyName + "." + attributeName, attributeValue); return wrappedSubmit(new FindLogs(mMap)); } @@ -589,7 +645,7 @@ public SearchResult search(Map map) { List logs = findLogs(map); return SearchResult.of(logs, logs.size()); } - + @Override public List findLogs(Map map) { return wrappedSubmit(new FindLogs(map)); @@ -600,7 +656,7 @@ private class FindLogs implements Callable> { private final MultivaluedMap map; public FindLogs(String queryParameter, String pattern) { - MultivaluedMap mMap = new MultivaluedMapImpl(); + MultivaluedMap mMap = new MultivaluedHashMap<>(); mMap.putSingle(queryParameter, pattern); this.map = mMap; } @@ -610,7 +666,7 @@ public FindLogs(MultivaluedMap map) { } public FindLogs(Map map) { - MultivaluedMap mMap = new MultivaluedMapImpl(); + MultivaluedMap mMap = new MultivaluedHashMap<>(); Iterator> itr = map.entrySet().iterator(); while (itr.hasNext()) { Map.Entry entry = itr.next(); @@ -621,29 +677,37 @@ public FindLogs(Map map) { @Override public List call() throws Exception { - List logs = new ArrayList(); + List logs = new ArrayList<>(); // Map Phoebus logbook search parameters to Olog ones // desc, title -> search // size -> limit - if(map.containsKey("desc")) { + if (map.containsKey("desc")) { map.put("search", map.get("desc")); } - if(map.containsKey("size")) { + if (map.containsKey("size")) { map.put("limit", map.get("size")); } - if(map.containsKey("start")) { + if (map.containsKey("start")) { map.putSingle("start", parseTemporalValue(map.getFirst("start"))); } - if(map.containsKey("end")) { + if (map.containsKey("end")) { map.putSingle("end", parseTemporalValue(map.getFirst("end"))); } - XmlLogs xmlLogs = service - .path("logs") - .queryParams(map) - .accept(MediaType.APPLICATION_XML) - .accept(MediaType.APPLICATION_JSON) - .get(XmlLogs.class); + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(Preferences.olog_url + "/logs?" + QueryParamsHelper.mapToQueryParams(map))) + .header("Accept", MediaType.APPLICATION_JSON) + .header("Accept", MediaType.APPLICATION_XML) + .GET() + .build(); + + HttpResponse httpResponse = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); + if (httpResponse.statusCode() < 300) { + LOGGER.log(Level.WARNING, "Failed to search for logs: " + httpResponse.body()); + throw new OlogException(httpResponse.statusCode(), httpResponse.body()); + } + + XmlLogs xmlLogs = OBJECT_MAPPER.readValue(httpResponse.body(), XmlLogs.class); for (XmlLog xmllog : xmlLogs.getLogs()) { OlogLog log = new OlogLog(xmllog); if (!xmllog.getXmlAttachments().getAttachments().isEmpty()) { @@ -682,26 +746,39 @@ private static String parseTemporalValue(String value) { private T wrappedSubmit(Callable callable) { try { return this.executor.submit(callable).get(); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } catch (ExecutionException e) { - if (e.getCause() != null && e.getCause() instanceof UniformInterfaceException) { - throw new OlogException((UniformInterfaceException) e.getCause()); - } + } catch (Exception e) { throw new RuntimeException(e); } } - private void wrappedSubmit(Runnable runnable) { - try { - this.executor.submit(runnable).get(60, TimeUnit.SECONDS); - } catch (ExecutionException e) { - if (e.getCause() != null && e.getCause() instanceof UniformInterfaceException) { - throw new OlogException((UniformInterfaceException) e.getCause()); - } - throw new RuntimeException(e); - } catch (Exception e) { - throw new RuntimeException(e); + private static class PromiscuousTrustManager extends X509ExtendedTrustManager { + @Override + public java.security.cert.X509Certificate[] getAcceptedIssuers() { + return new java.security.cert.X509Certificate[0]; + } + + @Override + public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) { + } + + @Override + public void checkClientTrusted(X509Certificate[] chain, String authType, Socket socket) { + } + + @Override + public void checkServerTrusted(X509Certificate[] chain, String authType, Socket socket) { + } + + @Override + public void checkServerTrusted(X509Certificate[] chain, String authType, SSLEngine engine) { + } + + @Override + public void checkClientTrusted(X509Certificate[] chain, String authType, SSLEngine engine) { + } + + @Override + public void checkClientTrusted(X509Certificate[] chain, String authType) { } } } diff --git a/app/logbook/olog/client/src/main/java/org/phoebus/olog/api/OlogException.java b/app/logbook/olog/client/src/main/java/org/phoebus/olog/api/OlogException.java index 8a3da46a9b..1c82b74cf0 100644 --- a/app/logbook/olog/client/src/main/java/org/phoebus/olog/api/OlogException.java +++ b/app/logbook/olog/client/src/main/java/org/phoebus/olog/api/OlogException.java @@ -4,8 +4,6 @@ package org.phoebus.olog.api; -import com.sun.jersey.api.client.ClientResponse.Status; -import com.sun.jersey.api.client.UniformInterfaceException; import java.io.IOException; import java.io.Reader; import java.io.StringReader; @@ -22,8 +20,8 @@ public class OlogException extends RuntimeException { * */ private static final long serialVersionUID = 6279865221993808192L; - - private Status status; + + private int status; public OlogException() { super(); @@ -33,35 +31,22 @@ public OlogException(String message){ super(message); } - public OlogException(UniformInterfaceException cause) { - super(parseErrorMsg(cause), cause); - this.setStatus(Status.fromStatusCode(cause.getResponse().getStatus())); - } - - private static String parseErrorMsg(UniformInterfaceException ex) { - String entity = ex.getResponse().getEntity(String.class); - try { - ClientResponseParser callback = new ClientResponseParser(); - Reader reader = new StringReader(entity); - new ParserDelegator().parse(reader, callback, false); - return callback.getMessage(); - } catch (IOException e) { - return "Could not retrieve message from server"; - } + public OlogException(int status, String message){ + super(message); + this.status = status; } - /** * @param status the status to set */ - public void setStatus(Status status) { + public void setStatus(int status) { this.status = status; } /** * @return the status */ - public Status getStatus() { + public int getStatus() { return status; } diff --git a/app/logbook/olog/client/src/main/java/org/phoebus/olog/api/OlogProperties.java b/app/logbook/olog/client/src/main/java/org/phoebus/olog/api/OlogProperties.java deleted file mode 100644 index 755960b554..0000000000 --- a/app/logbook/olog/client/src/main/java/org/phoebus/olog/api/OlogProperties.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.phoebus.olog.api; - -import org.phoebus.framework.preferences.PreferencesReader; - -public class OlogProperties { - - final PreferencesReader prefs; - - OlogProperties() { - - prefs = new PreferencesReader(OlogProperties.class, "/olog_preferences.properties"); - } - - /** - * check java preferences for the requested key - * @param key - * @return - */ - String getPreferenceValue(String key) { - return prefs.get(key); - } - -} diff --git a/app/logbook/olog/client/src/main/java/org/phoebus/olog/api/Preferences.java b/app/logbook/olog/client/src/main/java/org/phoebus/olog/api/Preferences.java new file mode 100644 index 0000000000..6af1a5fa68 --- /dev/null +++ b/app/logbook/olog/client/src/main/java/org/phoebus/olog/api/Preferences.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2024 European Spallation Source ERIC. + */ + +package org.phoebus.olog.api; + +import org.phoebus.framework.preferences.AnnotatedPreferences; +import org.phoebus.framework.preferences.Preference; + +public class Preferences { + + @Preference + public static String olog_url; + + @Preference + public static String username; + + @Preference + public static String password; + + @Preference + public static boolean debug; + + @Preference + public static int connectTimeout; + + static + { + AnnotatedPreferences.initialize(Preferences.class, "/olog_preferences.properties"); + } +} diff --git a/app/logbook/olog/client/src/main/java/org/phoebus/olog/api/RawLoggingFilter.java b/app/logbook/olog/client/src/main/java/org/phoebus/olog/api/RawLoggingFilter.java deleted file mode 100644 index 55f13245e8..0000000000 --- a/app/logbook/olog/client/src/main/java/org/phoebus/olog/api/RawLoggingFilter.java +++ /dev/null @@ -1,282 +0,0 @@ -/* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. - * - * The contents of this file are subject to the terms of either the GNU - * General Public License Version 2 only ("GPL") or the Common Development - * and Distribution License("CDDL") (collectively, the "License"). You - * may not use this file except in compliance with the License. You can obtain - * a copy of the License at https://jersey.dev.java.net/CDDL+GPL.html - * or jersey/legal/LICENSE.txt. See the License for the specific - * language governing permissions and limitations under the License. - * - * When distributing the software, include this License Header Notice in each - * file and include the License file at jersey/legal/LICENSE.txt. - * Sun designates this particular file as subject to the "Classpath" exception - * as provided by Sun in the GPL Version 2 section of the License file that - * accompanied this code. If applicable, add the following below the License - * Header, with the fields enclosed by brackets [] replaced by your own - * identifying information: "Portions Copyrighted [year] - * [name of copyright owner]" - * - * Contributor(s): - * - * If you wish your version of this file to be governed by only the CDDL or - * only the GPL Version 2, indicate your decision by adding "[Contributor] - * elects to include this software in this distribution under the [CDDL or GPL - * Version 2] license." If you don't indicate a single choice of license, a - * recipient has the option to distribute your version of this file under - * either the CDDL, the GPL Version 2 or to extend the choice of license to - * its licensees as provided above. However, if you add GPL Version 2 code - * and therefore, elected the GPL Version 2 license, then the option applies - * only if the new code is made subject to such option by the copyright - * holder. - */ -/* - * Copyright 2010 Brookhaven National Laboratory - * All rights reserved. Use is subject to license terms. - */ - - -package org.phoebus.olog.api; - -import com.sun.jersey.api.client.AbstractClientRequestAdapter; -import com.sun.jersey.api.client.ClientHandlerException; -import com.sun.jersey.api.client.ClientRequest; -import com.sun.jersey.api.client.ClientRequestAdapter; -import com.sun.jersey.api.client.ClientResponse; -import com.sun.jersey.api.client.filter.ClientFilter; -import com.sun.jersey.core.util.ReaderWriter; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.PrintStream; -import java.util.List; -import java.util.Map; -import java.util.logging.Level; -import java.util.logging.Logger; -import javax.ws.rs.core.MultivaluedMap; - -/** - * A Raw HTML request/response logging filter. - * added level check to the handle. - * - * @author Paul.Sandoz@Sun.Com, shroffk - */ -public class RawLoggingFilter extends ClientFilter { - - private static final Logger LOGGER = Logger - .getLogger(RawLoggingFilter.class.getName()); - - private static final String NOTIFICATION_PREFIX = "* "; - - private static final String REQUEST_PREFIX = "> "; - - private static final String RESPONSE_PREFIX = "< "; - - private final class Adapter extends AbstractClientRequestAdapter { - private final StringBuilder b; - - Adapter(ClientRequestAdapter cra, StringBuilder b) { - super(cra); - this.b = b; - } - - public OutputStream adapt(ClientRequest request, OutputStream out) - throws IOException { - return new LoggingOutputStream(getAdapter().adapt(request, out), b); - } - - } - - private final class LoggingOutputStream extends OutputStream { - private final OutputStream out; - - private final ByteArrayOutputStream baos = new ByteArrayOutputStream(); - - private final StringBuilder b; - - LoggingOutputStream(OutputStream out, StringBuilder b) { - this.out = out; - this.b = b; - } - - @Override - public void write(byte[] b) throws IOException { - baos.write(b); - out.write(b); - } - - @Override - public void write(byte[] b, int off, int len) throws IOException { - baos.write(b, off, len); - out.write(b, off, len); - } - - @Override - public void write(int b) throws IOException { - baos.write(b); - out.write(b); - } - - @Override - public void close() throws IOException { - printEntity(b, baos.toByteArray()); - log(b); - out.close(); - } - } - - private final PrintStream loggingStream; - - private final Logger logger; - - private long _id = 0; - - /** - * Create a logging filter logging the request and response to a default JDK - * logger, named as the fully qualified class name of this class. - */ - public RawLoggingFilter() { - this(LOGGER); - } - - /** - * Create a logging filter logging the request and response to a JDK logger. - * - * @param logger the logger to log requests and responses. - */ - public RawLoggingFilter(Logger logger) { - this.loggingStream = null; - this.logger = logger; - } - - /** - * Create a logging filter logging the request and response to print stream. - * - * @param loggingStream the print stream to log requests and responses. - */ - public RawLoggingFilter(PrintStream loggingStream) { - this.loggingStream = loggingStream; - this.logger = null; - } - - private void log(StringBuilder b) { - if (logger != null) { - logger.fine(b.toString()); - } else { - loggingStream.print(b); - } - } - - private StringBuilder prefixId(StringBuilder b, long id) { - b.append(Long.toString(id)).append(" "); - return b; - } - - @Override - public ClientResponse handle(ClientRequest request) - throws ClientHandlerException { - if (this.logger.isLoggable(Level.FINE)) { - long id = ++this._id; - logRequest(id, request); - - ClientResponse response = getNext().handle(request); - - logResponse(id, response); - - return response; - } else { - return getNext().handle(request); - } - - } - - private void logRequest(long id, ClientRequest request) { - StringBuilder b = new StringBuilder(); - - printRequestLine(b, id, request); - printRequestHeaders(b, id, request.getHeaders()); - - if (request.getEntity() != null) { - request.setAdapter(new Adapter(request.getAdapter(), b)); - } else { - log(b); - } - } - - private void printRequestLine(StringBuilder b, long id, - ClientRequest request) { - prefixId(b, id).append(NOTIFICATION_PREFIX) - .append("Client out-bound request").append("\n"); - prefixId(b, id).append(REQUEST_PREFIX).append(request.getMethod()) - .append(" ").append(request.getURI().toASCIIString()) - .append("\n"); - } - - private void printRequestHeaders(StringBuilder b, long id, - MultivaluedMap headers) { - for (Map.Entry> e : headers.entrySet()) { - String header = e.getKey(); - for (Object value : e.getValue()) { - prefixId(b, id).append(REQUEST_PREFIX).append(header) - .append(": ") - .append(ClientRequest.getHeaderValue(value)) - .append("\n"); - } - } - prefixId(b, id).append(REQUEST_PREFIX).append("\n"); - } - - private void logResponse(long id, ClientResponse response) { - StringBuilder b = new StringBuilder(); - - printResponseLine(b, id, response); - printResponseHeaders(b, id, response.getHeaders()); - - ByteArrayOutputStream out = new ByteArrayOutputStream(); - InputStream in = response.getEntityInputStream(); - try { - ReaderWriter.writeTo(in, out); - - byte[] requestEntity = out.toByteArray(); - printEntity(b, requestEntity); - response.setEntityInputStream(new ByteArrayInputStream( - requestEntity)); - } catch (IOException ex) { - throw new ClientHandlerException(ex); - } - log(b); - } - - private void printResponseLine(StringBuilder b, long id, - ClientResponse response) { - prefixId(b, id).append(NOTIFICATION_PREFIX) - .append("Client in-bound response").append("\n"); - prefixId(b, id).append(RESPONSE_PREFIX) - .append(Integer.toString(response.getStatus())).append("\n"); - } - - private void printResponseHeaders(StringBuilder b, long id, - MultivaluedMap headers) { - for (Map.Entry> e : headers.entrySet()) { - String header = e.getKey(); - for (String value : e.getValue()) { - prefixId(b, id).append(RESPONSE_PREFIX).append(header) - .append(": ").append(value).append("\n"); - } - } - prefixId(b, id).append(RESPONSE_PREFIX).append("\n"); - } - - private void printEntity(StringBuilder b, byte[] entity) throws IOException { - if (entity.length == 0) - return; - b.append(new String(entity)).append("\n"); - } -} \ No newline at end of file diff --git a/dependencies/phoebus-target/.classpath b/dependencies/phoebus-target/.classpath index 276b6b4c62..b40a52a677 100644 --- a/dependencies/phoebus-target/.classpath +++ b/dependencies/phoebus-target/.classpath @@ -82,10 +82,6 @@ - - - - diff --git a/dependencies/phoebus-target/pom.xml b/dependencies/phoebus-target/pom.xml index f3f2951dd9..8f0c7803c6 100644 --- a/dependencies/phoebus-target/pom.xml +++ b/dependencies/phoebus-target/pom.xml @@ -181,27 +181,7 @@ 1.7.12
- - - com.sun.jersey - jersey-core - 1.19 - - - com.sun.jersey - jersey-server - 1.19 - - - com.sun.jersey - jersey-client - 1.19 - - - com.sun.jersey.contribs - jersey-multipart - 1.19 - + javax.xml.bind jaxb-api