Search in sources :

Example 1 with ByteBuffer

use of io.apiman.gateway.engine.io.ByteBuffer 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 2 with ByteBuffer

use of io.apiman.gateway.engine.io.ByteBuffer 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)

Example 3 with ByteBuffer

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

the class SoapHeaderScannerTest method testScanSimpleWithHeadersSmallBuffer.

/**
 * Test method for {@link io.apiman.gateway.engine.soap.SoapHeaderScanner#scan(io.apiman.gateway.engine.io.IApimanBuffer)}.
 */
@Test
public void testScanSimpleWithHeadersSmallBuffer() 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:MyHeader1 xmlns:ns1=\"urn:namespace1\">Foo 1</ns1:MyHeader1>\r\n" + "    <ns1:MyHeader2 xmlns:ns1=\"urn:namespace1\">Foo 2</ns1:MyHeader2>\r\n" + "    <ns2:MyHeader3 xmlns:ns2=\"urn:namespace2\">Foo 3</ns2:MyHeader3>\r\n" + "    <ns2:MyHeader4 xmlns:ns2=\"urn:namespace2\">Foo 4</ns2:MyHeader4>\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();
    scanner.setMaxBufferLength(100);
    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:MyHeader1 xmlns:ns1=\"urn:namespace1\">Foo 1</ns1:MyHeader1>\r\n" + "    <ns1:MyHeader2 xmlns:ns1=\"urn:namespace1\">Foo 2</ns1:MyHeader2>\r\n" + "    <ns2:MyHeader3 xmlns:ns2=\"urn:namespace2\">Foo 3</ns2:MyHeader3>\r\n" + "    <ns2:MyHeader4 xmlns:ns2=\"urn:namespace2\">Foo 4</ns2:MyHeader4>\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)

Example 4 with ByteBuffer

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

the class SoapHeaderScannerTest method testScanNoEnvelopeFound.

/**
 * Test method for {@link io.apiman.gateway.engine.soap.SoapHeaderScanner#scan(io.apiman.gateway.engine.io.IApimanBuffer)}.
 */
@Test(expected = SoapEnvelopeNotFoundException.class)
public void testScanNoEnvelopeFound() throws SoapEnvelopeNotFoundException {
    String testData = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin finibus mauris " + "vel fermentum finibus. Proin lacus nulla, placerat in velit tristique, semper congue nisi. " + "Quisque ultricies metus felis, eu aliquet ligula gravida euismod. Integer et nulla eget " + "metus pretium consectetur eu id arcu. Fusce odio turpis, gravida sit amet finibus eu, " + "consequat in est. Nunc eu volutpat leo. Praesent sollicitudin est vitae lacus egestas, " + "iaculis dictum libero suscipit. Morbi vitae egestas diam. Nulla eu molestie urna.";
    IApimanBuffer buffer = new ByteBuffer(testData);
    SoapHeaderScanner scanner = new SoapHeaderScanner();
    scanner.setMaxBufferLength(100);
    scanner.scan(buffer);
}
Also used : IApimanBuffer(io.apiman.gateway.engine.io.IApimanBuffer) ByteBuffer(io.apiman.gateway.engine.io.ByteBuffer) Test(org.junit.Test)

Example 5 with ByteBuffer

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

the class SoapHeaderScannerTest method testScanSimple.

/**
 * Test method for {@link io.apiman.gateway.engine.soap.SoapHeaderScanner#scan(io.apiman.gateway.engine.io.IApimanBuffer)}.
 */
@Test
public void testScanSimple() 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" + "  </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" + "  </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

ByteBuffer (io.apiman.gateway.engine.io.ByteBuffer)16 IApimanBuffer (io.apiman.gateway.engine.io.IApimanBuffer)12 Test (org.junit.Test)11 ISignalWriteStream (io.apiman.gateway.engine.io.ISignalWriteStream)5 IApiRequestExecutor (io.apiman.gateway.engine.IApiRequestExecutor)2 IEngineResult (io.apiman.gateway.engine.IEngineResult)2 IAsyncHandler (io.apiman.gateway.engine.async.IAsyncHandler)2 ApiRequest (io.apiman.gateway.engine.beans.ApiRequest)2 ApiResponse (io.apiman.gateway.engine.beans.ApiResponse)2 IOException (java.io.IOException)2 InputStream (java.io.InputStream)2 IEngine (io.apiman.gateway.engine.IEngine)1 PolicyFailure (io.apiman.gateway.engine.beans.PolicyFailure)1 ApiNotFoundException (io.apiman.gateway.engine.beans.exceptions.ApiNotFoundException)1 InvalidApiException (io.apiman.gateway.engine.beans.exceptions.InvalidApiException)1 InvalidContractException (io.apiman.gateway.engine.beans.exceptions.InvalidContractException)1 RequestAbortedException (io.apiman.gateway.engine.beans.exceptions.RequestAbortedException)1 BytesPayloadIO (io.apiman.gateway.engine.io.BytesPayloadIO)1 JsonPayloadIO (io.apiman.gateway.engine.io.JsonPayloadIO)1 SoapPayloadIO (io.apiman.gateway.engine.io.SoapPayloadIO)1