Search in sources :

Example 1 with Plugin

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;
}
Also used : IOException(java.io.IOException) URISyntaxException(java.net.URISyntaxException) TimeoutException(java.util.concurrent.TimeoutException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) IAsyncResult(io.apiman.gateway.engine.async.IAsyncResult) File(java.io.File) Plugin(io.apiman.common.plugin.Plugin)

Example 2 with Plugin

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);
    }
}
Also used : SystemErrorException(io.apiman.manager.api.rest.exceptions.SystemErrorException) PolicyDefinitionBean(io.apiman.manager.api.beans.policies.PolicyDefinitionBean) StringWriter(java.io.StringWriter) InputStream(java.io.InputStream) PluginCoordinates(io.apiman.common.plugin.PluginCoordinates) PluginBean(io.apiman.manager.api.beans.plugins.PluginBean) NewPluginBean(io.apiman.manager.api.beans.plugins.NewPluginBean) AbstractRestException(io.apiman.manager.api.rest.exceptions.AbstractRestException) AbstractRestException(io.apiman.manager.api.rest.exceptions.AbstractRestException) StorageException(io.apiman.manager.api.core.exceptions.StorageException) PluginNotFoundException(io.apiman.manager.api.rest.exceptions.PluginNotFoundException) PluginResourceNotFoundException(io.apiman.manager.api.rest.exceptions.PluginResourceNotFoundException) InvalidPluginException(io.apiman.manager.api.core.exceptions.InvalidPluginException) SystemErrorException(io.apiman.manager.api.rest.exceptions.SystemErrorException) IOException(java.io.IOException) PluginAlreadyExistsException(io.apiman.manager.api.rest.exceptions.PluginAlreadyExistsException) NotAuthorizedException(io.apiman.manager.api.rest.exceptions.NotAuthorizedException) PolicyDefinitionNotFoundException(io.apiman.manager.api.rest.exceptions.PolicyDefinitionNotFoundException) Plugin(io.apiman.common.plugin.Plugin) PluginClassLoader(io.apiman.common.plugin.PluginClassLoader)

Example 3 with Plugin

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())));
            }
        }
    });
}
Also used : PolicyNotFoundException(io.apiman.gateway.engine.beans.exceptions.PolicyNotFoundException) PolicyNotFoundException(io.apiman.gateway.engine.beans.exceptions.PolicyNotFoundException) PluginClassLoader(io.apiman.common.plugin.PluginClassLoader) PluginCoordinates(io.apiman.common.plugin.PluginCoordinates) Plugin(io.apiman.common.plugin.Plugin) PluginClassLoader(io.apiman.common.plugin.PluginClassLoader)

Example 4 with Plugin

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);
        }
    }
}
Also used : PluginSpec(io.apiman.common.plugin.PluginSpec) InvalidPluginException(io.apiman.manager.api.core.exceptions.InvalidPluginException) IOException(java.io.IOException) File(java.io.File) URL(java.net.URL) IOException(java.io.IOException) InvalidPluginException(io.apiman.manager.api.core.exceptions.InvalidPluginException) Plugin(io.apiman.common.plugin.Plugin) PluginClassLoader(io.apiman.common.plugin.PluginClassLoader)

Example 5 with Plugin

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());
}
Also used : PluginCoordinates(io.apiman.common.plugin.PluginCoordinates) File(java.io.File) Plugin(io.apiman.common.plugin.Plugin) Test(org.junit.Test)

Aggregations

Plugin (io.apiman.common.plugin.Plugin)11 PluginCoordinates (io.apiman.common.plugin.PluginCoordinates)8 File (java.io.File)7 IOException (java.io.IOException)5 Test (org.junit.Test)5 PluginClassLoader (io.apiman.common.plugin.PluginClassLoader)4 IPluginRegistry (io.apiman.gateway.engine.IPluginRegistry)4 VertxEngineConfig (io.apiman.gateway.platforms.vertx3.common.config.VertxEngineConfig)4 JsonObject (io.vertx.core.json.JsonObject)4 Async (io.vertx.ext.unit.Async)4 Path (java.nio.file.Path)4 InvalidPluginException (io.apiman.manager.api.core.exceptions.InvalidPluginException)3 URL (java.net.URL)3 PluginSpec (io.apiman.common.plugin.PluginSpec)2 NewPluginBean (io.apiman.manager.api.beans.plugins.NewPluginBean)2 PluginBean (io.apiman.manager.api.beans.plugins.PluginBean)2 PolicyDefinitionBean (io.apiman.manager.api.beans.policies.PolicyDefinitionBean)2 StorageException (io.apiman.manager.api.core.exceptions.StorageException)2 AbstractRestException (io.apiman.manager.api.rest.exceptions.AbstractRestException)2 NotAuthorizedException (io.apiman.manager.api.rest.exceptions.NotAuthorizedException)2