diff options
author | Loïc Prieur-Drevon | 2018-02-19 21:44:30 +0000 |
---|---|---|
committer | Loic Prieur-Drevon | 2018-02-22 20:55:34 +0000 |
commit | df5b90b98be96a402648f00885bd938c5e64848b (patch) | |
tree | b1b5aab477747102ee990b879ccd291486eb084f | |
parent | 80c3a71d7814b4bd49f366bc3c36f3083d996dff (diff) | |
download | org.eclipse.tracecompass.incubator-df5b90b98be96a402648f00885bd938c5e64848b.tar.gz org.eclipse.tracecompass.incubator-df5b90b98be96a402648f00885bd938c5e64848b.tar.xz org.eclipse.tracecompass.incubator-df5b90b98be96a402648f00885bd938c5e64848b.zip |
rest: add support for XML treeXy providers.
Change-Id: I3445f2ebbd783f55cc8d223bf3c91b7bb4b11dbf
Signed-off-by: Loïc Prieur-Drevon <loic.prieurdrevon@gmail.com>
Reviewed-on: https://git.eclipse.org/r/117698
Tested-by: Hudson CI
Reviewed-by: Bernd Hufmann <bernd.hufmann@ericsson.com>
Tested-by: Bernd Hufmann <bernd.hufmann@ericsson.com>
8 files changed, 294 insertions, 8 deletions
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 b5e58c779..0b8c184b9 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 @@ -15,7 +15,8 @@ Require-Bundle: org.eclipse.core.runtime, com.fasterxml.jackson.jaxrs.jackson-jaxrs-json-provider, com.fasterxml.jackson.core.jackson-databind, org.eclipse.tracecompass.tmf.core, - org.eclipse.tracecompass.lttng2.ust.core + org.eclipse.tracecompass.lttng2.ust.core, + org.eclipse.tracecompass.tmf.analysis.xml.core.tests Export-Package: org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core.tests Import-Package: com.fasterxml.jackson.annotation, com.fasterxml.jackson.jaxrs.base, 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/DataProviderServiceTest.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/DataProviderServiceTest.java index b734e200d..bf5d8165e 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/DataProviderServiceTest.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/DataProviderServiceTest.java @@ -25,9 +25,9 @@ import org.junit.Test; * @author Loic Prieur-Drevon */ public class DataProviderServiceTest extends RestServerTest { - private static final String PROVIDERS_PATH = "providers"; + static final String PROVIDERS_PATH = "providers"; private static final String CALL_STACK_DATAPROVIDER_ID = "org.eclipse.tracecompass.internal.tmf.core.callstack.provider.CallStackDataProvider"; - private static final String TREE_PATH = "tree"; + static final String TREE_PATH = "tree"; /** * Ensure that the Call Stack data provider exists for the trace. 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/XmlManagerServiceTest.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/XmlManagerServiceTest.java new file mode 100644 index 000000000..a2302a703 --- /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/services/XmlManagerServiceTest.java @@ -0,0 +1,111 @@ +/******************************************************************************* + * Copyright (c) 2018 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + *******************************************************************************/ + +package org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core.tests.services; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.Collections; +import java.util.Map; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.Form; +import javax.ws.rs.core.GenericType; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Platform; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.tracecompass.incubator.internal.trace.server.jersey.rest.core.services.XmlManagerService; +import org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core.tests.utils.RestServerTest; +import org.junit.Test; +import org.osgi.framework.Bundle; + +import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider; + +/** + * Basic test for the {@link XmlManagerService}. + * + * @author Loic Prieur-Drevon + */ +public class XmlManagerServiceTest extends RestServerTest { + private static final Bundle XML_CORE_TESTS = Platform.getBundle("org.eclipse.tracecompass.tmf.analysis.xml.core.tests"); + private static final GenericType<Map<String, String>> STRING_LIST_TYPE = new GenericType<Map<String, String>>() { + }; + + /** + * Test that XML files POST to the server correctly, and are accessible for + * providers + * + * @throws URISyntaxException + * if this URL is not formatted strictly according to to RFC2396 and + * cannot be converted to a URI. + * @throws IOException + * if an error occurs during the URL conversion + */ + @Test + public void test() throws URISyntaxException, IOException { + Client client = ClientBuilder.newClient(); + client.register(JacksonJsonProvider.class); + WebTarget application = client.target("http://localhost:8378/tracecompass"); + WebTarget xmlEndpoint = application.path("xml"); + + String invalidPath = getPath("test_xml_files/test_invalid/test_invalid.xml"); + Response invalidResponse = xmlEndpoint.request(MediaType.APPLICATION_JSON) + .post(Entity.form(new Form(PATH, invalidPath))); + assertEquals(500, invalidResponse.getStatus()); + assertEquals("Invalid path should not be added to XML collection", + 0, xmlEndpoint.request().get(STRING_LIST_TYPE).size()); + + String validPath = getPath("test_xml_files/test_valid/test_valid.xml"); + Response validResponse = xmlEndpoint.request(MediaType.APPLICATION_JSON) + .post(Entity.form(new Form(PATH, validPath))); + assertEquals(200, validResponse.getStatus()); + Map<String, String> map = xmlEndpoint.request().get(STRING_LIST_TYPE); + assertEquals("valid XML should have posted successfully", + Collections.singleton("test_valid.xml"), map.keySet()); + + WebTarget traces = application.path("traces"); + assertPost(traces, TRACE2_STUB); + + WebTarget xmlProviderPath = traces.path(TRACE2_UUID.toString()) + .path(DataProviderServiceTest.PROVIDERS_PATH) + // path to the tree XY data provider from the valid XML file + .path("org.eclipse.linuxtools.tmf.analysis.xml.core.tests.xy") + .path(DataProviderServiceTest.TREE_PATH); + Response xmlTree = xmlProviderPath.request(MediaType.APPLICATION_JSON).get(); + assertEquals("The end point for the XML data provider should be available.", 200, xmlTree.getStatus()); + + assertEquals(200, xmlEndpoint.path("test_valid.xml").request().delete().getStatus()); + assertEquals("XML file should have been deleted", + 0, xmlEndpoint.request().get(STRING_LIST_TYPE).size()); + + Response noXmlTree = xmlProviderPath.request(MediaType.APPLICATION_JSON).get(); + assertEquals("The end point for the XML data provider should no longer be available.", + 405, noXmlTree.getStatus()); + } + + private static @NonNull String getPath(String bundlePath) throws URISyntaxException, IOException { + assertNotNull(XML_CORE_TESTS); + URL location = FileLocator.find(XML_CORE_TESTS, new Path(bundlePath), null); + String path = FileLocator.toFileURL(location).toURI().getPath(); + assertNotNull(path); + return path; + } + +} 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/utils/RestServerTest.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/utils/RestServerTest.java index 465552de2..8a810e0d3 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/utils/RestServerTest.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/utils/RestServerTest.java @@ -46,7 +46,7 @@ public abstract class RestServerTest { private static final String SERVER = "http://localhost:8378/tracecompass/traces"; //$NON-NLS-1$ private static final WebApplication fWebApp = new WebApplication(WebApplication.TEST_PORT); private static final String NAME = "name"; - private static final String PATH = "path"; //$NON-NLS-1$ + protected static final String PATH = "path"; //$NON-NLS-1$ private static final GenericType<Set<TraceModelStub>> TRACE_MODEL_SET_TYPE = new GenericType<Set<TraceModelStub>>() { }; diff --git a/trace-server/org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core/META-INF/MANIFEST.MF b/trace-server/org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core/META-INF/MANIFEST.MF index c050b75bb..5f7aad72b 100644 --- a/trace-server/org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core/META-INF/MANIFEST.MF +++ b/trace-server/org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core/META-INF/MANIFEST.MF @@ -38,7 +38,9 @@ Require-Bundle: org.eclipse.core.runtime, com.fasterxml.jackson.datatype.jackson-datatype-guava, com.fasterxml.jackson.jaxrs.jackson-jaxrs-base Import-Package: com.google.common.base, - com.google.common.collect;version="15.0.0" + com.google.common.collect, + org.eclipse.tracecompass.internal.tmf.analysis.xml.core.module, + org.eclipse.tracecompass.tmf.analysis.xml.core.module Bundle-ClassPath: ., lib/validation-api-1.1.0.Final.jar, lib/jackson-module-jaxb-annotations-2.6.2.jar, 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/services/DataProviderService.java b/trace-server/org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core/src/org/eclipse/tracecompass/incubator/internal/trace/server/jersey/rest/core/services/DataProviderService.java index 5c40a24d7..e36460c60 100644 --- a/trace-server/org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core/src/org/eclipse/tracecompass/incubator/internal/trace/server/jersey/rest/core/services/DataProviderService.java +++ b/trace-server/org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core/src/org/eclipse/tracecompass/incubator/internal/trace/server/jersey/rest/core/services/DataProviderService.java @@ -6,8 +6,10 @@ * accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ + package org.eclipse.tracecompass.incubator.internal.trace.server.jersey.rest.core.services; +import java.util.EnumSet; import java.util.List; import java.util.Set; import java.util.UUID; @@ -25,6 +27,7 @@ import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; 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.GenericView; import org.eclipse.tracecompass.internal.provisional.tmf.core.model.filters.SelectionTimeQueryFilter; import org.eclipse.tracecompass.internal.provisional.tmf.core.model.filters.TimeQueryFilter; @@ -37,8 +40,16 @@ import org.eclipse.tracecompass.internal.provisional.tmf.core.model.tree.ITmfTre import org.eclipse.tracecompass.internal.provisional.tmf.core.model.xy.ITmfTreeXYDataProvider; import org.eclipse.tracecompass.internal.provisional.tmf.core.model.xy.ITmfXyModel; import org.eclipse.tracecompass.internal.provisional.tmf.core.response.TmfModelResponse; +import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.module.XmlOutputElement; +import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.module.XmlUtils; +import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.module.XmlUtils.OutputType; +import org.eclipse.tracecompass.tmf.analysis.xml.core.module.TmfXmlUtils; +import org.eclipse.tracecompass.tmf.analysis.xml.core.module.XmlDataProviderManager; import org.eclipse.tracecompass.tmf.core.dataprovider.DataProviderManager; import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.w3c.dom.Element; + +import com.google.common.collect.Iterables; /** * Service to query the {@link ITmfTreeDataProvider}s @@ -81,15 +92,21 @@ public class DataProviderService { return Response.status(Status.NOT_FOUND).entity(NO_SUCH_TRACE).build(); } - ITmfTreeDataProvider<@NonNull ITmfTreeDataModel> provider = manager.getDataProvider(trace, + ITmfTreeDataProvider<? extends @NonNull ITmfTreeDataModel> provider = manager.getDataProvider(trace, providerId, ITmfTreeDataProvider.class); + + if (provider == null && providerId != null) { + // try and find the XML provider for the ID. + provider = getXmlProvider(trace, providerId, EnumSet.allOf(OutputType.class)); + } + if (provider == null) { // The analysis cannot be run on this trace return Response.status(Status.METHOD_NOT_ALLOWED).entity(NO_PROVIDER).build(); } - TmfModelResponse<@NonNull List<@NonNull ITmfTreeDataModel>> response = provider.fetchTree(new TimeQueryFilter(start, end, nb), null); - return Response.ok().entity(new GenericView<>(trace, response)).build(); + TmfModelResponse<?> treeResponse = provider.fetchTree(new TimeQueryFilter(start, end, nb), null); + return Response.ok().entity(new GenericView<>(trace, treeResponse)).build(); } /** @@ -125,6 +142,12 @@ public class DataProviderService { ITmfTreeXYDataProvider<@NonNull ITmfTreeDataModel> provider = manager.getDataProvider(trace, providerId, ITmfTreeXYDataProvider.class); + + if (provider == null && providerId != null) { + // try and find the XML provider for the ID. + provider = getXmlProvider(trace, providerId, EnumSet.of(OutputType.XY)); + } + if (provider == null) { // The analysis cannot be run on this trace return Response.status(Status.METHOD_NOT_ALLOWED).entity(NO_PROVIDER).build(); @@ -167,6 +190,12 @@ public class DataProviderService { ITimeGraphDataProvider<@NonNull ITimeGraphEntryModel> provider = manager.getDataProvider(trace, providerId, ITimeGraphDataProvider.class); + + if (provider == null && providerId != null) { + // try and find the XML provider for the ID. + provider = getXmlProvider(trace, providerId, EnumSet.of(OutputType.TIME_GRAPH)); + } + if (provider == null) { // The analysis cannot be run on this trace return Response.status(Status.METHOD_NOT_ALLOWED).entity(NO_PROVIDER).build(); @@ -206,6 +235,12 @@ public class DataProviderService { ITimeGraphDataProvider<@NonNull ITimeGraphEntryModel> provider = manager.getDataProvider(trace, providerId, ITimeGraphDataProvider.class); + + if (provider == null && providerId != null) { + // try and find the XML provider for the ID. + provider = getXmlProvider(trace, providerId, EnumSet.of(OutputType.TIME_GRAPH)); + } + if (provider == null) { // The analysis cannot be run on this trace return Response.status(Status.METHOD_NOT_ALLOWED).entity(NO_PROVIDER).build(); @@ -215,4 +250,32 @@ public class DataProviderService { return Response.ok().entity(new GenericView<>(trace, response)).build(); } + /** + * Get the XML data provider for a trace, provider id and XML {@link OutputType} + * + * @param trace + * the queried trace + * @param id + * the queried ID + * @param types + * the data provider type + * @return the provider if an XML containing the ID exists and applies to the + * trace, else null + */ + private static <@Nullable P extends ITmfTreeDataProvider<? extends @NonNull ITmfTreeDataModel>> P + getXmlProvider(@NonNull ITmfTrace trace, @NonNull String id, EnumSet<OutputType> types) { + for (OutputType viewType : types) { + for (XmlOutputElement element : Iterables.filter(XmlUtils.getXmlOutputElements().values(), + element -> element.getXmlElem().equals(viewType.getXmlElem()) && id.equals(element.getId()))) { + Element viewElement = TmfXmlUtils.getElementInFile(element.getPath(), viewType.getXmlElem(), id); + if (viewElement != null && viewType == OutputType.XY) { + return (P) XmlDataProviderManager.getInstance().getXyProvider(trace, viewElement); + } else if (viewElement != null && viewType == OutputType.TIME_GRAPH) { + return (P) XmlDataProviderManager.getInstance().getTimeGraphProvider(trace, viewElement); + } + } + } + return null; + } + } 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/services/XmlManagerService.java b/trace-server/org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core/src/org/eclipse/tracecompass/incubator/internal/trace/server/jersey/rest/core/services/XmlManagerService.java new file mode 100644 index 000000000..e9d679fe5 --- /dev/null +++ b/trace-server/org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core/src/org/eclipse/tracecompass/incubator/internal/trace/server/jersey/rest/core/services/XmlManagerService.java @@ -0,0 +1,107 @@ +/******************************************************************************* + * Copyright (c) 2018 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + *******************************************************************************/ + +package org.eclipse.tracecompass.incubator.internal.trace.server.jersey.rest.core.services; + +import java.io.File; + +import javax.ws.rs.DELETE; +import javax.ws.rs.FormParam; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.module.XmlAnalysisModuleSource; +import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.module.XmlUtils; + +import com.google.common.collect.Maps; + +/** + * XML analysis and provider management + * + * @author Loic Prieur-Drevon + */ +@Path("/xml") +@SuppressWarnings("restriction") +public class XmlManagerService { + + /** + * Getter for the list of available XML files + * + * @return list of available XML files, encapsulated in a response. + */ + @GET + @Produces({ MediaType.APPLICATION_JSON }) + public Response getXml() { + return Response.ok().entity(Maps.transformValues(XmlUtils.listFiles(), File::getAbsolutePath)).build(); + } + + /** + * POST a new XML file to the server + * + * @param path + * path to the file + * @return status for adding new XML + */ + @POST + public Response postXml(@FormParam("path") String path) { + return updateXml(path, true); + } + + /** + * PUT an XML file to the server + * + * @param path + * path to the file + * @return status for adding new XML + */ + @PUT + public Response putXml(@FormParam("path") String path) { + return updateXml(path, false); + } + + /** + * End point to delete an XML file by name + * + * @param path + * XML file name + * @return OK + */ + @DELETE + @Path("/{name}") + public Response deleteXml(@PathParam("name") String path) { + XmlUtils.deleteFile(path); + return Response.ok().build(); + } + + private static Response updateXml(String path, boolean addFile) { + File file = new File(path); + + IStatus status = XmlUtils.xmlValidate(file); + if (status.isOK()) { + if (addFile) { + status = XmlUtils.addXmlFile(file); + } else { + XmlUtils.updateXmlFile(file); + } + if (status.isOK()) { + XmlAnalysisModuleSource.notifyModuleChange(); + return Response.ok().build(); + } + } + return Response.serverError().build(); + } + +} 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/WebApplication.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/WebApplication.java index 7e3be8295..cb21aa672 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/WebApplication.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/WebApplication.java @@ -14,6 +14,7 @@ import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.tracecompass.incubator.internal.trace.server.jersey.rest.core.services.DataProviderService; import org.eclipse.tracecompass.incubator.internal.trace.server.jersey.rest.core.services.EventTableService; import org.eclipse.tracecompass.incubator.internal.trace.server.jersey.rest.core.services.TraceManagerService; +import org.eclipse.tracecompass.incubator.internal.trace.server.jersey.rest.core.services.XmlManagerService; import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; import org.glassfish.jersey.server.ResourceConfig; import org.glassfish.jersey.servlet.ServletContainer; @@ -75,6 +76,7 @@ public class WebApplication { rc.register(TraceManagerService.class); rc.register(EventTableService.class); rc.register(DataProviderService.class); + rc.register(XmlManagerService.class); rc.register(CORSFilter.class); rc.register(registerCustomMappers()); |