Skip to content

Commit e2caa20

Browse files
committed
Merge branch 'develop'
2 parents a8d9f8b + e3f4ea3 commit e2caa20

File tree

15 files changed

+263
-191
lines changed

15 files changed

+263
-191
lines changed

config-layers/test/in/erail/service/BinaryBodyService.properties

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,3 @@ serviceUniqueId=API_V1_BROADCAST_V2_SERVICE
66
vertx=/io/vertx/core/Vertx
77
enable=true
88
log=true
9-
bodyAsJson=false

pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<modelVersion>4.0.0</modelVersion>
55
<groupId>in.erail</groupId>
66
<artifactId>api-framework</artifactId>
7-
<version>2.1</version>
7+
<version>2.2-SNAPSHOT</version>
88
<packaging>jar</packaging>
99
<developers>
1010
<developer>
@@ -177,7 +177,7 @@
177177
<dependency>
178178
<groupId>in.erail</groupId>
179179
<artifactId>glue</artifactId>
180-
<version>2.1</version>
180+
<version>2.2</version>
181181
</dependency>
182182
<dependency>
183183
<groupId>org.mockito</groupId>

src/main/java/in/erail/common/FrameworkConstants.java

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,26 @@ public static class RoutingContext {
1515

1616
public static class Json {
1717

18+
public static final String COOKIES = "cookies";
19+
20+
public static class Cookie {
21+
22+
public static final String NAME = "name";
23+
public static final String VALUE = "value";
24+
public static final String HTTP_ONLY = "httpOnly";
25+
public static final String SECURE = "secure";
26+
public static final String PATH = "path";
27+
public static final String MAX_AGE = "maxAge";
28+
public static final String DOMAIN = "domain";
29+
}
30+
1831
public static final String HEADERS = "headers";
1932
public static final String PATH_PARAM = "pathParameters";
2033
public static final String QUERY_STRING_PARAM = "queryStringParameters";
2134
public static final String BODY = "body";
2235
public static final String STATUS_CODE = "statusCode";
2336
public static final String IS_BASE64_ENCODED = "isBase64Encoded";
2437
}
25-
26-
public static class Attribute {
27-
28-
public static final String BODY_AS_JSON = "bodyAsJson";
29-
}
3038
}
3139

3240
public static class SockJS {

src/main/java/in/erail/route/OpenAPI3RouteBuilder.java

Lines changed: 93 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,15 @@
44
import com.codahale.metrics.Metered;
55
import com.codahale.metrics.MetricRegistry;
66
import com.codahale.metrics.Timer;
7-
import com.google.common.base.Strings;
87
import com.google.common.net.HttpHeaders;
98
import com.google.common.net.MediaType;
109
import java.io.File;
1110
import java.io.IOException;
1211
import java.util.Map;
1312
import java.util.stream.Collectors;
1413

15-
import in.erail.common.FrameworkConstants;
14+
import static in.erail.common.FrameworkConstants.RoutingContext.Json;
1615
import in.erail.glue.annotation.StartService;
17-
import in.erail.glue.component.ServiceArray;
1816
import io.netty.handler.codec.http.HttpHeaderNames;
1917
import io.netty.handler.codec.http.HttpResponseStatus;
2018
import io.vertx.core.eventbus.DeliveryOptions;
@@ -26,7 +24,13 @@
2624
import io.vertx.reactivex.ext.web.RoutingContext;
2725
import io.vertx.reactivex.ext.web.api.contract.openapi3.OpenAPI3RouterFactory;
2826
import 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;
2931
import 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();

src/main/java/in/erail/route/SessionRouteBuillder.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
public class SessionRouteBuillder extends AbstractRouterBuilderImpl {
1515

1616
private SessionStore mSessionStore;
17+
private boolean mEnableSession = false;
1718

1819
public SessionStore getSessionStore() {
1920
return mSessionStore;
@@ -28,8 +29,18 @@ public Router getRouter(Router pRouter) {
2829
Route route = pRouter.route();
2930
route.handler(BodyHandler.create());
3031
route.handler(CookieHandler.create());
31-
route.handler(SessionHandler.create(getSessionStore()));
32+
if (isEnableSession()) {
33+
route.handler(SessionHandler.create(getSessionStore()));
34+
}
3235
return pRouter;
3336
}
3437

38+
public boolean isEnableSession() {
39+
return mEnableSession;
40+
}
41+
42+
public void setEnableSession(boolean pEnableSession) {
43+
this.mEnableSession = pEnableSession;
44+
}
45+
3546
}

src/main/java/in/erail/server/Server.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ public class Server {
2525
private Logger mLog;
2626
private SockJSHandler mSockJSHandler;
2727
private HttpServerOptions mHttpServerOptions;
28+
private HttpServer mHttpServer;
2829

2930
@StartService
3031
public void start() {
@@ -46,7 +47,7 @@ public void start() {
4647
router.mountSubRouter(mMountPath[i], mRouter[i]);
4748
}
4849

49-
server
50+
mHttpServer = server
5051
.requestHandler(router::accept)
5152
.rxListen()
5253
.blockingGet();
@@ -106,4 +107,12 @@ public void setHttpServerOptions(HttpServerOptions pHttpServerOptions) {
106107
this.mHttpServerOptions = pHttpServerOptions;
107108
}
108109

110+
public HttpServer getHttpServer() {
111+
return mHttpServer;
112+
}
113+
114+
public void setHttpServer(HttpServer pHttpServer) {
115+
this.mHttpServer = pHttpServer;
116+
}
117+
109118
}

src/main/java/in/erail/service/RESTService.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,5 @@
1111
public interface RESTService {
1212
String getOperationId();
1313
String getServiceUniqueId();
14-
boolean isBodyAsJson();
1514
void process(Message<JsonObject> pMessage);
1615
}

0 commit comments

Comments
 (0)