Switch to using RoutingMetadata API

Closes gh-23137
This commit is contained in:
Rossen Stoyanchev
2019-09-02 12:09:43 +01:00
parent 702dad6cec
commit 71f3498a26
5 changed files with 57 additions and 27 deletions

View File

@@ -15,11 +15,11 @@
*/
package org.springframework.messaging.rsocket;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;
@@ -28,6 +28,7 @@ import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.rsocket.Payload;
import io.rsocket.metadata.CompositeMetadata;
import io.rsocket.metadata.RoutingMetadata;
import io.rsocket.metadata.WellKnownMimeType;
import org.springframework.core.ParameterizedTypeReference;
@@ -36,6 +37,7 @@ import org.springframework.core.codec.Decoder;
import org.springframework.core.io.buffer.NettyDataBuffer;
import org.springframework.core.io.buffer.NettyDataBufferFactory;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.MimeType;
/**
@@ -166,14 +168,19 @@ public class DefaultMetadataExtractor implements MetadataExtractor {
}
private void extractEntry(ByteBuf content, @Nullable String mimeType, Map<String, Object> result) {
if (content.readableBytes() == 0) {
return;
}
EntryExtractor<?> extractor = this.registrations.get(mimeType);
if (extractor != null) {
extractor.extract(content, result);
return;
}
if (mimeType != null && mimeType.equals(WellKnownMimeType.MESSAGE_RSOCKET_ROUTING.getString())) {
// TODO: use rsocket-core API when available
result.put(MetadataExtractor.ROUTE_KEY, content.toString(StandardCharsets.UTF_8));
Iterator<String> iterator = new RoutingMetadata(content).iterator();
if (iterator.hasNext()) {
result.put(MetadataExtractor.ROUTE_KEY, iterator.next());
}
}
}

View File

@@ -15,16 +15,17 @@
*/
package org.springframework.messaging.rsocket;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.netty.buffer.CompositeByteBuf;
import io.rsocket.metadata.CompositeMetadataFlyweight;
import io.rsocket.metadata.TaggingMetadataFlyweight;
import io.rsocket.metadata.WellKnownMimeType;
import org.springframework.core.ResolvableType;
@@ -161,25 +162,15 @@ final class MetadataEncoder {
public DataBuffer encode() {
if (this.isComposite) {
CompositeByteBuf composite = this.allocator.compositeBuffer();
if (this.route != null) {
CompositeMetadataFlyweight.encodeAndAddMetadata(composite, this.allocator,
WellKnownMimeType.MESSAGE_RSOCKET_ROUTING,
PayloadUtils.asByteBuf(bufferFactory().wrap(this.route.getBytes(StandardCharsets.UTF_8))));
}
try {
this.metadata.forEach((value, mimeType) -> {
DataBuffer buffer = encodeEntry(value, mimeType);
CompositeMetadataFlyweight.encodeAndAddMetadata(
composite, this.allocator, mimeType.toString(), PayloadUtils.asByteBuf(buffer));
});
if (bufferFactory() instanceof NettyDataBufferFactory) {
return ((NettyDataBufferFactory) bufferFactory()).wrap(composite);
}
else {
DataBuffer buffer = bufferFactory().wrap(composite.nioBuffer());
composite.release();
return buffer;
if (this.route != null) {
CompositeMetadataFlyweight.encodeAndAddMetadata(composite, this.allocator,
WellKnownMimeType.MESSAGE_RSOCKET_ROUTING, encodeRoute());
}
this.metadata.forEach((value, mimeType) ->
CompositeMetadataFlyweight.encodeAndAddMetadata(composite, this.allocator,
mimeType.toString(), PayloadUtils.asByteBuf(encodeEntry(value, mimeType))));
return asDataBuffer(composite);
}
catch (Throwable ex) {
composite.release();
@@ -189,7 +180,7 @@ final class MetadataEncoder {
else if (this.route != null) {
Assert.isTrue(this.metadata.isEmpty(), "Composite metadata required for route and other entries");
return this.metadataMimeType.toString().equals(WellKnownMimeType.MESSAGE_RSOCKET_ROUTING.getString()) ?
bufferFactory().wrap(this.route.getBytes(StandardCharsets.UTF_8)) :
asDataBuffer(encodeRoute()) :
encodeEntry(this.route, this.metadataMimeType);
}
else {
@@ -204,6 +195,11 @@ final class MetadataEncoder {
}
}
private ByteBuf encodeRoute() {
return TaggingMetadataFlyweight.createRoutingMetadata(
this.allocator, Collections.singletonList(this.route)).getContent();
}
@SuppressWarnings("unchecked")
private <T> DataBuffer encodeEntry(Object metadata, MimeType mimeType) {
if (metadata instanceof DataBuffer) {
@@ -215,4 +211,14 @@ final class MetadataEncoder {
return encoder.encodeValue((T) metadata, bufferFactory(), type, mimeType, Collections.emptyMap());
}
private DataBuffer asDataBuffer(ByteBuf byteBuf) {
if (bufferFactory() instanceof NettyDataBufferFactory) {
return ((NettyDataBufferFactory) bufferFactory()).wrap(byteBuf);
}
else {
DataBuffer buffer = bufferFactory().wrap(byteBuf.nioBuffer());
byteBuf.release();
return buffer;
}
}
}

View File

@@ -19,6 +19,7 @@ import java.util.Map;
import io.rsocket.Payload;
import org.springframework.core.codec.DecodingException;
import org.springframework.util.MimeType;
/**
@@ -45,6 +46,8 @@ public interface MetadataExtractor {
* @param payload the payload whose metadata should be read
* @param metadataMimeType the metadata MimeType for the connection.
* @return name values pairs extracted from the metadata
* @throws DecodingException if the metadata cannot be decoded
* @throws IllegalArgumentException if routing metadata cannot be decoded
*/
Map<String, Object> extract(Payload payload, MimeType metadataMimeType);