Search in sources :

Example 1 with IAsyncHandler

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

the class ApiRequestExecutorImpl method createRequestChain.

/**
 * Creates the chain used to apply policies in order to the api request.
 */
private Chain<ApiRequest> createRequestChain(IAsyncHandler<ApiRequest> requestHandler) {
    RequestChain chain = new RequestChain(policyImpls, context);
    chain.headHandler(requestHandler);
    chain.policyFailureHandler(failure -> {
        // It will likely not have been initialised, so create one.
        if (responseChain == null) {
            // Its response will not be used as we take the failure path only, so we just use an empty lambda.
            responseChain = createResponseChain((ignored) -> {
            });
        }
        responseChain.doFailure(failure);
    });
    chain.policyErrorHandler(policyErrorHandler);
    return chain;
}
Also used : Date(java.util.Date) IPayloadIO(io.apiman.gateway.engine.io.IPayloadIO) JsonPayloadIO(io.apiman.gateway.engine.io.JsonPayloadIO) ApiResponse(io.apiman.gateway.engine.beans.ApiResponse) IAsyncResult(io.apiman.gateway.engine.async.IAsyncResult) RequestChain(io.apiman.gateway.engine.policy.RequestChain) BytesPayloadIO(io.apiman.gateway.engine.io.BytesPayloadIO) IAsyncResultHandler(io.apiman.gateway.engine.async.IAsyncResultHandler) Map(java.util.Map) IApiConnector(io.apiman.gateway.engine.IApiConnector) GatewayConfigProperties(io.apiman.gateway.engine.GatewayConfigProperties) StrSubstitutor(org.apache.commons.lang3.text.StrSubstitutor) ISignalWriteStream(io.apiman.gateway.engine.io.ISignalWriteStream) RequestAbortedException(io.apiman.gateway.engine.beans.exceptions.RequestAbortedException) RequestMetric(io.apiman.gateway.engine.metrics.RequestMetric) IDataPolicy(io.apiman.gateway.engine.policy.IDataPolicy) Policy(io.apiman.gateway.engine.beans.Policy) Set(java.util.Set) PolicyFailure(io.apiman.gateway.engine.beans.PolicyFailure) IConnectorInterceptor(io.apiman.gateway.engine.policy.IConnectorInterceptor) List(java.util.List) IApimanBuffer(io.apiman.gateway.engine.io.IApimanBuffer) InvalidApiException(io.apiman.gateway.engine.beans.exceptions.InvalidApiException) Messages(io.apiman.gateway.engine.i18n.Messages) IRegistry(io.apiman.gateway.engine.IRegistry) Entry(java.util.Map.Entry) IApiConnection(io.apiman.gateway.engine.IApiConnection) Chain(io.apiman.gateway.engine.policy.Chain) IPolicy(io.apiman.gateway.engine.policy.IPolicy) IApiConnectionResponse(io.apiman.gateway.engine.IApiConnectionResponse) PolicyContextKeys(io.apiman.gateway.engine.policy.PolicyContextKeys) AsyncResultImpl(io.apiman.gateway.engine.async.AsyncResultImpl) TreeSet(java.util.TreeSet) ArrayList(java.util.ArrayList) PolicyWithConfiguration(io.apiman.gateway.engine.policy.PolicyWithConfiguration) HashSet(java.util.HashSet) ApimanStrLookup(io.apiman.common.util.ApimanStrLookup) SoapPayloadIO(io.apiman.gateway.engine.io.SoapPayloadIO) IConnectorConfig(io.apiman.gateway.engine.IConnectorConfig) IApiRequestExecutor(io.apiman.gateway.engine.IApiRequestExecutor) RequiredAuthType(io.apiman.gateway.engine.auth.RequiredAuthType) IBufferFactoryComponent(io.apiman.gateway.engine.components.IBufferFactoryComponent) StrLookup(org.apache.commons.lang3.text.StrLookup) IEngineResult(io.apiman.gateway.engine.IEngineResult) ByteBuffer(io.apiman.gateway.engine.io.ByteBuffer) InvalidContractException(io.apiman.gateway.engine.beans.exceptions.InvalidContractException) ApiRequest(io.apiman.gateway.engine.beans.ApiRequest) Api(io.apiman.gateway.engine.beans.Api) ResponseChain(io.apiman.gateway.engine.policy.ResponseChain) ApiNotFoundException(io.apiman.gateway.engine.beans.exceptions.ApiNotFoundException) IMetrics(io.apiman.gateway.engine.IMetrics) IConnectorFactory(io.apiman.gateway.engine.IConnectorFactory) IAsyncHandler(io.apiman.gateway.engine.async.IAsyncHandler) IPolicyContext(io.apiman.gateway.engine.policy.IPolicyContext) ApiContract(io.apiman.gateway.engine.beans.ApiContract) IPolicyFactory(io.apiman.gateway.engine.policy.IPolicyFactory) XmlPayloadIO(io.apiman.gateway.engine.io.XmlPayloadIO) RequestChain(io.apiman.gateway.engine.policy.RequestChain)

Example 2 with IAsyncHandler

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

the class InMemoryCacheStoreComponent method getBinary.

/**
 * @see io.apiman.gateway.engine.components.ICacheStoreComponent#getBinary(java.lang.String, java.lang.Class, io.apiman.gateway.engine.async.IAsyncResultHandler)
 */
@Override
public <T> void getBinary(String cacheKey, Class<T> type, IAsyncResultHandler<ISignalReadStream<T>> handler) {
    boolean expired = false;
    ISignalReadStream<T> rval;
    Object object;
    IApimanBuffer buffer;
    synchronized (mapMutex) {
        object = objectCache.get(cacheKey);
        if (object != null) {
            Long expiresOn = expireOnMap.get(cacheKey);
            if (System.currentTimeMillis() > expiresOn) {
                expired = true;
            }
        }
        buffer = dataCache.get(cacheKey);
        if (buffer == null) {
            object = null;
        }
    }
    if (object == null) {
        rval = null;
    } else if (expired) {
        synchronized (cacheSizeMutex) {
            synchronized (mapMutex) {
                objectCache.remove(cacheKey);
                expireOnMap.remove(cacheKey);
                dataCache.remove(cacheKey);
                cacheSize -= buffer.length();
            }
        }
        rval = null;
    } else {
        @SuppressWarnings("unchecked") final T head = (T) object;
        final IApimanBuffer data = buffer;
        rval = new ISignalReadStream<T>() {

            IAsyncHandler<IApimanBuffer> bodyHandler;

            IAsyncHandler<Void> endHandler;

            boolean finished = false;

            @Override
            public void bodyHandler(IAsyncHandler<IApimanBuffer> bodyHandler) {
                this.bodyHandler = bodyHandler;
            }

            @Override
            public void endHandler(IAsyncHandler<Void> endHandler) {
                this.endHandler = endHandler;
            }

            @Override
            public T getHead() {
                return head;
            }

            @Override
            public boolean isFinished() {
                return finished;
            }

            @Override
            public void abort(Throwable t) {
                finished = true;
            }

            @Override
            public void transmit() {
                bodyHandler.handle(data);
                endHandler.handle(null);
            }
        };
    }
    handler.handle(AsyncResultImpl.create(rval));
}
Also used : IApimanBuffer(io.apiman.gateway.engine.io.IApimanBuffer) ISignalReadStream(io.apiman.gateway.engine.io.ISignalReadStream) IAsyncHandler(io.apiman.gateway.engine.async.IAsyncHandler)

Example 3 with IAsyncHandler

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

the class LDAPIdentityValidator method doValidate.

private void doValidate(final String username, final String password, final ApiRequest request, final IPolicyContext context, final LDAPIdentitySource config, final IAsyncResultHandler<Boolean> handler) {
    final ILdapComponent ldapComponent = context.getComponent(ILdapComponent.class);
    String bindDn = formatDn(config.getDnPattern(), username, request);
    String bindDnPwd = password;
    int port = config.getUri().getPort();
    String scheme = config.getUri().getScheme();
    if (port == -1) {
        if ("ldap".equalsIgnoreCase(scheme)) {
            // $NON-NLS-1$
            port = 389;
        }
        if ("ldaps".equalsIgnoreCase(scheme)) {
            // $NON-NLS-1$
            port = 636;
        }
    }
    final LdapConfigBean ldapConfigBean = new LdapConfigBean();
    ldapConfigBean.setBindDn(bindDn);
    ldapConfigBean.setBindPassword(bindDnPwd);
    ldapConfigBean.setHost(config.getUri().getHost());
    ldapConfigBean.setPort(port);
    ldapConfigBean.setScheme(scheme);
    // Bind as one account, search for other.
    if (config.getBindAs() == LDAPBindAsType.ServiceAccount) {
        ldapConfigBean.setBindDn(formatDn(config.getDnPattern(), config.getCredentials().getUsername(), request));
        ldapConfigBean.setBindPassword(config.getCredentials().getPassword());
        ldapComponent.connect(ldapConfigBean, successHandler(handler, new IAsyncHandler<ILdapClientConnection>() {

            @Override
            public void handle(final ILdapClientConnection connection) {
                String searchBaseDN = formatDn(config.getUserSearch().getBaseDn(), username, request);
                String searchExpr = formatDn(config.getUserSearch().getExpression(), username, request);
                connection.search(searchBaseDN, searchExpr, LdapSearchScope.SUBTREE).setLdapErrorHandler(new IAsyncHandler<LdapException>() {

                    // At the moment it's just generic, but in future we can make better use of it.
                    @Override
                    public void handle(LdapException exception) {
                        handler.handle(AsyncResultImpl.<Boolean>create(exception));
                    }
                }).search(successHandler(handler, new IAsyncHandler<List<ILdapSearchEntry>>() {

                    @Override
                    public void handle(List<ILdapSearchEntry> searchEntries) {
                        handleLdapSearch(connection, searchEntries, config, ldapConfigBean, ldapComponent, context, username, password, handler);
                    }
                }));
            }
        }));
    } else {
        bind(config, ldapConfigBean, ldapComponent, context, new IAsyncResultHandler<ILdapResult>() {

            @Override
            public void handle(IAsyncResult<ILdapResult> result) {
                if (result.isSuccess()) {
                    if (LdapResultCode.isSuccess(result.getResult().getResultCode())) {
                        handler.handle(AsyncResultImpl.create(Boolean.TRUE));
                    } else {
                        // An auth failure
                        handler.handle(AsyncResultImpl.create(Boolean.FALSE));
                    }
                } else {
                    // Unexpected exception
                    handler.handle(AsyncResultImpl.<Boolean>create(result.getError()));
                }
            }
        });
    }
}
Also used : LdapConfigBean(io.apiman.gateway.engine.components.ldap.LdapConfigBean) ILdapSearchEntry(io.apiman.gateway.engine.components.ldap.ILdapSearchEntry) ILdapResult(io.apiman.gateway.engine.components.ldap.ILdapResult) ILdapClientConnection(io.apiman.gateway.engine.components.ldap.ILdapClientConnection) List(java.util.List) IAsyncHandler(io.apiman.gateway.engine.async.IAsyncHandler) LdapException(io.apiman.gateway.engine.components.ldap.result.LdapException) ILdapComponent(io.apiman.gateway.engine.components.ILdapComponent)

Example 4 with IAsyncHandler

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

the class LDAPIdentityValidator method extractRoles.

private void extractRoles(final ILdapClientConnection connection, final String userDn, final LDAPIdentitySource config, final IPolicyContext context, final IAsyncResultHandler<ILdapResult> resultHandler) {
    final Set<String> roles = new HashSet<>();
    // $NON-NLS-1$
    connection.search(userDn, "(objectClass=*)", LdapSearchScope.SUBTREE).setLdapErrorHandler(new IAsyncHandler<LdapException>() {

        // At the moment it's just generic, but in future we can make better use of it.
        @Override
        public void handle(LdapException exception) {
            resultHandler.handle(AsyncResultImpl.<ILdapResult>create(exception));
        }
    }).search(successHandler(resultHandler, new IAsyncHandler<List<ILdapSearchEntry>>() {

        @Override
        public void handle(List<ILdapSearchEntry> result) {
            // Look through all results (usually should only be 1)
            for (ILdapSearchEntry searchResult : result) {
                // Get membership attribute (if any)
                List<ILdapAttribute> attrs = searchResult.getAttributes();
                try {
                    // Look through all attrs - grab relevant RDNS, for each attribute (e.g. cn)
                    for (ILdapAttribute attr : attrs) {
                        if (attr.getBaseName().equals(config.getMembershipAttribute())) {
                            addRoles(attr);
                        }
                    }
                    context.setAttribute(AuthorizationPolicy.AUTHENTICATED_USER_ROLES, roles);
                    resultHandler.handle(AsyncResultImpl.create(LdapResult.SUCCESS));
                } catch (Exception e) {
                    // Potentially invalid RDN format
                    resultHandler.handle(AsyncResultImpl.<ILdapResult>create(e));
                }
            }
        }

        private void addRoles(ILdapAttribute attr) {
            // Treat value as an RDN
            for (ILdapDn dn : attr.getValuesAsDn()) {
                for (ILdapRdn rdns : dn.getRdns()) {
                    if (rdns.hasAttribute(config.getRolenameAttribute())) {
                        for (String value : rdns.getAttributeValues()) {
                            roles.add(value);
                        }
                    }
                }
            }
        }
    }));
}
Also used : ILdapAttribute(io.apiman.gateway.engine.components.ldap.ILdapAttribute) ILdapSearchEntry(io.apiman.gateway.engine.components.ldap.ILdapSearchEntry) NamingException(javax.naming.NamingException) LdapException(io.apiman.gateway.engine.components.ldap.result.LdapException) ILdapResult(io.apiman.gateway.engine.components.ldap.ILdapResult) ILdapRdn(io.apiman.gateway.engine.components.ldap.ILdapRdn) List(java.util.List) ILdapDn(io.apiman.gateway.engine.components.ldap.ILdapDn) IAsyncHandler(io.apiman.gateway.engine.async.IAsyncHandler) LdapException(io.apiman.gateway.engine.components.ldap.result.LdapException) HashSet(java.util.HashSet)

Example 5 with IAsyncHandler

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

the class GatewayServlet method doAction.

/**
 * Generic handler for all types of http actions/verbs.
 * @param req
 * @param resp
 * @param action
 */
protected void doAction(final HttpServletRequest req, final HttpServletResponse resp, String action) {
    // Read the request.
    ApiRequest srequest;
    try {
        srequest = readRequest(req);
        srequest.setType(action);
    } catch (Exception e) {
        writeError(null, resp, e);
        return;
    }
    final CountDownLatch latch = new CountDownLatch(1);
    final ApiRequest finalRequest = srequest;
    // Now execute the request via the apiman engine
    IApiRequestExecutor executor = getEngine().executor(srequest, new IAsyncResultHandler<IEngineResult>() {

        @Override
        public void handle(IAsyncResult<IEngineResult> asyncResult) {
            if (asyncResult.isSuccess()) {
                IEngineResult engineResult = asyncResult.getResult();
                if (engineResult.isResponse()) {
                    try {
                        writeResponse(resp, engineResult.getApiResponse());
                        final ServletOutputStream outputStream = resp.getOutputStream();
                        engineResult.bodyHandler(new IAsyncHandler<IApimanBuffer>() {

                            @Override
                            public void handle(IApimanBuffer chunk) {
                                try {
                                    if (chunk instanceof ByteBuffer) {
                                        byte[] buffer = (byte[]) chunk.getNativeBuffer();
                                        outputStream.write(buffer, 0, chunk.length());
                                    } else {
                                        outputStream.write(chunk.getBytes());
                                    }
                                } catch (IOException e) {
                                    // connection to the back-end API.
                                    throw new RuntimeException(e);
                                }
                            }
                        });
                        engineResult.endHandler(new IAsyncHandler<Void>() {

                            @Override
                            public void handle(Void result) {
                                try {
                                    resp.flushBuffer();
                                } catch (IOException e) {
                                    // connection to the back-end API.
                                    throw new RuntimeException(e);
                                } finally {
                                    latch.countDown();
                                }
                            }
                        });
                    } catch (IOException e) {
                        // this would mean we couldn't get the output stream from the response, so we
                        // need to abort the engine result (which will let the back-end connection
                        // close down).
                        engineResult.abort(e);
                        latch.countDown();
                        throw new RuntimeException(e);
                    }
                } else {
                    writeFailure(finalRequest, resp, engineResult.getPolicyFailure());
                    latch.countDown();
                }
            } else {
                writeError(finalRequest, resp, asyncResult.getError());
                latch.countDown();
            }
        }
    });
    executor.streamHandler(new IAsyncHandler<ISignalWriteStream>() {

        @Override
        public void handle(ISignalWriteStream connectorStream) {
            try {
                final InputStream is = req.getInputStream();
                ByteBuffer buffer = new ByteBuffer(2048);
                int numBytes = buffer.readFrom(is);
                while (numBytes != -1) {
                    connectorStream.write(buffer);
                    numBytes = buffer.readFrom(is);
                }
                connectorStream.end();
            } catch (Throwable e) {
                connectorStream.abort(e);
            }
        }
    });
    executor.execute();
    try {
        latch.await();
    } catch (InterruptedException e) {
    }
}
Also used : IApimanBuffer(io.apiman.gateway.engine.io.IApimanBuffer) IEngineResult(io.apiman.gateway.engine.IEngineResult) ServletOutputStream(javax.servlet.ServletOutputStream) InputStream(java.io.InputStream) IOException(java.io.IOException) ApiRequest(io.apiman.gateway.engine.beans.ApiRequest) CountDownLatch(java.util.concurrent.CountDownLatch) ISignalWriteStream(io.apiman.gateway.engine.io.ISignalWriteStream) ByteBuffer(io.apiman.gateway.engine.io.ByteBuffer) ServletException(javax.servlet.ServletException) IOException(java.io.IOException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) IAsyncHandler(io.apiman.gateway.engine.async.IAsyncHandler) IApiRequestExecutor(io.apiman.gateway.engine.IApiRequestExecutor)

Aggregations

IAsyncHandler (io.apiman.gateway.engine.async.IAsyncHandler)8 IApimanBuffer (io.apiman.gateway.engine.io.IApimanBuffer)6 IApiRequestExecutor (io.apiman.gateway.engine.IApiRequestExecutor)3 IEngineResult (io.apiman.gateway.engine.IEngineResult)3 ApiRequest (io.apiman.gateway.engine.beans.ApiRequest)3 HashSet (java.util.HashSet)3 List (java.util.List)3 ApiResponse (io.apiman.gateway.engine.beans.ApiResponse)2 PolicyFailure (io.apiman.gateway.engine.beans.PolicyFailure)2 ILdapResult (io.apiman.gateway.engine.components.ldap.ILdapResult)2 ILdapSearchEntry (io.apiman.gateway.engine.components.ldap.ILdapSearchEntry)2 LdapException (io.apiman.gateway.engine.components.ldap.result.LdapException)2 ByteBuffer (io.apiman.gateway.engine.io.ByteBuffer)2 ISignalReadStream (io.apiman.gateway.engine.io.ISignalReadStream)2 ISignalWriteStream (io.apiman.gateway.engine.io.ISignalWriteStream)2 CacheEntry (io.apiman.gateway.engine.storage.model.CacheEntry)2 ApimanStrLookup (io.apiman.common.util.ApimanStrLookup)1 GatewayConfigProperties (io.apiman.gateway.engine.GatewayConfigProperties)1 IApiConnection (io.apiman.gateway.engine.IApiConnection)1 IApiConnectionResponse (io.apiman.gateway.engine.IApiConnectionResponse)1