diff --git a/app/alarm/logging-ui/pom.xml b/app/alarm/logging-ui/pom.xml index 31c26eae33..1ffe47e007 100644 --- a/app/alarm/logging-ui/pom.xml +++ b/app/alarm/logging-ui/pom.xml @@ -38,11 +38,6 @@ 4.7.4-SNAPSHOT compile - - com.sun.jersey - jersey-client - 1.19 - com.fasterxml.jackson.core jackson-core @@ -63,10 +58,5 @@ jackson-datatype-jsr310 ${jackson.version} - - javax.ws.rs - javax.ws.rs-api - 2.1 - diff --git a/app/alarm/logging-ui/src/main/java/org/phoebus/applications/alarm/logging/ui/AdvancedSearchViewController.java b/app/alarm/logging-ui/src/main/java/org/phoebus/applications/alarm/logging/ui/AdvancedSearchViewController.java index 92be088ad9..ff5053cb41 100644 --- a/app/alarm/logging-ui/src/main/java/org/phoebus/applications/alarm/logging/ui/AdvancedSearchViewController.java +++ b/app/alarm/logging-ui/src/main/java/org/phoebus/applications/alarm/logging/ui/AdvancedSearchViewController.java @@ -1,6 +1,5 @@ package org.phoebus.applications.alarm.logging.ui; -import com.sun.jersey.api.client.WebResource; import javafx.application.Platform; import javafx.beans.binding.Bindings; import javafx.beans.value.ObservableValue; @@ -21,6 +20,7 @@ import org.phoebus.util.time.TimeRelativeInterval; import org.phoebus.util.time.TimestampFormats; +import java.net.http.HttpClient; import java.util.logging.Logger; import static org.phoebus.ui.time.TemporalAmountPane.Type.TEMPORAL_AMOUNTS_AND_NOW; @@ -57,7 +57,8 @@ public class AdvancedSearchViewController { PopOver timeSearchPopover; - private WebResource searchClient; + //private WebResource searchClient; + private HttpClient httpClient; // Search parameters ObservableMap searchParameters; @@ -65,8 +66,8 @@ public class AdvancedSearchViewController { @FXML private AnchorPane advancedSearchPane; - public AdvancedSearchViewController(WebResource client){ - this.searchClient = client; + public AdvancedSearchViewController(HttpClient httpClient) { + this.httpClient = httpClient; } @FXML @@ -169,7 +170,7 @@ public void initialize() { }); } - public void setSearchParameters(ObservableMap params){ + public void setSearchParameters(ObservableMap params) { searchParameters = params; searchParameters.addListener((MapChangeListener) change -> { searchPV.setText(searchParameters.get(Keys.PV)); @@ -194,7 +195,7 @@ public void setSearchParameters(ObservableMap params){ searchCommand.setText(searchParameters.get(Keys.COMMAND)); } - public AnchorPane getPane(){ + public AnchorPane getPane() { return advancedSearchPane; } } diff --git a/app/alarm/logging-ui/src/main/java/org/phoebus/applications/alarm/logging/ui/AlarmLogConfigSearchJob.java b/app/alarm/logging-ui/src/main/java/org/phoebus/applications/alarm/logging/ui/AlarmLogConfigSearchJob.java index 573b7c2657..f9e3d573bc 100644 --- a/app/alarm/logging-ui/src/main/java/org/phoebus/applications/alarm/logging/ui/AlarmLogConfigSearchJob.java +++ b/app/alarm/logging-ui/src/main/java/org/phoebus/applications/alarm/logging/ui/AlarmLogConfigSearchJob.java @@ -1,17 +1,20 @@ package org.phoebus.applications.alarm.logging.ui; -import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; -import com.sun.jersey.api.client.WebResource; import org.phoebus.framework.jobs.Job; import org.phoebus.framework.jobs.JobManager; import org.phoebus.framework.jobs.JobRunnableWithCancel; +import org.phoebus.util.http.QueryParamsHelper; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MultivaluedHashMap; import javax.ws.rs.core.MultivaluedMap; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; import java.util.Arrays; import java.util.List; import java.util.function.BiConsumer; @@ -23,7 +26,7 @@ * @author Kunal Shroff */ public class AlarmLogConfigSearchJob extends JobRunnableWithCancel { - private final WebResource client; + private final HttpClient httpClient; private final String pattern; private final Consumer alarmMessageHandler; @@ -31,20 +34,20 @@ public class AlarmLogConfigSearchJob extends JobRunnableWithCancel { private final ObjectMapper objectMapper; - public static Job submit(WebResource client, + public static Job submit(HttpClient httpClient, final String pattern, final Consumer alarmMessageHandler, final BiConsumer errorHandler) { return JobManager.schedule("searching alarm log messages for : " + pattern, - new AlarmLogConfigSearchJob(client, pattern, alarmMessageHandler, errorHandler)); + new AlarmLogConfigSearchJob(httpClient, pattern, alarmMessageHandler, errorHandler)); } - private AlarmLogConfigSearchJob(WebResource client, + private AlarmLogConfigSearchJob(HttpClient httpClient, String pattern, Consumer alarmMessageHandler, BiConsumer errorHandler) { super(); - this.client = client; + this.httpClient = httpClient; this.pattern = pattern; this.alarmMessageHandler = alarmMessageHandler; this.errorHandler = errorHandler; @@ -66,8 +69,17 @@ public Runnable getRunnable() { try { MultivaluedMap map = new MultivaluedHashMap<>(); map.put("config", Arrays.asList(pattern)); + + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(Preferences.service_uri + "/search/alarm/config?" + QueryParamsHelper.mapToQueryParams(map))) + .header("Content-Type", MediaType.APPLICATION_JSON) + .GET() + .build(); + + HttpResponse response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); + List result = objectMapper - .readValue(client.path("/search/alarm/config").queryParams(map).accept(MediaType.APPLICATION_JSON).get(String.class), + .readValue(response.body(), new TypeReference>() { }); if (result.size() >= 1) { @@ -75,7 +87,7 @@ public Runnable getRunnable() { } else { alarmMessageHandler.accept(null); } - } catch (JsonProcessingException e) { + } catch (Exception e) { errorHandler.accept("Failed to search for alarm logs ", e); } }; diff --git a/app/alarm/logging-ui/src/main/java/org/phoebus/applications/alarm/logging/ui/AlarmLogSearchJob.java b/app/alarm/logging-ui/src/main/java/org/phoebus/applications/alarm/logging/ui/AlarmLogSearchJob.java index b6d4849bbe..39cf293b2e 100644 --- a/app/alarm/logging-ui/src/main/java/org/phoebus/applications/alarm/logging/ui/AlarmLogSearchJob.java +++ b/app/alarm/logging-ui/src/main/java/org/phoebus/applications/alarm/logging/ui/AlarmLogSearchJob.java @@ -3,7 +3,6 @@ import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; -import com.sun.jersey.api.client.WebResource; import javafx.collections.ObservableMap; import org.phoebus.applications.alarm.logging.ui.AlarmLogTableQueryUtil.Keys; import org.phoebus.framework.jobs.Job; @@ -11,10 +10,17 @@ import org.phoebus.framework.jobs.JobMonitor; import org.phoebus.framework.jobs.JobRunnable; import org.phoebus.framework.preferences.PreferencesReader; +import org.phoebus.util.http.QueryParamsHelper; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MultivaluedHashMap; import javax.ws.rs.core.MultivaluedMap; +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.util.List; import java.util.function.BiConsumer; import java.util.function.Consumer; @@ -34,25 +40,26 @@ public class AlarmLogSearchJob implements JobRunnable { private final BiConsumer errorHandler; private final ObjectMapper objectMapper; - private final WebResource client; + //private final WebResource client; + private final HttpClient httpClient; private final PreferencesReader prefs = new PreferencesReader(AlarmLogTableApp.class, "/alarm_logging_preferences.properties"); - public static Job submit(WebResource client, + public static Job submit(HttpClient httpClient, final String pattern, Boolean isNodeTable, ObservableMap searchParameters, final Consumer> alarmMessageHandler, final BiConsumer errorHandler) { return JobManager.schedule("searching alarm log messages for : " + pattern, - new AlarmLogSearchJob(client, isNodeTable, searchParameters, alarmMessageHandler, errorHandler)); + new AlarmLogSearchJob(httpClient, isNodeTable, searchParameters, alarmMessageHandler, errorHandler)); } - private AlarmLogSearchJob(WebResource client, Boolean isNodeTable, ObservableMap searchParameters, + private AlarmLogSearchJob(HttpClient httpClient, Boolean isNodeTable, ObservableMap searchParameters, Consumer> alarmMessageHandler, BiConsumer errorHandler) { super(); - this.client = client; + this.httpClient = httpClient; this.searchParameters = searchParameters; this.alarmMessageHandler = alarmMessageHandler; this.errorHandler = errorHandler; @@ -69,19 +76,26 @@ public void run(JobMonitor monitor) { int size = prefs.getInt("results_max_size"); MultivaluedMap map = new MultivaluedHashMap<>(); - searchParameters.forEach((key, value) -> { if (!value.equals("")) map.add(key.getName(), value); }); + searchParameters.forEach((key, value) -> { + if (!value.equals("")) map.add(key.getName(), value); + }); map.putIfAbsent("size", List.of(String.valueOf(size))); try { long start = System.currentTimeMillis(); - String resultStr = client.path("/search/alarm") - .queryParams(map) - .accept(MediaType.APPLICATION_JSON).get(String.class); + + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(Preferences.service_uri + "/search/alarm?" + QueryParamsHelper.mapToQueryParams(map))) + .header("Content-Type", MediaType.APPLICATION_JSON) + .GET() + .build(); + + HttpResponse response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); logger.log(Level.FINE, "String response = " + (System.currentTimeMillis() - start)); start = System.currentTimeMillis(); - List result = objectMapper.readValue(resultStr, new TypeReference<>() { + List result = objectMapper.readValue(response.body(), new TypeReference<>() { }); logger.log(Level.FINE, "Object mapper response = " + (System.currentTimeMillis() - start)); alarmMessageHandler.accept(result); diff --git a/app/alarm/logging-ui/src/main/java/org/phoebus/applications/alarm/logging/ui/AlarmLogTable.java b/app/alarm/logging-ui/src/main/java/org/phoebus/applications/alarm/logging/ui/AlarmLogTable.java index 6c34dfc5f3..8e81f7c45d 100644 --- a/app/alarm/logging-ui/src/main/java/org/phoebus/applications/alarm/logging/ui/AlarmLogTable.java +++ b/app/alarm/logging-ui/src/main/java/org/phoebus/applications/alarm/logging/ui/AlarmLogTable.java @@ -2,13 +2,13 @@ import java.io.IOException; import java.net.URI; +import java.net.http.HttpClient; import java.util.Arrays; import java.util.ResourceBundle; import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; -import com.sun.jersey.api.client.WebResource; import org.phoebus.framework.nls.NLS; import org.phoebus.framework.spi.AppDescriptor; import org.phoebus.framework.spi.AppInstance; @@ -34,12 +34,12 @@ public class AlarmLogTable implements AppInstance { loader.setControllerFactory(clazz -> { try { if(clazz.isAssignableFrom(AlarmLogTableController.class)){ - return clazz.getConstructor(WebResource.class) - .newInstance(app.getClient()); + return clazz.getConstructor(HttpClient.class) + .newInstance(app.httpClient()); } else if(clazz.isAssignableFrom(AdvancedSearchViewController.class)){ - return clazz.getConstructor(WebResource.class) - .newInstance(app.getClient()); + return clazz.getConstructor(HttpClient.class) + .newInstance(app.httpClient()); } } catch (Exception e) { Logger.getLogger(AlarmLogTable.class.getName()).log(Level.SEVERE, "Failed to construct controller for Alarm Log Table View", e); diff --git a/app/alarm/logging-ui/src/main/java/org/phoebus/applications/alarm/logging/ui/AlarmLogTableApp.java b/app/alarm/logging-ui/src/main/java/org/phoebus/applications/alarm/logging/ui/AlarmLogTableApp.java index c7421c9afb..e3c0c184ec 100644 --- a/app/alarm/logging-ui/src/main/java/org/phoebus/applications/alarm/logging/ui/AlarmLogTableApp.java +++ b/app/alarm/logging-ui/src/main/java/org/phoebus/applications/alarm/logging/ui/AlarmLogTableApp.java @@ -1,25 +1,23 @@ package org.phoebus.applications.alarm.logging.ui; -import com.sun.jersey.api.client.Client; -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.client.urlconnection.HTTPSProperties; -import org.phoebus.framework.preferences.PreferencesReader; +import javafx.scene.image.Image; import org.phoebus.framework.spi.AppInstance; import org.phoebus.framework.spi.AppResourceDescriptor; import org.phoebus.ui.javafx.ImageCache; -import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLSession; +import javax.net.ssl.SSLEngine; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509ExtendedTrustManager; +import java.net.Socket; import java.net.URI; -import java.security.NoSuchAlgorithmException; +import java.net.http.HttpClient; +import java.security.SecureRandom; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; import java.util.logging.Level; import java.util.logging.Logger; -import javafx.scene.image.Image; - public class AlarmLogTableApp implements AppResourceDescriptor { public static final Logger logger = Logger.getLogger(AlarmLogTableApp.class.getName()); @@ -30,8 +28,7 @@ public class AlarmLogTableApp implements AppResourceDescriptor { public static final Image icon = ImageCache.getImage(AlarmLogTableApp.class, "/icons/alarmtable.png"); - private PreferencesReader prefs; - private WebResource alarmResource; + private HttpClient httpClient; @Override public String getName() { @@ -61,42 +58,51 @@ public boolean canOpenResource(String resource) { @Override public void start() { - prefs = new PreferencesReader(AlarmLogTableApp.class, "/alarm_logging_preferences.properties"); - String serviceUri = prefs.get("service_uri"); - String protocol = URI.create(serviceUri).getAuthority().toLowerCase().equals("https") ? "https" : "http"; - ClientConfig clientConfig = new DefaultClientConfig(); + try { - logger.info("Creating a alarm logging rest client to : " + serviceUri); - if (protocol.equalsIgnoreCase("https")) { //$NON-NLS-1$ - if (clientConfig == null) { - SSLContext sslContext = null; - try { - sslContext = SSLContext.getInstance("SSL"); //$NON-NLS-1$ - //sslContext.init(null, this.trustManager, null); - } catch (NoSuchAlgorithmException e) { - logger.log(Level.SEVERE, "failed to create the alarm logging rest client : " + e.getMessage(), e); + String protocol = URI.create(Preferences.service_uri).getAuthority().toLowerCase().equals("https") ? "https" : "http"; + if ("https".equals(protocol)) { + TrustManager PROMISCUOUS_TRUST_MANAGER = new 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) throws CertificateException { + } + + @Override + public void checkClientTrusted(X509Certificate[] chain, String authType, Socket socket) throws CertificateException { } - clientConfig.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES, - new HTTPSProperties(new HostnameVerifier() { - - @Override - public boolean verify(String hostname, SSLSession session) { - return true; - } - }, sslContext)); - } - } - Client client = Client.create(clientConfig); - client.setFollowRedirects(true); - alarmResource = client.resource(serviceUri.toString()); - // TODO add a preference to add logging - if (prefs.getBoolean("rawFiltering")) { - //client.addFilter(new RawLoggingFilter(Logger.getLogger(RawLoggingFilter.class.getName()))); + @Override + public void checkServerTrusted(X509Certificate[] chain, String authType, Socket socket) throws CertificateException { + } + + @Override + public void checkServerTrusted(X509Certificate[] chain, String authType, SSLEngine engine) throws CertificateException { + } + + @Override + public void checkClientTrusted(X509Certificate[] chain, String authType, SSLEngine engine) throws CertificateException { + } + + @Override + public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { + } + }; + + SSLContext sslContext = SSLContext.getInstance("SSL"); // OR TLS + sslContext.init(null, new TrustManager[]{PROMISCUOUS_TRUST_MANAGER}, new SecureRandom()); + httpClient = HttpClient.newBuilder().sslContext(sslContext).build(); + } else { + httpClient = HttpClient.newBuilder().build(); } + } catch (Exception e) { logger.log(Level.WARNING, - "Failed to properly create the elastic rest client to: " + prefs.get("service_uri") + "Failed to properly create the elastic rest client to: " + Preferences.service_uri , e); } } @@ -106,7 +112,7 @@ public void stop() { } - public WebResource getClient() { - return this.alarmResource; + public HttpClient httpClient() { + return httpClient; } } diff --git a/app/alarm/logging-ui/src/main/java/org/phoebus/applications/alarm/logging/ui/AlarmLogTableController.java b/app/alarm/logging-ui/src/main/java/org/phoebus/applications/alarm/logging/ui/AlarmLogTableController.java index 26e88c1689..b8dfbf8297 100644 --- a/app/alarm/logging-ui/src/main/java/org/phoebus/applications/alarm/logging/ui/AlarmLogTableController.java +++ b/app/alarm/logging-ui/src/main/java/org/phoebus/applications/alarm/logging/ui/AlarmLogTableController.java @@ -4,7 +4,6 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; -import com.sun.jersey.api.client.WebResource; import javafx.animation.KeyFrame; import javafx.animation.KeyValue; import javafx.animation.Timeline; @@ -55,6 +54,7 @@ import java.net.URI; import java.net.URISyntaxException; +import java.net.http.HttpClient; import java.time.Instant; import java.util.Arrays; import java.util.List; @@ -133,7 +133,7 @@ public class AlarmLogTableController { private List alarmMessages; private Job alarmLogSearchJob; - private WebResource searchClient; + private HttpClient httpClient; @FXML private ProgressIndicator progressIndicator; @@ -144,7 +144,7 @@ public class AlarmLogTableController { private final ContextMenu configsContextMenu = new ContextMenu(); - public AlarmLogTableController(WebResource client) { + public AlarmLogTableController(HttpClient client) { setClient(client); } @@ -364,7 +364,7 @@ private void periodicSearch() { sortTableCol = tableView.getSortOrder().get(0); sortColType = sortTableCol.getSortType(); } - alarmLogSearchJob = AlarmLogSearchJob.submit(searchClient, searchString, isNodeTable, searchParameters, + alarmLogSearchJob = AlarmLogSearchJob.submit(httpClient, searchString, isNodeTable, searchParameters, result -> Platform.runLater(() -> { setAlarmMessages(result); searchInProgress.set(false); @@ -411,8 +411,8 @@ public void setAlarmMessages(List alarmMessages) { } } - public void setClient(WebResource client) { - this.searchClient = client; + public void setClient(HttpClient client) { + this.httpClient = client; } /** @@ -541,7 +541,7 @@ public void createContextMenu() { }) .collect(Collectors.toList()); // TODO place holder method for showing additional alarm info - AlarmLogConfigSearchJob.submit(searchClient, + AlarmLogConfigSearchJob.submit(httpClient, configs.get(0), result -> Platform.runLater(() -> { Alert alarmInfo = new Alert(Alert.AlertType.INFORMATION); diff --git a/app/alarm/logging-ui/src/main/java/org/phoebus/applications/alarm/logging/ui/Preferences.java b/app/alarm/logging-ui/src/main/java/org/phoebus/applications/alarm/logging/ui/Preferences.java new file mode 100644 index 0000000000..c7250b05bb --- /dev/null +++ b/app/alarm/logging-ui/src/main/java/org/phoebus/applications/alarm/logging/ui/Preferences.java @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2024 European Spallation Source ERIC. + */ + +package org.phoebus.applications.alarm.logging.ui; + +import org.phoebus.framework.preferences.AnnotatedPreferences; +import org.phoebus.framework.preferences.Preference; + +public class Preferences { + + @Preference + public static String service_uri; + + @Preference + public static int results_max_size; + + static + { + AnnotatedPreferences.initialize(Preferences.class, "/alarm_logging_preferences.properties"); + } +} diff --git a/app/logbook/olog/client-es/pom.xml b/app/logbook/olog/client-es/pom.xml index 0f1a6b60fa..32736ec0f7 100644 --- a/app/logbook/olog/client-es/pom.xml +++ b/app/logbook/olog/client-es/pom.xml @@ -10,11 +10,6 @@ app-logbook-olog-client-es - - jakarta.ws.rs - jakarta.ws.rs-api - 4.0.0 - com.fasterxml.jackson.datatype jackson-datatype-jsr310 diff --git a/app/logbook/olog/client-es/src/main/java/org/phoebus/olog/es/api/OlogHttpClient.java b/app/logbook/olog/client-es/src/main/java/org/phoebus/olog/es/api/OlogHttpClient.java index e8e871620b..853cfd8fe1 100644 --- a/app/logbook/olog/client-es/src/main/java/org/phoebus/olog/es/api/OlogHttpClient.java +++ b/app/logbook/olog/client-es/src/main/java/org/phoebus/olog/es/api/OlogHttpClient.java @@ -9,8 +9,6 @@ import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; -import jakarta.ws.rs.core.MultivaluedHashMap; -import jakarta.ws.rs.core.MultivaluedMap; import org.phoebus.logbook.Attachment; import org.phoebus.logbook.LogClient; import org.phoebus.logbook.LogEntry; @@ -30,7 +28,10 @@ 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 javax.ws.rs.core.MultivaluedHashMap; +import javax.ws.rs.core.MultivaluedMap; import java.io.InputStream; import java.net.CookieManager; import java.net.CookiePolicy; @@ -158,7 +159,7 @@ public LogEntry set(LogEntry log) throws LogbookException { */ private LogEntry save(LogEntry log, LogEntry inReplyTo) throws LogbookException { try { - MultivaluedMap queryParams = new MultivaluedHashMap<>(); + javax.ws.rs.core.MultivaluedMap queryParams = new javax.ws.rs.core.MultivaluedHashMap<>(); queryParams.putSingle("markup", "commonmark"); if (inReplyTo != null) { queryParams.putSingle("inReplyTo", Long.toString(inReplyTo.getId())); @@ -172,7 +173,7 @@ private LogEntry save(LogEntry log, LogEntry inReplyTo) throws LogbookException } HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(Preferences.olog_url + "/logs/multipart?" + mapToQueryParams(queryParams))) + .uri(URI.create(Preferences.olog_url + "/logs/multipart?" + QueryParamsHelper.mapToQueryParams(queryParams))) .header("Content-Type", httpRequestMultipartBody.getContentType()) .header(OLOG_CLIENT_INFO_HEADER, CLIENT_INFO) .header("Authorization", basicAuthenticationHeader) diff --git a/core/util/pom.xml b/core/util/pom.xml index 6c1c162381..177527f3ce 100644 --- a/core/util/pom.xml +++ b/core/util/pom.xml @@ -7,6 +7,11 @@ core-util + + javax.ws.rs + javax.ws.rs-api + 2.1 + org.junit.jupiter junit-jupiter diff --git a/core/util/src/main/java/org/phoebus/util/http/QueryParamsHelper.java b/core/util/src/main/java/org/phoebus/util/http/QueryParamsHelper.java new file mode 100644 index 0000000000..55ed571a17 --- /dev/null +++ b/core/util/src/main/java/org/phoebus/util/http/QueryParamsHelper.java @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2024 European Spallation Source ERIC. + */ + +package org.phoebus.util.http; + +import javax.ws.rs.core.MultivaluedMap; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.List; + +public class QueryParamsHelper { + + public static String mapToQueryParams(MultivaluedMap map) { + StringBuilder stringBuilder = new StringBuilder(); + map.keySet().forEach(k -> { + List value = map.get(k); + if (value != null && !value.isEmpty()) { + stringBuilder.append(k).append("="); + stringBuilder.append(String.join(",", + value.stream().map(v -> URLEncoder.encode(v, StandardCharsets.UTF_8)).toList())); + stringBuilder.append("&"); + } + }); + return stringBuilder.toString(); + } +} diff --git a/core/util/src/test/java/org/phoebus/util/http/QueryParamsHelperTest.java b/core/util/src/test/java/org/phoebus/util/http/QueryParamsHelperTest.java new file mode 100644 index 0000000000..98da2bb6c6 --- /dev/null +++ b/core/util/src/test/java/org/phoebus/util/http/QueryParamsHelperTest.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2024 European Spallation Source ERIC. + */ + +package org.phoebus.util.http; + +import org.junit.jupiter.api.Test; + +import javax.ws.rs.core.MultivaluedHashMap; +import javax.ws.rs.core.MultivaluedMap; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; + +public class QueryParamsHelperTest { + + @Test + public void testBasic(){ + MultivaluedMap map = new MultivaluedHashMap<>(); + map.put("key1", List.of("value1", "value2")); + map.put("key2", List.of("value 3")); + map.put("key3", List.of("value:4")); + + String queryParamString = QueryParamsHelper.mapToQueryParams(map); + + assertEquals(queryParamString, "key1=value1,value2&key2=value+3&key3=value%3A4&"); + } +} diff --git a/services/alarm-logger/pom.xml b/services/alarm-logger/pom.xml index 4e98977b0f..54b72729d8 100644 --- a/services/alarm-logger/pom.xml +++ b/services/alarm-logger/pom.xml @@ -77,11 +77,11 @@ jackson-core ${jackson.version} - + com.fasterxml.jackson.core jackson-annotations