From 7868dc39575d71eaec26ebbc6a7aa5b94e2b21b0 Mon Sep 17 00:00:00 2001 From: jmatsuok Date: Thu, 25 Apr 2024 11:32:03 -0400 Subject: [PATCH] Remove Local and Merged template services --- .../cryostat/core/net/JFRJMXConnection.java | 4 +- .../LocalStorageTemplateService.java | 257 ----------------- .../core/templates/MergedTemplateService.java | 89 ------ .../LocalStorageTemplateServiceTest.java | 270 ------------------ 4 files changed, 2 insertions(+), 618 deletions(-) delete mode 100644 src/main/java/io/cryostat/core/templates/LocalStorageTemplateService.java delete mode 100644 src/main/java/io/cryostat/core/templates/MergedTemplateService.java delete mode 100644 src/test/java/io/cryostat/core/templates/LocalStorageTemplateServiceTest.java diff --git a/src/main/java/io/cryostat/core/net/JFRJMXConnection.java b/src/main/java/io/cryostat/core/net/JFRJMXConnection.java index f1244e25..3283e7ab 100644 --- a/src/main/java/io/cryostat/core/net/JFRJMXConnection.java +++ b/src/main/java/io/cryostat/core/net/JFRJMXConnection.java @@ -55,7 +55,7 @@ import io.cryostat.core.sys.Clock; import io.cryostat.core.sys.Environment; import io.cryostat.core.sys.FileSystem; -import io.cryostat.core.templates.MergedTemplateService; +import io.cryostat.core.templates.RemoteTemplateService; import io.cryostat.core.templates.TemplateService; import io.cryostat.core.tui.ClientWriter; @@ -110,7 +110,7 @@ public synchronized CryostatFlightRecorderService getService() } public TemplateService getTemplateService() { - return new MergedTemplateService(this, fs, env); + return new RemoteTemplateService(this); } public synchronized long getApproximateServerTime(Clock clock) { diff --git a/src/main/java/io/cryostat/core/templates/LocalStorageTemplateService.java b/src/main/java/io/cryostat/core/templates/LocalStorageTemplateService.java deleted file mode 100644 index bf97c3f1..00000000 --- a/src/main/java/io/cryostat/core/templates/LocalStorageTemplateService.java +++ /dev/null @@ -1,257 +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.core.templates; - -import java.io.IOException; -import java.io.InputStream; -import java.nio.charset.StandardCharsets; -import java.nio.file.Path; -import java.text.ParseException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; - -import org.openjdk.jmc.common.unit.IConstrainedMap; -import org.openjdk.jmc.common.unit.SimpleConstrainedMap; -import org.openjdk.jmc.common.unit.UnitLookup; -import org.openjdk.jmc.flightrecorder.configuration.events.EventOptionID; -import org.openjdk.jmc.flightrecorder.controlpanel.ui.configuration.model.xml.JFCGrammar; -import org.openjdk.jmc.flightrecorder.controlpanel.ui.configuration.model.xml.XMLAttributeInstance; -import org.openjdk.jmc.flightrecorder.controlpanel.ui.configuration.model.xml.XMLModel; -import org.openjdk.jmc.flightrecorder.controlpanel.ui.configuration.model.xml.XMLTagInstance; -import org.openjdk.jmc.flightrecorder.controlpanel.ui.configuration.model.xml.XMLValidationResult; -import org.openjdk.jmc.flightrecorder.controlpanel.ui.model.EventConfiguration; - -import io.cryostat.core.FlightRecorderException; -import io.cryostat.core.sys.Environment; -import io.cryostat.core.sys.FileSystem; - -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -import org.jsoup.Jsoup; -import org.jsoup.nodes.Document; -import org.jsoup.nodes.Element; -import org.jsoup.parser.Parser; -import org.jsoup.select.Elements; - -public class LocalStorageTemplateService extends AbstractTemplateService - implements MutableTemplateService { - - public static final String TEMPLATE_PATH = "CRYOSTAT_TEMPLATE_PATH"; - - private final FileSystem fs; - private final Environment env; - - @SuppressFBWarnings( - value = "EI_EXPOSE_REP2", - justification = "fields are not exposed since there are no getters") - public LocalStorageTemplateService(FileSystem fs, Environment env) { - this.fs = fs; - this.env = env; - } - - @Override - protected TemplateType providedTemplateType() { - return TemplateType.CUSTOM; - } - - @Override - public Template addTemplate(InputStream templateStream) - throws InvalidXmlException, InvalidEventTemplateException, IOException { - if (!env.hasEnv(TEMPLATE_PATH)) { - throw new IOException( - String.format( - "Template directory does not exist, must be set using environment" - + " variable %s", - TEMPLATE_PATH)); - } - Path dir = fs.pathOf(env.getEnv(TEMPLATE_PATH)); - if (!fs.exists(dir) || !fs.isDirectory(dir) || !fs.isReadable(dir) || !fs.isWritable(dir)) { - throw new IOException( - String.format( - "Template directory %s does not exist, is not a directory, or does not" - + " have appropriate permissions", - dir.toString())); - } - try (templateStream) { - XMLModel model = EventConfiguration.createModel(templateStream); - model.checkErrors(); - - for (XMLValidationResult result : model.getResults()) { - if (result.isError()) { - throw new InvalidEventTemplateException(result.getText()); - } - } - - XMLTagInstance configuration = model.getRoot(); - XMLAttributeInstance labelAttr = null; - for (XMLAttributeInstance attr : configuration.getAttributeInstances()) { - if (attr.getAttribute().getName().equals("label")) { - labelAttr = attr; - break; - } - } - - if (labelAttr == null) { - throw new InvalidEventTemplateException( - "Template has no configuration label attribute"); - } - - String templateName = labelAttr.getExplicitValue(); - templateName = templateName.replaceAll("[\\W]+", "_"); - Path path = fs.pathOf(env.getEnv(TEMPLATE_PATH), templateName); - - if (fs.exists(path)) { - throw new InvalidEventTemplateException( - String.format("Event template \"%s\" already exists", templateName)); - } - - XMLTagInstance root = model.getRoot(); - root.setValue(JFCGrammar.ATTRIBUTE_LABEL_MANDATORY, templateName); - - fs.writeString(path, model.toString()); - - return new Template( - templateName, - getAttributeValue(root, "description"), - getAttributeValue(root, "provider"), - providedTemplateType()); - } catch (IOException ioe) { - throw new InvalidXmlException("Unable to parse XML stream", ioe); - } catch (ParseException | IllegalArgumentException e) { - throw new InvalidEventTemplateException("Invalid XML", e); - } - } - - @Override - public void deleteTemplate(String templateName) - throws IOException, InvalidEventTemplateException { - if (!env.hasEnv(TEMPLATE_PATH)) { - throw new IOException( - String.format( - "Template directory does not exist, must be set using environment" - + " variable %s", - TEMPLATE_PATH)); - } - Path dir = fs.pathOf(env.getEnv(TEMPLATE_PATH)); - if (!fs.exists(dir) || !fs.isDirectory(dir) || !fs.isReadable(dir) || !fs.isWritable(dir)) { - throw new IOException( - String.format( - "Template directory %s does not exist, is not a directory, or does not" - + " have appropriate permissions", - dir.toString())); - } - if (!fs.deleteIfExists(fs.pathOf(env.getEnv(TEMPLATE_PATH), templateName))) { - throw new InvalidEventTemplateException( - String.format("Event template \"%s\" does not exist", templateName)); - } - } - - @Override - public Optional getXml(String templateName, TemplateType type) - throws FlightRecorderException { - if (!providedTemplateType().equals(type)) { - return Optional.empty(); - } - for (Path path : getLocalTemplates()) { - try (InputStream stream = fs.newInputStream(path)) { - Document doc = - Jsoup.parse(stream, StandardCharsets.UTF_8.name(), "", Parser.xmlParser()); - Elements els = doc.getElementsByTag("configuration"); - if (els.isEmpty()) { - throw new MalformedXMLException( - "Document did not contain \"configuration\" element"); - } - if (els.size() > 1) { - throw new MalformedXMLException( - "Document contains multiple \"configuration\" elements"); - } - Element configuration = els.first(); - if (!configuration.hasAttr("label")) { - throw new MalformedXMLException( - "Configuration element did not have \"label\" attribute"); - } - if (configuration.attr("label").equals(templateName)) { - return Optional.of(doc); - } - } catch (IOException e) { - throw new FlightRecorderException("Could not get XML", e); - } - } - return Optional.empty(); - } - - @Override - public Optional> getEvents( - String templateName, TemplateType type) throws FlightRecorderException { - if (!providedTemplateType().equals(type)) { - return Optional.empty(); - } - return getTemplateModels().stream() - .filter( - m -> - m.getRoot().getAttributeInstances().stream() - .anyMatch( - attr -> - attr.getAttribute() - .getName() - .equals("label") - && attr.getValue() - .equals(templateName))) - .findFirst() - .map( - model -> - new EventConfiguration(model) - .getEventOptions( - new SimpleConstrainedMap<>( - UnitLookup.PLAIN_TEXT.getPersister()))); - } - - protected List getLocalTemplates() throws FlightRecorderException { - if (!env.hasEnv(TEMPLATE_PATH)) { - return Collections.emptyList(); - } - String dirName = env.getEnv(TEMPLATE_PATH); - Path dir = fs.pathOf(dirName); - if (!fs.isDirectory(dir) || !fs.isReadable(dir)) { - throw new FlightRecorderException( - new IOException(String.format("%s is not a readable directory", dirName))); - } - try { - return fs.listDirectoryChildren(dir).stream() - .map(name -> fs.pathOf(dirName, name)) - .collect(Collectors.toList()); - } catch (IOException e) { - throw new FlightRecorderException("Could not get local templates", e); - } - } - - @Override - protected List getTemplateModels() throws FlightRecorderException { - try { - List models = new ArrayList<>(); - for (Path path : getLocalTemplates()) { - try (InputStream stream = fs.newInputStream(path)) { - models.add(EventConfiguration.createModel(stream)); - } - } - return models; - } catch (IOException | ParseException e) { - throw new FlightRecorderException("Could not get template models", e); - } - } -} diff --git a/src/main/java/io/cryostat/core/templates/MergedTemplateService.java b/src/main/java/io/cryostat/core/templates/MergedTemplateService.java deleted file mode 100644 index ddd288fd..00000000 --- a/src/main/java/io/cryostat/core/templates/MergedTemplateService.java +++ /dev/null @@ -1,89 +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.core.templates; - -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; - -import org.openjdk.jmc.common.unit.IConstrainedMap; -import org.openjdk.jmc.flightrecorder.configuration.events.EventOptionID; - -import io.cryostat.core.FlightRecorderException; -import io.cryostat.core.net.JFRConnection; -import io.cryostat.core.sys.Environment; -import io.cryostat.core.sys.FileSystem; - -import org.jsoup.nodes.Document; - -public class MergedTemplateService implements MutableTemplateService { - - protected final RemoteTemplateService remote; - protected final LocalStorageTemplateService local; - - public MergedTemplateService(JFRConnection conn, FileSystem fs, Environment env) { - this.remote = new RemoteTemplateService(conn); - this.local = new LocalStorageTemplateService(fs, env); - } - - @Override - public List