Just one more thing ... 
If a SOAP API is published on Apiman and you request the WSDL by using the gateway endpoint URL, you get the original WSDL - address is pointing to the real endpoint URL and not the gateway endpoint URL.
I have solved this temporarily by adding URL rewrite policies to all SOAP APIs, which replace the real endpoint URL with the gateway endpoint URL.
I guess it would be best if this policy was handled by the gateway internally so that you wouldn't have to worry by adding a correct policy to the API configuration.

2016-03-29 20:29 GMT+02:00 Benjamin Kastelic <kastelic.benjamin@gmail.com>:
OK, now I understand what you meant.
I believe this would be a reasonable solution :)

2016-03-29 20:18 GMT+02:00 Eric Wittmann <eric.wittmann@redhat.com>:
My plan was unclear!  Let's go with another example:

Step 1 - the Gateway receives the following HTTP request:

----
POST /apiman-gateway/MyOrg/soap-api/2.7 HTTP/1.1
Host: www.example.org
Content-Type: application/soap+xml; charset=utf-8
X-API-Key: API-KEY-FOR-ACTIVE-CLIENT
SOAPAction: ExampleAction

<?xml version="1.0"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
  <soap:Header>
    <ns1:Header1 xmlns:ns1="uri:ns1">foo</ns1:Header1>
    <ns2:Header2 xmlns:ns2="uri:ns2">bar</ns2:Header2>
  </soap:Header>
  <soap:Body>
    <m:GetStockPrice xmlns:m="http://www.example.org/stock/RHT">
      <m:StockName>Red Hat</m:StockName>
    </m:GetStockPrice>
  </soap:Body>
</soap:Envelope>
----

We'll parse the first part of the envelope so that we can read the headers and make them available to any policies.  After that's done, we'll invoke the policy chain as per normal.  However, because it's a SOAP api, there will exist a SOAPRequestInfo object in the policy context.  So policies can read and/or modify the soap information.  This class might look something like this:

public class SOAPRequestInfo {
    private String action;
    private String encoding;
    private Map<QName, SOAPHeader> headers;
}

This allows interested policies (like your ws-security) policy to have easy access to all the soap related stuff.  It also allows you to alter these things.  Including adding/removing/modifying the SOAP headers.

So let's assume that we have a policy which *adds* a SOAP header (ns3:AddedHeader) and another policy which *removes* one (ns2:Header2).  The policy code might look like this:

SOAPRequestInfo soapInfo = context.getAttribute(
        Constants.SOAP_INFO, (SOAPRequestInfo) null);
soapInfo.getHeaders().remove(new QName("uri:ns2", "Header2"));
soapInfo.getHeaders().put(
    new QName("uri:ns3", "AddedHeader"),
    createSoapHeader()
);


In that case, this is the HTTP request that will be sent/proxied to the back-end API:

----
POST / HTTP/1.1
Host: www.example.org
Content-Type: application/soap+xml; charset=utf-8
SOAPAction: ExampleAction

<?xml version="1.0"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
  <soap:Header>
    <ns1:Header1 xmlns:ns1="uri:ns1">foo</ns1:Header1>
    <ns3:AddedHeader xmlns:ns3="uri:ns3">bar</ns3:AddedHeader>
  </soap:Header>
  <soap:Body>
    <m:GetStockPrice xmlns:m="http://www.example.org/stock/RHT">
      <m:StockName>Red Hat</m:StockName>
    </m:GetStockPrice>
  </soap:Body>
</soap:Envelope>
----

Sound reasonable?

-Eric


On 3/29/2016 1:42 PM, Benjamin Kastelic wrote:
If I understand you correctly Eric, only the soap:Body part will be
forwarded to the registered API?
What if the API still needs to receive the soap:Header part?

2016-03-29 15:34 GMT+02:00 Keith Babo <kbabo@redhat.com
<mailto:kbabo@redhat.com>>:

    Sounds cool to me.  Header policy will need to be QName and
    DOM-aware, so that namespace-qualified headers can be added and
    appropriate namespace definitions can be added to the DOM if
    required.  Of course you already know all this, but pointing it out
    makes me feel useful.

     > On Mar 29, 2016, at 8:38 AM, Eric Wittmann
    <eric.wittmann@redhat.com <mailto:eric.wittmann@redhat.com>> wrote:
     >
     > That's an interesting idea.  It'd be harder to inject the headers
    into the request than it is to inject HTTP request headers,
    obviously.  But not impossible.  We'd need to be aware of the change
    to any Content-Length that may be set.
     >
     > This makes the implementation slightly more complicated, because
    I think the HTTP connector will need to be made smarter (it will
    need to send the <soap:Envelope> and <soap:Header> sections first,
    then just stream the remaining request body as-is.
     >
     > So perhaps what we have is this:
     >
     > 1.  <?xml version="1.0"?>
     > 2.  <soap:Envelope
    xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
     > 3.    <soap:Header>
     > 4.      <ns1:Foo actor="..." xmlns:ns1="uri:ns1">BAR</ns1:Foo>
     > 5.    </soap:Header>
     > 6.    <soap:Body>
     > 7.      <m:GetStockPrice
    xmlns:m="http://www.example.org/stock/Surya">
     > 8.        <m:StockName>IBM</m:StockName>
     > 9.      </m:GetStockPrice>
     > 10.   </soap:Body>
     > 11. </soap:Envelope>
     >
     > Lines 1-5 will be read and consumed by apiman *before* any
    policies are executed.  We'll actually keep reading until we find
    <soap:Body> in the request body.  We'll throw out everything before
    line #6 from our in-memory buffer, resulting in a buffer with just
    line #6 (and any extra bytes after that based on our I/O chunk size).
     >
     > The policies will be executed, which may result in soap headers
    being added, modified, or removed.  If all policies pass, then we
    proxy the request to the back-end.  Normally the HTTP connection
    would simply send all bytes from the HTTP request as-is.  Instead,
    we'll need to *generate* new content for lines 1-5, with the newly
    modified soap headers.  Once the generated content is sent, then we
    send the contents of the in-memory buffer (which contains line #6+
    any additional bytes).  After that, we proxy the remaining bytes
    from the HTTP request as-is.
     >
     > This may be starting to take shape.  :)
     >
     > Additional thoughts?
     >
     > -Eric
     >
     > PS:  @Keith - we'll likely have a separate Policy for
    manipulating SOAP headers, rather than re-use the existing HTTP
    headers policy.
     >
     > On 3/29/2016 8:13 AM, Keith Babo wrote:
     >> Sounds like a reasonable first step to me.  Just to make life
    slightly
     >> more complicated, will the headers policy be updated to allow
    add/remove
     >> of SOAP:Headers? :-)
     >>
     >> ~ keith
     >>
     >>> On Mar 29, 2016, at 7:52 AM, Eric Wittmann
    <eric.wittmann@redhat.com <mailto:eric.wittmann@redhat.com>
     >>> <mailto:eric.wittmann@redhat.com
    <mailto:eric.wittmann@redhat.com>>> wrote:
     >>>
     >>> OK so here's what I propose (feedback welcome):
     >>>
     >>> *If* an API's 'type' is set to SOAP, then we will *always* look
    for a
     >>> soap envelope in the body.  If no body is found or no soap
    envelope is
     >>> found in the body, then a standard apiman error will be thrown.
     >>>
     >>> If an envelope *is* found, then we will read the body of the HTTP
     >>> request until we find "<soap:Body>".  We'll extract the
    <soap:Header>
     >>> and parse its children.  While parsing, we'll obviously keep
    the data
     >>> we read in a memory buffer.  Once parsing is done, we'll
    include the
     >>> soap headers, soap action, and the global encoding type in some
    sort
     >>> of soapinfo object and include that in the policy context.
     >>>
     >>> Finally, after all that is done, we'll process the request as
    normal,
     >>> executing the policy chain, then processing the request body,
    etc. The
     >>> entire request payload will still be processed (remember that
    we saved
     >>> the bytes we read in a memory buffer).
     >>>
     >>> So from the perspective of a policy, everything will look identical
     >>> except that a SOAPInfo object will be available in the policy
    context.
     >>>
     >>> Thoughts?
     >>>
     >>> -Eric
     >>>
     >>> On 3/28/2016 1:48 PM, Benjamin Kastelic wrote:
     >>>> Yup, I agree. That would probably be best, since several
    validators
     >>>> (wss4j for example) require DOM Elements
    (javax.xml.soap.SOAPHeader) to
     >>>> function.
     >>>>
     >>>> Best regards,
     >>>> Benjamin
     >>>>
     >>>> 2016-03-28 19:14 GMT+02:00 Eric Wittmann
    <eric.wittmann@redhat.com <mailto:eric.wittmann@redhat.com>
     >>>> <mailto:eric.wittmann@redhat.com
    <mailto:eric.wittmann@redhat.com>>
     >>>> <mailto:eric.wittmann@redhat.com
    <mailto:eric.wittmann@redhat.com>>>:
     >>>>
     >>>>   Thanks!  In that case, making the headers available as DOM
    Element
     >>>>   objects (perhaps with a simple QName based lookup) would be
    best.
     >>>>
     >>>>   -Eric
     >>>>
     >>>>   On 3/28/2016 12:39 PM, Keith Babo wrote:
     >>>>
     >>>>       SOAP:Headers can be complex types.  WS-Security is a good
     >>>> example of
     >>>>       this in practice.
     >>>>
     >>>>       ~ keith
     >>>>
     >>>>           On Mar 28, 2016, at 11:37 AM, Eric Wittmann
     >>>>           <eric.wittmann@redhat.com
    <mailto:eric.wittmann@redhat.com>
     >>>> <mailto:eric.wittmann@redhat.com
    <mailto:eric.wittmann@redhat.com>><mailto:eric.wittmann@redhat.com
    <mailto:eric.wittmann@redhat.com>>
     >>>>           <mailto:eric.wittmann@redhat.com
    <mailto:eric.wittmann@redhat.com>
     >>>>           <mailto:eric.wittmann@redhat.com
    <mailto:eric.wittmann@redhat.com>>>> wrote:
     >>>>
     >>>>           That's a bit hacky, but also sort of a genius
    approach as
     >>>>           well.  I'm
     >>>>           actually a little bummed I didn't think of it.  :)
     >>>>
     >>>>           As for extending SOAP support - I was thinking that
    I could
     >>>>           make the
     >>>>           relevant changes to apiman if you would be willing
    to provide
     >>>>           feedback/guidance/testing.  My SOAP expertise is
    quite stale
     >>>>           at this
     >>>>           point, so having some eyeballs on these changes would be
     >>>>           very useful.
     >>>>
     >>>>           To start off with, what pieces of the SOAP envelope
    should
     >>>>           be extracted
     >>>>           prior to calling the policy chain?  Some candidates are:
     >>>>
     >>>>           * The encoding style
     >>>>           * All SOAP headers
     >>>>           * SOAPAction (already available as an HTTP header)
     >>>>           * ???
     >>>>
     >>>>           For the soap headers, all of the examples I've seen
    take the
     >>>>           following
     >>>>           form:
     >>>>
     >>>>           <HeaderName xmlns="elementNS">Header-Value</HeaderName>
     >>>>
     >>>>           It can also have the optional "actor" or
    "mustUnderstand"
     >>>>           attributes.
     >>>>           The SOAP envelope schema is pretty lax though, so
    I'm not
     >>>>           sure if the
     >>>>           above is a convention or a rule.  Can headers be more
     >>>>           complex than the
     >>>>           above?
     >>>>
     >>>>           -Eric
     >>>>
     >>>>           On 3/26/2016 7:06 AM, Benjamin Kastelic wrote:
     >>>>
     >>>>               Hi,
     >>>>
     >>>>               I temporarily solved the problem by storing the
    request
     >>>>               body, which is
     >>>>               contained in ApiRequest.rawRequest object, in a
     >>>>               temporary buffer. I then
     >>>>               process the data (authentication) and based on the
     >>>>               results proceed with
     >>>>               the policy chain or report a failure. Then in
    the end()
     >>>>               method of the
     >>>>               requestDataHandler method I write the contents of my
     >>>>               temporary buffer
     >>>>               using super.write(IApimanBuffer). That way I can
    forward
     >>>>               the request to
     >>>>               then ext policy in the chain. But this is still
    a hacky
     >>>>               way of doing
     >>>>               this.
     >>>>
     >>>>               I would be glad to help with extending SOAP
    support. But
     >>>>               I would need a
     >>>>               few pointers where to start. The way of storing SOAP
     >>>>               headers in the
     >>>>               ApiRequest object seems like a good idea.
     >>>>
     >>>>               2016-03-24 18:40 GMT+01:00 Eric Wittmann
     >>>>               <eric.wittmann@redhat.com
    <mailto:eric.wittmann@redhat.com>
     >>>> <mailto:eric.wittmann@redhat.com
    <mailto:eric.wittmann@redhat.com>><mailto:eric.wittmann@redhat.com
    <mailto:eric.wittmann@redhat.com>>
     >>>>               <mailto:eric.wittmann@redhat.com
    <mailto:eric.wittmann@redhat.com>
     >>>>               <mailto:eric.wittmann@redhat.com
    <mailto:eric.wittmann@redhat.com>>>
     >>>>               <mailto:eric.wittmann@redhat.com
    <mailto:eric.wittmann@redhat.com>
     >>>>               <mailto:eric.wittmann@redhat.com
    <mailto:eric.wittmann@redhat.com>>>>:
     >>>>
     >>>>                   Hi Benjamin - thanks for the excellent
    question.  I
     >>>>               will do my best
     >>>>                   to answer and note that I am CC'ing the
    apiman-dev
     >>>>               mailing list so
     >>>>                   others can chime in.
     >>>>
     >>>>                   First let me say that a WS-Security policy
    sounds
     >>>>               great - we haven't
     >>>>                   focused much on the WS-* protocols because
    we get
     >>>>               much more demand
     >>>>                   for managing REST APIs than SOAP APIs.  That
    said,
     >>>>               better SOAP
     >>>>                   support is certainly on the radar.  When that
     >>>>               happens, my hope is
     >>>>                   that processing the envelope might be a core
    part of
     >>>>               the gateway and
     >>>>                   so implementing policies that use information in
     >>>>               there will be
     >>>>                   easier.  Perhaps your implementation can be the
     >>>>               genesis of some of
     >>>>                   that work!
     >>>>
     >>>>                   To your question - without core changes to
    apiman,
     >>>>               the approach you
     >>>>                   *need* to take is to have your policy implement
     >>>>               IDataPolicy.  I
     >>>>                   believe you may have already tried that, and
     >>>>               observed that you
     >>>>                   cannot send proper policy failures from that
     >>>>               method.  You are right
     >>>>                   - that's something we will need to fix!  I
    think you
     >>>>               should be able
     >>>>                   to throw a runtime exception from the
     >>>>               write(IApimanBuffer chunk)
     >>>>                   method if you detect an error.  However,
    this is a
     >>>>               little bit hacky!
     >>>>
     >>>>                   Instead, I suggest (if you're up for it) that we
     >>>>               perhaps work
     >>>>                   together to bake SOAP support directly into
    the core
     >>>>               of apiman, such
     >>>>                   that the SOAP envelope is read/parsed
    *before* the
     >>>>               policy chain is
     >>>>                   executed.  We could expose, for example, the
    SOAP
     >>>>               headers as a
     >>>>                   proper Map<> stored either in the context or
    on the
     >>>>               ApiRequest.
     >>>>                   This would allow you to properly implement most
     >>>>               (all?) WS-*
     >>>>                   protocols as proper apiman policies in the
     >>>>               apply(ApiRequest request)
     >>>>                   method.
     >>>>
     >>>>                   Thoughts?
     >>>>
     >>>>                   -Eric
     >>>>
     >>>>
     >>>>                   On 3/24/2016 7:58 AM, Benjamin Kastelic wrote:
     >>>>
     >>>>                       Greetings,
     >>>>
     >>>>                       I first thought to write this question as an
     >>>>               issue on Github,
     >>>>               but it
     >>>>                       seemed better to write you a direct email.
     >>>>
     >>>>                       I am making a custom WS Security policy,
    that
     >>>>               reads the body and
     >>>>                       check
     >>>>                       the UsernameToken security header. This
    works
     >>>>               OK, but now I've
     >>>>                       hit a wall.
     >>>>
     >>>>                       In the doApply method I get the rawRequest
     >>>>               object and read the
     >>>>                       body from
     >>>>                       the ServletInputStream of the request. The
     >>>>               problem I'm facing
     >>>>               now is
     >>>>                       that the input stream was read and it
    can't be
     >>>>               reset back to it's
     >>>>                       initial state.
     >>>>
     >>>>                       I was also trying to implement the same
    logic
     >>>> in the
     >>>>                       requestDataHandler
     >>>>                       method, but I don't know if it is even
    possible
     >>>>               to send a failure
     >>>>                       message to the request chain from there.
     >>>>
     >>>>                       Any suggesstions ?
     >>>>
     >>>>                       Best regards,
     >>>>                       Benjamin
     >>>>
     >>>>
     >>>>
     >>>>
     >>>>               --
     >>>>               Lp, Benjamin
     >>>>
     >>>>           _______________________________________________
     >>>>           Apiman-dev mailing list
     >>>> Apiman-dev@lists.jboss.org <mailto:Apiman-dev@lists.jboss.org>
    <mailto:Apiman-dev@lists.jboss.org <mailto:Apiman-dev@lists.jboss.org>>
     >>>>           <mailto:Apiman-dev@lists.jboss.org
    <mailto:Apiman-dev@lists.jboss.org>>
     >>>>           <mailto:Apiman-dev@lists.jboss.org
    <mailto:Apiman-dev@lists.jboss.org>
     >>>>           <mailto:Apiman-dev@lists.jboss.org
    <mailto:Apiman-dev@lists.jboss.org>>>
     >>>> https://lists.jboss.org/mailman/listinfo/apiman-dev
     >>>>
     >>>>
     >>>>
     >>>>
     >>>>
     >>>> --
     >>>> Lp, Benjamin
     >>




--
Lp, Benjamin



--
Lp, Benjamin



--
Lp, Benjamin