From 543470a7b39c34b754caaa4cdf3d1c120319e392 Mon Sep 17 00:00:00 2001 From: Bernd Hufmann Date: Tue, 27 Aug 2024 09:54:36 -0400 Subject: [PATCH] server: Serialize TmfConfigurationSourceType schema as UTF8 string See eclipse-cdt-cloud/trace-server-protocol#103 Also, add test for TmfConfigurationSourceType with schema as string. [Added] Serialize TmfConfigurationSourceType schema as string Signed-off-by: Bernd Hufmann --- .../META-INF/MANIFEST.MF | 3 +- .../build.properties | 4 +- .../plugin.xml | 11 ++ .../schema/custom-execution-analysis.json | 30 +++++ .../ConfigurationManagerServiceTest.java | 20 +++- .../stubs/TmfConfigurationSourceTypeStub.java | 29 ++--- .../config/TestSchemaConfigurationSource.java | 108 ++++++++++++++++++ .../TmfConfigurationSourceTypeSerializer.java | 16 +++ 8 files changed, 204 insertions(+), 17 deletions(-) create mode 100644 trace-server/org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core.tests/plugin.xml create mode 100644 trace-server/org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core.tests/schema/custom-execution-analysis.json create mode 100644 trace-server/org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core.tests/src/org/eclipse/tracecompass/incubator/trace/server/jersey/rest/core/tests/stubs/config/TestSchemaConfigurationSource.java diff --git a/trace-server/org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core.tests/META-INF/MANIFEST.MF b/trace-server/org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core.tests/META-INF/MANIFEST.MF index dc12051bb..3cb671102 100644 --- a/trace-server/org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core.tests/META-INF/MANIFEST.MF +++ b/trace-server/org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core.tests/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name Bundle-Vendor: %Bundle-Vendor -Bundle-SymbolicName: org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core.tests +Bundle-SymbolicName: org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core.tests;singleton:=true Bundle-Version: 0.1.9.qualifier Bundle-Localization: plugin Bundle-ActivationPolicy: lazy @@ -29,6 +29,7 @@ Export-Package: org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core.tests.stubs.webapp, org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core.tests.utils Import-Package: com.fasterxml.jackson.annotation, + com.fasterxml.jackson.core, com.fasterxml.jackson.jaxrs.base, com.fasterxml.jackson.jaxrs.json, com.google.common.base, diff --git a/trace-server/org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core.tests/build.properties b/trace-server/org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core.tests/build.properties index cf0366079..e3b4e8580 100644 --- a/trace-server/org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core.tests/build.properties +++ b/trace-server/org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core.tests/build.properties @@ -14,4 +14,6 @@ output.. = bin/ bin.includes = META-INF/,\ .,\ about.html,\ - plugin.properties + plugin.properties,\ + plugin.xml,\ + schema/ diff --git a/trace-server/org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core.tests/plugin.xml b/trace-server/org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core.tests/plugin.xml new file mode 100644 index 000000000..d740c328b --- /dev/null +++ b/trace-server/org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core.tests/plugin.xml @@ -0,0 +1,11 @@ + + + + + + + + diff --git a/trace-server/org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core.tests/schema/custom-execution-analysis.json b/trace-server/org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core.tests/schema/custom-execution-analysis.json new file mode 100644 index 000000000..209bdcae2 --- /dev/null +++ b/trace-server/org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core.tests/schema/custom-execution-analysis.json @@ -0,0 +1,30 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://org.eclipse.tracecompass/custom-execution-analysis.json", + "title": "Custom Execution Analysis", + "description": "Custom Execution Analysis schema", + "type": "object", + "properties": { + "cpus": { + "description": "array of integer", + "type": "array", + "items": { + "type": "number" + } + }, + "thread": { + "description": "Thread regular expression pattern", + "type": "string" + }, + "phone": { + "description": "Phone number", + "type": "string", + "pattern": "^(\\([0-9]{3}\\))?[0-9]{3}-[0-9]{4}$" + }, + "label": { + "description": "Optional label text", + "type": "string" + } + }, + "required": ["thread"] +} diff --git a/trace-server/org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core.tests/src/org/eclipse/tracecompass/incubator/trace/server/jersey/rest/core/tests/services/ConfigurationManagerServiceTest.java b/trace-server/org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core.tests/src/org/eclipse/tracecompass/incubator/trace/server/jersey/rest/core/tests/services/ConfigurationManagerServiceTest.java index 2c36d4804..d68332d48 100644 --- a/trace-server/org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core.tests/src/org/eclipse/tracecompass/incubator/trace/server/jersey/rest/core/tests/services/ConfigurationManagerServiceTest.java +++ b/trace-server/org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core.tests/src/org/eclipse/tracecompass/incubator/trace/server/jersey/rest/core/tests/services/ConfigurationManagerServiceTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2023 Ericsson + * Copyright (c) 2023, 2024 Ericsson * * All rights reserved. This program and the accompanying materials are * made available under the terms of the Eclipse Public License 2.0 which @@ -50,6 +50,10 @@ import org.junit.Test; import org.osgi.framework.Bundle; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; + /** * Basic test for the {@link ConfigurationManagerService}. * @@ -101,9 +105,11 @@ public void emptyXmlFolder() { /** * Test getting configuration source types and verify existing XML source * type + * @throws JsonProcessingException if invalid json (schema) + * @throws JsonMappingException if invalid json (schema) */ @Test - public void testSourceType() { + public void testSourceType() throws JsonMappingException, JsonProcessingException { WebTarget endpoint = getApplicationEndpoint() .path(CONFIG_PATH) .path(TYPES_PATH); @@ -142,6 +148,16 @@ public void testSourceType() { assertEquals(EXPECTED_DATA_TYPE, desc.getDataType()); assertEquals(EXPECTED_PARAM_DESCRIPTION, desc.getDescription()); assertTrue(desc.isRequired()); + + // Verify configuration source type with schema + Optional optional2 = configurations.stream().filter(config -> config.getId().equals("org.eclipse.tracecompass.tmf.core.config.testschemasourcetype")).findAny(); + assertTrue(optional2.isPresent()); + TmfConfigurationSourceTypeStub type2 = optional2.get(); + String schemaString = type2.getSchema(); + assertNotNull(schemaString); + ObjectMapper objectMapper = new ObjectMapper(); + // Verify that schemaString is a valid JSON (no exception thrown) + objectMapper.readTree(schemaString); } /** diff --git a/trace-server/org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core.tests/src/org/eclipse/tracecompass/incubator/trace/server/jersey/rest/core/tests/stubs/TmfConfigurationSourceTypeStub.java b/trace-server/org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core.tests/src/org/eclipse/tracecompass/incubator/trace/server/jersey/rest/core/tests/stubs/TmfConfigurationSourceTypeStub.java index 0eab6972a..f523b5723 100644 --- a/trace-server/org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core.tests/src/org/eclipse/tracecompass/incubator/trace/server/jersey/rest/core/tests/stubs/TmfConfigurationSourceTypeStub.java +++ b/trace-server/org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core.tests/src/org/eclipse/tracecompass/incubator/trace/server/jersey/rest/core/tests/stubs/TmfConfigurationSourceTypeStub.java @@ -36,6 +36,7 @@ public class TmfConfigurationSourceTypeStub implements Serializable, ITmfConfigu */ private static final long serialVersionUID = 6934234848155424428L; private final ITmfConfigurationSourceType fConfig; + private final String fSchema; /** * {@link JsonCreator} Constructor for final fields @@ -46,7 +47,9 @@ public class TmfConfigurationSourceTypeStub implements Serializable, ITmfConfigu * the name * @param description * the help text - * @param queryParamKeys + * @param schema + * the JSON schema string + * @param parameterDescriptors * the list of keys * */ @@ -55,6 +58,7 @@ public class TmfConfigurationSourceTypeStub implements Serializable, ITmfConfigu public TmfConfigurationSourceTypeStub(@JsonProperty("id") String id, @JsonProperty("name") String name, @JsonProperty("description") String description, + @JsonProperty("schema") String schema, @JsonProperty("parameterDescriptors") List parameterDescriptors) { super(); @@ -66,8 +70,15 @@ public TmfConfigurationSourceTypeStub(@JsonProperty("id") String id, builder.setConfigParamDescriptors(parameterDescriptors.stream().map(stub -> stub.getConfig()).collect(Collectors.toList())); } fConfig = builder.build(); + fSchema = schema; } + /** + * @return the JSON schema string + */ + public String getSchema() { + return fSchema; + } ITmfConfigurationSourceType getConfig() { return fConfig; @@ -75,24 +86,16 @@ ITmfConfigurationSourceType getConfig() { @Override public int hashCode() { - return fConfig.hashCode(); + return Objects.hash(fConfig, fSchema == null ? "null" : fSchema); } @Override public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { + if (!(obj instanceof TmfConfigurationSourceTypeStub)) { return false; } - if (obj instanceof TmfConfigurationSourceTypeStub) { - return Objects.equals(this.getConfig(), ((TmfConfigurationSourceTypeStub) obj).getConfig()); - } - if (obj instanceof TmfConfigurationSourceType) { - return Objects.equals(this.getConfig(), obj); - } - return false; + TmfConfigurationSourceTypeStub other = (TmfConfigurationSourceTypeStub) obj; + return Objects.equals(fConfig, other.fConfig) && Objects.equals(fSchema, other.fSchema); } @Override diff --git a/trace-server/org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core.tests/src/org/eclipse/tracecompass/incubator/trace/server/jersey/rest/core/tests/stubs/config/TestSchemaConfigurationSource.java b/trace-server/org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core.tests/src/org/eclipse/tracecompass/incubator/trace/server/jersey/rest/core/tests/stubs/config/TestSchemaConfigurationSource.java new file mode 100644 index 000000000..c7f6d438e --- /dev/null +++ b/trace-server/org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core.tests/src/org/eclipse/tracecompass/incubator/trace/server/jersey/rest/core/tests/stubs/config/TestSchemaConfigurationSource.java @@ -0,0 +1,108 @@ +/******************************************************************************* + * Copyright (c) 2023 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License 2.0 which + * accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ +package org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core.tests.stubs.config; + +import static org.eclipse.tracecompass.common.core.NonNullUtils.nullToEmptyString; + +import java.io.File; +import java.io.IOException; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Platform; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.tracecompass.tmf.core.config.ITmfConfiguration; +import org.eclipse.tracecompass.tmf.core.config.ITmfConfigurationSource; +import org.eclipse.tracecompass.tmf.core.config.ITmfConfigurationSourceType; +import org.eclipse.tracecompass.tmf.core.config.TmfConfigurationSourceType; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfConfigurationException; +import org.osgi.framework.Bundle; + +/** + * Test class + */ +public class TestSchemaConfigurationSource implements ITmfConfigurationSource { + + private static final @NonNull ITmfConfigurationSourceType fType; + + private static final @NonNull String TEST_ANALYSIS_TYPE_ID = "org.eclipse.tracecompass.tmf.core.config.testschemasourcetype"; //$NON-NLS-1$ + private static final @NonNull String NAME = nullToEmptyString("Test Schema Type"); //$NON-NLS-1$ + private static final @NonNull String DESCRIPTION = nullToEmptyString("Test Type with schema"); //$NON-NLS-1$ + + static { + Bundle bundle = Platform.getBundle("org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core.tests"); + IPath defaultPath = new org.eclipse.core.runtime.Path("schema/custom-execution-analysis.json"); //$NON-NLS-1$ + URL url = FileLocator.find(bundle, defaultPath, null); + File schemaFile = null; + try { + schemaFile = new File(FileLocator.toFileURL(url).toURI()); + } catch (URISyntaxException | IOException e) { + e.printStackTrace(); + } + fType = new TmfConfigurationSourceType.Builder() + .setId(TEST_ANALYSIS_TYPE_ID) + .setDescription(DESCRIPTION) + .setName(NAME) + .setSchemaFile(schemaFile) + .setConfigParamDescriptors(Collections.emptyList()).build(); + } + + /** + * Constructor + */ + public TestSchemaConfigurationSource() { + } + + @Override + public @NonNull ITmfConfigurationSourceType getConfigurationSourceType() { + return fType; + } + + @Override + public @NonNull ITmfConfiguration create(@NonNull Map<@NonNull String, @NonNull Object> parameters) throws TmfConfigurationException { + throw new TmfConfigurationException("Not implemented yet"); //$NON-NLS-1$ + } + + @Override + public @NonNull ITmfConfiguration update(@NonNull String id, @NonNull Map<@NonNull String, @NonNull Object> parameters) throws TmfConfigurationException { + throw new TmfConfigurationException("Not implemented yet"); //$NON-NLS-1$ + } + + @Override + public @Nullable ITmfConfiguration get(@NonNull String id) { + return null; + } + + @Override + public @Nullable ITmfConfiguration remove(@NonNull String id) { + return null; + } + + @Override + public boolean contains(@NonNull String id) { + return false; + } + + @Override + public @NonNull List<@NonNull ITmfConfiguration> getConfigurations() { + return Collections.emptyList(); + } + + @Override + public void dispose() { + } +} diff --git a/trace-server/org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core/src/org/eclipse/tracecompass/incubator/internal/trace/server/jersey/rest/core/webapp/TmfConfigurationSourceTypeSerializer.java b/trace-server/org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core/src/org/eclipse/tracecompass/incubator/internal/trace/server/jersey/rest/core/webapp/TmfConfigurationSourceTypeSerializer.java index a8c331014..4eee84cb6 100644 --- a/trace-server/org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core/src/org/eclipse/tracecompass/incubator/internal/trace/server/jersey/rest/core/webapp/TmfConfigurationSourceTypeSerializer.java +++ b/trace-server/org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core/src/org/eclipse/tracecompass/incubator/internal/trace/server/jersey/rest/core/webapp/TmfConfigurationSourceTypeSerializer.java @@ -11,7 +11,11 @@ package org.eclipse.tracecompass.incubator.internal.trace.server.jersey.rest.core.webapp; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; import java.io.IOException; +import java.io.InputStream; import org.eclipse.tracecompass.tmf.core.config.ITmfConfigurationSourceType; @@ -48,6 +52,18 @@ public void serialize(ITmfConfigurationSourceType value, JsonGenerator gen, Seri if (!value.getConfigParamDescriptors().isEmpty()) { gen.writeObjectField("parameterDescriptors", value.getConfigParamDescriptors()); //$NON-NLS-1$ } + File schemaFile = value.getSchemaFile(); + if (schemaFile != null) { + try (InputStream inputStream = new FileInputStream(schemaFile)) { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + for (int length; (length = inputStream.read(buffer)) != -1; ) { + result.write(buffer, 0, length); + } + gen.writeFieldName("schema"); //$NON-NLS-1$ + gen.writeUTF8String(buffer, 0, buffer.length); + } + } gen.writeEndObject(); } }