use of io.apiman.common.plugin.Plugin in project apiman by apiman.
the class DefaultPluginRegistry method loadPlugin.
/**
* @see io.apiman.gateway.engine.IPluginRegistry#loadPlugin(io.apiman.common.plugin.PluginCoordinates, io.apiman.gateway.engine.async.IAsyncResultHandler)
*/
@Override
public Future<IAsyncResult<Plugin>> loadPlugin(final PluginCoordinates coordinates, final IAsyncResultHandler<Plugin> userHandler) {
final PluginFuture future = new PluginFuture();
final boolean isSnapshot = PluginUtils.isSnapshot(coordinates);
// Wrap the user provided handler so we can hook into the response. We want to cache
// the result (regardless of whether it's a success or failure)
final IAsyncResultHandler<Plugin> handler = (IAsyncResult<Plugin> result) -> {
synchronized (pluginCache) {
if (result.isError()) {
errorCache.put(coordinates, result.getError());
} else {
// This is OK as long as we make sure we only ever use one.
if (pluginCache.containsKey(coordinates)) {
try {
result.getResult().getLoader().close();
} catch (IOException e) {
LOGGER.error(e);
}
result = AsyncResultImpl.create(pluginCache.get(coordinates));
} else {
pluginCache.put(coordinates, result.getResult());
}
}
}
if (userHandler != null) {
userHandler.handle(result);
}
future.setResult(result);
};
boolean handled = false;
synchronized (pluginCache) {
// First check the cache.
if (pluginCache.containsKey(coordinates)) {
// Invoke the user handler directly - we know we don't need to re-cache it.
AsyncResultImpl<Plugin> result = AsyncResultImpl.create(pluginCache.get(coordinates));
if (userHandler != null) {
userHandler.handle(result);
}
future.setResult(result);
handled = true;
}
// Check the error cache - don't keep trying again and again for a failure.
if (!handled && errorCache.containsKey(coordinates)) {
// Invoke the user handle directly - we know we don't need to re-cache it.
AsyncResultImpl<Plugin> result = AsyncResultImpl.create(errorCache.get(coordinates), Plugin.class);
if (userHandler != null) {
userHandler.handle(result);
}
future.setResult(result);
handled = true;
}
}
String pluginRelativePath = PluginUtils.getPluginRelativePath(coordinates);
File pluginDir = new File(pluginsDir, pluginRelativePath);
// $NON-NLS-1$
File pluginFile = new File(pluginDir, "plugin." + coordinates.getType());
// Next try to load it from the plugin file registry
if (!handled && pluginFile.isFile()) {
// means that snapshot plugins will be redownloaded each time the server is restarted.
if (isSnapshot) {
try {
FileUtils.deleteDirectory(pluginDir);
} catch (IOException | IllegalArgumentException e) {
}
} else {
handled = true;
try {
handler.handle(AsyncResultImpl.create(readPluginFile(coordinates, pluginFile)));
} catch (Exception error) {
handler.handle(AsyncResultImpl.<Plugin>create(error));
}
}
}
if (!pluginDir.exists()) {
pluginDir.mkdirs();
}
// registry first though)
if (!handled) {
File m2Dir = PluginUtils.getUserM2Repository();
if (m2Dir != null) {
File artifactFile = PluginUtils.getM2Path(m2Dir, coordinates);
if (artifactFile.isFile()) {
handled = true;
try {
File tmpFile = File.createTempFile("plugin", ".tmp", pluginDir);
tmpFile.deleteOnExit();
FileUtils.copyFile(artifactFile, tmpFile);
tmpFile.renameTo(pluginFile);
handler.handle(AsyncResultImpl.create(readPluginFile(coordinates, pluginFile)));
} catch (Exception error) {
handler.handle(AsyncResultImpl.<Plugin>create(error));
}
}
}
}
// we have to simply report "plugin not found".
if (!handled) {
downloadPlugin(coordinates, (IAsyncResult<File> result) -> {
if (result.isSuccess()) {
File downloadedArtifactFile = result.getResult();
if (downloadedArtifactFile == null || !downloadedArtifactFile.isFile()) {
// $NON-NLS-1$
handler.handle(AsyncResultImpl.<Plugin>create(new Exception(Messages.i18n.format("DefaultPluginRegistry.PluginNotFound"))));
} else {
try {
String pluginRelativePath1 = PluginUtils.getPluginRelativePath(coordinates);
File pluginDir1 = new File(pluginsDir, pluginRelativePath1);
if (!pluginDir1.exists()) {
pluginDir1.mkdirs();
}
// $NON-NLS-1$
File pluginFile1 = new File(pluginDir1, "plugin." + coordinates.getType());
if (!pluginFile1.exists()) {
FileUtils.copyFile(downloadedArtifactFile, pluginFile1);
FileUtils.deleteQuietly(downloadedArtifactFile);
} else {
FileUtils.deleteQuietly(downloadedArtifactFile);
}
handler.handle(AsyncResultImpl.create(readPluginFile(coordinates, pluginFile1)));
} catch (Exception error) {
handler.handle(AsyncResultImpl.<Plugin>create(error));
}
}
} else {
handler.handle(AsyncResultImpl.<Plugin>create(result.getError()));
}
});
}
return future;
}
use of io.apiman.common.plugin.Plugin in project apiman by apiman.
the class PluginResourceImpl method getPolicyForm.
/**
* @see IPluginResource#getPolicyForm(java.lang.Long, java.lang.String)
*/
@Override
public String getPolicyForm(Long pluginId, String policyDefId) throws PluginNotFoundException, PluginResourceNotFoundException, PolicyDefinitionNotFoundException {
// No permission check is needed
PluginBean pbean;
PolicyDefinitionBean pdBean;
try {
pbean = storage.getPlugin(pluginId);
if (pbean == null) {
throw ExceptionFactory.pluginNotFoundException(pluginId);
}
pdBean = storage.getPolicyDefinition(policyDefId);
} catch (AbstractRestException e) {
throw e;
} catch (Exception e) {
throw new SystemErrorException(e);
}
PluginCoordinates coordinates = new PluginCoordinates(pbean.getGroupId(), pbean.getArtifactId(), pbean.getVersion(), pbean.getClassifier(), pbean.getType());
try {
if (pdBean == null) {
throw ExceptionFactory.policyDefNotFoundException(policyDefId);
}
if (pdBean.getPluginId() == null || !pdBean.getPluginId().equals(pbean.getId())) {
throw ExceptionFactory.pluginNotFoundException(pluginId);
}
if (pdBean.getFormType() == PolicyFormType.JsonSchema && pdBean.getForm() != null) {
String formPath = pdBean.getForm();
if (!formPath.startsWith("/")) {
// $NON-NLS-1$
// $NON-NLS-1$
formPath = "META-INF/apiman/policyDefs/" + formPath;
} else {
formPath = formPath.substring(1);
}
Plugin plugin = pluginRegistry.loadPlugin(coordinates);
PluginClassLoader loader = plugin.getLoader();
InputStream resource = null;
try {
resource = loader.getResourceAsStream(formPath);
if (resource == null) {
throw ExceptionFactory.pluginResourceNotFoundException(formPath, coordinates);
}
StringWriter writer = new StringWriter();
IOUtils.copy(resource, writer);
return writer.toString();
} finally {
IOUtils.closeQuietly(resource);
}
} else {
throw ExceptionFactory.pluginResourceNotFoundException(null, coordinates);
}
} catch (AbstractRestException e) {
throw e;
} catch (Throwable t) {
throw new SystemErrorException(t);
}
}
use of io.apiman.common.plugin.Plugin in project apiman by apiman.
the class PolicyFactoryImpl method doLoadFromPlugin.
/**
* Loads a policy from a plugin.
* @param policyImpl
* @param handler
*/
private void doLoadFromPlugin(final String policyImpl, final IAsyncResultHandler<IPolicy> handler) {
PluginCoordinates coordinates = PluginCoordinates.fromPolicySpec(policyImpl);
if (coordinates == null) {
handler.handle(AsyncResultImpl.<IPolicy>create(new PolicyNotFoundException(policyImpl)));
return;
}
int ssidx = policyImpl.indexOf('/');
if (ssidx == -1) {
handler.handle(AsyncResultImpl.<IPolicy>create(new PolicyNotFoundException(policyImpl)));
return;
}
final String classname = policyImpl.substring(ssidx + 1);
this.pluginRegistry.loadPlugin(coordinates, new IAsyncResultHandler<Plugin>() {
@Override
public void handle(IAsyncResult<Plugin> result) {
if (result.isSuccess()) {
IPolicy rval;
Plugin plugin = result.getResult();
PluginClassLoader pluginClassLoader = plugin.getLoader();
ClassLoader oldCtxLoader = Thread.currentThread().getContextClassLoader();
try {
Thread.currentThread().setContextClassLoader(pluginClassLoader);
Class<?> c = pluginClassLoader.loadClass(classname);
rval = (IPolicy) c.newInstance();
} catch (Exception e) {
handler.handle(AsyncResultImpl.<IPolicy>create(new PolicyNotFoundException(policyImpl, e)));
return;
} finally {
Thread.currentThread().setContextClassLoader(oldCtxLoader);
}
policyCache.put(policyImpl, rval);
handler.handle(AsyncResultImpl.create(rval));
} else {
handler.handle(AsyncResultImpl.<IPolicy>create(new PolicyNotFoundException(policyImpl, result.getError())));
}
}
});
}
use of io.apiman.common.plugin.Plugin in project apiman by apiman.
the class AbstractPluginRegistry method loadPlugin.
/**
* @see io.apiman.manager.api.core.IPluginRegistry#loadPlugin(io.apiman.common.plugin.PluginCoordinates)
*/
@Override
public Plugin loadPlugin(PluginCoordinates coordinates) throws InvalidPluginException {
boolean isSnapshot = PluginUtils.isSnapshot(coordinates);
synchronized (mutex) {
if (pluginCache.containsKey(coordinates)) {
Plugin cachedPlugin = pluginCache.get(coordinates);
if (isSnapshot) {
pluginCache.remove(coordinates);
try {
cachedPlugin.getLoader().close();
} catch (IOException e) {
e.printStackTrace();
}
} else {
return cachedPlugin;
}
}
String pluginRelativePath = PluginUtils.getPluginRelativePath(coordinates);
File pluginDir = new File(pluginsDir, pluginRelativePath);
if (!pluginDir.exists()) {
pluginDir.mkdirs();
}
// $NON-NLS-1$
File pluginFile = new File(pluginDir, "plugin." + coordinates.getType());
// Clean up stale files in the case of a snapshot.
if (pluginFile.exists() && isSnapshot) {
try {
FileUtils.deleteDirectory(pluginFile.getParentFile());
pluginFile.getParentFile().mkdirs();
} catch (IOException e) {
e.printStackTrace();
}
}
// Doesn't exist (or it's a snapshot)? Better download it.
if (!pluginFile.exists()) {
downloadPlugin(pluginFile, coordinates);
}
// Still doesn't exist? That's a failure.
if (!pluginFile.exists()) {
// $NON-NLS-1$
throw new InvalidPluginException(Messages.i18n.format("AbstractPluginRegistry.PluginNotFound"));
}
PluginClassLoader pluginClassLoader;
try {
pluginClassLoader = createPluginClassLoader(pluginFile);
} catch (IOException e) {
// $NON-NLS-1$
throw new InvalidPluginException(Messages.i18n.format("AbstractPluginRegistry.InvalidPlugin", pluginFile.getAbsolutePath()), e);
}
URL specFile = pluginClassLoader.getResource(PluginUtils.PLUGIN_SPEC_PATH);
if (specFile == null) {
// $NON-NLS-1$
throw new InvalidPluginException(Messages.i18n.format("AbstractPluginRegistry.MissingPluginSpecFile", PluginUtils.PLUGIN_SPEC_PATH));
}
try {
PluginSpec spec = PluginUtils.readPluginSpecFile(specFile);
Plugin plugin = new Plugin(spec, coordinates, pluginClassLoader);
pluginCache.put(coordinates, plugin);
return plugin;
} catch (Exception e) {
// $NON-NLS-1$
throw new InvalidPluginException(Messages.i18n.format("AbstractPluginRegistry.FailedToReadSpecFile", PluginUtils.PLUGIN_SPEC_PATH), e);
}
}
}
use of io.apiman.common.plugin.Plugin in project apiman by apiman.
the class AbstractPluginRegistryTest method testLoadPlugin.
/**
* Test method for {@link io.apiman.manager.api.core.plugin.AbstractPluginRegistry#loadPlugin(io.apiman.common.plugin.PluginCoordinates)}.
* @throws Exception any exception
*/
@Test
public void testLoadPlugin() throws Exception {
File targetDir = new File("target").getAbsoluteFile();
File tmpDir = new File(targetDir, "_plugintmp");
AbstractPluginRegistry registry = new TestPluginRegistry(tmpDir);
PluginCoordinates coords = new PluginCoordinates("io.apiman.test", "apiman-test-plugin", "1.0");
Plugin plugin = registry.loadPlugin(coords);
Assert.assertNotNull(plugin);
;
Assert.assertEquals("Test Plugin", plugin.getName());
Assert.assertEquals("The first ever plugin for testing.", plugin.getDescription());
}
Aggregations