Guten Tag Thorsten Schöning,
am Donnerstag, 7. Juni 2018 um 18:58 schrieben Sie:

> So "7.1. Custom client connections" seem to be the way to go: Provide
> a custom HttpConnectionFactory and make Axis2 to use that, while I've
> already provided a custom connection manager to Axis2 in the past with
> non-default settings. What I'm missing currently is the part where the
> request body gets serialized, "DefaultHttpRequestWriterFactory" reads
> like it only handles headers...

> https://hc.apache.org/httpcomponents-client-ga/tutorial/html/advanced.html#d5e913

The important part to understand seems to be that the connection
factory provides some instances of "HttpClientConnection" in the end
and those distinguishe between serializing headers and bodies:

https://hc.apache.org/httpcomponents-core-ga/httpcore/apidocs/org/apache/http/HttpClientConnection.html#sendRequestHeader(org.apache.http.HttpRequest)
https://hc.apache.org/httpcomponents-core-ga/httpcore/apidocs/org/apache/http/HttpClientConnection.html#sendRequestEntity(org.apache.http.HttpEntityEnclosingRequest)

The request writers are only used in "sendRequestHeader", while bodies
are serialized using whatever body-containing object is given. In case
of Axis2 this seems to be "AxisRequestEntityImpl", which takes care of
serializing according to some "MessageFormatter", which itself exists
for various different formats like JSON and SOAP and things like MTOM
vs. inline vs. SOAP with attachments are handled somewhere in that
chain as well...

In the end, every data is written to a stream created within
"sendRequestEntity" and that seems to be a good place to put a rate
limiter in:

>     @Override
>     public void sendRequestEntity(final HttpEntityEnclosingRequest request)
>             throws HttpException, IOException {
>         Args.notNull(request, "HTTP request");
>         ensureOpen();
>         final HttpEntity entity = request.getEntity();
>         if (entity == null) {
>             return;
>         }
>         final OutputStream outstream = prepareOutput(request);
>         entity.writeTo(outstream);
>         outstream.close();
>     }

>     protected OutputStream createOutputStream(
>             final long len,
>             final SessionOutputBuffer outbuffer) {
>         if (len == ContentLengthStrategy.CHUNKED) {
>             return new ChunkedOutputStream(2048, outbuffer);
>        } else if (len == ContentLengthStrategy.IDENTITY) {
>             return new IdentityOutputStream(outbuffer);
>         } else {
>             return new ContentLengthOutputStream(outbuffer, len);
>         }
>     }

>     protected OutputStream prepareOutput(final HttpMessage message) throws 
> HttpException {
>         final long len = 
> this.outgoingContentStrategy.determineLength(message);
>         return createOutputStream(len, this.outbuffer);
>     }

So, the connection factory is needed to provide custom client
connections and one needs to create one which overrides
"createOutputStream" by calling the super implementation and
afterwards wrapping the resulting "OutputStream" once more in some
"RateLimitOutputStream" or such.

From my understanding, that "RateLimitOutputStream" would "only" need
to make sure that writes are somewhat small, so that not e.g. 1 GB of
data is transferred during one call, but smaller blocks of some kB or
MB or such. Each transfer of some small block is forwarded to the
wrapped "OutputStream" after some rate limiting resources have been
aquired like in the following example:

https://stackoverflow.com/a/6271935/2055163

For that to work, transfers need to be small enough to actually make
subsequent calls to aquire resources wait. One large call with 1 GB of
data would transfer that 1 GB and make calls afterwards wait, which
might never occur because the 1 GB of data already has been
transferred. From what I've seen in the sources of Axis2 and
HTTPComponents, things should get called already with small chunks of
data because of the usage of "DataHandler".

Not sure if there's an easier way, better ideas welcome. :-)

Mit freundlichen Grüßen,

Thorsten Schöning

-- 
Thorsten Schöning       E-Mail: [email protected]
AM-SoFT IT-Systeme      http://www.AM-SoFT.de/

Telefon...........05151-  9468- 55
Fax...............05151-  9468- 88
Mobil..............0178-8 9468- 04

AM-SoFT GmbH IT-Systeme, Brandenburger Str. 7c, 31789 Hameln
AG Hannover HRB 207 694 - Geschäftsführer: Andreas Muchow


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to