org.glowroot.agent.config.PluginCache Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of glowroot-agent-it-harness Show documentation
Show all versions of glowroot-agent-it-harness Show documentation
Glowroot Agent Integration Test Harness
/*
* Copyright 2014-2019 the original author or 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 org.glowroot.agent.config;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.net.URL;
import java.util.List;
import org.glowroot.agent.shaded.com.fasterxml.jackson.core.JsonProcessingException;
import org.glowroot.agent.shaded.com.fasterxml.jackson.core.type.TypeReference;
import org.glowroot.agent.shaded.com.fasterxml.jackson.databind.ObjectMapper;
import org.glowroot.agent.shaded.com.fasterxml.jackson.databind.module.SimpleModule;
import org.glowroot.agent.shaded.org.glowroot.agent.it.harness.shaded.com.google.common.collect.ImmutableList;
import org.glowroot.agent.shaded.org.glowroot.agent.it.harness.shaded.com.google.common.collect.Iterators;
import org.glowroot.agent.shaded.org.glowroot.agent.it.harness.shaded.com.google.common.collect.Lists;
import org.glowroot.agent.shaded.org.glowroot.agent.it.harness.shaded.com.google.common.collect.Ordering;
import org.glowroot.agent.shaded.org.glowroot.agent.it.harness.shaded.com.google.common.io.Resources;
import org.glowroot.agent.shaded.org.checkerframework.checker.nullness.qual.Nullable;
import org.immutables.value.Value;
import org.glowroot.agent.shaded.org.glowroot.agent.shaded.org.slf4j.Logger;
import org.glowroot.agent.shaded.org.glowroot.agent.shaded.org.slf4j.LoggerFactory;
import org.glowroot.agent.shaded.org.glowroot.common.config.ImmutableInstrumentationConfig;
import org.glowroot.agent.shaded.org.glowroot.common.config.InstrumentationConfig;
import org.glowroot.agent.shaded.org.glowroot.common.util.ObjectMappers;
import static org.glowroot.agent.shaded.org.glowroot.agent.it.harness.shaded.com.google.common.base.Charsets.UTF_8;
import static org.glowroot.agent.shaded.org.glowroot.agent.it.harness.shaded.com.google.common.base.Preconditions.checkNotNull;
@Value.Immutable
public abstract class PluginCache {
private static final Logger logger = LoggerFactory.getLogger(PluginCache.class);
private static final ObjectMapper mapper = ObjectMappers.create();
static {
SimpleModule module = new SimpleModule();
module.addAbstractTypeMapping(InstrumentationConfig.class,
ImmutableInstrumentationConfig.class);
module.addAbstractTypeMapping(PropertyDescriptor.class, ImmutablePropertyDescriptor.class);
mapper.registerModule(module);
}
public abstract ImmutableList pluginJars();
public abstract ImmutableList pluginDescriptors();
public static PluginCache create(@Nullable File pluginsDir, boolean offlineViewer)
throws Exception {
ImmutablePluginCache.Builder builder = ImmutablePluginCache.builder();
List pluginJars = getPluginJars(pluginsDir);
builder.addAllPluginJars(pluginJars);
List unsortedPluginDescriptors = Lists.newArrayList();
if (offlineViewer) {
unsortedPluginDescriptors.addAll(createForOfflineViewer(pluginJars, pluginsDir));
} else {
unsortedPluginDescriptors.addAll(readPluginDescriptors(pluginJars, pluginsDir));
}
// when using uber jar, get the (aggregated) plugin list
URL plugins = PluginCache.class.getResource("/META-INF/glowroot.plugins.json");
if (plugins != null) {
List pluginDescriptors = mapper.readValue(plugins,
new TypeReference>() {});
checkNotNull(pluginDescriptors);
unsortedPluginDescriptors.addAll(pluginDescriptors);
}
return builder
.addAllPluginDescriptors(
new PluginDescriptorOrdering().sortedCopy(unsortedPluginDescriptors))
.build();
}
private static ImmutableList getPluginJars(@Nullable File pluginsDir) {
if (pluginsDir == null) {
return ImmutableList.of();
}
File[] pluginJars = pluginsDir.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.endsWith(".jar");
}
});
if (pluginJars == null) {
logger.warn("listFiles() returned null on directory: {}", pluginsDir.getAbsolutePath());
return ImmutableList.of();
}
return ImmutableList.copyOf(pluginJars);
}
private static ImmutableList getStandaloneDescriptors(@Nullable File pluginsDir) {
if (pluginsDir == null) {
return ImmutableList.of();
}
File[] pluginDescriptorFiles = pluginsDir.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.endsWith(".json");
}
});
if (pluginDescriptorFiles == null) {
logger.warn("listFiles() returned null on directory: {}", pluginsDir.getAbsolutePath());
return ImmutableList.of();
}
return ImmutableList.copyOf(pluginDescriptorFiles);
}
private static ImmutableList getResources(String resourceName) throws IOException {
ClassLoader loader = PluginCache.class.getClassLoader();
if (loader == null) {
return ImmutableList
.copyOf(Iterators.forEnumeration(ClassLoader.getSystemResources(resourceName)));
} else {
return ImmutableList
.copyOf(Iterators.forEnumeration(loader.getResources(resourceName)));
}
}
private static List createForOfflineViewer(List pluginJars,
@Nullable File pluginsDir) throws IOException {
List pluginDescriptors = readPluginDescriptors(pluginJars, pluginsDir);
List pluginDescriptorsWithoutAdvice = Lists.newArrayList();
for (PluginDescriptor pluginDescriptor : pluginDescriptors) {
pluginDescriptorsWithoutAdvice.add(ImmutablePluginDescriptor.builder()
.copyFrom(pluginDescriptor)
.aspects(ImmutableList.of())
.build());
}
return pluginDescriptorsWithoutAdvice;
}
private static List readPluginDescriptors(List pluginJars,
@Nullable File pluginsDir) throws IOException {
List pluginDescriptors = Lists.newArrayList();
for (File pluginJar : pluginJars) {
URL url = new URL("jar:" + pluginJar.toURI() + "!/META-INF/glowroot.plugin.json");
buildPluginDescriptor(url, pluginJar, pluginDescriptors);
}
for (File file : getStandaloneDescriptors(pluginsDir)) {
buildPluginDescriptor(file.toURI().toURL(), null, pluginDescriptors);
}
// also add descriptors on the class path (this is primarily for integration tests)
for (URL url : getResources("META-INF/glowroot.plugin.json")) {
buildPluginDescriptor(url, null, pluginDescriptors);
}
return pluginDescriptors;
}
private static void buildPluginDescriptor(URL url, @Nullable File pluginJar,
List pluginDescriptors) throws IOException {
String content = Resources.toString(url, UTF_8);
ImmutablePluginDescriptor pluginDescriptor;
try {
pluginDescriptor = mapper.readValue(content, ImmutablePluginDescriptor.class);
} catch (JsonProcessingException e) {
logger.error("error parsing plugin descriptor: {}", url.toExternalForm(), e);
return;
}
pluginDescriptors.add(pluginDescriptor.withPluginJar(pluginJar));
}
private static class PluginDescriptorOrdering extends Ordering {
@Override
public int compare(PluginDescriptor left, PluginDescriptor right) {
return left.id().compareToIgnoreCase(right.id());
}
}
}