Skip to content
This repository has been archived by the owner on May 23, 2023. It is now read-only.

Change BINARY to be resizable and stream-oriented. #223

Merged
merged 10 commits into from
Dec 6, 2017
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*
* Copyright 2016-2017 The OpenTracing Authors
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: as this is new code, (c) is only 2017 (same in other files)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:) Had missed that, will fix.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, btw, if I use 2017 alone the build fails. Guess we need to issue a PR for fixing this part in pom.xml ;)

*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package io.opentracing.propagation;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;

public final class Adapters {
private Adapters() {}

/**
* Creates an outbound Binary instance used for injection, backed up
* by the specified OutputStream as output.
*
* @param stream The OutputStream used as the output.
*
* @return The new Binary carrier used for injection.
*/
public static Binary injectBinary(OutputStream stream) {
if (stream == null) {
throw new IllegalArgumentException("stream cannot be null");
}

return new BinaryAdapter(Channels.newChannel(stream));
}

/**
* Creates an outbound Binary instance used for injection, backed up
* by the specified WritableByteChannel as the output.
*
* @param channel The WritableByteChannel used as output.
*
* @return The new Binary carrier used for injection.
*/
public static Binary injectBinary(WritableByteChannel channel) {
if (channel == null) {
throw new IllegalArgumentException("channel cannot be null");
}

return new BinaryAdapter(channel);
}

/**
* Creates an inbound Binary instance used for extraction with the
* specified InputStream as the input.
*
* @param stream The InputStream used as input.
*
* @return The new Binary carrier used for extraction.
*/
public static Binary extractBinary(InputStream stream) {
if (stream == null) {
throw new IllegalArgumentException("stream cannot be null");
}

return new BinaryAdapter(Channels.newChannel(stream));
}

/**
* Creates an inbound Binary instance used for extraction with the
* specified ReadableByteChannel as the input.
*
* @param channel The ReadableByteChannel used as input.
*
* @return The new Binary carrier used for extraction.
*/
public static Binary extractBinary(ReadableByteChannel channel) {
if (channel == null) {
throw new IllegalArgumentException("channel cannot be null");
}

return new BinaryAdapter(channel);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* Copyright 2016-2017 The OpenTracing Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package io.opentracing.propagation;

import java.io.IOException;
import java.nio.ByteBuffer;

/**
* Binary is an interface defining the required operations for a binary carrier for
* Tracer.inject() and Tracer.extract(). Binary can be defined either as inbound (extraction)
* or outbound (injection).
*
* When Binary is defined as inbound, read() must be used to read data,
* and it is an error to call read().
*
* When Binary is defined as outbound, write() must be used to write data,
* and it is an error to call write().
*
* @see Format.Builtin#BINARY
* @see io.opentracing.Tracer#inject(SpanContext, Format, Object)
* @see io.opentracing.Tracer#extract(Format, Object)
*/
public interface Binary {
/**
* Writes a sequence of bytes to this channel from the given buffer.
* The internal buffer is expected to grow as more data is written.
*
* The behavior of this method is expected to be the same as WritableByteChannel.write().
*
* @param buffer The buffer from which bytes are to be retrieved.
*
* @return The number of bytes written, possibly zero.
*/
int write(ByteBuffer buffer) throws IOException;

/**
* Reads a sequence of bytes into the given buffer.
*
* The behavior of this method is expected to be the same as ReadableByteChannel.read().
*
* @param buffer The buffer into which bytes are to be transferred.
*
* @return The number of bytes read, possibly zero, or -1 if the channel has reached end-of-stream.
*/
int read(ByteBuffer buffer) throws IOException;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Copyright 2016-2017 The OpenTracing Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package io.opentracing.propagation;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;

/**
* BinaryAdapter is a built-in carrier for Tracer.inject() and Tracer.extract(). BinaryAdapter
* is backed up by either a ReadableByteChannel or a WritableByteChannel, depending
* on whether it's defined as injection or extraction, respectively.
*/
final class BinaryAdapter implements Binary {
private final ReadableByteChannel readChannel;
private final WritableByteChannel writeChannel;

/**
* Create an outbound BinaryAdapter backed by the specified write channel.
*/
BinaryAdapter(WritableByteChannel writeChannel) {
this.writeChannel = writeChannel;
this.readChannel = null;
}

/**
* Create an inbound BinaryAdapter backed by the specified read channel.
*/
BinaryAdapter(ReadableByteChannel readChannel) {
this.readChannel = readChannel;
this.writeChannel = null;
}

ReadableByteChannel readChannel() {
return readChannel;
}

WritableByteChannel writeChannel() {
return writeChannel;
}

public int write(ByteBuffer buffer) throws IOException {
if (writeChannel == null) {
throw new UnsupportedOperationException();
}

return writeChannel.write(buffer);
}

public int read(ByteBuffer buffer) throws IOException {
if (readChannel == null) {
throw new UnsupportedOperationException();
}

return readChannel.read(buffer);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ private Builtin(String name) {
* @see io.opentracing.Tracer#extract(Format, Object)
* @see Format
*/
public final static Format<ByteBuffer> BINARY = new Builtin<ByteBuffer>("BINARY");
public final static Format<Binary> BINARY = new Builtin<Binary>("BINARY");

/**
* @return Short name for built-in formats as they tend to show up in exception messages.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* Copyright 2016-2017 The OpenTracing Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package io.opentracing.propagation;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import org.junit.Test;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

public class AdaptersTest {

@Test
public void testExtractBinaryStream() {
byte[] ctx = new byte[0];
BinaryAdapter binary = (BinaryAdapter) Adapters.extractBinary(new ByteArrayInputStream(ctx));
assertNotNull(binary.readChannel());
}

@Test
public void testExtractBinaryChannel() {
byte[] ctx = new byte[0];
ReadableByteChannel channel = Channels.newChannel(new ByteArrayInputStream(new byte[0]));
BinaryAdapter binary = (BinaryAdapter) Adapters.extractBinary(channel);
assertEquals(channel, binary.readChannel());
}

@Test(expected = IllegalArgumentException.class)
public void testExtractNullStream() {
Adapters.extractBinary((InputStream)null);
}

@Test(expected = IllegalArgumentException.class)
public void testExtractNullChannel() {
Adapters.extractBinary((ReadableByteChannel)null);
}

@Test
public void testInjectBinaryStream() {
BinaryAdapter binary = (BinaryAdapter) Adapters.injectBinary(new ByteArrayOutputStream());
assertNotNull(binary.writeChannel());
}

@Test
public void testInjectBinaryChannel() {
WritableByteChannel channel = Channels.newChannel(new ByteArrayOutputStream());
BinaryAdapter binary = (BinaryAdapter) Adapters.injectBinary(channel);
assertEquals(channel, binary.writeChannel());
}

@Test(expected = IllegalArgumentException.class)
public void testInjectNullStream() {
Adapters.injectBinary((OutputStream)null);
}

@Test(expected = IllegalArgumentException.class)
public void testInjectNullChannel() {
Adapters.injectBinary((WritableByteChannel)null);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Copyright 2016-2017 The OpenTracing Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package io.opentracing.propagation;

import java.io.ByteArrayOutputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import org.junit.Test;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;

public class BinaryAdapterTest {

@Test
public void testRead() throws IOException {
ByteArrayInputStream stream = new ByteArrayInputStream(new byte[] { 1, 2, 3, 4, 4, 3, 2, 1 });
BinaryAdapter binary = new BinaryAdapter(Channels.newChannel(stream));
assertNotNull(binary.readChannel());
assertNull(binary.writeChannel());

ByteBuffer buffer = ByteBuffer.allocate(4);
assertEquals(4, binary.read(buffer));
assertArrayEquals(new byte[] { 1, 2, 3, 4 }, buffer.array());

buffer.rewind();
assertEquals(4, binary.read(buffer));
assertArrayEquals(new byte[] { 4, 3, 2, 1 }, buffer.array());

buffer.rewind();
assertEquals(-1, binary.read(buffer));
}

@Test
public void testWrite() throws IOException {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
BinaryAdapter binary = new BinaryAdapter(Channels.newChannel(stream));
assertNotNull(binary.writeChannel());
assertNull(binary.readChannel());

assertEquals(4, binary.write(ByteBuffer.wrap(new byte [] { 1, 2, 3, 4 })));
assertEquals(4, binary.write(ByteBuffer.wrap(new byte [] { 4, 3, 2, 1 })));

assertArrayEquals(new byte[] { 1, 2, 3, 4, 4, 3, 2, 1 }, stream.toByteArray());
}
}
Loading