-
Notifications
You must be signed in to change notification settings - Fork 24
server: Add get report data provider endpoint #174
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -48,13 +48,15 @@ | |
| import org.eclipse.tracecompass.tmf.core.model.DataProviderDescriptor; | ||
| import org.eclipse.tracecompass.tmf.core.model.tree.ITmfTreeDataModel; | ||
| import org.eclipse.tracecompass.tmf.core.model.tree.ITmfTreeDataProvider; | ||
| import org.eclipse.tracecompass.tmf.core.response.TmfModelResponse; | ||
| import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler; | ||
| import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager; | ||
| import org.eclipse.tracecompass.tmf.core.signal.TmfTraceClosedSignal; | ||
| import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal; | ||
| import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; | ||
| import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager; | ||
| import org.eclipse.tracecompass.incubator.internal.analysis.core.Activator; | ||
| import org.eclipse.tracecompass.internal.provisional.tmf.core.dataprovider.TmfDataProviderDataModel; | ||
|
|
||
| import com.google.common.collect.HashBasedTable; | ||
| import com.google.common.collect.Table; | ||
|
|
@@ -726,4 +728,28 @@ public void dispose() { | |
| fTmfConfigurationHierarchy.clear(); | ||
| } | ||
|
|
||
| @SuppressWarnings("restriction") | ||
| @Override | ||
| public TmfModelResponse<TmfDataProviderDataModel<?>> getData(ITmfTrace trace, IDataProviderDescriptor descriptor) throws Exception { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The factory should be responsible create data providers (see line 121 above which needs to be implemented). Then the instance of data provider that was created there needs to be this method getData(). |
||
| if (descriptor.getType() != ProviderType.NONE) { | ||
| throw new TmfConfigurationException("The requested output is not a MIME report"); //$NON-NLS-1$ | ||
| } | ||
|
|
||
| ITmfConfiguration configuration = descriptor.getConfiguration(); | ||
| if (configuration == null) { | ||
| throw new TmfConfigurationException("Missing configuration for report"); //$NON-NLS-1$ " | ||
| } | ||
|
|
||
| ReportProviderType reportType = getReportType(configuration); | ||
| IReportDataProvider provider = ReportsDataProviderRegistry.getProvider(reportType); | ||
| if (provider == null) { | ||
| throw new TmfConfigurationException("No provider found for report type"); //$NON-NLS-1$ | ||
| } | ||
|
|
||
| if (provider instanceof ReportsDataProviderFactory) { | ||
| throw new TmfConfigurationException("Cannot get data from the report factory"); //$NON-NLS-1$ | ||
| } | ||
|
|
||
| return provider.getData(trace, descriptor); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -35,6 +35,7 @@ | |
| import static org.eclipse.tracecompass.incubator.internal.trace.server.jersey.rest.core.services.EndpointConstants.EXP_UUID; | ||
| import static org.eclipse.tracecompass.incubator.internal.trace.server.jersey.rest.core.services.EndpointConstants.FILTER_QUERY_PARAMETERS; | ||
| import static org.eclipse.tracecompass.incubator.internal.trace.server.jersey.rest.core.services.EndpointConstants.FILTER_QUERY_PARAMETERS_EX; | ||
| import static org.eclipse.tracecompass.incubator.internal.trace.server.jersey.rest.core.services.EndpointConstants.RPT; | ||
| import static org.eclipse.tracecompass.incubator.internal.trace.server.jersey.rest.core.services.EndpointConstants.INDEX; | ||
| import static org.eclipse.tracecompass.incubator.internal.trace.server.jersey.rest.core.services.EndpointConstants.INDEX_EX; | ||
| import static org.eclipse.tracecompass.incubator.internal.trace.server.jersey.rest.core.services.EndpointConstants.INVALID_PARAMETERS; | ||
|
|
@@ -133,6 +134,8 @@ | |
| import org.eclipse.tracecompass.incubator.internal.trace.server.jersey.rest.core.model.views.TreeModelWrapper; | ||
| import org.eclipse.tracecompass.incubator.internal.trace.server.jersey.rest.core.model.views.VirtualTableModelWrapper; | ||
| import org.eclipse.tracecompass.internal.analysis.timing.core.event.matching.EventMatchingLatencyAnalysis; | ||
| import org.eclipse.tracecompass.internal.provisional.tmf.core.dataprovider.ITmfDataProviderDataFetcher; | ||
| import org.eclipse.tracecompass.internal.provisional.tmf.core.dataprovider.TmfDataProviderDataModel; | ||
| import org.eclipse.tracecompass.internal.provisional.tmf.core.model.table.ITmfVirtualTableDataProvider; | ||
| import org.eclipse.tracecompass.internal.provisional.tmf.core.model.table.ITmfVirtualTableModel; | ||
| import org.eclipse.tracecompass.internal.provisional.tmf.core.model.table.IVirtualTableLine; | ||
|
|
@@ -1101,6 +1104,78 @@ private Response getTree(UUID expUUID, String outputId, QueryParameters queryPar | |
| } | ||
| } | ||
|
|
||
| /** | ||
| * Query the provider for a MIME report. Based on the given output, this | ||
| * endpoint will return a specific report, which can be an image, a | ||
| * textual data, a HTML, etc. | ||
| * | ||
| * @param expUUID | ||
| * desired experiment UUID | ||
| * @param outputId | ||
| * Output ID for the data provider to query | ||
| * @return {@link Response} with the corresponding report data | ||
| */ | ||
| @GET | ||
| @Path("/report/{outputId}") | ||
| @Tag(name = RPT) | ||
| @Produces(MediaType.WILDCARD) | ||
| @Operation(summary = "API to get a MIME report", responses = { | ||
| @ApiResponse(responseCode = "200", description = "Returns the report data"), | ||
| @ApiResponse(responseCode = "400", description = MISSING_PARAMETERS, content = @Content(schema = @Schema(implementation = String.class))), | ||
| @ApiResponse(responseCode = "404", description = "Provider not found, missing subtype, or requested resource not found", content = @Content(schema = @Schema(implementation = String.class))), | ||
| @ApiResponse(responseCode = "500", description = "Error retrieving the report data", content = @Content(schema = @Schema(implementation = String.class))), | ||
| }) | ||
| public Response getReport( | ||
| @Parameter(description = EXP_UUID) @PathParam("expUUID") UUID expUUID, | ||
| @Parameter(description = OUTPUT_ID) @PathParam("outputId") String outputId) { | ||
|
|
||
| if (outputId == null) { | ||
| return Response.status(Status.BAD_REQUEST).entity(MISSING_OUTPUTID).build(); | ||
| } | ||
|
|
||
| TmfExperiment experiment = ExperimentManagerService.getExperimentByUUID(expUUID); | ||
| if (experiment == null) { | ||
| return Response.status(Status.NOT_FOUND).entity(NO_SUCH_TRACE).build(); | ||
| } | ||
|
|
||
| IDataProviderDescriptor descriptor = getDescriptor(experiment, outputId); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This will always return null, because the DataProviderManager doesn't know about the data provider with that ID (unless it was registered). This shows some issue with the DataProviderManager because it manages ITmfTreeDataProviders. So, either the reports data provider implements ITmfTreeDataProvider which is created by the reports data provider factory (not the cleanest implementation), or in Trace Compass mainline the DataProviderManager is updated to handle other data providers than trees or a new data provider manager is created for new types of data providers. Trace Compass designers will have to be involved with this design in Trace Compass core. We need something like this below:
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have already tested this endpoint, and I could see that this code block is not returning I'm not sure if I have understood your point correctly or not, but please correct me if I'm wrong. |
||
| if (descriptor == null) { | ||
| return Response.status(Status.NOT_FOUND).entity(NO_SUCH_PROVIDER).build(); | ||
| } | ||
|
|
||
| IDataProviderFactory factory = manager.getFactory(REPORTS_FACTORY_ID); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This endpoint has to be independent of the reports customization. For example, if the incubator analysis.core plug-in not installed, how would one fetch the data of a data provider of type MIME?.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here, I tried to decouple this endpoint from As the What do you think of this?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. REPORTS_FACTORY_ID is only available if the incubator.analysis.core plug-in is installed. Otherwise there can't be any reports create by anything else.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess that's fine. Since the endpoint is only for this specific DP, in case of missing (e.g., not being installed), we can tell the user that it's not installed as a plug-in. wdyt?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
That's not really an option. Users cannot install plug-ins. Trace server applications are pre-build. |
||
| if (factory == null) { | ||
| return Response.status(Status.NOT_FOUND).entity(NO_SUCH_PROVIDER).build(); | ||
|
kavehshahedi marked this conversation as resolved.
|
||
| } | ||
|
|
||
| ITmfDataProviderDataFetcher dataFetcher = factory.getAdapter(ITmfDataProviderDataFetcher.class); | ||
| if (dataFetcher == null) { | ||
| return Response.status(Status.NOT_FOUND).entity("Report data fetcher not found").build(); //$NON-NLS-1$ " | ||
| } | ||
|
|
||
| try { | ||
| TmfModelResponse<TmfDataProviderDataModel<?>> reportResponse = dataFetcher.getData(experiment, descriptor); | ||
| if (reportResponse == null) { | ||
| return Response.status(Status.NOT_FOUND).entity("Report data not found").build(); //$NON-NLS-1$ | ||
| } | ||
|
|
||
| if (reportResponse.getStatus() != ITmfResponse.Status.COMPLETED) { | ||
| return Response.status(Status.INTERNAL_SERVER_ERROR).entity(reportResponse.getStatusMessage()).build(); | ||
| } | ||
|
|
||
| TmfDataProviderDataModel<?> responseModel = reportResponse.getModel(); | ||
| if (responseModel == null) { | ||
| return Response.status(Status.NOT_FOUND).entity("Report data model not found").build(); //$NON-NLS-1$ | ||
| } | ||
|
|
||
| return Response.ok(responseModel.getContent(), responseModel.getContentType()).build(); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For images, responseModel.getContent() returns a object of type
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Now the endpoint is producing
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How, will it work? Clients could ask for e.g. applicationt/pdf and the endpoint will allow it because of the wildcard but then the implementation won't be able to create a PDF but an image instead. I'm not clear about the procedure and header negotiation yet.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So, basically, the client can ask only based on the report type. For instance, the client only knows that it's an image, but doesn't know if it's a JPG or PNG or SVG. The endpoint then fetches the DP data, and returns the output with a specific content type, which can be image/jpg or image/png or etc. This information is provided in the response's headers as the content type (I have checked it already). |
||
| } catch (TmfConfigurationException e) { | ||
| return Response.status(Status.NOT_FOUND).entity(e.getMessage()).build(); | ||
| } catch (Exception e) { | ||
| return Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build(); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Query the provider for styles | ||
| * | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A data provider should not be a data provider factory. Generally,, we have data provider factories that create data provider instances which provide data (tree, xy, states, reports data). In this implementation, the reports data provider is a configurator, factory and data provider. The factory's main responsibility to create data providers. It can have the capabilities of a configurator. Using the configurator the data provider factory will be able to create instances of data providers using configuration.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are absolutely right. I was working around with this
IDataProiderFactoryto see how we can solve themanager.getFactory()issue in theDataProviderServiceclass, but I forgot to remove it in the end from the class. I will fix it.