Skip to content

Commit

Permalink
Bag for request specific data and its support
Browse files Browse the repository at this point in the history
In order to support aspect related operations such as authentication,
session management etc, we need to carry a bag of arbitrary objects on
the request.

When integrated with Vertx, for instance, developers can assign their
own authentication handler that would set some sort of auth context for
the request, which we will pick up in qbit.
  • Loading branch information
bbyk committed Mar 10, 2016
1 parent 61d23dd commit 3752c0a
Show file tree
Hide file tree
Showing 10 changed files with 141 additions and 14 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Copyright (c) 2015. Rick Hightower, Geoff Chandler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* QBit - The Microservice lib for Java : JSON, WebSocket, REST. Be The Web!
*/

package io.advantageous.qbit.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* Defines a data parameter for mapping service methods to HTTP like calls.
*
* @author Boris Byk
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(value = {ElementType.PARAMETER})
public @interface DataParam {

/** Name of the data param. */
String value();

boolean required() default false;

/** Default value.
* The default value is set to AnnotationConstants.NOT_SET which is used
* to indicate a default value was not set.
* @return default value
*/
String defaultValue() default AnnotationConstants.NOT_SET;


/**
* Used to document endpoint
* @return description
*/
String description() default "no description";


}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import io.advantageous.qbit.util.MultiMap;
import java.nio.charset.StandardCharsets;
import java.util.function.Supplier;
import java.util.Map;


/**
Expand All @@ -33,6 +34,7 @@
*/
public class HttpRequest implements Request<Object> {

private final Map<String, Object> data;
private final String uri;
private final String remoteAddress;
private final MultiMap<String, String> params;
Expand All @@ -51,6 +53,7 @@ public class HttpRequest implements Request<Object> {
public HttpRequest(final long id,
final String uri,
final String method,
final Map<String, Object> data,
final MultiMap<String, String> params,
final MultiMap<String, String> headers,
final Supplier<Object> bodySupplier,
Expand All @@ -60,6 +63,7 @@ public HttpRequest(final long id,
final Supplier<MultiMap<String, String>> formParamsSupplier,
final long timestamp) {

this.data = data;
this.uri = uri;
this.messageId = id;
this.params = params;
Expand Down Expand Up @@ -185,6 +189,10 @@ public String getMethod() {
return method;
}

public Map<String, Object> data() {
return data;
}

public String getUri() {
return uri;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ protected RequestIdGenerator initialValue() {

private HttpResponseReceiver receiver = (code, mimeType, body1) -> {
};
private Map<String, Object> data;

public Supplier<MultiMap<String, String>> getFormParamsSupplier() {
return formParamsSupplier;
Expand Down Expand Up @@ -233,7 +234,7 @@ public HttpRequest buildClientRequest() {
if (contentType != null) {
this.addHeader("Content-Type", contentType);
}
return new HttpRequest(this.getId(), newURI, this.getMethod(), this.getParams(),
return new HttpRequest(this.getId(), newURI, this.getMethod(), this.getData(), this.getParams(),
this.getHeaders(),
this.getBodySupplier(),
this.getRemoteAddress(), this.getContentType(), httpResponse,
Expand All @@ -260,7 +261,7 @@ public HttpRequest build() {
if (contentType != null) {
this.addHeader("Content-Type", contentType);
}
final HttpRequest request = new HttpRequest(this.getId(), newURI, this.getMethod(), this.getParams(),
final HttpRequest request = new HttpRequest(this.getId(), newURI, this.getMethod(), this.getData(), this.getParams(),
this.getHeaders(),
this.getBodySupplier(),
this.getRemoteAddress(), this.getContentType(), httpResponse,
Expand Down Expand Up @@ -437,7 +438,6 @@ public HttpRequestBuilder setFormPostAndCreateFormBody() {
setBodyBytes(paramString.getBytes(StandardCharsets.UTF_8));



return this;
}

Expand Down Expand Up @@ -489,13 +489,12 @@ public HttpRequestBuilder initFormIfNeeded() {
}



return this;
}

/**
*
* Copies the request's body, headers, uri, request params, content type, etc into this builder
*
* @param request request to copy
* @return this
*/
Expand All @@ -506,7 +505,7 @@ public HttpRequestBuilder copyRequest(final HttpRequest request) {

this.setMethod(request.getMethod());

if (request.getHeaders().size()>0) {
if (request.getHeaders().size() > 0) {
if (this.headers == null) {
this.setHeaders(new MultiMapImpl<>());
}
Expand All @@ -516,10 +515,10 @@ public HttpRequestBuilder copyRequest(final HttpRequest request) {
});
}

if (request.getParams().size()>0) {
if (request.getParams().size() > 0) {


if (this.params==null) {
if (this.params == null) {
this.setParams(new MultiMapImpl<>());
}

Expand All @@ -538,6 +537,15 @@ public HttpRequestBuilder copyRequest(final HttpRequest request) {
return this;
}

public HttpRequestBuilder setData(Map<String, Object> data) {
this.data = data;
return this;
}

public Map<String, Object> getData() {
return data;
}

private static class RequestIdGenerator {
private long value;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,9 @@ private Param getParam(final String path, final AnnotationData annotationData, f
case "headerParam":
param = new HeaderParam(required, paramName, defaultValue, description);
break;
case "dataParam":
param = new DataParam(required, paramName, defaultValue, description);
break;
case "pathVariable":

if (!path.contains("{")) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright (c) 2015. Rick Hightower, Geoff Chandler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* QBit - The Microservice lib for Java : JSON, WebSocket, REST. Be The Web!
*/
package io.advantageous.qbit.meta.params;


/**
* Holds meta data about a body where a header represents a single argument to a method.
*/
public class DataParam extends NamedParam {


public DataParam(final boolean required, final String name, Object defaultValue,
final String description) {
super(required, name, defaultValue, ParamType.DATA, description);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public enum ParamType {
BODY,
REQUEST,
HEADER,
DATA,
PATH_BY_NAME,
PATH_BY_POSITION,
BODY_BY_POSITION,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,17 @@ public MethodCall<Object> transform(final HttpRequest request,
}
value = value !=null ? decodeURLEncoding(value.toString()) : value;
break;
case DATA:
namedParam = ((NamedParam) parameterMeta.getParam());
value = request.data().get(namedParam.getName());
if (namedParam.isRequired() && Str.isEmpty(value)) {
errorsList.add(sputs("Unable to find required data param", namedParam.getName()));
break loop;
}
if (value == null) {
value = namedParam.getDefaultValue();
}
break;
case PATH_BY_NAME:
URINamedParam uriNamedParam = ((URINamedParam) parameterMeta.getParam());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
Expand Down Expand Up @@ -309,7 +310,7 @@ private void handleHttpRequest(final HttpServerRequest request) {

private void handleRequestWithNoBody(HttpServerRequest request) {
final HttpRequest getRequest;
getRequest = vertxUtils.createRequest(request, null,
getRequest = vertxUtils.createRequest(request, null, new HashMap<>(),
simpleHttpServer.getDecorators(), simpleHttpServer.getHttpResponseCreator());
simpleHttpServer.handleRequest(getRequest);
}
Expand All @@ -325,7 +326,7 @@ private void handleRequestWithBody(HttpServerRequest request) {
}

request.bodyHandler((Buffer buffer) -> {
final HttpRequest postRequest = vertxUtils.createRequest(request, buffer,
final HttpRequest postRequest = vertxUtils.createRequest(request, buffer, new HashMap<>(),
simpleHttpServer.getDecorators(), simpleHttpServer.getHttpResponseCreator());

simpleHttpServer.handleRequest(postRequest);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
Expand Down Expand Up @@ -137,9 +139,9 @@ public void start() {


if ( route!=null ) {
route.handler(event -> handleHttpRequest(event.request()));
route.handler(event -> handleHttpRequest(event.request(), event.data()));
} else if (router!=null) {
router.route().handler(event -> handleHttpRequest(event.request()));
router.route().handler(event -> handleHttpRequest(event.request(), event.data()));
} else {
httpServer.requestHandler(this::handleHttpRequest);
}
Expand All @@ -156,6 +158,10 @@ public void stop() {


private void handleHttpRequest(final HttpServerRequest request) {
handleHttpRequest(request, new HashMap<>());
}

private void handleHttpRequest(final HttpServerRequest request, final Map<String, Object> data) {


if (debug) {
Expand All @@ -179,7 +185,7 @@ private void handleHttpRequest(final HttpServerRequest request) {
}

request.bodyHandler((Buffer buffer) -> {
final HttpRequest postRequest = vertxUtils.createRequest(request, buffer,
final HttpRequest postRequest = vertxUtils.createRequest(request, buffer, data,
simpleHttpServer.getDecorators(), simpleHttpServer.getHttpResponseCreator());

simpleHttpServer.handleRequest(postRequest);
Expand All @@ -194,7 +200,7 @@ private void handleHttpRequest(final HttpServerRequest request) {
case "DELETE":
case "GET":
final HttpRequest getRequest;
getRequest = vertxUtils.createRequest(request, null,
getRequest = vertxUtils.createRequest(request, null, data,
simpleHttpServer.getDecorators(), simpleHttpServer.getHttpResponseCreator());
simpleHttpServer.handleRequest(getRequest);
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicLong;

Expand All @@ -62,6 +63,7 @@ public void setTime(long time) {

public HttpRequest createRequest(final HttpServerRequest request,
final Buffer buffer,
final Map<String, Object> data,
final CopyOnWriteArrayList<HttpResponseDecorator> decorators,
final HttpResponseCreator httpResponseCreator) {

Expand All @@ -74,6 +76,7 @@ public HttpRequest createRequest(final HttpServerRequest request,
final String requestPath = request.path();

httpRequestBuilder.setId(requestId.incrementAndGet())
.setData(data)
.setUri(requestPath).setMethod(request.method().toString())
.setBodySupplier(() -> buffer == null ?
null : buffer.getBytes())
Expand Down

0 comments on commit 3752c0a

Please sign in to comment.