44import com .codahale .metrics .Metered ;
55import com .codahale .metrics .MetricRegistry ;
66import com .codahale .metrics .Timer ;
7- import com .google .common .base .Strings ;
87import com .google .common .net .HttpHeaders ;
98import com .google .common .net .MediaType ;
109import java .io .File ;
1110import java .io .IOException ;
1211import java .util .Map ;
1312import java .util .stream .Collectors ;
1413
15- import in .erail .common .FrameworkConstants ;
14+ import static in .erail .common .FrameworkConstants . RoutingContext . Json ;
1615import in .erail .glue .annotation .StartService ;
17- import in .erail .glue .component .ServiceArray ;
1816import io .netty .handler .codec .http .HttpHeaderNames ;
1917import io .netty .handler .codec .http .HttpResponseStatus ;
2018import io .vertx .core .eventbus .DeliveryOptions ;
2624import io .vertx .reactivex .ext .web .RoutingContext ;
2725import io .vertx .reactivex .ext .web .api .contract .openapi3 .OpenAPI3RouterFactory ;
2826import in .erail .service .RESTService ;
27+ import io .vertx .core .json .JsonArray ;
28+ import io .vertx .reactivex .core .buffer .Buffer ;
29+ import io .vertx .reactivex .ext .web .Cookie ;
30+ import java .util .Arrays ;
2931import java .util .HashMap ;
32+ import java .util .Iterator ;
33+ import java .util .Optional ;
3034
3135/**
3236 *
@@ -36,7 +40,7 @@ public class OpenAPI3RouteBuilder extends AbstractRouterBuilderImpl {
3640
3741 private static final String AUTHORIZATION_PREFIX = "realm" ;
3842 private static final String FAIL_SUFFIX = ".fail" ;
39- private ServiceArray mServices ;
43+ private RESTService [] mServices ;
4044 private File mOpenAPI3File ;
4145 private DeliveryOptions mDeliveryOptions ;
4246 private boolean mSecurityEnable = true ;
@@ -51,22 +55,20 @@ public void setOpenAPI3File(File pOpenAPI3File) {
5155 this .mOpenAPI3File = pOpenAPI3File ;
5256 }
5357
54- public ServiceArray getServices () {
58+ public RESTService [] getServices () {
5559 return mServices ;
5660 }
5761
58- public void setServices (ServiceArray pServices ) {
62+ public void setServices (RESTService [] pServices ) {
5963 this .mServices = pServices ;
6064 }
6165
6266 @ StartService
6367 public void start () {
6468
65- getServices ()
66- .getServices ()
67- .stream ()
68- .forEach ((api ) -> {
69- RESTService service = (RESTService ) api ;
69+ Arrays
70+ .stream (getServices ())
71+ .forEach ((service ) -> {
7072 getMetrics ()
7173 .put (service .getServiceUniqueId (),
7274 getMetricRegistry ().timer ("api.framework.service." + service .getServiceUniqueId ()));
@@ -103,51 +105,50 @@ public void process(RoutingContext pRequestContext, String pServiceUniqueId) {
103105
104106 }
105107
108+ /**
109+ * In case of post request. Body is sent in binary
110+ *
111+ * @param pContext Routing Context
112+ * @return JsonObject representing RoutingContext
113+ */
106114 public JsonObject serialiseRoutingContext (RoutingContext pContext ) {
107115
108116 JsonObject result = new JsonObject ();
109117
110118 if (pContext .request ().method () == HttpMethod .POST ) {
111- boolean bodyAsJson = pContext .<Boolean >get (FrameworkConstants .RoutingContext .Attribute .BODY_AS_JSON );
112- if (bodyAsJson ) {
113- String mediaTypeHeader = pContext .request ().headers ().get (HttpHeaders .CONTENT_TYPE );
114- MediaType contentType ;
115- if (Strings .isNullOrEmpty (mediaTypeHeader )) {
116- contentType = MediaType .JSON_UTF_8 ;
117- } else {
118- contentType = MediaType .parse (mediaTypeHeader );
119- }
120- if (MediaType .JSON_UTF_8 .type ().equals (contentType .type ()) && MediaType .JSON_UTF_8 .subtype ().equals (contentType .subtype ())) {
121- result .put (FrameworkConstants .RoutingContext .Json .BODY , pContext .getBodyAsJson ());
122- }
123- } else {
124- result .put (FrameworkConstants .RoutingContext .Json .BODY , pContext .getBody ().getDelegate ().getBytes ());
125- }
119+ result .put (Json .BODY , pContext .getBody ().getDelegate ().getBytes ());
126120 } else {
127- result .put (FrameworkConstants . RoutingContext . Json .BODY , new JsonObject () );
121+ result .put (Json .BODY , new byte []{} );
128122 }
129123
130124 JsonObject headers = new JsonObject (convertMultiMapIntoMap (pContext .request ().headers ()));
131- result .put (FrameworkConstants . RoutingContext . Json .HEADERS , headers );
125+ result .put (Json .HEADERS , headers );
132126
133127 JsonObject query = new JsonObject (convertMultiMapIntoMap (pContext .queryParams ()));
134- result .put (FrameworkConstants . RoutingContext . Json .QUERY_STRING_PARAM , query );
128+ result .put (Json .QUERY_STRING_PARAM , query );
135129
136130 JsonObject params = new JsonObject (convertMultiMapIntoMap (pContext .request ().params ()));
137- result .put (FrameworkConstants . RoutingContext . Json .PATH_PARAM , params );
131+ result .put (Json .PATH_PARAM , params );
138132
139133 getLog ().debug (() -> "Context to JSON:" + result .toString ());
140134
141135 return result ;
142136 }
143137
138+ /**
139+ * All response content is written in binary. If Content type is not provided then application/octet-stream content type is set.
140+ *
141+ * @param pReplyResponse Service Body
142+ * @param pContext Routing Context
143+ * @return HttpServerResponse
144+ */
144145 public HttpServerResponse buildResponseFromReply (JsonObject pReplyResponse , RoutingContext pContext ) {
145146
146- JsonObject headers = pReplyResponse .getJsonObject (FrameworkConstants . RoutingContext . Json .HEADERS , new JsonObject ());
147- String statusCode = pReplyResponse .getString (FrameworkConstants . RoutingContext . Json .STATUS_CODE , HttpResponseStatus .OK .codeAsText ().toString ());
147+ JsonObject headers = pReplyResponse .getJsonObject (Json .HEADERS , new JsonObject ());
148+ String statusCode = pReplyResponse .getString (Json .STATUS_CODE , HttpResponseStatus .OK .codeAsText ().toString ());
148149
149150 if (!headers .containsKey (HttpHeaders .CONTENT_TYPE )) {
150- headers .put (HttpHeaders .CONTENT_TYPE , MediaType .JSON_UTF_8 .toString ());
151+ headers .put (HttpHeaders .CONTENT_TYPE , MediaType .OCTET_STREAM .toString ());
151152 }
152153
153154 headers
@@ -159,14 +160,39 @@ public HttpServerResponse buildResponseFromReply(JsonObject pReplyResponse, Rout
159160
160161 pContext .response ().setStatusCode (HttpResponseStatus .parseLine (statusCode ).code ());
161162
162- Object body = pReplyResponse .getMap ().get (FrameworkConstants .RoutingContext .Json .BODY );
163+ Optional <JsonArray > cookies = Optional .ofNullable (pReplyResponse .getJsonArray (Json .COOKIES ));
164+
165+ cookies .ifPresent ((cooky ) -> {
166+ for (Iterator <Object > iterator = cooky .iterator (); iterator .hasNext ();) {
167+ JsonObject next = (JsonObject ) iterator .next ();
168+ Optional cookieName = Optional .ofNullable (next .getString (Json .Cookie .NAME ));
169+ if (cookieName .isPresent ()) {
170+ Cookie c = Cookie .cookie ((String ) cookieName .get (), "" );
171+ Optional .ofNullable (next .getString (Json .Cookie .VALUE )).ifPresent (t -> c .setValue (t ));
172+ Optional .ofNullable (next .getString (Json .Cookie .PATH )).ifPresent (t -> c .setPath (t ));
173+ Optional .ofNullable (next .getDouble (Json .Cookie .MAX_AGE )).ifPresent (t -> c .setMaxAge (t .longValue ()));
174+ Optional .ofNullable (next .getString (Json .Cookie .DOMAIN )).ifPresent (t -> c .setDomain (t ));
175+ Optional .ofNullable (next .getBoolean (Json .Cookie .SECURE )).ifPresent (t -> c .setSecure (t ));
176+ Optional .ofNullable (next .getBoolean (Json .Cookie .HTTP_ONLY )).ifPresent (t -> c .setHttpOnly (t ));
177+ pContext .addCookie (c );
178+ }
179+ }
180+ });
181+
182+ Optional <byte []> body ;
163183
164- if (body != null ) {
165- String bodyStr = body .toString ();
166- pContext .response ().putHeader (HttpHeaderNames .CONTENT_LENGTH .toString (), Integer .toString (bodyStr .length ()));
167- pContext .response ().write (bodyStr );
184+ try {
185+ body = Optional .ofNullable (pReplyResponse .getBinary (Json .BODY ));
186+ } catch (IllegalArgumentException e ) {
187+ getLog ().error (() -> "Could not get message body as binary. Please check if service is sending body in binary." + pContext .request ().absoluteURI () + ":" + e .toString ());
188+ body = Optional .empty ();
168189 }
169190
191+ body .ifPresent ((t ) -> {
192+ pContext .response ().putHeader (HttpHeaderNames .CONTENT_LENGTH .toString (), Integer .toString (t .length ));
193+ pContext .response ().write (Buffer .newInstance (io .vertx .core .buffer .Buffer .buffer (t )));
194+ });
195+
170196 return pContext .response ();
171197 }
172198
@@ -193,35 +219,35 @@ public Router getRouter(Router pRouter) {
193219 .rxCreateRouterFactoryFromFile (getVertx (), getOpenAPI3File ().getAbsolutePath ())
194220 .blockingGet ();
195221
196- getServices ()
197- .getServices ()
198- .forEach (( api ) -> {
199- RESTService service = ( RESTService ) api ;
200-
201- apiFactory . addHandlerByOperationId ( service . getOperationId (), ( routingContext ) -> {
202-
203- routingContext . put ( FrameworkConstants . RoutingContext . Attribute . BODY_AS_JSON , service . isBodyAsJson ());
204-
205- if ( isSecurityEnable ()) {
206-
207- if ( routingContext .user () == null ) {
208- routingContext . fail ( 401 ) ;
209- return ;
210- }
211-
212- routingContext . user (). isAuthorized ( AUTHORIZATION_PREFIX + ":" + service . getOperationId (), ( event ) -> {
213- boolean authSuccess = event . succeeded () ? event . result () : false ;
214- if ( authSuccess ) {
215- process ( routingContext , service . getServiceUniqueId ());
216- } else {
217- routingContext . fail ( 401 );
218- }
219- });
220- } else {
221- getLog (). warn ( "Security disabled for " + service .getServiceUniqueId ());
222- process ( routingContext , service . getServiceUniqueId ());
223- }
224- });
222+ Optional
223+ .ofNullable ( getServices () )
224+ .ifPresent ( t -> {
225+ Arrays
226+ . asList ( t )
227+ . stream ()
228+ . forEach (( service ) -> {
229+ apiFactory . addHandlerByOperationId ( service . getOperationId (), ( routingContext ) -> {
230+ if ( isSecurityEnable ()) {
231+
232+ if ( routingContext . user () == null ) {
233+ routingContext .fail ( 401 );
234+ return ;
235+ }
236+
237+ routingContext . user (). isAuthorized ( AUTHORIZATION_PREFIX + ":" + service . getOperationId (), ( event ) -> {
238+ boolean authSuccess = event . succeeded () ? event . result () : false ;
239+ if ( authSuccess ) {
240+ process ( routingContext , service . getServiceUniqueId ());
241+ } else {
242+ routingContext . fail ( 401 );
243+ }
244+ });
245+ } else {
246+ getLog (). warn ( "Security disabled for " + service . getServiceUniqueId ());
247+ process ( routingContext , service .getServiceUniqueId ());
248+ }
249+ });
250+ });
225251 });
226252
227253 return apiFactory .getRouter ();
0 commit comments