Skip to content

Commit

Permalink
JAMES-1648 Method can return a response Stream. Contributed by Baechl…
Browse files Browse the repository at this point in the history
…er <matthieu.baechler@gmail.com>

git-svn-id: https://svn.apache.org/repos/asf/james/project/trunk@1724384 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information
Antoine Duprat committed Jan 13, 2016
1 parent c1cffc5 commit 32b44b0
Show file tree
Hide file tree
Showing 13 changed files with 320 additions and 173 deletions.
Expand Up @@ -63,7 +63,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws S
requestAsJsonStream(req)
.map(ProtocolRequest::deserialize)
.map(x -> AuthenticatedProtocolRequest.decorate(x, req))
.map(requestHandler::handle)
.flatMap(requestHandler::handle)
.map(ProtocolResponse::asProtocolSpecification)
.collect(Collectors.toList());

Expand Down
Expand Up @@ -20,9 +20,11 @@
package org.apache.james.jmap.methods;

import java.util.Optional;
import java.util.stream.Stream;

import javax.inject.Inject;

import org.apache.james.jmap.model.ClientId;
import org.apache.james.jmap.model.GetMailboxesRequest;
import org.apache.james.jmap.model.GetMailboxesResponse;
import org.apache.james.jmap.model.mailbox.Mailbox;
Expand Down Expand Up @@ -64,36 +66,32 @@ public Method.Request.Name requestHandled() {
return METHOD_NAME;
}

@Override
public Method.Response.Name responseName() {
return RESPONSE_NAME;
}

@Override
public Class<? extends JmapRequest> requestType() {
return GetMailboxesRequest.class;
}

@Override
public GetMailboxesResponse process(JmapRequest request, MailboxSession mailboxSession) {

public Stream<JmapResponse> process(JmapRequest request, ClientId clientId, MailboxSession mailboxSession) {
Preconditions.checkArgument(request instanceof GetMailboxesRequest);
return Stream.of(
JmapResponse.builder().clientId(clientId)
.response(getMailboxesResponse(mailboxSession))
.responseName(RESPONSE_NAME)
.build());
}

private GetMailboxesResponse getMailboxesResponse(MailboxSession mailboxSession) {
GetMailboxesResponse.Builder builder = GetMailboxesResponse.builder();
try {
return getMailboxesResponse(mailboxSession);
mailboxManager.list(mailboxSession)
.stream()
.map(mailboxPath -> mailboxFromMailboxPath(mailboxPath, mailboxSession))
.forEach(mailbox -> builder.add(mailbox.get()));
return builder.build();
} catch (MailboxException e) {
throw Throwables.propagate(e);
}
}

private GetMailboxesResponse getMailboxesResponse(MailboxSession mailboxSession) throws MailboxException {
GetMailboxesResponse.Builder builder = GetMailboxesResponse.builder();

mailboxManager.list(mailboxSession)
.stream()
.map(mailboxPath -> mailboxFromMailboxPath(mailboxPath, mailboxSession))
.forEach(mailbox -> builder.add(mailbox.get()));

return builder.build();
}

private Optional<Mailbox> mailboxFromMailboxPath(MailboxPath mailboxPath, MailboxSession mailboxSession) {
try {
Expand Down
Expand Up @@ -28,6 +28,7 @@
import javax.inject.Inject;
import javax.inject.Named;

import org.apache.james.jmap.model.ClientId;
import org.apache.james.jmap.model.FilterCondition;
import org.apache.james.jmap.model.GetMessageListRequest;
import org.apache.james.jmap.model.GetMessageListResponse;
Expand Down Expand Up @@ -83,39 +84,38 @@ public Method.Request.Name requestHandled() {
return METHOD_NAME;
}

@Override
public Method.Response.Name responseName() {
return RESPONSE_NAME;
}

@Override
public Class<? extends JmapRequest> requestType() {
return GetMessageListRequest.class;
}

@Override
public GetMessageListResponse process(JmapRequest request, MailboxSession mailboxSession) {
public Stream<JmapResponse> process(JmapRequest request, ClientId clientId, MailboxSession mailboxSession) {
Preconditions.checkArgument(request instanceof GetMessageListRequest);
try {
return getMessageListResponse((GetMessageListRequest) request, mailboxSession);
} catch (MailboxException e) {
throw Throwables.propagate(e);
}
return Stream.of(
JmapResponse.builder().clientId(clientId)
.response(getMessageListResponse((GetMessageListRequest) request, mailboxSession))
.responseName(RESPONSE_NAME)
.build());
}

private GetMessageListResponse getMessageListResponse(GetMessageListRequest jmapRequest, MailboxSession mailboxSession) throws MailboxException {
private GetMessageListResponse getMessageListResponse(GetMessageListRequest jmapRequest, MailboxSession mailboxSession) {
GetMessageListResponse.Builder builder = GetMessageListResponse.builder();
try {

mailboxManager.list(mailboxSession)
.stream()
.filter(mailboxPath -> isMailboxRequested(jmapRequest, mailboxPath))
.flatMap(mailboxPath -> listMessages(mailboxPath, mailboxSession, jmapRequest))
.skip(jmapRequest.getPosition())
.limit(limit(jmapRequest.getLimit()))
.map(MessageId::serialize)
.forEach(builder::messageId);

return builder.build();
mailboxManager.list(mailboxSession)
.stream()
.filter(mailboxPath -> isMailboxRequested(jmapRequest, mailboxPath))
.flatMap(mailboxPath -> listMessages(mailboxPath, mailboxSession, jmapRequest))
.skip(jmapRequest.getPosition())
.limit(limit(jmapRequest.getLimit()))
.map(MessageId::serialize)
.forEach(builder::messageId);

return builder.build();
} catch (MailboxException e) {
throw Throwables.propagate(e);
}
}

private Stream<MessageId> listMessages(MailboxPath mailboxPath, MailboxSession mailboxSession, GetMessageListRequest jmapRequest) {
Expand Down
Expand Up @@ -29,6 +29,7 @@
import javax.inject.Inject;

import org.apache.commons.lang.NotImplementedException;
import org.apache.james.jmap.model.ClientId;
import org.apache.james.jmap.model.GetMessagesRequest;
import org.apache.james.jmap.model.GetMessagesResponse;
import org.apache.james.jmap.model.Message;
Expand Down Expand Up @@ -69,22 +70,24 @@ public Method.Request.Name requestHandled() {
return METHOD_NAME;
}

@Override
public Method.Response.Name responseName() {
return RESPONSE_NAME;
}

@Override
public Class<? extends JmapRequest> requestType() {
return GetMessagesRequest.class;
}

@Override
public GetMessagesResponse process(JmapRequest request, MailboxSession mailboxSession) {
public Stream<JmapResponse> process(JmapRequest request, ClientId clientId, MailboxSession mailboxSession) {
Preconditions.checkNotNull(request);
Preconditions.checkNotNull(mailboxSession);
Preconditions.checkArgument(request instanceof GetMessagesRequest);
GetMessagesRequest getMessagesRequest = (GetMessagesRequest) request;
return Stream.of(JmapResponse.builder().clientId(clientId)
.response(getMessagesResponse(mailboxSession, getMessagesRequest))
.responseName(RESPONSE_NAME)
.build());
}

private GetMessagesResponse getMessagesResponse(MailboxSession mailboxSession, GetMessagesRequest getMessagesRequest) {
getMessagesRequest.getAccountId().ifPresent(GetMessagesMethod::notImplemented);

Function<MessageId, Stream<Pair<MailboxMessage<Id>, MailboxPath>>> loadMessages = loadMessage(mailboxSession);
Expand Down
Expand Up @@ -21,8 +21,10 @@

import org.apache.james.jmap.model.ProtocolResponse;

import java.util.stream.Stream;

public interface JmapResponseWriter {

ProtocolResponse formatMethodResponse(JmapResponse jmapResponse);
Stream<ProtocolResponse> formatMethodResponse(Stream<JmapResponse> jmapResponse);

}
Expand Up @@ -21,6 +21,7 @@

import java.util.Optional;
import java.util.Set;
import java.util.stream.Stream;

import javax.inject.Inject;

Expand All @@ -44,13 +45,15 @@ public JmapResponseWriterImpl(Set<Module> jacksonModules) {
}

@Override
public ProtocolResponse formatMethodResponse(JmapResponse jmapResponse) {
ObjectMapper objectMapper = newConfiguredObjectMapper(jmapResponse);

return new ProtocolResponse(
jmapResponse.getResponseName(),
objectMapper.valueToTree(jmapResponse.getResponse()),
jmapResponse.getClientId());
public Stream<ProtocolResponse> formatMethodResponse(Stream<JmapResponse> jmapResponses) {
return jmapResponses.map(jmapResponse -> {
ObjectMapper objectMapper = newConfiguredObjectMapper(jmapResponse);

return new ProtocolResponse(
jmapResponse.getResponseName(),
objectMapper.valueToTree(jmapResponse.getResponse()),
jmapResponse.getClientId());
});
}

private FilterProvider buildPropertiesFilter(Optional<Set<String>> properties) {
Expand Down
Expand Up @@ -22,7 +22,9 @@
import static com.google.common.base.Objects.toStringHelper;

import java.util.Objects;
import java.util.stream.Stream;

import org.apache.james.jmap.model.ClientId;
import org.apache.james.mailbox.MailboxSession;

import com.fasterxml.jackson.annotation.JsonValue;
Expand Down Expand Up @@ -118,10 +120,8 @@ public String toString() {

Request.Name requestHandled();

Response.Name responseName();

Class<? extends JmapRequest> requestType();

Response process(JmapRequest request, MailboxSession mailboxSession);
Stream<JmapResponse> process(JmapRequest request, ClientId clientId, MailboxSession mailboxSession);

}
Expand Up @@ -25,11 +25,11 @@
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import javax.inject.Inject;

import org.apache.commons.lang.NotImplementedException;
import org.apache.james.jmap.methods.JmapResponse.Builder;
import org.apache.james.jmap.model.AuthenticatedProtocolRequest;
import org.apache.james.jmap.model.ProtocolResponse;
import org.apache.james.mailbox.MailboxSession;
Expand All @@ -48,32 +48,31 @@ public RequestHandler(Set<Method> methods, JmapRequestParser jmapRequestParser,
.collect(Collectors.toMap(Method::requestHandled, Function.identity()));
}

public ProtocolResponse handle(AuthenticatedProtocolRequest request) {
Builder responseBuilder = JmapResponse.builder().clientId(request.getClientId());
public Stream<ProtocolResponse> handle(AuthenticatedProtocolRequest request) {
return Optional.ofNullable(methods.get(request.getMethodName()))
.map(extractAndProcess(request, responseBuilder))
.map(extractAndProcess(request))
.map(jmapResponseWriter::formatMethodResponse)
.orElseThrow(() -> new IllegalStateException("unknown method"));
}

private Function<Method, JmapResponse> extractAndProcess(AuthenticatedProtocolRequest request, JmapResponse.Builder responseBuilder) {
private Function<Method, Stream<JmapResponse>> extractAndProcess(AuthenticatedProtocolRequest request) {
MailboxSession mailboxSession = request.getMailboxSession();
return (Method method) -> {
try {
JmapRequest jmapRequest = jmapRequestParser.extractJmapRequest(request, method.requestType());
return responseBuilder
.response(method.process(jmapRequest, mailboxSession))
.responseName(method.responseName())
.build();
return method.process(jmapRequest, request.getClientId(), mailboxSession);
} catch (IOException e) {
if (e.getCause() instanceof NotImplementedException) {
return responseBuilder.error("Not yet implemented").build();
return error(request, "Not yet implemented");
}
return responseBuilder.error("invalidArguments").build();
return error(request, "invalidArguments");
} catch (NotImplementedException e) {
return responseBuilder.error("Not yet implemented").build();
return error(request, "Not yet implemented");
}
};

}

private Stream<JmapResponse> error(AuthenticatedProtocolRequest request, String message) {
return Stream.of(JmapResponse.builder().clientId(request.getClientId()).error(message).build());
}
}
Expand Up @@ -44,6 +44,8 @@
import com.jayway.restassured.RestAssured;
import com.jayway.restassured.http.ContentType;

import java.util.stream.Stream;

public class JMAPServletTest {

private JettyHttpServer server;
Expand Down Expand Up @@ -92,7 +94,7 @@ public void mustReturnInvalidArgumentOnInvalidState() {
json.put("type", "invalidArgument");

when(requestHandler.handle(any()))
.thenReturn(new ProtocolResponse(JmapResponse.ERROR_METHOD, json, ClientId.of("#0")));
.thenReturn(Stream.of(new ProtocolResponse(JmapResponse.ERROR_METHOD, json, ClientId.of("#0"))));

given()
.accept(ContentType.JSON)
Expand All @@ -116,7 +118,7 @@ public void mustReturnAccountsOnValidRequest() {
arrayNode.add(list);

when(requestHandler.handle(any()))
.thenReturn(new ProtocolResponse(Method.Response.name("accounts"), json, ClientId.of("#0")));
.thenReturn(Stream.of(new ProtocolResponse(Method.Response.name("accounts"), json, ClientId.of("#0"))));

given()
.accept(ContentType.JSON)
Expand All @@ -136,5 +138,4 @@ public void mustReturnAccountsOnValidRequest() {
"]" +
"},\"#0\"]]"));
}

}

0 comments on commit 32b44b0

Please sign in to comment.