Updating the TODO app for 1.0.0.Final
by Jay Balunas
Hi All,
I've mentioned this to one or two of you but I wanted to have a wider discussion. We need a showcase application for 1.0.0.Final, something we can point people to and show off at presentations We don't have time to create a whole new example. So...
I propose we review the existing TODO app and estimate the work required to get it updated to support paging, and the latest security updates. We should also discuss if it makes sense to move this to use the controller for the backend, or even have one with and one without the controller.
Lets discuss this at next weeks team meeting because one way or another I think we need a complete demo ;-)
-Jay
11 years, 1 month
[ag-controller] PaginationStrategy
by Daniel Bevenius
For AEROGEAR-863 "Make PagingStrategy pluggable" the following suggestion
is being proposed:
Custom PaginationStrategy
This section describes how a custom pagination strategy can be implemented
in AeroGear Controller.
Depending on if you need a completely different strategy, or if you simply
want to change/add/rename the returned HTTP response headers, you have two
options:
- Extend AbstractPaginationStrategy
- Implement PaginationStrategy
<https://gist.github.com/danbev/ed51e57e9a1f718f1848#extend-abstractpagina...>Extend
AbstractPaginationStrategy
You would extend AbstractPaginationStrategy if you simply want to
change/add/rename the returned HTTP response headers.
<https://gist.github.com/danbev/ed51e57e9a1f718f1848#example-of-extending-...>Example
of extending AbstractPaginationStrategy:
public class MyStrategy extends AbstractPaginationStrategy {
@Override
public void setResponseHeaders(PaginationMetadata md,
HttpServletResponse response,
int resultSize) {
for (Entry<String, String> entry :
md.getHeaders(resultSize).entrySet()) {
response.setHeader(entry.getKey(), entry.getValue());
}
}
}
This implementation actually does exactly what the default implementation
does. But you can of course modify this to suite your own requirements. You
have access to all the
metadata<http://aerogear.org/docs/specs/aerogear-controller/org/jboss/aerogear/con...>
for
the pagination, like the raw
links<http://aerogear.org/docs/specs/aerogear-controller/org/jboss/aerogear/con...>
etc,
so you could assemble headers in any way you see fit.
<https://gist.github.com/danbev/ed51e57e9a1f718f1848#implement-paginations...>Implement
PaginationStrategy
This will give you more control over the pagination strategy. The interface
you have to implement looks like this:
/** * A strategy for implementing pagination in AeroGear Controller.
*/public interface PaginationStrategy {
/** * Creates a PaginationInfo instance. * How this
information is gathered, be it from an Annotation on the target *
endpoint method, or by using separate request parameters is up to the
* concrete implementation. * * @param routeContext the
{@link RouteContext} of the route being processed. * @param
arguments the extracted arguments from the current request. *
@return {@link PaginationInfo} the information requred for paging.
*/
PaginationInfo createPaginationInfo(RouteContext routeContext,
Map<String, Object> arguments);
/** * Called before the target endpoint method has been
invoked and enables a * concrete strategy to manipulate the
arguments that will be passed to * the target endpoint method.
* * @param pagingInfo the {@link PaginationInfo} instance
created by * this strategy. * @param arguments the extracted
arguments from the current request. * * @return {@code
Object[]} the arguments that will be passed to the target *
endpoint method. */
Object[] preInvocation(PaginationInfo pagingInfo, Map<String,
Object> arguments);
/** * Called after the target endpoint method has been invoked
and * allows the strategy to set HTTP Response headers. *
* @param result the result returned from the target endpoint
method. * @param routeContext the {@link RouteContext}. *
@param pagingInfo the {@link PaginationInfo} instance created by this
strategy. * * @return {@code Object} Either the unchanged
result or a modified result * depending on the underlying
implementation. */
Object postInvocation(Object result,
RouteContext routeContext,
PaginationInfo pagingInfo);
}
The createPaginationInfo method is called by AeroGear Controller prior to
invoking the target endpoint method. The arguments extracted from the
current request are made available to this method. The implementation can
choose whatever way it likes to match information from the request that are
related to pagination. This could be using an annotation on the target
endpoint method (which is what the default implementation does) or it could
simply pick known parameters from the request.
The preInvocation methods gives the strategy a chance to modify the actual
arguments that will be used to invoke the target endpoint method. Depending
on the concrete implementation there might not be anything to be done here
other than simply returning the value of the arguments map. But, for
example with the default strategy, an endpoint has the option to accept a
PaginationInfo type a parameter. In this case we have to add this instance
to the arguments before calling the endpoint.
The postInvocation method is called after the target endpoint method has
been invoked allows the strategy to set the HTTP Response headers. This
method has access to the results of the invocation which is can use to
decide on what links should be returned, for example one might not want to
return a previous next link header if there is no more data (the number of
items in the results is less than the limit).
<https://gist.github.com/danbev/ed51e57e9a1f718f1848#configuring-the-strat...>Configuring
the Strategy to be used
Configuration is done by adding a CDI Producer, for example:
public class PaginationStrategyProducer {
@Produces
public PaginationStrategy createPagingStrategy() {
return new AbstractPaginationStrategy() {
@Override
public void setResponseHeaders(PaginationMetadata md,
HttpServletResponse response,
int resultSize) {
Set<Entry<String, String>> hds =
md.getHeaders(resultSize).entrySet();
for (Entry<String, String> header : hds) {
response.setHeader(header.getKey(), header.getValue());
}
}
};
}
}
11 years, 1 month
AeroGear Controller, Security…(SoC), oh my
by Bruno Oliveira
Good morning slackers.
Today I was chatting with Dan about some cross-cutting concerns like CORS, XSS mitigation, HSTS, CSP. They have something related with security, but is not because it has "security" into the specification, that it MUST be inside AG-sec.
They're cross-cutting concerns and I'd like to have it in a single place to be used as dependency. So what are the alternatives?
1- Put it inside AG-Controller and AG sec will be just the bridge to providers like PicketLink
2- Put it inside AG-Sec and decoupled from AG-Controller, if you want to add security on AG-Controller based apps, you just include AG-Sec as dependency
3- And Matthias suggested the creation of ag-controller plugins.
So…...what do you think?
--
"The measure of a man is what he does with power" - Plato
-
@abstractj
-
Volenti Nihil Difficile
--
"The measure of a man is what he does with power" - Plato
-
@abstractj
-
Volenti Nihil Difficile
11 years, 2 months
AeroGear Controller, Security & PicketLink 1.0.0.CR1-20022013-SNAPSHOT released!
by Bruno Oliveira
Good morning slackers!
I was holding this release and waiting for the latest stable release from PicketLink, it happened today (http://lists.jboss.org/pipermail/security-dev/2013-February/000831.html). Special thanks to the #picketlink team, which has been working hard and helping us.
What has changed?
- aerogear-security-picketbox is now aerogear-security-picketlink most of the dependencies on PicketBox were removed. Shane did several improvements on PicketLink.
What's next?
- HTTP Basic/Digest authentication
Feedback? File @jiras, it makes me happy
--
"The measure of a man is what he does with power" - Plato
-
@abstractj
-
Volenti Nihil Difficile
11 years, 2 months
[ag-controller] Simplifying Route testing
by Daniel Bevenius
Simplifying Route testing
For AEROGEAR-778 <https://issues.jboss.org/browse/AEROGEAR-778> we have
been looking into making it easier to test routes. We have been using
Mockito which works nicely, but there was a bit of duplicated code spread
across different tests and also the test were not that easy to read.
Below are examples of one of the tests before and after, hopefully the
after will be easier to read.
Before
@Test
public void testRestRouteWithPathParam() throws Exception {
final RoutingModule routingModule = new AbstractRoutingModule() {
@Override
public void configuration() {
route()
.from("/car/{id}").roles("admin")
.on(GET)
.produces(mockJsp(), mockJson())
.to(SampleController.class).find(param("id"));
}
};
final Routes routes = routingModule.build();
when(request.getMethod()).thenReturn(RequestMethod.GET.toString());
when(request.getServletContext()).thenReturn(servletContext);
when(servletContext.getContextPath()).thenReturn("/abc");
when(request.getRequestURI()).thenReturn("/abc/car/3");
when(request.getHeader("Accept")).thenReturn("application/json");
when(jsonResponder.accepts("application/json")).thenReturn(true);
when(jsonResponder.mediaType()).thenReturn(mockJson());
final Route route = routes.routeFor(GET, "/car/{id}",
acceptHeaders(JSON.getMediaType()));
router.process(new RouteContext(route, request, response, routes));
verify(jsonResponder).respond(anyObject(), any(RouteContext.class));
}
<https://gist.github.com/danbev/4983976#after>After
@Test
public void testRestRouteWithPathParam() throws Exception {
final RouteTester routeTester = RouteTester.from(new
AbstractRoutingModule() {
@Override
public void configuration() {
route()
.from("/car/{id}").roles("admin")
.on(GET)
.produces(JSP, JSON)
.to(SampleController.class).find(param("id"));
}
});
routeTester.acceptHeader(JSON).processGetRequest("/car/3");
verify(routeTester.<SampleController>getController()).find("3");
verify(routeTester.jsonResponder()).respond(any(),
any(RouteContext.class));
}
11 years, 2 months
"cancel" method on Pipe
by Summers Pittman
We have three JIRA's[1] to add a cancel method to Pipe.
In Android (and presumably iOS and to a lesser extent JS) Pipes are
shared among multiple threads and each request exists in its own scope.
(IE multiple threads can have multiple requests running at one time).
When a "cancel" is called, which request is cancelled?
I've attempted to address this (and some larger issues) here:
https://github.com/aerogear/aerogear.org/blob/pipe_spec/docs/specs/aeroge...
Summers
1: (898,901,895)
11 years, 2 months