Search in sources :

Example 1 with IAsyncResult

use of io.apiman.gateway.engine.async.IAsyncResult in project apiman by apiman.

the class ApiRequestExecutorImpl method loadPolicies.

/**
 * Get/resolve the list of policies into a list of policies with config.  This operation is
 * done asynchronously so that plugins can be downloaded if needed.  Any errors in resolving
 * the policies will be reported back via the policyErrorHandler.
 */
private void loadPolicies(final IAsyncHandler<List<PolicyWithConfiguration>> handler) {
    final Set<Integer> totalCounter = new HashSet<>();
    final Set<Integer> errorCounter = new TreeSet<>();
    final List<PolicyWithConfiguration> rval = new ArrayList<>(policies.size());
    final List<Throwable> errors = new ArrayList<>(policies.size());
    final int numPolicies = policies.size();
    int index = 0;
    // If there aren't any policies, then no need to asynchronously load them!
    if (policies.isEmpty()) {
        handler.handle(policyImpls);
        return;
    }
    for (final Policy policy : policies) {
        rval.add(null);
        errors.add(null);
        final int localIdx = index++;
        policyFactory.loadPolicy(policy.getPolicyImpl(), (IAsyncResult<IPolicy> result) -> {
            if (result.isSuccess()) {
                IPolicy policyImpl = result.getResult();
                // Test whether pipeline contains any data policies. Connectors can use this for Content-Length pass-through.
                if (policyImpl instanceof IDataPolicy) {
                    hasDataPolicy = true;
                }
                try {
                    Object policyConfig = policyFactory.loadConfig(policyImpl, policy.getPolicyImpl(), policy.getPolicyJsonConfig());
                    PolicyWithConfiguration pwc = new PolicyWithConfiguration(policyImpl, policyConfig);
                    rval.set(localIdx, pwc);
                } catch (Throwable t) {
                    errors.set(localIdx, t);
                    errorCounter.add(localIdx);
                }
            } else {
                Throwable error = result.getError();
                errors.set(localIdx, error);
                errorCounter.add(localIdx);
            }
            totalCounter.add(localIdx);
            // Have we done them all?
            if (totalCounter.size() == numPolicies) {
                // the fully resolved list of policies.
                if (!errorCounter.isEmpty()) {
                    int errorIdx = errorCounter.iterator().next();
                    Throwable error = errors.get(errorIdx);
                    // TODO add some logging here to indicate which policy error'd out
                    // Policy errorPolicy = policies.get(errorIdx);
                    policyErrorHandler.handle(error);
                } else {
                    handler.handle(rval);
                }
            }
        });
    }
}
Also used : IDataPolicy(io.apiman.gateway.engine.policy.IDataPolicy) Policy(io.apiman.gateway.engine.beans.Policy) IPolicy(io.apiman.gateway.engine.policy.IPolicy) IPolicy(io.apiman.gateway.engine.policy.IPolicy) ArrayList(java.util.ArrayList) TreeSet(java.util.TreeSet) IDataPolicy(io.apiman.gateway.engine.policy.IDataPolicy) IAsyncResult(io.apiman.gateway.engine.async.IAsyncResult) PolicyWithConfiguration(io.apiman.gateway.engine.policy.PolicyWithConfiguration) HashSet(java.util.HashSet)

Example 2 with IAsyncResult

use of io.apiman.gateway.engine.async.IAsyncResult in project apiman by apiman.

the class DefaultLdapComponent method connect.

@Override
public void connect(LdapConfigBean config, final IAsyncResultHandler<ILdapClientConnection> handler) {
    final DefaultLdapClientConnection connection = new DefaultLdapClientConnection(config, socketFactory);
    connection.connect((IAsyncResult<ILdapResult> result) -> {
        if (result.isSuccess()) {
            // Could still be a non-success return
            ILdapResult ldapResult = result.getResult();
            if (ldapResult.getResultCode().isSuccess()) {
                handler.handle(AsyncResultImpl.<ILdapClientConnection>create(connection));
            } else {
                // We don't have any fine-grained handling of exceptions, so bundle all into one.
                handler.handle(AsyncResultImpl.<ILdapClientConnection>create(DefaultExceptionFactory.create(ldapResult)));
            }
        } else {
            handler.handle(AsyncResultImpl.<ILdapClientConnection>create(result.getError()));
        }
    });
}
Also used : ILdapResult(io.apiman.gateway.engine.components.ldap.ILdapResult) IAsyncResult(io.apiman.gateway.engine.async.IAsyncResult)

Example 3 with IAsyncResult

use of io.apiman.gateway.engine.async.IAsyncResult 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 4 with IAsyncResult

use of io.apiman.gateway.engine.async.IAsyncResult in project apiman by apiman.

the class BasicMutualAuthTest method shouldSucceedWithValidMTLS.

/**
 * Scenario:
 *   - no CA inherited trust
 *   - gateway trusts API certificate directly
 *   - API trusts gateway certificate directly
 */
@Test
public void shouldSucceedWithValidMTLS() {
    config.put(TLSOptions.TLS_TRUSTSTORE, getResourcePath("2waytest/basic_mutual_auth/gateway_ts.jks"));
    config.put(TLSOptions.TLS_TRUSTSTOREPASSWORD, "changeme");
    config.put(TLSOptions.TLS_KEYSTORE, getResourcePath("2waytest/basic_mutual_auth/gateway_ks.jks"));
    config.put(TLSOptions.TLS_KEYSTOREPASSWORD, "changeme");
    config.put(TLSOptions.TLS_KEYPASSWORD, "changeme");
    config.put(TLSOptions.TLS_ALLOWANYHOST, "true");
    config.put(TLSOptions.TLS_ALLOWSELFSIGNED, "false");
    HttpConnectorFactory factory = new HttpConnectorFactory(config);
    IApiConnector connector = factory.createConnector(request, api, RequiredAuthType.MTLS, false, new ConnectorConfigImpl());
    IApiConnection connection = connector.connect(request, (IAsyncResult<IApiConnectionResponse> result) -> {
        if (result.isError())
            throw new RuntimeException(result.getError());
        Assert.assertTrue(result.isSuccess());
    });
    connection.end();
}
Also used : IApiConnection(io.apiman.gateway.engine.IApiConnection) HttpConnectorFactory(io.apiman.gateway.platforms.servlet.connectors.HttpConnectorFactory) ConnectorConfigImpl(io.apiman.gateway.platforms.servlet.connectors.ConnectorConfigImpl) IAsyncResult(io.apiman.gateway.engine.async.IAsyncResult) IApiConnector(io.apiman.gateway.engine.IApiConnector) Test(org.junit.Test)

Example 5 with IAsyncResult

use of io.apiman.gateway.engine.async.IAsyncResult in project apiman by apiman.

the class BasicMutualAuthTest method shouldFailWithInValidKeyAlias.

/**
 * Scenario:
 *   - Select invalid key alias (no such key).
 *   - Negotiation will fail
 * @throws CertificateException the certificate exception
 * @throws IOException the IO exception
 */
@Test
public void shouldFailWithInValidKeyAlias() throws CertificateException, IOException {
    config.put(TLSOptions.TLS_TRUSTSTORE, getResourcePath("2waytest/basic_mutual_auth_2/gateway_ts.jks"));
    config.put(TLSOptions.TLS_TRUSTSTOREPASSWORD, "changeme");
    config.put(TLSOptions.TLS_KEYSTORE, getResourcePath("2waytest/basic_mutual_auth_2/gateway_ks.jks"));
    config.put(TLSOptions.TLS_KEYSTOREPASSWORD, "changeme");
    config.put(TLSOptions.TLS_KEYPASSWORD, "changeme");
    config.put(TLSOptions.TLS_ALLOWANYHOST, "true");
    config.put(TLSOptions.TLS_ALLOWSELFSIGNED, "false");
    // No such key exists in the keystore
    config.put(TLSOptions.TLS_KEYALIASES, "xxx");
    HttpConnectorFactory factory = new HttpConnectorFactory(config);
    IApiConnector connector = factory.createConnector(request, api, RequiredAuthType.MTLS, false, new ConnectorConfigImpl());
    IApiConnection connection = connector.connect(request, (IAsyncResult<IApiConnectionResponse> result) -> {
        Assert.assertTrue(result.isError());
    });
    connection.end();
}
Also used : IApiConnection(io.apiman.gateway.engine.IApiConnection) HttpConnectorFactory(io.apiman.gateway.platforms.servlet.connectors.HttpConnectorFactory) ConnectorConfigImpl(io.apiman.gateway.platforms.servlet.connectors.ConnectorConfigImpl) IAsyncResult(io.apiman.gateway.engine.async.IAsyncResult) IApiConnector(io.apiman.gateway.engine.IApiConnector) Test(org.junit.Test)

Aggregations

IAsyncResult (io.apiman.gateway.engine.async.IAsyncResult)18 IApiConnector (io.apiman.gateway.engine.IApiConnector)9 IApiConnection (io.apiman.gateway.engine.IApiConnection)8 ConnectorConfigImpl (io.apiman.gateway.platforms.servlet.connectors.ConnectorConfigImpl)8 HttpConnectorFactory (io.apiman.gateway.platforms.servlet.connectors.HttpConnectorFactory)8 Test (org.junit.Test)8 IAsyncResultHandler (io.apiman.gateway.engine.async.IAsyncResultHandler)6 ArrayList (java.util.ArrayList)3 ConnectorException (io.apiman.gateway.engine.beans.exceptions.ConnectorException)2 IJdbcResultSet (io.apiman.gateway.engine.components.jdbc.IJdbcResultSet)2 PolicyWithConfiguration (io.apiman.gateway.engine.policy.PolicyWithConfiguration)2 File (java.io.File)2 FileInputStream (java.io.FileInputStream)2 InputStream (java.io.InputStream)2 X509Certificate (java.security.cert.X509Certificate)2 HashSet (java.util.HashSet)2 Plugin (io.apiman.common.plugin.Plugin)1 IConnectorConfig (io.apiman.gateway.engine.IConnectorConfig)1 IEngineResult (io.apiman.gateway.engine.IEngineResult)1 ApiContract (io.apiman.gateway.engine.beans.ApiContract)1