Search in sources :

Example 1 with IApimanBuffer

use of io.apiman.gateway.engine.io.IApimanBuffer in project apiman-plugins by apiman.

the class JsonpPolicy method getResponseDataHandler.

/**
 * @see io.apiman.gateway.engine.policy.IDataPolicy#getResponseDataHandler(io.apiman.gateway.engine.beans.ApiResponse, io.apiman.gateway.engine.policy.IPolicyContext, java.lang.Object)
 */
@Override
public IReadWriteStream<ApiResponse> getResponseDataHandler(final ApiResponse response, IPolicyContext context, Object policyConfiguration) {
    final String callbackFunctionName = (String) context.getAttribute(CALLBACK_FUNCTION_NAME, null);
    if (callbackFunctionName != null) {
        HttpHeaders httpHeaders = new HttpHeaders(response.getHeaders());
        final String encoding = httpHeaders.getCharsetFromContentType(StandardCharsets.UTF_8.name());
        final int additionalContentLength = callbackFunctionName.length() + OPEN_PARENTHESES.length() + CLOSE_PARENTHESES.length();
        // JSONP responses should have the Content-Type header set to "application/javascript"
        httpHeaders.setContentType(APPLICATION_JAVASCRIPT);
        // the Content-Length will need to be longer
        httpHeaders.incrementContentLength(additionalContentLength);
        final IBufferFactoryComponent bufferFactory = context.getComponent(IBufferFactoryComponent.class);
        return new AbstractStream<ApiResponse>() {

            private boolean firstChunk = true;

            @Override
            public ApiResponse getHead() {
                return response;
            }

            @Override
            protected void handleHead(ApiResponse head) {
            }

            @Override
            public void write(IApimanBuffer chunk) {
                if (firstChunk) {
                    IApimanBuffer buffer = bufferFactory.createBuffer(callbackFunctionName.length() + OPEN_PARENTHESES.length());
                    try {
                        buffer.append(callbackFunctionName, encoding);
                        buffer.append(OPEN_PARENTHESES, encoding);
                    } catch (UnsupportedEncodingException e) {
                        // TODO Review the exception handling. A better approach might be throwing an IOException.
                        throw new RuntimeException(e);
                    }
                    // Write callbackFunctionName(
                    super.write(buffer);
                    firstChunk = false;
                }
                super.write(chunk);
            }

            @Override
            public void end() {
                // Write close parenth ) on end if something has been written
                if (!firstChunk) {
                    IApimanBuffer buffer = bufferFactory.createBuffer(CLOSE_PARENTHESES.length());
                    try {
                        buffer.append(CLOSE_PARENTHESES, encoding);
                    } catch (UnsupportedEncodingException e) {
                        // TODO Review the exception handling. A better approach might be throwing an IOException.
                        throw new RuntimeException(e);
                    }
                    super.write(buffer);
                }
                super.end();
            }
        };
    }
    return null;
}
Also used : HttpHeaders(io.apiman.plugins.jsonp_policy.http.HttpHeaders) IApimanBuffer(io.apiman.gateway.engine.io.IApimanBuffer) IBufferFactoryComponent(io.apiman.gateway.engine.components.IBufferFactoryComponent) AbstractStream(io.apiman.gateway.engine.io.AbstractStream) UnsupportedEncodingException(java.io.UnsupportedEncodingException) ApiResponse(io.apiman.gateway.engine.beans.ApiResponse)

Example 2 with IApimanBuffer

use of io.apiman.gateway.engine.io.IApimanBuffer in project apiman-plugins by apiman.

the class TransformationPolicy method getRequestDataHandler.

/**
 * @see io.apiman.gateway.engine.policy.IDataPolicy#getRequestDataHandler(io.apiman.gateway.engine.beans.ApiRequest, io.apiman.gateway.engine.policy.IPolicyContext, java.lang.Object)
 */
@Override
public IReadWriteStream<ApiRequest> getRequestDataHandler(final ApiRequest request, IPolicyContext context, Object policyConfiguration) {
    final IBufferFactoryComponent bufferFactory = context.getComponent(IBufferFactoryComponent.class);
    final int contentLength = request.getHeaders().containsKey(CONTENT_LENGTH) ? Integer.parseInt(request.getHeaders().get(CONTENT_LENGTH)) : 0;
    return new AbstractStream<ApiRequest>() {

        private IApimanBuffer readBuffer = bufferFactory.createBuffer(contentLength);

        @Override
        public ApiRequest getHead() {
            return request;
        }

        @Override
        protected void handleHead(ApiRequest head) {
        }

        @Override
        public void write(IApimanBuffer chunk) {
            readBuffer.append(chunk.getBytes());
        }

        @Override
        public void end() {
            final DataFormat clientFormat = (DataFormat) context.getAttribute(CLIENT_FORMAT, null);
            final DataFormat serverFormat = (DataFormat) context.getAttribute(SERVER_FORMAT, null);
            if (readBuffer.length() > 0) {
                if (isValidTransformation(clientFormat, serverFormat)) {
                    DataTransformer dataTransformer = DataTransformerFactory.getDataTransformer(clientFormat, serverFormat);
                    IApimanBuffer writeBuffer = bufferFactory.createBuffer(readBuffer.length());
                    String data = dataTransformer.transform(new String(readBuffer.getBytes()));
                    writeBuffer.append(data);
                    super.write(writeBuffer);
                } else {
                    super.write(readBuffer);
                }
            }
            super.end();
        }
    };
}
Also used : IApimanBuffer(io.apiman.gateway.engine.io.IApimanBuffer) IBufferFactoryComponent(io.apiman.gateway.engine.components.IBufferFactoryComponent) DataTransformer(io.apiman.plugins.transformation_policy.transformer.DataTransformer) AbstractStream(io.apiman.gateway.engine.io.AbstractStream) DataFormat(io.apiman.plugins.transformation_policy.beans.DataFormat) ApiRequest(io.apiman.gateway.engine.beans.ApiRequest)

Example 3 with IApimanBuffer

use of io.apiman.gateway.engine.io.IApimanBuffer in project apiman-plugins by apiman.

the class TransformationPolicy method getResponseDataHandler.

/**
 * @see io.apiman.gateway.engine.policy.IDataPolicy#getResponseDataHandler(io.apiman.gateway.engine.beans.ApiResponse, io.apiman.gateway.engine.policy.IPolicyContext, java.lang.Object)
 */
@Override
public IReadWriteStream<ApiResponse> getResponseDataHandler(final ApiResponse response, IPolicyContext context, Object policyConfiguration) {
    final DataFormat clientFormat = (DataFormat) context.getAttribute(CLIENT_FORMAT, null);
    final DataFormat serverFormat = (DataFormat) context.getAttribute(SERVER_FORMAT, null);
    if (isValidTransformation(clientFormat, serverFormat)) {
        final IBufferFactoryComponent bufferFactory = context.getComponent(IBufferFactoryComponent.class);
        final int contentLength = response.getHeaders().containsKey(CONTENT_LENGTH) ? Integer.parseInt(response.getHeaders().get(CONTENT_LENGTH)) : 0;
        return new AbstractStream<ApiResponse>() {

            private IApimanBuffer readBuffer = bufferFactory.createBuffer(contentLength);

            @Override
            public ApiResponse getHead() {
                return response;
            }

            @Override
            protected void handleHead(ApiResponse head) {
            }

            @Override
            public void write(IApimanBuffer chunk) {
                byte[] bytes = chunk.getBytes();
                readBuffer.append(bytes);
            }

            @Override
            public void end() {
                if (readBuffer.length() > 0) {
                    DataTransformer dataTransformer = DataTransformerFactory.getDataTransformer(serverFormat, clientFormat);
                    IApimanBuffer writeBuffer = bufferFactory.createBuffer(readBuffer.length());
                    String data = dataTransformer.transform(new String(readBuffer.getBytes()));
                    writeBuffer.append(data);
                    super.write(writeBuffer);
                }
                super.end();
            }
        };
    }
    return null;
}
Also used : IApimanBuffer(io.apiman.gateway.engine.io.IApimanBuffer) IBufferFactoryComponent(io.apiman.gateway.engine.components.IBufferFactoryComponent) DataTransformer(io.apiman.plugins.transformation_policy.transformer.DataTransformer) DataFormat(io.apiman.plugins.transformation_policy.beans.DataFormat) AbstractStream(io.apiman.gateway.engine.io.AbstractStream) ApiResponse(io.apiman.gateway.engine.beans.ApiResponse)

Example 4 with IApimanBuffer

use of io.apiman.gateway.engine.io.IApimanBuffer in project apiman by apiman.

the class ApiRequestExecutorImpl method parsePayload.

/**
 * Parse the inbound request's body into a payload object.  The object that is
 * produced will depend on the type and content-type of the API.  Options
 * include, but may not be limited to:
 * <ul>
 *   <li>REST+json</li>
 *   <li>REST+xml</li>
 *   <li>SOAP+xml</li>
 * </ul>
 * @param payloadResultHandler
 */
protected void parsePayload(IAsyncResultHandler<Object> payloadResultHandler) {
    // Strip out any content-length header from the request.  It will very likely
    // no longer be accurate.
    // $NON-NLS-1$
    request.getHeaders().remove("Content-Length");
    // Configure the api's max payload buffer size, if it's not already set.
    if (api.getMaxPayloadBufferSize() <= 0) {
        api.setMaxPayloadBufferSize(maxPayloadBufferSize);
    }
    // Now "handle" the inbound request stream, which will cause bytes to be streamed
    // to the writeStream we provide (which will store the bytes in a buffer for parsing)
    final ByteBuffer buffer = new ByteBuffer(2048);
    inboundStreamHandler.handle(new ISignalWriteStream() {

        private boolean done = false;

        @Override
        public void abort(Throwable t) {
            done = true;
            // $NON-NLS-1$
            payloadResultHandler.handle(AsyncResultImpl.create(new RuntimeException("Inbound request stream aborted.", t)));
        }

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

        @Override
        public void write(IApimanBuffer chunk) {
            if (done) {
                return;
            }
            if (buffer.length() > api.getMaxPayloadBufferSize()) {
                // $NON-NLS-1$
                payloadResultHandler.handle(AsyncResultImpl.create(new Exception("Max request payload size exceeded.")));
                done = true;
                return;
            }
            buffer.append(chunk);
        }

        @Override
        public void end() {
            if (done) {
                return;
            }
            // When end() is called, the stream of bytes is done and we can parse them into
            // an appropriate payload object.
            done = true;
            if (buffer.length() == 0) {
                payloadResultHandler.handle(AsyncResultImpl.create(null));
            } else {
                payloadIO = null;
                if ("soap".equalsIgnoreCase(api.getEndpointType())) {
                    // $NON-NLS-1$
                    payloadIO = new SoapPayloadIO();
                } else if ("rest".equalsIgnoreCase(api.getEndpointType())) {
                    // $NON-NLS-1$
                    if ("xml".equalsIgnoreCase(api.getEndpointContentType())) {
                        // $NON-NLS-1$
                        payloadIO = new XmlPayloadIO();
                    } else if ("json".equalsIgnoreCase(api.getEndpointContentType())) {
                        // $NON-NLS-1$
                        payloadIO = new JsonPayloadIO();
                    }
                }
                if (payloadIO == null) {
                    payloadIO = new BytesPayloadIO();
                }
                try {
                    Object payload = payloadIO.unmarshall(buffer.getBytes());
                    payloadResultHandler.handle(AsyncResultImpl.create(payload));
                } catch (Exception e) {
                    // $NON-NLS-1$
                    payloadResultHandler.handle(AsyncResultImpl.create(new Exception("Failed to parse inbound request payload.", e)));
                }
            }
        }

        /**
         * Because of the way the parsePayload code was written, it's possible
         * with async for apiConnection to be +null+ when this is called.
         *
         * This is because parsePayload invokes inboundStreamHandler before
         * policiesLoadedHandler has had a chance to return (and assigned apiConnection).
         *
         * To work around this we check whether apiConnection is null for #drainHandler
         * and #isFull.
         */
        @Override
        public void drainHandler(IAsyncHandler<Void> drainHandler) {
            if (apiConnection != null)
                apiConnection.drainHandler(drainHandler);
        }

        @Override
        public boolean isFull() {
            if (apiConnection != null) {
                return apiConnection.isFull();
            } else {
                return false;
            }
        }
    });
}
Also used : IApimanBuffer(io.apiman.gateway.engine.io.IApimanBuffer) BytesPayloadIO(io.apiman.gateway.engine.io.BytesPayloadIO) ISignalWriteStream(io.apiman.gateway.engine.io.ISignalWriteStream) ByteBuffer(io.apiman.gateway.engine.io.ByteBuffer) JsonPayloadIO(io.apiman.gateway.engine.io.JsonPayloadIO) RequestAbortedException(io.apiman.gateway.engine.beans.exceptions.RequestAbortedException) InvalidApiException(io.apiman.gateway.engine.beans.exceptions.InvalidApiException) InvalidContractException(io.apiman.gateway.engine.beans.exceptions.InvalidContractException) ApiNotFoundException(io.apiman.gateway.engine.beans.exceptions.ApiNotFoundException) SoapPayloadIO(io.apiman.gateway.engine.io.SoapPayloadIO) XmlPayloadIO(io.apiman.gateway.engine.io.XmlPayloadIO)

Example 5 with IApimanBuffer

use of io.apiman.gateway.engine.io.IApimanBuffer in project apiman by apiman.

the class SoapHeaderScannerTest method testScanSimpleWithHeader.

/**
 * Test method for {@link io.apiman.gateway.engine.soap.SoapHeaderScanner#scan(io.apiman.gateway.engine.io.IApimanBuffer)}.
 */
@Test
public void testScanSimpleWithHeader() throws SoapEnvelopeNotFoundException {
    String testData = "<?xml version=\"1.0\"?>\r\n" + "<soap:Envelope xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\">\r\n" + "  <soap:Header>\r\n" + "    <ns1:MyHeader xmlns:ns1=\"urn:namespace1\">Foo</ns1:MyHeader>\r\n" + "  </soap:Header>\r\n" + "  <soap:Body>\r\n" + "    <m:GetStockPrice xmlns:m=\"http://www.example.org/stock/Surya\">\r\n" + "      <m:StockName>IBM</m:StockName>\r\n" + "    </m:GetStockPrice>\r\n" + "  </soap:Body>\r\n" + "</soap:Envelope>";
    IApimanBuffer buffer = new ByteBuffer(testData);
    SoapHeaderScanner scanner = new SoapHeaderScanner();
    boolean done = scanner.scan(buffer);
    Assert.assertTrue("Expected the scan to be complete but was not.", done);
    Assert.assertTrue("Expected the scan to find an XML preamble.", scanner.hasXmlPreamble());
    Assert.assertEquals("<?xml version=\"1.0\"?>", scanner.getXmlPreamble());
    String expectedEnvelopeDecl = "<soap:Envelope xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\">";
    Assert.assertEquals(expectedEnvelopeDecl, scanner.getEnvelopeDeclaration());
    String expectedHeaders = "<soap:Header>\r\n" + "    <ns1:MyHeader xmlns:ns1=\"urn:namespace1\">Foo</ns1:MyHeader>\r\n" + "  </soap:Header>";
    Assert.assertEquals(expectedHeaders, scanner.getHeaders());
    IApimanBuffer remainingBuffer = new ByteBuffer(scanner.getRemainingBytes());
    String expectedRemaining = "\r\n" + "  <soap:Body>\r\n" + "    <m:GetStockPrice xmlns:m=\"http://www.example.org/stock/Surya\">\r\n" + "      <m:StockName>IBM</m:StockName>\r\n" + "    </m:GetStockPrice>\r\n" + "  </soap:Body>\r\n" + "</soap:Envelope>";
    Assert.assertEquals(expectedRemaining, remainingBuffer.getString(0, remainingBuffer.length()));
}
Also used : IApimanBuffer(io.apiman.gateway.engine.io.IApimanBuffer) ByteBuffer(io.apiman.gateway.engine.io.ByteBuffer) Test(org.junit.Test)

Aggregations

IApimanBuffer (io.apiman.gateway.engine.io.IApimanBuffer)31 ByteBuffer (io.apiman.gateway.engine.io.ByteBuffer)12 ISignalWriteStream (io.apiman.gateway.engine.io.ISignalWriteStream)11 Test (org.junit.Test)11 ApiRequest (io.apiman.gateway.engine.beans.ApiRequest)7 ApiResponse (io.apiman.gateway.engine.beans.ApiResponse)7 AbstractStream (io.apiman.gateway.engine.io.AbstractStream)6 IAsyncHandler (io.apiman.gateway.engine.async.IAsyncHandler)5 IEngineResult (io.apiman.gateway.engine.IEngineResult)4 IBufferFactoryComponent (io.apiman.gateway.engine.components.IBufferFactoryComponent)4 ISignalReadStream (io.apiman.gateway.engine.io.ISignalReadStream)4 IApiRequestExecutor (io.apiman.gateway.engine.IApiRequestExecutor)3 IAsyncResultHandler (io.apiman.gateway.engine.async.IAsyncResultHandler)3 CacheEntry (io.apiman.gateway.engine.storage.model.CacheEntry)3 IOException (java.io.IOException)3 UnsupportedEncodingException (java.io.UnsupportedEncodingException)3 IApiConnector (io.apiman.gateway.engine.IApiConnector)2 IConnectorConfig (io.apiman.gateway.engine.IConnectorConfig)2 IEngine (io.apiman.gateway.engine.IEngine)2 IAsyncResult (io.apiman.gateway.engine.async.IAsyncResult)2