Skip to content

Commit

Permalink
server: support json object in query parameters for configurations
Browse files Browse the repository at this point in the history
This commit also includes the corresponding swagger updates.

[Added] support json object in query parameters for configurations

Signed-off-by: Bernd Hufmann <[email protected]>
  • Loading branch information
bhufmann committed Sep 23, 2024
1 parent 049f390 commit 81ddcd2
Show file tree
Hide file tree
Showing 11 changed files with 331 additions and 71 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ Import-Package: com.fasterxml.jackson.annotation,
com.fasterxml.jackson.jaxrs.json,
com.google.common.base,
com.google.common.collect,
com.google.gson;version="2.8.2",
com.google.gson.annotations;version="2.8.2",
com.google.gson.reflect;version="2.8.2",
javax.ws.rs,
javax.ws.rs.client,
javax.ws.rs.core,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ bin.includes = META-INF/,\
about.html,\
plugin.properties,\
plugin.xml,\
schema/
schema/,\
config/
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"cpus": ["0", "1", "2"],
"thread": "my-thread",
"phone": "(123)345-567"
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
import static org.junit.Assert.fail;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Collections;
Expand All @@ -33,14 +35,18 @@
import javax.ws.rs.core.Response;

import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.tracecompass.incubator.internal.trace.server.jersey.rest.core.model.views.ConfigurationQueryParameters;
import org.eclipse.tracecompass.incubator.internal.trace.server.jersey.rest.core.model.views.QueryParameters;
import org.eclipse.tracecompass.incubator.internal.trace.server.jersey.rest.core.services.ConfigurationManagerService;
import org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core.tests.stubs.ExperimentModelStub;
import org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core.tests.stubs.TmfConfigurationSourceTypeStub;
import org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core.tests.stubs.TmfConfigurationStub;
import org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core.tests.stubs.config.TestSchemaConfigurationSource.Parameters;
import org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core.tests.utils.RestServerTest;
import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.module.XmlUtils;
import org.eclipse.tracecompass.tmf.core.config.ITmfConfigParamDescriptor;
Expand All @@ -51,6 +57,8 @@
import org.osgi.framework.Bundle;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;

/**
* Basic test for the {@link ConfigurationManagerService}.
Expand All @@ -60,13 +68,15 @@
@SuppressWarnings("restriction")
public class ConfigurationManagerServiceTest extends RestServerTest {

private static final Bundle TEST_BUNDLE = Platform.getBundle("org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core.tests");
private static final Bundle XML_CORE_TESTS = Platform.getBundle("org.eclipse.tracecompass.tmf.analysis.xml.core.tests");

private static final String UNKNOWN_TYPE = "test-test-test";
private static final String PATH_INVALID = "test_xml_files/test_invalid/";
private static final String PATH_VALID = "test_xml_files/test_valid/";
private static final String PATH = "path";
private static final String XML_ANALYSIS_TYPE_ID = "org.eclipse.tracecompass.tmf.core.config.xmlsourcetype";
private static final String CONFIG_WITH_SCHEMA_ANALYSIS_TYPE_ID = "org.eclipse.tracecompass.tmf.core.config.testschemasourcetype";
private static final String EXPECTED_TYPE_NAME = "XML Data-driven analyses"; //$NON-NLS-1$
private static final String EXPECTED_TYPE_DESCRIPTION = "Data-driven analyses described in XML"; //$NON-NLS-1$
private static final String EXPECTED_KEY_NAME = "path";
Expand All @@ -80,6 +90,12 @@ public class ConfigurationManagerServiceTest extends RestServerTest {
private static final String EXPECTED_CONFIG_DESCRIPTION = "XML Data-driven analysis: " + VALID_NAME;
private static final String PATH_TO_INVALID_PATH = getPath(PATH_INVALID + INVALID_XML_FILE);
private static final String PATH_TO_VALID_PATH = getPath(PATH_VALID + VALID_XML_FILE);
private static final String CONFIG_FOLDER_NAME = "config";
private static final String VALID_JSON_FILENAME = "custom-execution-analysis.json";

private static final String EXPECTED_JSON_CONFIG_NAME = "My Config Name";
private static final String EXPECTED_JSON_CONFIG_DESCRIPTION = "My Config Description";
private static final String EXPECTED_JSON_CONFIG_ID = "My Config Id";

private static final GenericType<TmfConfigurationStub> CONFIGURATION = new GenericType<>() { };
private static final GenericType<List<TmfConfigurationStub>> LIST_CONFIGURATION_TYPE = new GenericType<>() { };
Expand Down Expand Up @@ -204,6 +220,37 @@ public void testCreateGetAndDelete() {
}
}

/**
* Test POST to create configurations using a schema.
*
* @throws IOException
* if exception occurs
* @throws URISyntaxException
* if exception occurs
*/
@Test
public void testCreateGetAndDeleteSchema() throws URISyntaxException, IOException {
try (Response response = createJsonConfig(VALID_JSON_FILENAME)) {
assertEquals(200, response.getStatus());
TmfConfigurationStub config = response.readEntity(CONFIGURATION);
assertNotNull(config);
validateJsonConfig(config);
}

List<TmfConfigurationStub> configurations = getConfigurations(CONFIG_WITH_SCHEMA_ANALYSIS_TYPE_ID);
assertEquals("Valid JSON configuration should be added", 1, configurations.size());
assertTrue("Valid configuration instance should exist", configurations.stream().anyMatch(conf -> conf.getName().equals(EXPECTED_JSON_CONFIG_NAME)));

TmfConfigurationStub config = getConfiguration(CONFIG_WITH_SCHEMA_ANALYSIS_TYPE_ID, configurations.get(0).getId());
assertNotNull(config);
assertTrue("JSON configuration instance should exist", config.getId().equals(EXPECTED_JSON_CONFIG_ID));

try (Response response = deleteConfig(CONFIG_WITH_SCHEMA_ANALYSIS_TYPE_ID, config.getId())) {
assertEquals(200, response.getStatus());
assertEquals("JSON configuration should have been deleted", 0, getConfigurations(CONFIG_WITH_SCHEMA_ANALYSIS_TYPE_ID).size());
}
}

/**
* Test PUT to update configurations using XML configuration source type.
*/
Expand Down Expand Up @@ -316,8 +363,28 @@ private static Response createConfig(String path, boolean isCorrectType) {
if (path != null) {
parameters.put(PATH, path);
}
ObjectMapper mapper = new ObjectMapper();
return endpoint.request(MediaType.APPLICATION_JSON)
.post(Entity.json(new QueryParameters(parameters, Collections.emptyList())));
.post(Entity.json(new ConfigurationQueryParameters(mapper.valueToTree(parameters))));
}

private static Response createJsonConfig(String jsonFileName) throws URISyntaxException, IOException {
String typeId = CONFIG_WITH_SCHEMA_ANALYSIS_TYPE_ID;
WebTarget endpoint = getApplicationEndpoint()
.path(CONFIG_PATH)
.path(TYPES_PATH)
.path(typeId)
.path(CONFIG_INSTANCES_PATH);

IPath defaultPath = new org.eclipse.core.runtime.Path(CONFIG_FOLDER_NAME).append(jsonFileName);
URL url = FileLocator.find(TEST_BUNDLE, defaultPath, null);
File jsonFile = new File(FileLocator.toFileURL(url).toURI());
try (InputStream inputStream = new FileInputStream(jsonFile)) {
ObjectMapper mapper = new ObjectMapper();
JsonNode json = mapper.readTree(inputStream);
return endpoint.request(MediaType.APPLICATION_JSON)
.post(Entity.json(new ConfigurationQueryParameters(json)));
}
}

private static Response updateConfig(String path, String id) {
Expand Down Expand Up @@ -348,33 +415,59 @@ private static Response updateConfig(String path, String id, boolean isCorrectTy
if (path != null) {
parameters.put(PATH, path);
}
ObjectMapper mapper = new ObjectMapper();
return endpoint.request(MediaType.APPLICATION_JSON)
.put(Entity.json(new QueryParameters(parameters, Collections.emptyList())));
.put(Entity.json(new ConfigurationQueryParameters(mapper.valueToTree(parameters))));
}

private static Response deleteConfig(String id) {
return deleteConfig(null, id);
}

private static Response deleteConfig(String type, String id) {
String requestType = type;
if (requestType == null) {
requestType = XML_ANALYSIS_TYPE_ID;
}
WebTarget endpoint = getApplicationEndpoint()
.path(CONFIG_PATH)
.path(TYPES_PATH)
.path(XML_ANALYSIS_TYPE_ID)
.path(requestType)
.path(CONFIG_INSTANCES_PATH);
return endpoint.path(id).request().delete();
}

private static List<TmfConfigurationStub> getConfigurations() {
return getConfigurations(null);
}

private static List<TmfConfigurationStub> getConfigurations(@Nullable String type) {
String requestType = type;
if (requestType == null) {
requestType = XML_ANALYSIS_TYPE_ID;
}

WebTarget endpoint = getApplicationEndpoint()
.path(CONFIG_PATH)
.path(TYPES_PATH)
.path(XML_ANALYSIS_TYPE_ID)
.path(requestType)
.path(CONFIG_INSTANCES_PATH);
return endpoint.request().get(LIST_CONFIGURATION_TYPE);
}

private static TmfConfigurationStub getConfiguration(String configId) {
return getConfiguration(null, configId);
}

private static TmfConfigurationStub getConfiguration(String type, String configId) {
String requestType = type;
if (requestType == null) {
requestType = XML_ANALYSIS_TYPE_ID;
}
WebTarget endpoint = getApplicationEndpoint()
.path(CONFIG_PATH)
.path(TYPES_PATH)
.path(XML_ANALYSIS_TYPE_ID)
.path(requestType)
.path(CONFIG_INSTANCES_PATH)
.path(configId);
return endpoint.request().get(CONFIGURATION);
Expand All @@ -388,4 +481,19 @@ private static void validateConfig(ITmfConfiguration config) {
assertEquals(EXPECTED_CONFIG_DESCRIPTION, config.getDescription());
assertTrue(config.getParameters().isEmpty());
}

@SuppressWarnings("null")
private static void validateJsonConfig(ITmfConfiguration config) {
assertEquals(EXPECTED_JSON_CONFIG_NAME, config.getName());
assertEquals(EXPECTED_JSON_CONFIG_ID, config.getId());
assertEquals(CONFIG_WITH_SCHEMA_ANALYSIS_TYPE_ID, config.getSourceTypeId());
assertEquals(EXPECTED_JSON_CONFIG_DESCRIPTION, config.getDescription());
Map<String, Object> parameters = config.getParameters();
assertNotNull(parameters);
String json = config.getJsonParameters();
assertNotNull(json);
// Use Gson to verify JsonString
Parameters paramObj = new Gson().fromJson(json, Parameters.class);
assertNotNull(paramObj);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@

import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.tracecompass.tmf.core.config.ITmfConfiguration;
import org.eclipse.tracecompass.tmf.core.config.TmfConfiguration;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.JsonNode;

/**
* Basic Implementation of the serialized ITmfConfiguration model used by clients.
Expand All @@ -33,7 +33,12 @@ public class TmfConfigurationStub implements Serializable, ITmfConfiguration {
* Generated Serial Version UID
*/
private static final long serialVersionUID = 6934234848155424428L;
private final ITmfConfiguration fConfig;
private final String fId;
private final String fName;
private final String fDescription;
private final String fSourceTypeId;
private final Map<String, Object> fParameters;
private final JsonNode fJsonParameters;

/**
* {@link JsonCreator} Constructor for final fields
Expand All @@ -50,75 +55,65 @@ public class TmfConfigurationStub implements Serializable, ITmfConfiguration {
* the parameters
*
*/
@SuppressWarnings("null")
@JsonCreator
public TmfConfigurationStub(@JsonProperty("id") String id,
@JsonProperty("name") String name,
@JsonProperty("description") String description,
@JsonProperty("sourceTypeId") String type,
@JsonProperty("parameters") Map<String, Object> parameters) {
@JsonProperty("parameters") Map<String, Object> parameters,
@JsonProperty("jsonParameters") JsonNode jsonParameters) {
super();

TmfConfiguration.Builder builder = new TmfConfiguration.Builder()
.setDescription(description)
.setName(name)
.setId(id)
.setSourceTypeId(type);
if (parameters != null) {
builder.setParameters(parameters);
}
fConfig = builder.build();
}


ITmfConfiguration getConfig() {
return fConfig;
fId = id;
fName = name;
fDescription = description;
fSourceTypeId = type;
fParameters = parameters;
fJsonParameters = jsonParameters;
}

@Override
public int hashCode() {
return fConfig.hashCode();
return Objects.hash(fId, fDescription, fSourceTypeId, fJsonParameters);
}

@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
public boolean equals(Object arg0) {
if (!(arg0 instanceof TmfConfigurationStub)) {
return false;
}
if (obj instanceof TmfConfigurationStub) {
return Objects.equals(this.getConfig(), ((TmfConfigurationStub) obj).getConfig());
}
if (obj instanceof TmfConfiguration) {
return Objects.equals(this.getConfig(), obj);
}
return false;
TmfConfigurationStub other = (TmfConfigurationStub) arg0;
return Objects.equals(fName, other.fName) && Objects.equals(fId, other.fId)
&& Objects.equals(fSourceTypeId, other.fSourceTypeId) && Objects.equals(fDescription, other.fDescription)
&& Objects.equals(fJsonParameters, other.fJsonParameters);
}

@Override
public @NonNull String getName() {
return fConfig.getName();
return fName;
}

@Override
public @NonNull String getId() {
return fConfig.getId();
return fId;
}

@Override
public @NonNull String getDescription() {
return fConfig.getDescription();
return fDescription;
}

@Override
public @NonNull String getSourceTypeId() {
return fConfig.getSourceTypeId();
return fSourceTypeId;
}

@Override
public @NonNull Map<@NonNull String, @NonNull Object> getParameters() {
return fConfig.getParameters();
return fParameters;
}

@Override
public @NonNull String getJsonParameters() {
return fJsonParameters == null ? "" :fJsonParameters.toString();
}
}
Loading

0 comments on commit 81ddcd2

Please sign in to comment.