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

Binary format proposal. #252

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Copyright 2016-2018 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.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;

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 NullPointerException();
}

return new BinaryAdapter(stream);
}

/**
* 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 NullPointerException();
}

return new BinaryAdapter(stream);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* Copyright 2016-2018 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), and is expected to work synchronously.
*
* 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 carrier from the given buffer.
* The internal buffer is expected to grow as more data is written.
Copy link
Member

Choose a reason for hiding this comment

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

what does this line refer to? Whose internal buffer? Seems we can remove it without loss.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Internal storage, basically (which would mean that many writes are possible). So based on your comment, it sounds like it definitely needs improvement (either by mentioning that multiple writes are allowed, or removing this line altogether).

*
* @param buffer The buffer from which bytes are to be retrieved.
*/
void write(ByteBuffer buffer) throws IOException;

/**
* Reads a sequence of bytes into the given buffer.
*
* @param buffer The buffer into which bytes are to be transferred.
*
* @return The number of bytes read, possibly zero, or -1 if the carrier has reached end-of-stream.
*/
int read(ByteBuffer buffer) throws IOException;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*
* Copyright 2016-2018 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.io.OutputStream;
import java.io.InputStream;
import java.nio.ByteBuffer;

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

/**
* Create an outbound BinaryAdapter backed by the specified OutputStream.
*/
BinaryAdapter(OutputStream outputStream) {
this.outputStream = outputStream;
this.inputStream = null;
}

/**
* Create an inbound BinaryAdapter backed by the specified InputStream.
*/
BinaryAdapter(InputStream inputStream) {
this.inputStream = inputStream;
this.outputStream = null;
}

OutputStream outputStream() {
return outputStream;
}

InputStream inputStream() {
return inputStream;
}

public void write(ByteBuffer buffer) throws IOException {
if (buffer == null) {
throw new NullPointerException();
}
if (outputStream == null) {
throw new UnsupportedOperationException();
}
if (buffer.remaining() == 0) { // No data to write.
return;
}

byte[] b = new byte[buffer.remaining()];
buffer.get(b);
outputStream.write(b);
}

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

// Need to read always as:
// 1. InputStream.available() always returns 0 for some implementations.
// 2. Even buffer.remaining() == 0, we need to know whether we have reached
// the end of the stream or not.
byte[] b = new byte[buffer.remaining()];
int available = inputStream.read(b);
if (available < 0)

Choose a reason for hiding this comment

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

please add curly braces for if body

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Will update 👍

return -1;

buffer.put(b, 0, available);
return available;
}
}
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,50 @@
/*
* Copyright 2016-2018 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 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.inputStream());
}

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

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

@Test(expected = NullPointerException.class)
public void testInjectNullStream() {
Adapters.injectBinary((OutputStream)null);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* Copyright 2016-2018 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 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(stream);
assertNotNull(binary.inputStream());
assertNull(binary.outputStream());

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(stream);
assertNotNull(binary.outputStream());
assertNull(binary.inputStream());

binary.write(ByteBuffer.wrap(new byte [] { 1, 2, 3, 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