From 6958104b4b2c05cb2be378e7fceb615c509095d6 Mon Sep 17 00:00:00 2001 From: Andrew Azores Date: Fri, 22 Sep 2023 15:54:00 -0400 Subject: [PATCH] remove HTML-based rules report generation --- .../io/cryostat/configuration/Variables.java | 1 - .../AbstractReportGeneratorService.java | 5 +- .../reports/ActiveRecordingReportCache.java | 76 +++------ .../reports/ArchivedRecordingReportCache.java | 18 +-- .../net/reports/RemoteReportGenerator.java | 5 +- .../net/reports/ReportGeneratorService.java | 6 +- .../cryostat/net/reports/ReportService.java | 26 ++-- .../net/reports/ReportTransformerModule.java | 34 ---- .../cryostat/net/reports/ReportsModule.java | 13 +- .../reports/SubprocessReportGenerator.java | 145 ++---------------- .../api/beta/ReportGetFromPathHandler.java | 9 +- .../beta/ReportGetFromPathWithJwtHandler.java | 11 +- .../web/http/api/beta/ReportGetHandler.java | 9 +- .../api/beta/ReportGetWithJwtHandler.java | 11 +- .../net/web/http/api/v1/ReportGetHandler.java | 2 +- .../http/api/v1/TargetReportGetHandler.java | 12 +- .../net/web/http/api/v2/ReportGetHandler.java | 2 +- .../http/api/v2/TargetReportGetHandler.java | 12 +- .../recordings/RecordingArchiveHelper.java | 11 +- .../recordings/RecordingTargetHelper.java | 4 +- 20 files changed, 83 insertions(+), 329 deletions(-) delete mode 100644 src/main/java/io/cryostat/net/reports/ReportTransformerModule.java diff --git a/src/main/java/io/cryostat/configuration/Variables.java b/src/main/java/io/cryostat/configuration/Variables.java index b743da95e8..49c056642c 100644 --- a/src/main/java/io/cryostat/configuration/Variables.java +++ b/src/main/java/io/cryostat/configuration/Variables.java @@ -26,7 +26,6 @@ private Variables() {} // report generation public static final String REPORT_GENERATOR_ENV = "CRYOSTAT_REPORT_GENERATOR"; public static final String SUBPROCESS_MAX_HEAP_ENV = "CRYOSTAT_REPORT_GENERATION_MAX_HEAP"; - public static final String REPORT_STATS_PATH = "CRYOSTAT_REPORT_STATS_PATH"; public static final String ACTIVE_REPORTS_CACHE_EXPIRY_ENV = "CRYOSTAT_ACTIVE_REPORTS_CACHE_EXPIRY_SECONDS"; public static final String ACTIVE_REPORTS_CACHE_REFRESH_ENV = diff --git a/src/main/java/io/cryostat/net/reports/AbstractReportGeneratorService.java b/src/main/java/io/cryostat/net/reports/AbstractReportGeneratorService.java index a29eff0596..f0d19a52f7 100644 --- a/src/main/java/io/cryostat/net/reports/AbstractReportGeneratorService.java +++ b/src/main/java/io/cryostat/net/reports/AbstractReportGeneratorService.java @@ -50,15 +50,14 @@ protected AbstractReportGeneratorService( @Override public final CompletableFuture exec( - RecordingDescriptor recordingDescriptor, String filter, boolean formatted) - throws Exception { + RecordingDescriptor recordingDescriptor, String filter) throws Exception { Path recording = getRecordingFromLiveTarget( recordingDescriptor.recordingName, recordingDescriptor.connectionDescriptor); Path saveFile = fs.createTempFile(null, null); - CompletableFuture cf = exec(recording, saveFile, filter, formatted); + CompletableFuture cf = exec(recording, saveFile, filter); return cf.whenComplete( (p, t) -> { try { diff --git a/src/main/java/io/cryostat/net/reports/ActiveRecordingReportCache.java b/src/main/java/io/cryostat/net/reports/ActiveRecordingReportCache.java index f1ffb120dd..6431ffa2af 100644 --- a/src/main/java/io/cryostat/net/reports/ActiveRecordingReportCache.java +++ b/src/main/java/io/cryostat/net/reports/ActiveRecordingReportCache.java @@ -45,7 +45,6 @@ class ActiveRecordingReportCache implements NotificationListener> { protected final Provider reportGeneratorServiceProvider; protected final FileSystem fs; - protected final LoadingCache htmlCache; protected final LoadingCache jsonCache; protected final TargetConnectionManager targetConnectionManager; protected final long generationTimeoutSeconds; @@ -71,86 +70,52 @@ class ActiveRecordingReportCache implements NotificationListener getReport(k, true)); this.jsonCache = Caffeine.newBuilder() .scheduler(Scheduler.systemScheduler()) .expireAfterWrite(cacheExpirySeconds, TimeUnit.SECONDS) .refreshAfterWrite(cacheRefreshSeconds, TimeUnit.SECONDS) .softValues() - .build((k) -> getReport(k, false)); + .build(this::getReport); } Future get( - ConnectionDescriptor connectionDescriptor, - String recordingName, - String filter, - boolean formatted) { + ConnectionDescriptor connectionDescriptor, String recordingName, String filter) { CompletableFuture f = new CompletableFuture<>(); try { - if (formatted) { - if (filter.isBlank()) { - f.complete( - htmlCache.get( - new RecordingDescriptor(connectionDescriptor, recordingName))); - } else { - f.complete( - getReport( - new RecordingDescriptor(connectionDescriptor, recordingName), - filter, - true)); - } + if (filter.isBlank()) { + f.complete( + jsonCache.get( + new RecordingDescriptor(connectionDescriptor, recordingName))); } else { - if (filter.isBlank()) { - f.complete( - jsonCache.get( - new RecordingDescriptor(connectionDescriptor, recordingName))); - } else { - f.complete( - getReport( - new RecordingDescriptor(connectionDescriptor, recordingName), - filter, - false)); - } + f.complete( + getReport( + new RecordingDescriptor(connectionDescriptor, recordingName), + filter)); } - } catch (Exception e) { f.completeExceptionally(e); } return f; } - boolean delete( - ConnectionDescriptor connectionDescriptor, String recordingName, boolean formatted) { + boolean delete(ConnectionDescriptor connectionDescriptor, String recordingName) { RecordingDescriptor key = new RecordingDescriptor(connectionDescriptor, recordingName); - boolean hasKey = - formatted ? htmlCache.asMap().containsKey(key) : jsonCache.asMap().containsKey(key); + boolean hasKey = jsonCache.asMap().containsKey(key); if (hasKey) { logger.trace("Invalidated active report cache for {}", recordingName); - if (formatted) { - htmlCache.invalidate(key); - } else { - jsonCache.invalidate(key); - } + jsonCache.invalidate(key); } else { logger.trace("No cache entry for {} to invalidate", recordingName); } return hasKey; } - protected String getReport(RecordingDescriptor recordingDescriptor, boolean formatted) - throws Exception { - return getReport(recordingDescriptor, EMPTY_FILTERS, formatted); + protected String getReport(RecordingDescriptor recordingDescriptor) throws Exception { + return getReport(recordingDescriptor, EMPTY_FILTERS); } - protected String getReport( - RecordingDescriptor recordingDescriptor, String filter, boolean formatted) + protected String getReport(RecordingDescriptor recordingDescriptor, String filter) throws Exception { Path saveFile = null; try { @@ -160,16 +125,13 @@ protected String getReport( saveFile = reportGeneratorServiceProvider .get() - .exec(recordingDescriptor, filter, formatted) + .exec(recordingDescriptor, filter) .get(generationTimeoutSeconds, TimeUnit.SECONDS); return fs.readString(saveFile); } catch (ExecutionException | CompletionException e) { logger.error(e); - delete( - recordingDescriptor.connectionDescriptor, - recordingDescriptor.recordingName, - formatted); + delete(recordingDescriptor.connectionDescriptor, recordingDescriptor.recordingName); if (e.getCause() instanceof SubprocessReportGenerator.SubprocessReportGenerationException) { @@ -217,7 +179,7 @@ public void onNotification(Notification> notification) { ((HyperlinkedSerializableRecordingDescriptor) notification.getMessage().get("recording")) .getName(); - delete(new ConnectionDescriptor(targetId), recordingName, true); + delete(new ConnectionDescriptor(targetId), recordingName); break; default: break; diff --git a/src/main/java/io/cryostat/net/reports/ArchivedRecordingReportCache.java b/src/main/java/io/cryostat/net/reports/ArchivedRecordingReportCache.java index 3a657711cc..0c492297a2 100644 --- a/src/main/java/io/cryostat/net/reports/ArchivedRecordingReportCache.java +++ b/src/main/java/io/cryostat/net/reports/ArchivedRecordingReportCache.java @@ -49,15 +49,13 @@ class ArchivedRecordingReportCache { this.logger = logger; } - Future getFromPath( - String subdirectoryName, String recordingName, String filter, boolean formatted) { + Future getFromPath(String subdirectoryName, String recordingName, String filter) { CompletableFuture f = new CompletableFuture<>(); Path dest = null; try { dest = recordingArchiveHelper - .getCachedReportPathFromPath( - subdirectoryName, recordingName, filter, formatted) + .getCachedReportPathFromPath(subdirectoryName, recordingName, filter) .get(); if (fs.isReadable(dest) && fs.isRegularFile(dest)) { f.complete(dest); @@ -73,7 +71,7 @@ Future getFromPath( Path saveFile = reportGeneratorServiceProvider .get() - .exec(archivedRecording, dest, filter, formatted) + .exec(archivedRecording, dest, filter) .get(generationTimeoutSeconds, TimeUnit.SECONDS); f.complete(saveFile); } catch (Exception e) { @@ -88,17 +86,17 @@ Future getFromPath( return f; } - Future get(String recordingName, String filter, boolean formatted) { - return this.get(null, recordingName, filter, formatted); + Future get(String recordingName, String filter) { + return this.get(null, recordingName, filter); } - Future get(String sourceTarget, String recordingName, String filter, boolean formatted) { + Future get(String sourceTarget, String recordingName, String filter) { CompletableFuture f = new CompletableFuture<>(); Path dest = null; try { dest = recordingArchiveHelper - .getCachedReportPath(sourceTarget, recordingName, filter, formatted) + .getCachedReportPath(sourceTarget, recordingName, filter) .get(); if (fs.isReadable(dest) && fs.isRegularFile(dest)) { f.complete(dest); @@ -111,7 +109,7 @@ Future get(String sourceTarget, String recordingName, String filter, boole Path saveFile = reportGeneratorServiceProvider .get() - .exec(archivedRecording, dest, filter, formatted) + .exec(archivedRecording, dest, filter) .get(generationTimeoutSeconds, TimeUnit.SECONDS); f.complete(saveFile); } catch (Exception e) { diff --git a/src/main/java/io/cryostat/net/reports/RemoteReportGenerator.java b/src/main/java/io/cryostat/net/reports/RemoteReportGenerator.java index 8474608349..ae3426073a 100644 --- a/src/main/java/io/cryostat/net/reports/RemoteReportGenerator.java +++ b/src/main/java/io/cryostat/net/reports/RemoteReportGenerator.java @@ -59,8 +59,7 @@ class RemoteReportGenerator extends AbstractReportGeneratorService { @Override @SuppressFBWarnings("NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE") - public CompletableFuture exec( - Path recording, Path destination, String filter, boolean formatted) { + public CompletableFuture exec(Path recording, Path destination, String filter) { String reportGenerator = env.getEnv(Variables.REPORT_GENERATOR_ENV); logger.trace("POSTing {} to {}", recording, reportGenerator); var form = @@ -73,7 +72,7 @@ public CompletableFuture exec( HttpMimeType.OCTET_STREAM.mime()); var f = new CompletableFuture(); - String acceptHeader = formatted ? HttpMimeType.HTML.mime() : HttpMimeType.JSON.mime(); + String acceptHeader = HttpMimeType.JSON.mime(); this.http .postAbs(String.format("%s/report", reportGenerator)) .putHeader(HttpHeaders.ACCEPT.toString(), acceptHeader) diff --git a/src/main/java/io/cryostat/net/reports/ReportGeneratorService.java b/src/main/java/io/cryostat/net/reports/ReportGeneratorService.java index 3fb6b1de4b..422d174241 100644 --- a/src/main/java/io/cryostat/net/reports/ReportGeneratorService.java +++ b/src/main/java/io/cryostat/net/reports/ReportGeneratorService.java @@ -19,9 +19,7 @@ import java.util.concurrent.CompletableFuture; interface ReportGeneratorService { - CompletableFuture exec(Path in, Path out, String filter, boolean formatted) - throws Exception; + CompletableFuture exec(Path in, Path out, String filter) throws Exception; - CompletableFuture exec(RecordingDescriptor rd, String filter, boolean formatted) - throws Exception; + CompletableFuture exec(RecordingDescriptor rd, String filter) throws Exception; } diff --git a/src/main/java/io/cryostat/net/reports/ReportService.java b/src/main/java/io/cryostat/net/reports/ReportService.java index 9199a6f71d..2257e454e5 100644 --- a/src/main/java/io/cryostat/net/reports/ReportService.java +++ b/src/main/java/io/cryostat/net/reports/ReportService.java @@ -31,30 +31,24 @@ public class ReportService { this.archivedCache = archivedCache; } - public Future getFromPath( - String subdirectoryName, String recordingName, String filter, boolean formatted) { - return archivedCache.getFromPath(subdirectoryName, recordingName, filter, formatted); + public Future getFromPath(String subdirectoryName, String recordingName, String filter) { + return archivedCache.getFromPath(subdirectoryName, recordingName, filter); } - public Future get(String recordingName, String filter, boolean formatted) { - return archivedCache.get(recordingName, filter, formatted); + public Future get(String recordingName, String filter) { + return archivedCache.get(recordingName, filter); } - public Future get( - String sourceTarget, String recordingName, String filter, boolean formatted) { - return archivedCache.get(sourceTarget, recordingName, filter, formatted); + public Future get(String sourceTarget, String recordingName, String filter) { + return archivedCache.get(sourceTarget, recordingName, filter); } public Future get( - ConnectionDescriptor connectionDescriptor, - String recordingName, - String filter, - boolean formatted) { - return activeCache.get(connectionDescriptor, recordingName, filter, formatted); + ConnectionDescriptor connectionDescriptor, String recordingName, String filter) { + return activeCache.get(connectionDescriptor, recordingName, filter); } - public boolean delete( - ConnectionDescriptor connectionDescriptor, String recordingName, boolean formatted) { - return activeCache.delete(connectionDescriptor, recordingName, formatted); + public boolean delete(ConnectionDescriptor connectionDescriptor, String recordingName) { + return activeCache.delete(connectionDescriptor, recordingName); } } diff --git a/src/main/java/io/cryostat/net/reports/ReportTransformerModule.java b/src/main/java/io/cryostat/net/reports/ReportTransformerModule.java deleted file mode 100644 index d141f99543..0000000000 --- a/src/main/java/io/cryostat/net/reports/ReportTransformerModule.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright The Cryostat Authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.cryostat.net.reports; - -import java.util.Set; - -import io.cryostat.core.reports.ReportTransformer; - -import dagger.Module; -import dagger.Provides; -import dagger.multibindings.ElementsIntoSet; - -@Module -public abstract class ReportTransformerModule { - - @Provides - @ElementsIntoSet - static Set provideReportTransformers() { - return Set.of(); - } -} diff --git a/src/main/java/io/cryostat/net/reports/ReportsModule.java b/src/main/java/io/cryostat/net/reports/ReportsModule.java index 4eca24dd37..c6980e4e9d 100644 --- a/src/main/java/io/cryostat/net/reports/ReportsModule.java +++ b/src/main/java/io/cryostat/net/reports/ReportsModule.java @@ -15,15 +15,12 @@ */ package io.cryostat.net.reports; -import java.util.Set; - import javax.inject.Named; import javax.inject.Provider; import javax.inject.Singleton; import io.cryostat.configuration.Variables; import io.cryostat.core.log.Logger; -import io.cryostat.core.reports.ReportTransformer; import io.cryostat.core.sys.Environment; import io.cryostat.core.sys.FileSystem; import io.cryostat.messaging.notifications.NotificationListener; @@ -32,7 +29,6 @@ import io.cryostat.recordings.RecordingArchiveHelper; import io.cryostat.util.JavaProcess; -import com.google.gson.Gson; import dagger.Binds; import dagger.Module; import dagger.Provides; @@ -40,10 +36,7 @@ import io.vertx.core.Vertx; import io.vertx.ext.web.client.WebClient; -@Module( - includes = { - ReportTransformerModule.class, - }) +@Module public abstract class ReportsModule { public static final String REPORT_GENERATION_TIMEOUT_SECONDS = @@ -144,19 +137,15 @@ static RemoteReportGenerator provideRemoteReportGenerator( @Provides static SubprocessReportGenerator provideSubprocessReportGenerator( Environment env, - Gson gson, FileSystem fs, TargetConnectionManager targetConnectionManager, - Set reportTransformers, Provider javaProcessBuilder, @Named(REPORT_GENERATION_TIMEOUT_SECONDS) long generationTimeoutSeconds, Logger logger) { return new SubprocessReportGenerator( env, - gson, fs, targetConnectionManager, - reportTransformers, javaProcessBuilder, generationTimeoutSeconds, logger); diff --git a/src/main/java/io/cryostat/net/reports/SubprocessReportGenerator.java b/src/main/java/io/cryostat/net/reports/SubprocessReportGenerator.java index 5714a82ebf..09c36d50ab 100644 --- a/src/main/java/io/cryostat/net/reports/SubprocessReportGenerator.java +++ b/src/main/java/io/cryostat/net/reports/SubprocessReportGenerator.java @@ -15,7 +15,6 @@ */ package io.cryostat.net.reports; -import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.InvocationTargetException; @@ -24,12 +23,8 @@ import java.nio.file.StandardOpenOption; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Set; -import java.util.StringTokenizer; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; import java.util.concurrent.ForkJoinPool; @@ -46,11 +41,8 @@ import io.cryostat.core.CryostatCore; import io.cryostat.core.log.Logger; import io.cryostat.core.reports.InterruptibleReportGenerator; +import io.cryostat.core.reports.InterruptibleReportGenerator.AnalysisResult; import io.cryostat.core.reports.InterruptibleReportGenerator.ReportGenerationEvent; -import io.cryostat.core.reports.InterruptibleReportGenerator.ReportResult; -import io.cryostat.core.reports.InterruptibleReportGenerator.ReportStats; -import io.cryostat.core.reports.InterruptibleReportGenerator.RuleEvaluation; -import io.cryostat.core.reports.ReportTransformer; import io.cryostat.core.sys.Environment; import io.cryostat.core.sys.FileSystem; import io.cryostat.core.util.RuleFilterParser; @@ -64,31 +56,24 @@ public class SubprocessReportGenerator extends AbstractReportGeneratorService { private final Environment env; - private final Gson gson; - private final Set reportTransformers; private final Provider javaProcessBuilderProvider; private final long generationTimeoutSeconds; SubprocessReportGenerator( Environment env, - Gson gson, FileSystem fs, TargetConnectionManager targetConnectionManager, - Set reportTransformers, Provider javaProcessBuilderProvider, @Named(ReportsModule.REPORT_GENERATION_TIMEOUT_SECONDS) long generationTimeoutSeconds, Logger logger) { super(targetConnectionManager, fs, logger); this.env = env; - this.gson = gson; - this.reportTransformers = reportTransformers; this.javaProcessBuilderProvider = javaProcessBuilderProvider; this.generationTimeoutSeconds = generationTimeoutSeconds; } @Override - public synchronized CompletableFuture exec( - Path recording, Path saveFile, String filter, boolean formatted) + public synchronized CompletableFuture exec(Path recording, Path saveFile, String filter) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, IOException, InterruptedException, ReportGenerationException { @@ -101,13 +86,6 @@ public synchronized CompletableFuture exec( if (filter == null) { throw new IllegalArgumentException("Filter may not be null"); } - fs.writeString( - saveFile, - serializeTransformersSet(), - StandardOpenOption.CREATE, - StandardOpenOption.TRUNCATE_EXISTING, - StandardOpenOption.DSYNC, - StandardOpenOption.WRITE); JavaProcess.Builder procBuilder = javaProcessBuilderProvider .get() @@ -117,13 +95,12 @@ public synchronized CompletableFuture exec( Integer.parseInt( env.getEnv( Variables.SUBPROCESS_MAX_HEAP_ENV, "0")))) - .processArgs(createProcessArgs(recording, saveFile, filter, formatted)); + .processArgs(createProcessArgs(recording, saveFile, filter)); return CompletableFuture.supplyAsync( () -> { Process proc = null; ReportGenerationEvent evt = new ReportGenerationEvent(recording.toString()); evt.begin(); - Path reportStatsPath = Paths.get(Variables.REPORT_STATS_PATH); try { proc = procBuilder.exec(); @@ -134,15 +111,6 @@ public synchronized CompletableFuture exec( ? ExitStatus.TIMED_OUT : ExitStatus.byExitCode(proc.exitValue()); - if (fs.exists(reportStatsPath)) { - try (BufferedReader br = fs.readFile(reportStatsPath)) { - ReportStats stats = gson.fromJson(br, ReportStats.class); - evt.setRecordingSizeBytes(stats.getRecordingSizeBytes()); - evt.setRulesEvaluated(stats.getRulesEvaluated()); - evt.setRulesApplicable(stats.getRulesApplicable()); - } - } - switch (status) { case OK: return saveFile; @@ -167,13 +135,6 @@ public synchronized CompletableFuture exec( proc.destroyForcibly(); } - try { - fs.deleteIfExists(reportStatsPath); - } catch (IOException e) { - logger.error(e); - throw new CompletionException(e); - } - evt.end(); if (evt.shouldCommit()) { evt.commit(); @@ -197,38 +158,11 @@ private List createJvmArgs(int maxHeapMegabytes) throws IOException { return args; } - private List createProcessArgs( - Path recording, Path saveFile, String filter, boolean formatted) { + private List createProcessArgs(Path recording, Path saveFile, String filter) { return List.of( recording.toAbsolutePath().toString(), saveFile.toAbsolutePath().toString(), - filter, - String.valueOf(formatted)); - } - - private String serializeTransformersSet() { - var sb = new StringBuilder(); - for (var rt : reportTransformers) { - sb.append(rt.getClass().getCanonicalName()); - sb.append(System.lineSeparator()); - } - return sb.toString().trim(); - } - - static Set deserializeTransformers(String serial) - throws InstantiationException, IllegalAccessException, IllegalArgumentException, - InvocationTargetException, NoSuchMethodException, SecurityException, - ClassNotFoundException { - var st = new StringTokenizer(serial); - var res = new HashSet(); - while (st.hasMoreTokens()) { - // TODO does it ever make sense that a ReportTransformer would have constructor - // arguments, or otherwise require state? How would we handle that here if so? - res.add( - (ReportTransformer) - Class.forName(st.nextToken()).getDeclaredConstructor().newInstance()); - } - return res; + filter); } public static void main(String[] args) { @@ -273,51 +207,19 @@ public static void main(String[] args) { throw new IllegalArgumentException(Arrays.asList(args).toString()); } var recording = Paths.get(args[0]); - Set transformers = Collections.emptySet(); var saveFile = Paths.get(args[1]); String filter = args[2]; - String formatted = args[3]; - try { - transformers = deserializeTransformers(fs.readString(saveFile)); - } catch (Exception e) { - Logger.INSTANCE.error(e); - System.exit(ExitStatus.OTHER.code); - } try { Logger.INSTANCE.info(SubprocessReportGenerator.class.getName() + " processing report"); - if (Boolean.parseBoolean(formatted)) { - ReportResult reportResult = generateReportFromFile(recording, transformers, filter); - Logger.INSTANCE.info( - SubprocessReportGenerator.class.getName() + " writing report to file"); - fs.writeString( - saveFile, - reportResult.getHtml(), - StandardOpenOption.CREATE, - StandardOpenOption.TRUNCATE_EXISTING, - StandardOpenOption.DSYNC, - StandardOpenOption.WRITE); - - Path reportStats = Paths.get(Variables.REPORT_STATS_PATH); - fs.writeString( - reportStats, - gson.toJson(reportResult.getReportStats()), - StandardOpenOption.CREATE, - StandardOpenOption.TRUNCATE_EXISTING, - StandardOpenOption.DSYNC, - StandardOpenOption.WRITE); - - } else { - Map evalMapResult = - generateEvalMapFromFile(recording, transformers, filter); - fs.writeString( - saveFile, - gson.toJson(evalMapResult), - StandardOpenOption.CREATE, - StandardOpenOption.TRUNCATE_EXISTING, - StandardOpenOption.DSYNC, - StandardOpenOption.WRITE); - } + Map evalMapResult = generateEvalMapFromFile(recording, filter); + fs.writeString( + saveFile, + gson.toJson(evalMapResult), + StandardOpenOption.CREATE, + StandardOpenOption.TRUNCATE_EXISTING, + StandardOpenOption.DSYNC, + StandardOpenOption.WRITE); System.exit(ExitStatus.OK.code); } catch (ConnectionException e) { @@ -332,26 +234,11 @@ public static void main(String[] args) { } } - static ReportResult generateReportFromFile( - Path recording, Set transformers, String filter) throws Exception { - Pair, FileSystem> hPair = generateHelper(recording, filter); - try (InputStream stream = hPair.getRight().newInputStream(recording)) { - return new InterruptibleReportGenerator( - Logger.INSTANCE, transformers, ForkJoinPool.commonPool()) - .generateReportInterruptibly(stream, hPair.getLeft()) - .get(); - } catch (IOException ioe) { - ioe.printStackTrace(); - throw new SubprocessReportGenerationException(ExitStatus.IO_EXCEPTION); - } - } - - static Map generateEvalMapFromFile( - Path recording, Set transformers, String filter) throws Exception { + static Map generateEvalMapFromFile(Path recording, String filter) + throws Exception { Pair, FileSystem> hPair = generateHelper(recording, filter); try (InputStream stream = hPair.getRight().newInputStream(recording)) { - return new InterruptibleReportGenerator( - Logger.INSTANCE, transformers, ForkJoinPool.commonPool()) + return new InterruptibleReportGenerator(ForkJoinPool.commonPool(), Logger.INSTANCE) .generateEvalMapInterruptibly(stream, hPair.getLeft()) .get(); } catch (IOException ioe) { diff --git a/src/main/java/io/cryostat/net/web/http/api/beta/ReportGetFromPathHandler.java b/src/main/java/io/cryostat/net/web/http/api/beta/ReportGetFromPathHandler.java index 069445ec59..95b6e26204 100644 --- a/src/main/java/io/cryostat/net/web/http/api/beta/ReportGetFromPathHandler.java +++ b/src/main/java/io/cryostat/net/web/http/api/beta/ReportGetFromPathHandler.java @@ -95,7 +95,7 @@ public String path() { @Override public List produces() { - return List.of(HttpMimeType.HTML, HttpMimeType.JSON_RAW); + return List.of(HttpMimeType.JSON_RAW); } @Override @@ -110,14 +110,9 @@ public IntermediateResponse handle(RequestParameters params) throws Except try { List queriedFilter = params.getQueryParams().getAll("filter"); String rawFilter = queriedFilter.isEmpty() ? "" : queriedFilter.get(0); - String contentType = - (params.getAcceptableContentType() == null) - ? HttpMimeType.HTML.mime() - : params.getAcceptableContentType(); - boolean formatted = contentType.equals(HttpMimeType.HTML.mime()); Path report = reportService - .getFromPath(subdirectoryName, recordingName, rawFilter, formatted) + .getFromPath(subdirectoryName, recordingName, rawFilter) .get(reportGenerationTimeoutSeconds, TimeUnit.SECONDS); return new IntermediateResponse().body(report); } catch (ExecutionException | CompletionException e) { diff --git a/src/main/java/io/cryostat/net/web/http/api/beta/ReportGetFromPathWithJwtHandler.java b/src/main/java/io/cryostat/net/web/http/api/beta/ReportGetFromPathWithJwtHandler.java index b04ce5d281..f13bd3b513 100644 --- a/src/main/java/io/cryostat/net/web/http/api/beta/ReportGetFromPathWithJwtHandler.java +++ b/src/main/java/io/cryostat/net/web/http/api/beta/ReportGetFromPathWithJwtHandler.java @@ -96,7 +96,7 @@ public String path() { @Override public List produces() { - return List.of(HttpMimeType.HTML, HttpMimeType.JSON); + return List.of(HttpMimeType.JSON); } @Override @@ -116,17 +116,12 @@ public void handleWithValidJwt(RoutingContext ctx, JWT jwt) throws Exception { try { List queriedFilter = ctx.queryParam("filter"); String rawFilter = queriedFilter.isEmpty() ? "" : queriedFilter.get(0); - String contentType = - (ctx.getAcceptableContentType() == null) - ? HttpMimeType.HTML.mime() - : ctx.getAcceptableContentType(); - boolean formatted = contentType.equals(HttpMimeType.HTML.mime()); Path report = reportService - .getFromPath(subdirectoryName, recordingName, rawFilter, formatted) + .getFromPath(subdirectoryName, recordingName, rawFilter) .get(generationTimeoutSeconds, TimeUnit.SECONDS); ctx.response().putHeader(HttpHeaders.CONTENT_DISPOSITION, "inline"); - ctx.response().putHeader(HttpHeaders.CONTENT_TYPE, contentType); + ctx.response().putHeader(HttpHeaders.CONTENT_TYPE, ctx.getAcceptableContentType()); ctx.response().sendFile(report.toAbsolutePath().toString()); } catch (ExecutionException | CompletionException e) { if (ExceptionUtils.getRootCause(e) instanceof RecordingNotFoundException diff --git a/src/main/java/io/cryostat/net/web/http/api/beta/ReportGetHandler.java b/src/main/java/io/cryostat/net/web/http/api/beta/ReportGetHandler.java index 0542174424..c3b9bb1af7 100644 --- a/src/main/java/io/cryostat/net/web/http/api/beta/ReportGetHandler.java +++ b/src/main/java/io/cryostat/net/web/http/api/beta/ReportGetHandler.java @@ -99,7 +99,7 @@ public String path() { @Override public List produces() { - return List.of(HttpMimeType.HTML, HttpMimeType.JSON_RAW); + return List.of(HttpMimeType.JSON_RAW); } @Override @@ -115,14 +115,9 @@ public IntermediateResponse handle(RequestParameters params) throws Except recordingArchiveHelper.validateSourceTarget(sourceTarget); List queriedFilter = params.getQueryParams().getAll("filter"); String rawFilter = queriedFilter.isEmpty() ? "" : queriedFilter.get(0); - String contentType = - (params.getAcceptableContentType() == null) - ? HttpMimeType.HTML.mime() - : params.getAcceptableContentType(); - boolean formatted = contentType.equals(HttpMimeType.HTML.mime()); Path report = reportService - .get(sourceTarget, recordingName, rawFilter, formatted) + .get(sourceTarget, recordingName, rawFilter) .get(reportGenerationTimeoutSeconds, TimeUnit.SECONDS); return new IntermediateResponse().body(report); } catch (RecordingSourceTargetNotFoundException e) { diff --git a/src/main/java/io/cryostat/net/web/http/api/beta/ReportGetWithJwtHandler.java b/src/main/java/io/cryostat/net/web/http/api/beta/ReportGetWithJwtHandler.java index 4dedc79b2e..526f9067f6 100644 --- a/src/main/java/io/cryostat/net/web/http/api/beta/ReportGetWithJwtHandler.java +++ b/src/main/java/io/cryostat/net/web/http/api/beta/ReportGetWithJwtHandler.java @@ -98,7 +98,7 @@ public String path() { @Override public List produces() { - return List.of(HttpMimeType.HTML, HttpMimeType.JSON); + return List.of(HttpMimeType.JSON); } @Override @@ -119,17 +119,12 @@ public void handleWithValidJwt(RoutingContext ctx, JWT jwt) throws Exception { recordingArchiveHelper.validateSourceTarget(sourceTarget); List queriedFilter = ctx.queryParam("filter"); String rawFilter = queriedFilter.isEmpty() ? "" : queriedFilter.get(0); - String contentType = - (ctx.getAcceptableContentType() == null) - ? HttpMimeType.HTML.mime() - : ctx.getAcceptableContentType(); - boolean formatted = contentType.equals(HttpMimeType.HTML.mime()); Path report = reportService - .get(sourceTarget, recordingName, rawFilter, formatted) + .get(sourceTarget, recordingName, rawFilter) .get(generationTimeoutSeconds, TimeUnit.SECONDS); ctx.response().putHeader(HttpHeaders.CONTENT_DISPOSITION, "inline"); - ctx.response().putHeader(HttpHeaders.CONTENT_TYPE, contentType); + ctx.response().putHeader(HttpHeaders.CONTENT_TYPE, ctx.getAcceptableContentType()); ctx.response().sendFile(report.toAbsolutePath().toString()); } catch (RecordingSourceTargetNotFoundException e) { throw new ApiException(404, e.getMessage(), e); diff --git a/src/main/java/io/cryostat/net/web/http/api/v1/ReportGetHandler.java b/src/main/java/io/cryostat/net/web/http/api/v1/ReportGetHandler.java index 7cb1bb6f61..272dbe8682 100644 --- a/src/main/java/io/cryostat/net/web/http/api/v1/ReportGetHandler.java +++ b/src/main/java/io/cryostat/net/web/http/api/v1/ReportGetHandler.java @@ -113,7 +113,7 @@ public void handleAuthenticated(RoutingContext ctx) throws Exception { Path report = reportService - .get(recordingName, rawFilter, true) + .get(recordingName, rawFilter) .get(reportGenerationTimeoutSeconds, TimeUnit.SECONDS); ctx.response().putHeader(HttpHeaders.CONTENT_TYPE, HttpMimeType.HTML.mime()); ctx.response() diff --git a/src/main/java/io/cryostat/net/web/http/api/v1/TargetReportGetHandler.java b/src/main/java/io/cryostat/net/web/http/api/v1/TargetReportGetHandler.java index d80ec79000..cb37b3784d 100644 --- a/src/main/java/io/cryostat/net/web/http/api/v1/TargetReportGetHandler.java +++ b/src/main/java/io/cryostat/net/web/http/api/v1/TargetReportGetHandler.java @@ -89,7 +89,7 @@ public Set resourceActions() { @Override public List produces() { - return List.of(HttpMimeType.HTML, HttpMimeType.JSON); + return List.of(HttpMimeType.JSON); } @Override @@ -107,21 +107,15 @@ public void handleAuthenticated(RoutingContext ctx) throws Exception { String recordingName = ctx.pathParam("recordingName"); List queriedFilter = ctx.queryParam("filter"); String rawFilter = queriedFilter.isEmpty() ? "" : queriedFilter.get(0); - String contentType = - (ctx.getAcceptableContentType() == null) - ? HttpMimeType.HTML.mime() - : ctx.getAcceptableContentType(); - boolean formatted = contentType.equals(HttpMimeType.HTML.mime()); try { ctx.response() - .putHeader(HttpHeaders.CONTENT_TYPE, contentType) + .putHeader(HttpHeaders.CONTENT_TYPE, ctx.getAcceptableContentType()) .end( reportService .get( getConnectionDescriptorFromContext(ctx), recordingName, - rawFilter, - formatted) + rawFilter) .get(reportGenerationTimeoutSeconds, TimeUnit.SECONDS)); } catch (CompletionException | ExecutionException ee) { diff --git a/src/main/java/io/cryostat/net/web/http/api/v2/ReportGetHandler.java b/src/main/java/io/cryostat/net/web/http/api/v2/ReportGetHandler.java index f412e299c0..211deb2b10 100644 --- a/src/main/java/io/cryostat/net/web/http/api/v2/ReportGetHandler.java +++ b/src/main/java/io/cryostat/net/web/http/api/v2/ReportGetHandler.java @@ -109,7 +109,7 @@ public void handleWithValidJwt(RoutingContext ctx, JWT jwt) throws Exception { try { Path report = reportService - .get(recordingName, rawFilter, true) + .get(recordingName, rawFilter) .get(reportGenerationTimeoutSeconds, TimeUnit.SECONDS); ctx.response().putHeader(HttpHeaders.CONTENT_DISPOSITION, "inline"); ctx.response() diff --git a/src/main/java/io/cryostat/net/web/http/api/v2/TargetReportGetHandler.java b/src/main/java/io/cryostat/net/web/http/api/v2/TargetReportGetHandler.java index cae5dbc5d7..be7498dc8e 100644 --- a/src/main/java/io/cryostat/net/web/http/api/v2/TargetReportGetHandler.java +++ b/src/main/java/io/cryostat/net/web/http/api/v2/TargetReportGetHandler.java @@ -91,7 +91,7 @@ public Set resourceActions() { @Override public List produces() { - return List.of(HttpMimeType.JSON, HttpMimeType.HTML); + return List.of(HttpMimeType.JSON); } @Override @@ -109,22 +109,16 @@ public void handleWithValidJwt(RoutingContext ctx, JWT jwt) throws Exception { String recordingName = ctx.pathParam("recordingName"); List queriedFilter = ctx.queryParam("filter"); String rawFilter = queriedFilter.isEmpty() ? "" : queriedFilter.get(0); - String contentType = - (ctx.getAcceptableContentType() == null) - ? HttpMimeType.HTML.mime() - : ctx.getAcceptableContentType(); - boolean formatted = contentType.equals(HttpMimeType.HTML.mime()); try { ctx.response() - .putHeader(HttpHeaders.CONTENT_TYPE, contentType) + .putHeader(HttpHeaders.CONTENT_TYPE, ctx.getAcceptableContentType()) .putHeader(HttpHeaders.CONTENT_DISPOSITION, "inline") .end( reportService .get( getConnectionDescriptorFromJwt(ctx, jwt), recordingName, - rawFilter, - formatted) + rawFilter) .get(reportGenerationTimeoutSeconds, TimeUnit.SECONDS)); } catch (CompletionException | ExecutionException ee) { diff --git a/src/main/java/io/cryostat/recordings/RecordingArchiveHelper.java b/src/main/java/io/cryostat/recordings/RecordingArchiveHelper.java index c5d45fab29..606b3dc676 100644 --- a/src/main/java/io/cryostat/recordings/RecordingArchiveHelper.java +++ b/src/main/java/io/cryostat/recordings/RecordingArchiveHelper.java @@ -576,17 +576,14 @@ public boolean deleteReports(String subdirectoryName, String recordingName) { } public Future getCachedReportPathFromPath( - String subdirectoryName, String recordingName, String filter, boolean formatted) { + String subdirectoryName, String recordingName, String filter) { CompletableFuture future = new CompletableFuture<>(); try { Path tempSubdirectory = archivedRecordingsReportPath.resolve(subdirectoryName); if (!fs.exists(tempSubdirectory)) { tempSubdirectory = fs.createDirectory(tempSubdirectory); } - String fileName = - String.format( - "%s-%s.report%s", - recordingName, filter.hashCode(), formatted ? ".html" : ".json"); + String fileName = String.format("%s-%s.report.json", recordingName, filter.hashCode()); future.complete(tempSubdirectory.resolve(fileName).toAbsolutePath()); } catch (IOException e) { future.completeExceptionally(e); @@ -595,7 +592,7 @@ public Future getCachedReportPathFromPath( } public Future getCachedReportPath( - String sourceTarget, String recordingName, String filter, boolean formatted) { + String sourceTarget, String recordingName, String filter) { try { String jvmId = jvmIdHelper.getJvmId(sourceTarget); String subdirectory = @@ -604,7 +601,7 @@ public Future getCachedReportPath( : sourceTarget.equals(UPLOADED_RECORDINGS_SUBDIRECTORY) ? UPLOADED_RECORDINGS_SUBDIRECTORY : base32.encodeAsString(jvmId.getBytes(StandardCharsets.UTF_8)); - return getCachedReportPathFromPath(subdirectory, recordingName, filter, formatted); + return getCachedReportPathFromPath(subdirectory, recordingName, filter); } catch (JvmIdGetException e) { return CompletableFuture.failedFuture(e); } diff --git a/src/main/java/io/cryostat/recordings/RecordingTargetHelper.java b/src/main/java/io/cryostat/recordings/RecordingTargetHelper.java index 1b01c98ef1..949f75e728 100644 --- a/src/main/java/io/cryostat/recordings/RecordingTargetHelper.java +++ b/src/main/java/io/cryostat/recordings/RecordingTargetHelper.java @@ -425,9 +425,7 @@ private Future deleteRecording( if (descriptor.isPresent()) { IRecordingDescriptor d = descriptor.get(); connection.getService().close(d); - reportService.delete(connectionDescriptor, recordingName, true); - reportService.delete( - connectionDescriptor, recordingName, false); + reportService.delete(connectionDescriptor, recordingName); this.cancelScheduledTasksIfExists(targetId, recordingName); HyperlinkedSerializableRecordingDescriptor linkedDesc = new HyperlinkedSerializableRecordingDescriptor(