Skip to content

Commit

Permalink
Provide MessageService#builder to build a message instance from Messa…
Browse files Browse the repository at this point in the history
…geService
  • Loading branch information
symphony-hong committed Oct 9, 2020
1 parent 09b9aef commit 865bf89
Show file tree
Hide file tree
Showing 10 changed files with 125 additions and 45 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ private PrivateKey loadPrivateKeyFromAuthenticationConfig(BdkAuthenticationConfi
try {
String privateKey;
if (isNotEmpty(config.getPrivateKeyContent())) {
privateKey = new String(config.getPrivateKeyContent());
privateKey = new String(config.getPrivateKeyContent(), StandardCharsets.UTF_8);
} else {
String privateKeyPath = config.getPrivateKeyPath();
log.debug("Loading RSA privateKey from path : {}", privateKeyPath);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.symphony.bdk.core.service.message.exception.MessageCreationException;
import com.symphony.bdk.core.service.message.model.Attachment;
import com.symphony.bdk.core.service.message.model.Message;
import com.symphony.bdk.core.service.message.model.MessageBuilder;
import com.symphony.bdk.core.service.pagination.PaginatedApi;
import com.symphony.bdk.core.service.pagination.PaginatedService;
import com.symphony.bdk.core.service.stream.constant.AttachmentSort;
Expand Down Expand Up @@ -98,6 +99,10 @@ public TemplateEngine templates() {
return templateEngine;
}

public MessageBuilder builder() {
return new MessageBuilder(this);
}

/**
* Get messages from an existing stream. Additionally returns any attachments associated with the message.
*
Expand Down Expand Up @@ -169,6 +174,7 @@ public Stream<V4Message> getMessagesStream(@Nonnull String streamId, @Nonnull In
* @param message the message payload in MessageML
* @return a {@link V4Message} object containing the details of the sent message
* @see <a href="https://developers.symphony.com/restapi/reference#create-message-v4">Create Message v4</a>
* @deprecated this method will be replaced by {@link MessageService#send(V4Stream, Message)}
*/
@Deprecated
public V4Message send(@Nonnull V4Stream stream, @Nonnull String message) {
Expand All @@ -182,6 +188,7 @@ public V4Message send(@Nonnull V4Stream stream, @Nonnull String message) {
* @param message the message payload in MessageML
* @return a {@link V4Message} object containing the details of the sent message
* @see <a href="https://developers.symphony.com/restapi/reference#create-message-v4">Create Message v4</a>
* @deprecated this method will be replaced by {@link MessageService#send(String, Message)}
*/
@Deprecated
public V4Message send(@Nonnull String streamId, @Nonnull String message) {
Expand Down Expand Up @@ -405,7 +412,7 @@ private File createTemporaryAttachmentFile(Attachment attachment) {
return null;
}
try {
String[] fileNameArrays = attachment.fileName().split("\\.");
String[] fileNameArrays = attachment.filename().split("\\.");
if (fileNameArrays.length < 2) {
throw new MessageCreationException("Invalid attachment's file name.");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
/**
* Exception thrown when a {@link com.symphony.bdk.core.service.message.model.Message} is failed to create.
*/
@API(status = API.Status.EXPERIMENTAL)
@API(status = API.Status.STABLE)
public class MessageCreationException extends RuntimeException {

public MessageCreationException(String message, Exception e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@
public class Attachment {

private InputStream inputStream;
private String fileName;
private String filename;
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,27 @@
package com.symphony.bdk.core.service.message.model;

import com.symphony.bdk.gen.api.model.V4Stream;

import lombok.Getter;
import lombok.Setter;
import org.apiguardian.api.API;

/**
* Message model to be used in {@link com.symphony.bdk.core.service.message.MessageService#send(V4Stream, Message)}
*/
@Getter
@Setter
@API(status = API.Status.EXPERIMENTAL)
public class Message {

// The version of the MessageML format
private String version;
private String content;
private String data;
private Attachment attachment;

protected Message(MessageBuilder builder) {
this.version = builder.version();
this.content = builder.content();
this.data = builder.data();
this.attachment = builder.attachment();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,23 @@

import static java.util.Collections.emptyMap;

import com.symphony.bdk.core.service.message.MessageService;
import com.symphony.bdk.core.service.message.exception.MessageCreationException;
import com.symphony.bdk.gen.api.model.V4Message;
import com.symphony.bdk.gen.api.model.V4Stream;
import com.symphony.bdk.template.api.Template;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.json.JsonMapper;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import org.apiguardian.api.API;

import java.io.InputStream;

/**
* Builder for {@link Message}.
* Allows configuring the field of the messages before constructing them with build()
Expand All @@ -25,40 +31,48 @@ public class MessageBuilder {

private static final ObjectMapper MAPPER = new JsonMapper();

private final MessageService messageService;
private String version = "2.0";
private String content;
private String data;
private Attachment attachment;

private MessageBuilder() {

public MessageBuilder(MessageService messageService) {
this.messageService = messageService;
}

/**
* Create a builder from a MessageML content.
* @param message MessageML content
* @return MessageBuilder with the MessageML content
* Add messageML content to the message.
*
* @param message messageML.
* @return this builder with the content configured.
*/
public static MessageBuilder fromMessageMl(String message) {
return new MessageBuilder().content(message);
public MessageBuilder messageML(String message) {
this.content = message;
return this;
}

/**
* Create a builder from a Template and parameters.
* @param template a custom or built-in message template.
* @return MessageBuilder with the MessageML content generated from the template with the passed parameters.
* Add content from a template to the message.
*
* @param template a custom or built-in template.
* @param parameters parameters to be used in the template.
* @return this builder with the content configured.
*/
public static MessageBuilder fromTemplate(Template template, Object parameters) {
return new MessageBuilder().content(template.process(parameters));
public MessageBuilder template(Template template, Object parameters) {
this.content = template.process(parameters);
return this;
}

/**
* Create a builder from a static Template with no parameter.
* @param template a custom or built-in message template.
* @return MessageBuilder with the MessageML content generated from the template.
* Add content from a static template to the message.
*
* @param template a custom or built-in template.
* @return this builder with the content configured.
*/
public static MessageBuilder fromTemplate(Template template) {
return new MessageBuilder().content(template.process(emptyMap()));
public MessageBuilder template(Template template) {
this.content = template.process(emptyMap());
return this;
}

/**
Expand All @@ -75,6 +89,25 @@ public MessageBuilder data(Object data) {
}
}

/**
* Add data to the message.
* @param data Data json node.
* @return this builder with the data configured.
*/
public MessageBuilder data(JsonNode data) {
try {
this.data = MAPPER.writeValueAsString(data);
return this;
} catch (JsonProcessingException e) {
throw new MessageCreationException("Failed to parse data to Json string", e);
}
}

public MessageBuilder attachment(InputStream inputStream, String filename) {
this.attachment = new Attachment().inputStream(inputStream).filename(filename);
return this;
}

/**
* Create a {@link Message} using the configuration within the builder.
* @return constructed {@link Message} using configuration within this builder.
Expand All @@ -83,4 +116,24 @@ public Message build() {
return new Message(this);
}

/**
* Build and send a {@link Message} using the {@link MessageService}.
*
* @param stream the stream where the message is sent to.
* @return a {@link V4Message} object containing the details of the sent message.
*/
public V4Message send(V4Stream stream) {
return this.messageService.send(stream, this.build());
}

/**
* Build and send a {@link Message} using the {@link MessageService}.
*
* @param streamId the id of the stream where the message is sent to.
* @return a {@link V4Message} object containing the details of the sent message.
*/
public V4Message send(String streamId) {
return this.messageService.send(streamId, this.build());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
import com.symphony.bdk.core.retry.RetryWithRecoveryBuilder;
import com.symphony.bdk.core.service.message.MessageService;
import com.symphony.bdk.core.service.message.exception.MessageCreationException;
import com.symphony.bdk.core.service.message.model.Attachment;
import com.symphony.bdk.core.service.message.model.Message;
import com.symphony.bdk.core.service.message.model.MessageBuilder;
import com.symphony.bdk.core.service.stream.constant.AttachmentSort;
Expand Down Expand Up @@ -55,6 +54,7 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.time.Instant;
import java.util.Arrays;
Expand Down Expand Up @@ -184,8 +184,10 @@ void testSendPassingMessageInstanceToStreamId(@TempDir Path tmpDir) throws IOExc
JsonHelper.readFromClasspath("/message/send_message.json"));

InputStream inputStream = new FileInputStream(tempFilePath.toString());
Attachment attachment = new Attachment().inputStream(inputStream).fileName("test.png");
Message message = MessageBuilder.fromMessageMl(MESSAGE).attachment(attachment).build();
Message message = new MessageBuilder(this.messageService)
.messageML(MESSAGE)
.attachment(inputStream, "test.png")
.build();

final V4Message sentMessage = messageService.send(STREAM_ID, message);

Expand All @@ -201,8 +203,10 @@ void testSendPassingMessageInstanceToStream(@TempDir Path tmpDir) throws IOExcep
JsonHelper.readFromClasspath("/message/send_message.json"));

InputStream inputStream = new FileInputStream(tempFilePath.toString());
Attachment attachment = new Attachment().inputStream(inputStream).fileName("test.png");
Message message = MessageBuilder.fromMessageMl(MESSAGE).attachment(attachment).build();
Message message = new MessageBuilder(this.messageService)
.messageML(MESSAGE)
.attachment(inputStream, "test.png")
.build();

final V4Message sentMessage = messageService.send(new V4Stream().streamId(STREAM_ID), message);

Expand All @@ -218,8 +222,10 @@ void testSendPassingMessageInstanceToStreamWrongAttachmentName(@TempDir Path tmp
JsonHelper.readFromClasspath("/message/send_message.json"));

InputStream inputStream = new FileInputStream(tempFilePath.toString());
Attachment attachment = new Attachment().inputStream(inputStream).fileName("wrong-name");
Message message = MessageBuilder.fromMessageMl(MESSAGE).attachment(attachment).build();
Message message = new MessageBuilder(this.messageService)
.messageML(MESSAGE)
.attachment(inputStream, "wrong-name")
.build();

assertThrows(MessageCreationException.class,
() -> messageService.send(new V4Stream().streamId(STREAM_ID), message));
Expand All @@ -231,9 +237,21 @@ void testMessageCreationFailed(@TempDir Path tmpDir) throws IOException {
IOUtils.write("test", new FileOutputStream(tempFilePath.toFile()), "utf-8");

InputStream inputStream = new FileInputStream(tempFilePath.toString());
Attachment attachment = new Attachment().inputStream(inputStream).fileName("wrong-name");
assertThrows(MessageCreationException.class,
() -> MessageBuilder.fromMessageMl(MESSAGE).attachment(attachment).data(new MockObject("wrong object")).build());
() -> new MessageBuilder(this.messageService)
.messageML(MESSAGE)
.attachment(inputStream, "test.png")
.data(new MockObject("wrong object")).build());
}

@Test
void testMessageCreationSuccess() {
InputStream inputStream = IOUtils.toInputStream("test string", StandardCharsets.UTF_8);
Message message = new MessageBuilder(this.messageService).messageML(MESSAGE).attachment(inputStream, "test.doc").build();

assertEquals(message.getVersion(), "2.0");
assertEquals(message.getContent(), MESSAGE);
assertEquals(message.getAttachment().filename(), "test.doc");
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@

import com.symphony.bdk.core.SymphonyBdk;
import com.symphony.bdk.core.service.datafeed.RealTimeEventListener;
import com.symphony.bdk.core.service.message.model.Attachment;
import com.symphony.bdk.core.service.message.model.Message;
import com.symphony.bdk.core.service.message.model.MessageBuilder;
import com.symphony.bdk.gen.api.model.V4Initiator;
import com.symphony.bdk.gen.api.model.V4MessageSent;
import com.symphony.bdk.template.api.Template;
Expand All @@ -25,17 +22,14 @@ public static void main(String[] args) throws Exception {

final SymphonyBdk bdk = new SymphonyBdk(loadFromSymphonyDir("config.yaml"));

Attachment attachment =
new Attachment().inputStream(IOUtils.toInputStream("This is string", StandardCharsets.UTF_8))
.fileName("test.doc");
Template template = bdk.messages().templates().newTemplateFromClasspath("/complex-message.ftl");
Message message = MessageBuilder.fromTemplate(template, Collections.singletonMap("name", "Freemarker"))
.attachment(attachment)
.build();
Template template = bdk.messages().templates().newTemplateFromClasspath("/complex-template.ftl");
bdk.datafeed().subscribe(new RealTimeEventListener() {
@Override
public void onMessageSent(V4Initiator initiator, V4MessageSent event) {
bdk.messages().send(event.getMessage().getStream(), message);
bdk.messages().builder()
.template(template,Collections.singletonMap("name", event.getMessage().getUser().getUsername()))
.attachment(IOUtils.toInputStream("This is string", StandardCharsets.UTF_8), "test.doc")
.send(event.getMessage().getStream());
}
});

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<messageML>
This is a complex message to answer the message from ${name}!
</messageML>
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@
import com.symphony.bdk.core.activity.model.ActivityInfo;
import com.symphony.bdk.core.activity.model.ActivityType;
import com.symphony.bdk.core.service.message.MessageService;
import com.symphony.bdk.core.service.message.model.Message;
import com.symphony.bdk.core.service.message.model.MessageBuilder;
import com.symphony.bdk.spring.annotation.Slash;
import com.symphony.bdk.template.api.Template;

Expand All @@ -34,8 +32,7 @@ public class GifFormActivity extends FormReplyActivity<FormReplyContext> {
@Slash("/gif")
public void displayGifForm(CommandContext context) {
Template template = this.messageService.templates().newTemplateFromClasspath("/templates/gif.ftl");
Message message = MessageBuilder.fromTemplate(template).build();
this.messageService.send(context.getStreamId(), message);
this.messageService.builder().template(template).send(context.getStreamId());
}

@Override
Expand Down

0 comments on commit 865bf89

Please sign in to comment.