1616
1717package org .cloudfoundry .reactor ;
1818
19+ import org .cloudfoundry .reactor .util .JsonCodec ;
20+ import org .cloudfoundry .reactor .util .Operator ;
21+ import org .cloudfoundry .reactor .util .OperatorContext ;
22+ import org .cloudfoundry .reactor .util .UserAgent ;
1923import org .immutables .value .Value ;
2024import org .springframework .web .util .UriComponents ;
2125import org .springframework .web .util .UriComponentsBuilder ;
26+
27+ import io .netty .handler .codec .http .HttpHeaders ;
2228import reactor .core .publisher .Mono ;
29+ import reactor .netty .http .client .HttpClient ;
2330
2431import java .util .Optional ;
2532import java .util .regex .Matcher ;
@@ -41,19 +48,19 @@ public final void checkForValidApiHost() {
4148 Matcher matcher = HOSTNAME_PATTERN .matcher (getApiHost ());
4249
4350 if (!matcher .matches ()) {
44- throw new IllegalArgumentException (String .format ("API hostname %s is not correctly formatted (e.g. 'api.local.pcfdev.io')" , getApiHost ()));
51+ throw new IllegalArgumentException (String .format ("API hostname %s is not correctly formatted (e.g. 'api.local.pcfdev.io')" ,
52+ getApiHost ()));
4553 }
4654 }
4755
4856 /**
49- * The hostname of the API root. Typically something like {@code api.run.pivotal.io}.
57+ * The hostname of the API root. Typically something like {@code api.run.pivotal.io}.
5058 */
5159 public abstract String getApiHost ();
5260
5361 @ Override
5462 public final Mono <String > getRoot (ConnectionContext connectionContext ) {
55- Mono <String > cached = doGetRoot (connectionContext )
56- .delayUntil (uri -> trust (uri .getHost (), uri .getPort (), connectionContext ))
63+ Mono <String > cached = doGetRoot (connectionContext ).delayUntil (uri -> trust (uri .getHost (), uri .getPort (), connectionContext ))
5764 .map (UriComponents ::toUriString );
5865
5966 return connectionContext .getCacheDuration ()
@@ -63,8 +70,7 @@ public final Mono<String> getRoot(ConnectionContext connectionContext) {
6370
6471 @ Override
6572 public final Mono <String > getRoot (String key , ConnectionContext connectionContext ) {
66- Mono <String > cached = doGetRoot (key , connectionContext )
67- .delayUntil (uri -> trust (uri .getHost (), uri .getPort (), connectionContext ))
73+ Mono <String > cached = doGetRoot (key , connectionContext ).delayUntil (uri -> trust (uri .getHost (), uri .getPort (), connectionContext ))
6874 .map (UriComponents ::toUriString );
6975
7076 return connectionContext .getCacheDuration ()
@@ -77,7 +83,9 @@ public final Mono<String> getRoot(String key, ConnectionContext connectionContex
7783 protected abstract Mono <UriComponents > doGetRoot (String key , ConnectionContext connectionContext );
7884
7985 protected final UriComponents getRoot () {
80- UriComponentsBuilder builder = UriComponentsBuilder .newInstance ().scheme ("https" ).host (getApiHost ());
86+ UriComponentsBuilder builder = UriComponentsBuilder .newInstance ()
87+ .scheme ("https" )
88+ .host (getApiHost ());
8189 getPort ().ifPresent (builder ::port );
8290
8391 return normalize (builder );
@@ -92,7 +100,8 @@ protected final UriComponents normalize(UriComponentsBuilder builder) {
92100 builder .port (getPort ().orElse (DEFAULT_PORT ));
93101 }
94102
95- return builder .build ().encode ();
103+ return builder .build ()
104+ .encode ();
96105 }
97106
98107 /**
@@ -101,7 +110,7 @@ protected final UriComponents normalize(UriComponentsBuilder builder) {
101110 abstract Optional <Integer > getPort ();
102111
103112 /**
104- * Whether the connection to the root API should be secure (i.e. using HTTPS). Defaults to {@code true}.
113+ * Whether the connection to the root API should be secure (i.e. using HTTPS). Defaults to {@code true}.
105114 */
106115 abstract Optional <Boolean > getSecure ();
107116
@@ -117,4 +126,16 @@ private Mono<Void> trust(String host, int port, ConnectionContext connectionCont
117126 return connectionContext .trust (host , port );
118127 }
119128
129+ public Mono <Operator > createOperator (ConnectionContext connectionContext ) {
130+ HttpClient httpClient = connectionContext .getHttpClient ();
131+ return getRoot (connectionContext ).map (root -> OperatorContext .of (connectionContext , root ))
132+ .map (operatorContext -> new Operator (operatorContext , httpClient ))
133+ .map (operator -> operator .headers (this ::addHeaders ));
134+ }
135+
136+ private void addHeaders (HttpHeaders httpHeaders ) {
137+ UserAgent .setUserAgent (httpHeaders );
138+ JsonCodec .setDecodeHeaders (httpHeaders );
139+ }
140+
120141}
0 commit comments