Skip to content

Instantly share code, notes, and snippets.

@Zenithar
Last active April 9, 2021 19:40
Show Gist options
  • Save Zenithar/5215005 to your computer and use it in GitHub Desktop.
Save Zenithar/5215005 to your computer and use it in GitHub Desktop.
public class BackendMessageConverter extends ProtobufMessageConverter {
public BackendMessageConverter() {
// Server object is the object generated by protoc
super(Server.getDescriptor());
}
}
package org.zenithar.mapper.protobuf.amqp;
import com.google.common.base.Preconditions;
import com.google.protobuf.Descriptors;
import com.google.protobuf.DynamicMessage;
import org.springframework.amqp.AmqpRejectAndDontRequeueException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.support.converter.AbstractMessageConverter;
import org.springframework.amqp.support.converter.MessageConversionException;
import java.util.Map;
/**
* Based on Scala version : https://github.com/gensen/spring-amqp-protobuf/blob/master/src/main/scala/com/gs/amqp/ProtobufMessageConverter.scala
* @author Thibault NORMAND
* @date 21/03/13
*/
public class ProtobufMessageConverter extends AbstractMessageConverter {
private final static String MESSAGE_TYPE_NAME = "_msg_type_name_";
private final static String CONTENT_TYPE_PROTOBUF = "application/x-backend-command";
private Descriptors.FileDescriptor fileDescriptor;
private ProtobufMessageConverter() {
super();
}
public ProtobufMessageConverter(Descriptors.FileDescriptor fileDescriptor) {
this.fileDescriptor = fileDescriptor;
}
@Override
protected Message createMessage(Object object, MessageProperties messageProperties) {
Preconditions.checkNotNull(object, "Object to send is null !");
if (!com.google.protobuf.Message.class.isAssignableFrom(object.getClass())) {
throw new MessageConversionException("Message wasn't a protobuf");
} else {
com.google.protobuf.Message protobuf = (com.google.protobuf.Message) object;
byte[] byteArray = protobuf.toByteArray();
messageProperties.setContentLength(byteArray.length);
messageProperties.setContentType(ProtobufMessageConverter.CONTENT_TYPE_PROTOBUF);
messageProperties.setHeader(ProtobufMessageConverter.MESSAGE_TYPE_NAME, protobuf.getDescriptorForType().getName());
return new Message(byteArray, messageProperties);
}
}
@Override
public Object fromMessage(Message message) throws MessageConversionException {
com.google.protobuf.Message parsedMessage = null;
try {
if(ProtobufMessageConverter.CONTENT_TYPE_PROTOBUF.equals(message.getMessageProperties().getContentType())) {
String typeName = getMessageTypeName(message);
Descriptors.Descriptor messageType = fileDescriptor.findMessageTypeByName(typeName);
parsedMessage = DynamicMessage.parseFrom(messageType, message.getBody());
}
} catch (Exception e) {
throw new AmqpRejectAndDontRequeueException("Cannot convert, unknown message type %s".format(getMessageTypeName(message)));
}
return parsedMessage;
}
private String getMessageTypeName(Message msg) {
Map<String, Object> headers = msg.getMessageProperties().getHeaders();
return Preconditions.checkNotNull(headers.get(ProtobufMessageConverter.MESSAGE_TYPE_NAME)).toString();
}
}
<bean id="rabbitProtobufMessageConverter" class="org.zenithar.converters.protobuf.amqp.BackendMessageConverter" />
<rabbit:template connection-factory="rabbitConnectionFactory"
message-converter="rabbitProtobufMessageConverter"/>
@adam-arold
Copy link

adam-arold commented Oct 18, 2016

Server.getDescriptor()

The Server class is missing from my generated files. Can I configure protoc somehow to generate it? I'm using Gradle.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment