/*
* This file is part of anycook. The new internet cookbook
* Copyright (C) 2014 Jan Graßegger
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see [http://www.gnu.org/licenses/].
*/
package de.anycook.api;
import de.anycook.api.providers.MessageNumberProvider;
import de.anycook.api.providers.MessageProvider;
import de.anycook.api.providers.MessageSessionProvider;
import de.anycook.api.util.MediaType;
import de.anycook.db.mysql.DBMessage;
import de.anycook.messages.Message;
import de.anycook.messages.MessageSession;
import de.anycook.session.Session;
import de.anycook.user.User;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.sql.SQLException;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.container.AsyncResponse;
import javax.ws.rs.container.Suspended;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.GenericEntity;
import javax.ws.rs.core.Response;
@Path("/message")
public class MessageApi {
private final Logger logger;
@Context
private Session session;
/**
*
*/
public MessageApi() {
logger = LogManager.getLogger(getClass());
}
@GET
@Produces(MediaType.APPLICATION_JSON)
public void get(@Suspended final AsyncResponse asyncResponse,
@QueryParam("lastChange") Long lastChange) {
asyncResponse
.setTimeoutHandler(asyncResponse1 -> asyncResponse1.resume(Response.ok().build()));
asyncResponse.setTimeout(5, TimeUnit.MINUTES);
User user = session.getUser();
if (lastChange == null) {
try {
List<MessageSession> sessions = MessageSession.getSessionsFromUser(user.getId());
GenericEntity<List<MessageSession>> entity =
new GenericEntity<List<MessageSession>>(sessions) { };
asyncResponse.resume(entity);
} catch (SQLException e) {
logger.error(e, e);
asyncResponse
.resume(new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR));
}
return;
}
Date changeDate = new Date(lastChange);
try {
List<MessageSession> sessions =
MessageSession.getSessionsFromUser(user.getId(), changeDate);
GenericEntity<List<MessageSession>> entity =
new GenericEntity<List<MessageSession>>(sessions) {};
if (!sessions.isEmpty()) {
asyncResponse.resume(entity);
} else {
MessageSessionProvider.INSTANCE.suspend(user.getId(), asyncResponse);
}
} catch (SQLException | DBMessage.SessionNotFoundException e) {
logger.error(e, e);
asyncResponse
.resume(new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR));
}
}
@POST
@Consumes(MediaType.APPLICATION_JSON)
public void newMessage(NewMessage message) {
if (message == null) {
throw new WebApplicationException(Response.Status.BAD_REQUEST);
}
try {
int userId = session.getUser().getId();
message.recipients.add(userId);
MessageSession.getSession(message.recipients).newMessage(userId, message.text);
} catch (SQLException | DBMessage.SessionNotFoundException e) {
logger.error(e, e);
throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
}
}
@GET
@Path("number")
@Produces(MediaType.APPLICATION_JSON)
public void getMessageNumber(@Suspended AsyncResponse asyncResponse,
@QueryParam("lastNum") int lastNumber) {
try {
int userId = session.getUser().getId();
int newMessageNum = MessageSession.getNewMessageNum(userId);
if (newMessageNum == lastNumber) {
MessageNumberProvider.INSTANCE.suspend(userId, asyncResponse);
} else {
logger.info("return message num");
asyncResponse.resume(newMessageNum);
}
} catch (SQLException e) {
logger.error(e, e);
asyncResponse
.resume(new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR));
}
}
@GET
@Path("{sessionId}")
@Produces(MediaType.APPLICATION_JSON)
public void getMessagesFromSession(@Suspended AsyncResponse asyncResponse,
@PathParam("sessionId") int sessionId,
@QueryParam("lastId") Integer lastId) {
int userId = session.getUser().getId();
try {
if (lastId == null) {
asyncResponse.resume(MessageSession.getSession(sessionId, userId));
return;
}
MessageSession messageSession = MessageSession.getSession(sessionId, userId, lastId);
if (!messageSession.isEmpty()) {
asyncResponse.resume(messageSession);
} else {
MessageProvider.INSTANCE.suspend(sessionId, userId, asyncResponse);
}
} catch (SQLException e) {
logger.error(e, e);
asyncResponse
.resume(new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR));
} catch (DBMessage.SessionNotFoundException e) {
logger.warn(e, e);
asyncResponse.resume(new WebApplicationException(Response.Status.BAD_REQUEST));
}
}
@POST
@Path("{sessionId}")
@Consumes(MediaType.APPLICATION_JSON)
public void answerSession(@PathParam("sessionId") int sessionId, String message) {
if (message == null) {
logger.info("text was null");
throw new WebApplicationException(400);
}
try {
int userId = session.getUser().getId();
MessageSession.getSession(sessionId, userId).newMessage(userId, message);
} catch (SQLException | DBMessage.SessionNotFoundException e) {
logger.error(e);
throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
}
}
@PUT
@Path("{sessionId}/{messageId}")
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public void readMessage(@PathParam("sessionId") int sessionId,
@PathParam("messageId") int messageId) {
try {
int userId = session.getUser().getId();
Message.read(sessionId, messageId, userId);
MessageNumberProvider.INSTANCE.wakeUpSuspended(userId);
} catch (SQLException e) {
logger.error(e);
throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
}
}
public static class NewMessage {
public List<Integer> recipients;
public String text;
@Override
public String toString() {
return String.format("{recipients : %s, text : %s}", StringUtils.join(recipients, ","),
text);
}
}
}