fi.evolver.basics.spring.messaging.MessageController Maven / Gradle / Ivy
package fi.evolver.basics.spring.messaging;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.zip.GZIPInputStream;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springdoc.api.annotations.ParameterObject;
import org.springdoc.core.converters.models.PageableAsQueryParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.web.PageableDefault;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import fi.evolver.basics.spring.common.ConfigurationRepository;
import fi.evolver.basics.spring.http.MessageType;
import fi.evolver.basics.spring.http.exception.HttpBadRequestException;
import fi.evolver.basics.spring.http.exception.HttpInternalServerErrorException;
import fi.evolver.basics.spring.http.exception.HttpNotFoundException;
import fi.evolver.basics.spring.log.LogPolicy;
import fi.evolver.basics.spring.log.LogPolicy.Policy;
import fi.evolver.basics.spring.messaging.entity.Message;
import fi.evolver.basics.spring.messaging.entity.Message.MessageState;
import fi.evolver.basics.spring.messaging.entity.MessageLite;
import fi.evolver.basics.spring.messaging.model.MessageQuery;
import fi.evolver.utils.format.FormatUtils;
import fi.evolver.utils.format.PrettyPrintUtils;
import fi.evolver.utils.format.PrettyPrintUtils.Format;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import jakarta.servlet.http.HttpServletResponse;
@RestController
@RequestMapping("/message")
public class MessageController {
private final ConfigurationRepository configurationRepository;
private final MessageLiteRepository messageLiteRepository;
private final MessageRepository messageRepository;
@Autowired
public MessageController(MessageLiteRepository messageLiteRepository, MessageRepository messageRepository, ConfigurationRepository configurationRepository) {
this.messageLiteRepository = messageLiteRepository;
this.messageRepository = messageRepository;
this.configurationRepository = configurationRepository;
}
@Operation(summary = "Fetch a page of messages")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "A page of messages"),
@ApiResponse(responseCode = "400", description = "Invalid request parameters", content = @Content),
@ApiResponse(responseCode = "500", description = "Internal server error", content = @Content)
})
@PageableAsQueryParam
@GetMapping
@LogPolicy(Policy.NONE)
public Page list(
@ParameterObject MessageQuery parameters,
@ParameterObject @PageableDefault(size = 100, direction = Direction.DESC, sort = "creationTime") Pageable page) {
return messageLiteRepository.search(parameters, page);
}
@Operation(summary = "Fetch a single entity by id")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "The requested message"),
@ApiResponse(responseCode = "404", description = "The message was not found", content = @Content),
@ApiResponse(responseCode = "500", description = "Internal server error", content = @Content)
})
@GetMapping("/{id}")
@LogPolicy(Policy.NONE)
public MessageLite show(@PathVariable long id) {
return messageLiteRepository.findById(id).orElseThrow(HttpNotFoundException::new);
}
@Operation(summary = "Mark a message ready for sending")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Message marked ready for sending"),
@ApiResponse(responseCode = "404", description = "The message was not found", content = @Content),
@ApiResponse(responseCode = "500", description = "Internal server error")
})
@PostMapping("/{id}/resend")
@MessageType("Message/resend")
@ResponseStatus(value = HttpStatus.NO_CONTENT)
public void resendMessage(@PathVariable long id) {
MessageLite message = messageLiteRepository.findById(id).orElseThrow(HttpNotFoundException::new);
message.setState(MessageState.PENDING);
messageLiteRepository.saveAndFlush(message);
}
@Operation(summary = "Mark messages ready for sending")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Messages marked ready for sending", content = @Content),
@ApiResponse(responseCode = "400", description = "Invalid request parameters", content = @Content),
@ApiResponse(responseCode = "500", description = "Internal server error", content = @Content)
})
@PostMapping("/resend")
@MessageType("Message/resend")
@ResponseStatus(value = HttpStatus.NO_CONTENT)
public int resendMessages(@ParameterObject MessageQuery parameters) {
List messages = messageLiteRepository.search(parameters);
if (!messages.isEmpty()) {
Integer maxCount = configurationRepository.getInteger("MessageResendMaxCount").orElse(1000);
if (messages.size() > maxCount)
throw new HttpBadRequestException("Too many messages (%d) match given filter. Max amount of messages to resend is %d", messages.size(), maxCount);
for (MessageLite message: messages)
message.setState(MessageState.PENDING);
messageLiteRepository.saveAll(messages);
messageLiteRepository.flush();
}
return messages.size();
}
@Operation(summary = "Fetch message contents")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Message data"),
@ApiResponse(responseCode = "404", description = "Not found"),
@ApiResponse(responseCode = "500", description = "Failed handling request", content = @Content)
})
@LogPolicy(Policy.NONE)
@GetMapping(path = "/{id}/data")
public void data(HttpServletResponse response, @PathVariable long id, @RequestParam(defaultValue = "false") boolean pretty) {
Message message = messageRepository.findById(id).orElseThrow(HttpNotFoundException::new);
try (Reader reader = new BufferedReader(new InputStreamReader(message.getDataStream(), StandardCharsets.UTF_8))) {
Format format = PrettyPrintUtils.inferFormat(reader);
response.addHeader("Content-disposition", FormatUtils.format("attachment; filename=message-%s%s.%s", id, pretty ? "-pretty" : "", format.name().toLowerCase()));
if (pretty && format != Format.UNKNOWN)
writePretty(response.getWriter(), message.getCompressedData(), format);
else
IOUtils.copy(message.getDataStream(), response.getOutputStream());
}
catch (IOException e) {
throw new HttpInternalServerErrorException(e);
}
}
private static void writePretty(Writer writer, byte[] data, Format format) throws IOException {
Reader reader = new InputStreamReader(new GZIPInputStream(new ByteArrayInputStream(data)), StandardCharsets.UTF_8);
PrettyPrintUtils.prettyPrint(reader, writer, format);
writer.flush();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy