diff options
author | Yang Song <songy23@users.noreply.github.com> | 2017-11-09 13:59:08 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-11-09 13:59:08 -0800 |
commit | 5923bdbee2ea12ad9c4fa962b5adf526d9fe839d (patch) | |
tree | 5eac15ce4178a53c1deb212b050c59034a9a6cfc /impl_core/src/main/java/io/opencensus/implcore/tags | |
parent | 32cc8dd045a2502dffa792fd87ff9e994d8e7496 (diff) | |
download | opencensus-java-5923bdbee2ea12ad9c4fa962b5adf526d9fe839d.tar.gz |
Move implementation directories (#786)
* Move directories: core_impl to impl_core, core_impl_java to impl, core_impl_android to impl_lite.
Diffstat (limited to 'impl_core/src/main/java/io/opencensus/implcore/tags')
11 files changed, 769 insertions, 0 deletions
diff --git a/impl_core/src/main/java/io/opencensus/implcore/tags/CurrentTagContextUtils.java b/impl_core/src/main/java/io/opencensus/implcore/tags/CurrentTagContextUtils.java new file mode 100644 index 00000000..1a4ef81b --- /dev/null +++ b/impl_core/src/main/java/io/opencensus/implcore/tags/CurrentTagContextUtils.java @@ -0,0 +1,73 @@ +/* + * Copyright 2017, OpenCensus 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.opencensus.implcore.tags; + +import io.grpc.Context; +import io.opencensus.common.Scope; +import io.opencensus.tags.TagContext; +import io.opencensus.tags.unsafe.ContextUtils; +import javax.annotation.Nullable; + +/** + * Utility methods for accessing the {@link TagContext} contained in the {@link io.grpc.Context}. + */ +final class CurrentTagContextUtils { + + private CurrentTagContextUtils() {} + + /** + * Returns the {@link TagContext} from the current context. + * + * @return the {@code TagContext} from the current context. + */ + @Nullable + static TagContext getCurrentTagContext() { + return ContextUtils.TAG_CONTEXT_KEY.get(); + } + + /** + * Enters the scope of code where the given {@link TagContext} is in the current context and + * returns an object that represents that scope. The scope is exited when the returned object is + * closed. + * + * @param tags the {@code TagContext} to be set to the current context. + * @return an object that defines a scope where the given {@code TagContext} is set to the current + * context. + */ + static Scope withTagContext(TagContext tags) { + return new WithTagContext(tags); + } + + private static final class WithTagContext implements Scope { + + private final Context orig; + + /** + * Constructs a new {@link WithTagContext}. + * + * @param tags the {@code TagContext} to be added to the current {@code Context}. + */ + private WithTagContext(TagContext tags) { + orig = Context.current().withValue(ContextUtils.TAG_CONTEXT_KEY, tags).attach(); + } + + @Override + public void close() { + Context.current().detach(orig); + } + } +} diff --git a/impl_core/src/main/java/io/opencensus/implcore/tags/CurrentTaggingState.java b/impl_core/src/main/java/io/opencensus/implcore/tags/CurrentTaggingState.java new file mode 100644 index 00000000..ab60ffa1 --- /dev/null +++ b/impl_core/src/main/java/io/opencensus/implcore/tags/CurrentTaggingState.java @@ -0,0 +1,41 @@ +/* + * Copyright 2017, OpenCensus 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.opencensus.implcore.tags; + +import static com.google.common.base.Preconditions.checkNotNull; + +import io.opencensus.tags.TaggingState; +import io.opencensus.tags.TagsComponent; +import javax.annotation.concurrent.ThreadSafe; + +/** + * The current {@link TaggingState} for a {@link TagsComponent}. + * + * <p>This class allows different tagging classes to share the state in a thread-safe way. + */ +@ThreadSafe +public final class CurrentTaggingState { + private volatile TaggingState currentState = TaggingState.ENABLED; + + public TaggingState get() { + return currentState; + } + + void set(TaggingState state) { + currentState = checkNotNull(state, "state"); + } +} diff --git a/impl_core/src/main/java/io/opencensus/implcore/tags/NoopTagContextBuilder.java b/impl_core/src/main/java/io/opencensus/implcore/tags/NoopTagContextBuilder.java new file mode 100644 index 00000000..eae54c5d --- /dev/null +++ b/impl_core/src/main/java/io/opencensus/implcore/tags/NoopTagContextBuilder.java @@ -0,0 +1,51 @@ +/* + * Copyright 2017, OpenCensus 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.opencensus.implcore.tags; + +import io.opencensus.common.Scope; +import io.opencensus.implcore.internal.NoopScope; +import io.opencensus.tags.TagContext; +import io.opencensus.tags.TagContextBuilder; +import io.opencensus.tags.TagKey; +import io.opencensus.tags.TagValue; + +/** {@link TagContextBuilder} that is used when tagging is disabled. */ +final class NoopTagContextBuilder extends TagContextBuilder { + static final NoopTagContextBuilder INSTANCE = new NoopTagContextBuilder(); + + private NoopTagContextBuilder() {} + + @Override + public TagContextBuilder put(TagKey key, TagValue value) { + return this; + } + + @Override + public TagContextBuilder remove(TagKey key) { + return this; + } + + @Override + public TagContext build() { + return TagContextImpl.EMPTY; + } + + @Override + public Scope buildScoped() { + return NoopScope.getInstance(); + } +} diff --git a/impl_core/src/main/java/io/opencensus/implcore/tags/TagContextBuilderImpl.java b/impl_core/src/main/java/io/opencensus/implcore/tags/TagContextBuilderImpl.java new file mode 100644 index 00000000..1f473454 --- /dev/null +++ b/impl_core/src/main/java/io/opencensus/implcore/tags/TagContextBuilderImpl.java @@ -0,0 +1,64 @@ +/* + * Copyright 2017, OpenCensus 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.opencensus.implcore.tags; + +import static com.google.common.base.Preconditions.checkNotNull; + +import io.opencensus.common.Scope; +import io.opencensus.tags.TagContextBuilder; +import io.opencensus.tags.TagKey; +import io.opencensus.tags.TagValue; +import java.util.HashMap; +import java.util.Map; + +final class TagContextBuilderImpl extends TagContextBuilder { + private final Map<TagKey, TagValue> tags; + + TagContextBuilderImpl(Map<TagKey, TagValue> tags) { + this.tags = new HashMap<TagKey, TagValue>(tags); + } + + TagContextBuilderImpl() { + this.tags = new HashMap<TagKey, TagValue>(); + } + + @Override + public TagContextBuilderImpl put(TagKey key, TagValue value) { + return setInternal(key, checkNotNull(value, "value")); + } + + private TagContextBuilderImpl setInternal(TagKey key, TagValue value) { + tags.put(checkNotNull(key), value); + return this; + } + + @Override + public TagContextBuilderImpl remove(TagKey key) { + tags.remove(key); + return this; + } + + @Override + public TagContextImpl build() { + return new TagContextImpl(tags); + } + + @Override + public Scope buildScoped() { + return CurrentTagContextUtils.withTagContext(build()); + } +} diff --git a/impl_core/src/main/java/io/opencensus/implcore/tags/TagContextImpl.java b/impl_core/src/main/java/io/opencensus/implcore/tags/TagContextImpl.java new file mode 100644 index 00000000..177ce639 --- /dev/null +++ b/impl_core/src/main/java/io/opencensus/implcore/tags/TagContextImpl.java @@ -0,0 +1,84 @@ +/* + * Copyright 2017, OpenCensus 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.opencensus.implcore.tags; + +import io.opencensus.tags.Tag; +import io.opencensus.tags.TagContext; +import io.opencensus.tags.TagKey; +import io.opencensus.tags.TagValue; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; +import javax.annotation.concurrent.Immutable; + +@Immutable +public final class TagContextImpl extends TagContext { + + public static final TagContextImpl EMPTY = + new TagContextImpl(Collections.<TagKey, TagValue>emptyMap()); + + // The types of the TagKey and value must match for each entry. + private final Map<TagKey, TagValue> tags; + + public TagContextImpl(Map<? extends TagKey, ? extends TagValue> tags) { + this.tags = Collections.unmodifiableMap(new HashMap<TagKey, TagValue>(tags)); + } + + public Map<TagKey, TagValue> getTags() { + return tags; + } + + @Override + protected Iterator<Tag> getIterator() { + return new TagIterator(tags); + } + + @Override + public boolean equals(Object other) { + // Directly compare the tags when both objects are TagContextImpls, for efficiency. + if (other instanceof TagContextImpl) { + return getTags().equals(((TagContextImpl) other).getTags()); + } + return super.equals(other); + } + + private static final class TagIterator implements Iterator<Tag> { + Iterator<Map.Entry<TagKey, TagValue>> iterator; + + TagIterator(Map<TagKey, TagValue> tags) { + iterator = tags.entrySet().iterator(); + } + + @Override + public boolean hasNext() { + return iterator.hasNext(); + } + + @Override + public Tag next() { + final Entry<TagKey, TagValue> next = iterator.next(); + return Tag.create(next.getKey(), next.getValue()); + } + + @Override + public void remove() { + throw new UnsupportedOperationException("TagIterator.remove()"); + } + } +} diff --git a/impl_core/src/main/java/io/opencensus/implcore/tags/TagContextUtils.java b/impl_core/src/main/java/io/opencensus/implcore/tags/TagContextUtils.java new file mode 100644 index 00000000..5fbc5050 --- /dev/null +++ b/impl_core/src/main/java/io/opencensus/implcore/tags/TagContextUtils.java @@ -0,0 +1,33 @@ +/* + * Copyright 2017, OpenCensus 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.opencensus.implcore.tags; + +import io.opencensus.tags.Tag; + +final class TagContextUtils { + private TagContextUtils() {} + + /** + * Add a {@code Tag} of any type to a builder. + * + * @param tag tag containing the key and value to set. + * @param builder the builder to update. + */ + static void addTagToBuilder(Tag tag, TagContextBuilderImpl builder) { + builder.put(tag.getKey(), tag.getValue()); + } +} diff --git a/impl_core/src/main/java/io/opencensus/implcore/tags/TaggerImpl.java b/impl_core/src/main/java/io/opencensus/implcore/tags/TaggerImpl.java new file mode 100644 index 00000000..82c1d8cf --- /dev/null +++ b/impl_core/src/main/java/io/opencensus/implcore/tags/TaggerImpl.java @@ -0,0 +1,114 @@ +/* + * Copyright 2017, OpenCensus 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.opencensus.implcore.tags; + +import io.opencensus.common.Scope; +import io.opencensus.implcore.internal.NoopScope; +import io.opencensus.tags.InternalUtils; +import io.opencensus.tags.Tag; +import io.opencensus.tags.TagContext; +import io.opencensus.tags.TagContextBuilder; +import io.opencensus.tags.Tagger; +import io.opencensus.tags.TaggingState; +import java.util.Iterator; + +public final class TaggerImpl extends Tagger { + // All methods in this class use TagContextImpl and TagContextBuilderImpl. For example, + // withTagContext(...) always puts a TagContextImpl into scope, even if the argument is another + // TagContext subclass. + + private final CurrentTaggingState state; + + TaggerImpl(CurrentTaggingState state) { + this.state = state; + } + + @Override + public TagContextImpl empty() { + return TagContextImpl.EMPTY; + } + + @Override + public TagContextImpl getCurrentTagContext() { + return state.get() == TaggingState.DISABLED + ? TagContextImpl.EMPTY + : toTagContextImpl(CurrentTagContextUtils.getCurrentTagContext()); + } + + @Override + public TagContextBuilder emptyBuilder() { + return state.get() == TaggingState.DISABLED + ? NoopTagContextBuilder.INSTANCE + : new TagContextBuilderImpl(); + } + + @Override + public TagContextBuilder currentBuilder() { + return state.get() == TaggingState.DISABLED + ? NoopTagContextBuilder.INSTANCE + : toBuilder(CurrentTagContextUtils.getCurrentTagContext()); + } + + @Override + public TagContextBuilder toBuilder(TagContext tags) { + return state.get() == TaggingState.DISABLED + ? NoopTagContextBuilder.INSTANCE + : toTagContextBuilderImpl(tags); + } + + @Override + public Scope withTagContext(TagContext tags) { + return state.get() == TaggingState.DISABLED + ? NoopScope.getInstance() + : CurrentTagContextUtils.withTagContext(toTagContextImpl(tags)); + } + + private static TagContextImpl toTagContextImpl(TagContext tags) { + if (tags instanceof TagContextImpl) { + return (TagContextImpl) tags; + } else { + Iterator<Tag> i = InternalUtils.getTags(tags); + if (!i.hasNext()) { + return TagContextImpl.EMPTY; + } + TagContextBuilderImpl builder = new TagContextBuilderImpl(); + while (i.hasNext()) { + Tag tag = i.next(); + if (tag != null) { + TagContextUtils.addTagToBuilder(tag, builder); + } + } + return builder.build(); + } + } + + private static TagContextBuilderImpl toTagContextBuilderImpl(TagContext tags) { + // Copy the tags more efficiently in the expected case, when the TagContext is a TagContextImpl. + if (tags instanceof TagContextImpl) { + return new TagContextBuilderImpl(((TagContextImpl) tags).getTags()); + } else { + TagContextBuilderImpl builder = new TagContextBuilderImpl(); + for (Iterator<Tag> i = InternalUtils.getTags(tags); i.hasNext(); ) { + Tag tag = i.next(); + if (tag != null) { + TagContextUtils.addTagToBuilder(tag, builder); + } + } + return builder; + } + } +} diff --git a/impl_core/src/main/java/io/opencensus/implcore/tags/TagsComponentImplBase.java b/impl_core/src/main/java/io/opencensus/implcore/tags/TagsComponentImplBase.java new file mode 100644 index 00000000..216afdc9 --- /dev/null +++ b/impl_core/src/main/java/io/opencensus/implcore/tags/TagsComponentImplBase.java @@ -0,0 +1,56 @@ +/* + * Copyright 2017, OpenCensus 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.opencensus.implcore.tags; + +import static com.google.common.base.Preconditions.checkNotNull; + +import io.opencensus.implcore.tags.propagation.TagPropagationComponentImpl; +import io.opencensus.tags.Tagger; +import io.opencensus.tags.TaggingState; +import io.opencensus.tags.TagsComponent; +import io.opencensus.tags.propagation.TagPropagationComponent; + +/** Base implementation of {@link TagsComponent}. */ +public class TagsComponentImplBase extends TagsComponent { + + // The TaggingState shared between the TagsComponent, Tagger, and TagPropagationComponent + private final CurrentTaggingState state = new CurrentTaggingState(); + + private final Tagger tagger = new TaggerImpl(state); + private final TagPropagationComponent tagPropagationComponent = + new TagPropagationComponentImpl(state); + + @Override + public Tagger getTagger() { + return tagger; + } + + @Override + public TagPropagationComponent getTagPropagationComponent() { + return tagPropagationComponent; + } + + @Override + public TaggingState getState() { + return state.get(); + } + + @Override + public void setState(TaggingState newState) { + state.set(checkNotNull(newState, "newState")); + } +} diff --git a/impl_core/src/main/java/io/opencensus/implcore/tags/propagation/SerializationUtils.java b/impl_core/src/main/java/io/opencensus/implcore/tags/propagation/SerializationUtils.java new file mode 100644 index 00000000..d889a4b8 --- /dev/null +++ b/impl_core/src/main/java/io/opencensus/implcore/tags/propagation/SerializationUtils.java @@ -0,0 +1,171 @@ +/* + * Copyright 2016-17, OpenCensus 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.opencensus.implcore.tags.propagation; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Charsets; +import com.google.common.io.ByteArrayDataOutput; +import com.google.common.io.ByteStreams; +import io.opencensus.implcore.internal.VarInt; +import io.opencensus.implcore.tags.TagContextImpl; +import io.opencensus.tags.InternalUtils; +import io.opencensus.tags.Tag; +import io.opencensus.tags.TagContext; +import io.opencensus.tags.TagKey; +import io.opencensus.tags.TagValue; +import io.opencensus.tags.propagation.TagContextDeserializationException; +import java.nio.BufferUnderflowException; +import java.nio.ByteBuffer; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +/** + * Methods for serializing and deserializing {@link TagContext}s. + * + * <p>The format defined in this class is shared across all implementations of OpenCensus. It allows + * tags to propagate across requests. + * + * <p>OpenCensus tag context encoding: + * + * <ul> + * <li>Tags are encoded in single byte sequence. The version 0 format is: + * <li>{@code <version_id><encoded_tags>} + * <li>{@code <version_id> == a single byte, value 0} + * <li>{@code <encoded_tags> == (<tag_field_id><tag_encoding>)*} + * <ul> + * <li>{@code <tag_field_id>} == a single byte, value 0 + * <li>{@code <tag_encoding>}: + * <ul> + * <li>{@code <tag_key_len><tag_key><tag_val_len><tag_val>} + * <ul> + * <li>{@code <tag_key_len>} == varint encoded integer + * <li>{@code <tag_key>} == tag_key_len bytes comprising tag key name + * <li>{@code <tag_val_len>} == varint encoded integer + * <li>{@code <tag_val>} == tag_val_len bytes comprising UTF-8 string + * </ul> + * </ul> + * </ul> + * </ul> + */ +final class SerializationUtils { + private SerializationUtils() {} + + @VisibleForTesting static final int VERSION_ID = 0; + @VisibleForTesting static final int TAG_FIELD_ID = 0; + + // Serializes a TagContext to the on-the-wire format. + // Encoded tags are of the form: <version_id><encoded_tags> + static byte[] serializeBinary(TagContext tags) { + // Use a ByteArrayDataOutput to avoid needing to handle IOExceptions. + final ByteArrayDataOutput byteArrayDataOutput = ByteStreams.newDataOutput(); + byteArrayDataOutput.write(VERSION_ID); + for (Iterator<Tag> i = InternalUtils.getTags(tags); i.hasNext(); ) { + Tag tag = i.next(); + encodeTag(tag, byteArrayDataOutput); + } + return byteArrayDataOutput.toByteArray(); + } + + // Deserializes input to TagContext based on the binary format standard. + // The encoded tags are of the form: <version_id><encoded_tags> + static TagContextImpl deserializeBinary(byte[] bytes) throws TagContextDeserializationException { + try { + if (bytes.length == 0) { + // Does not allow empty byte array. + throw new TagContextDeserializationException("Input byte[] can not be empty."); + } + + ByteBuffer buffer = ByteBuffer.wrap(bytes).asReadOnlyBuffer(); + int versionId = buffer.get(); + if (versionId != VERSION_ID) { + throw new TagContextDeserializationException( + "Wrong Version ID: " + versionId + ". Currently supported version is: " + VERSION_ID); + } + return new TagContextImpl(parseTags(buffer)); + } catch (BufferUnderflowException exn) { + throw new TagContextDeserializationException(exn.toString()); // byte array format error. + } + } + + private static Map<TagKey, TagValue> parseTags(ByteBuffer buffer) + throws TagContextDeserializationException { + Map<TagKey, TagValue> tags = new HashMap<TagKey, TagValue>(); + int limit = buffer.limit(); + while (buffer.position() < limit) { + int type = buffer.get(); + if (type == TAG_FIELD_ID) { + TagKey key = createTagKey(decodeString(buffer)); + TagValue val = createTagValue(key, decodeString(buffer)); + tags.put(key, val); + } else { + // Stop parsing at the first unknown field ID, since there is no way to know its length. + // TODO(sebright): Consider storing the rest of the byte array in the TagContext. + return tags; + } + } + return tags; + } + + // TODO(sebright): Consider exposing a TagKey name validation method to avoid needing to catch an + // IllegalArgumentException here. + private static final TagKey createTagKey(String name) throws TagContextDeserializationException { + try { + return TagKey.create(name); + } catch (IllegalArgumentException e) { + throw new TagContextDeserializationException("Invalid tag key: " + name, e); + } + } + + // TODO(sebright): Consider exposing a TagValue validation method to avoid needing to catch + // an IllegalArgumentException here. + private static final TagValue createTagValue(TagKey key, String value) + throws TagContextDeserializationException { + try { + return TagValue.create(value); + } catch (IllegalArgumentException e) { + throw new TagContextDeserializationException( + "Invalid tag value for key " + key + ": " + value, e); + } + } + + private static final void encodeTag(Tag tag, ByteArrayDataOutput byteArrayDataOutput) { + byteArrayDataOutput.write(TAG_FIELD_ID); + encodeString(tag.getKey().getName(), byteArrayDataOutput); + encodeString(tag.getValue().asString(), byteArrayDataOutput); + } + + private static final void encodeString(String input, ByteArrayDataOutput byteArrayDataOutput) { + putVarInt(input.length(), byteArrayDataOutput); + byteArrayDataOutput.write(input.getBytes(Charsets.UTF_8)); + } + + private static final void putVarInt(int input, ByteArrayDataOutput byteArrayDataOutput) { + byte[] output = new byte[VarInt.varIntSize(input)]; + VarInt.putVarInt(input, output, 0); + byteArrayDataOutput.write(output); + } + + private static final String decodeString(ByteBuffer buffer) { + int length = VarInt.getVarInt(buffer); + StringBuilder builder = new StringBuilder(); + for (int i = 0; i < length; i++) { + builder.append((char) buffer.get()); + } + return builder.toString(); + } +} diff --git a/impl_core/src/main/java/io/opencensus/implcore/tags/propagation/TagContextBinarySerializerImpl.java b/impl_core/src/main/java/io/opencensus/implcore/tags/propagation/TagContextBinarySerializerImpl.java new file mode 100644 index 00000000..eea24a33 --- /dev/null +++ b/impl_core/src/main/java/io/opencensus/implcore/tags/propagation/TagContextBinarySerializerImpl.java @@ -0,0 +1,48 @@ +/* + * Copyright 2017, OpenCensus 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.opencensus.implcore.tags.propagation; + +import io.opencensus.implcore.tags.CurrentTaggingState; +import io.opencensus.implcore.tags.TagContextImpl; +import io.opencensus.tags.TagContext; +import io.opencensus.tags.TaggingState; +import io.opencensus.tags.propagation.TagContextBinarySerializer; +import io.opencensus.tags.propagation.TagContextDeserializationException; + +final class TagContextBinarySerializerImpl extends TagContextBinarySerializer { + private static final byte[] EMPTY_BYTE_ARRAY = {}; + + private final CurrentTaggingState state; + + TagContextBinarySerializerImpl(CurrentTaggingState state) { + this.state = state; + } + + @Override + public byte[] toByteArray(TagContext tags) { + return state.get() == TaggingState.DISABLED + ? EMPTY_BYTE_ARRAY + : SerializationUtils.serializeBinary(tags); + } + + @Override + public TagContext fromByteArray(byte[] bytes) throws TagContextDeserializationException { + return state.get() == TaggingState.DISABLED + ? TagContextImpl.EMPTY + : SerializationUtils.deserializeBinary(bytes); + } +} diff --git a/impl_core/src/main/java/io/opencensus/implcore/tags/propagation/TagPropagationComponentImpl.java b/impl_core/src/main/java/io/opencensus/implcore/tags/propagation/TagPropagationComponentImpl.java new file mode 100644 index 00000000..5def0758 --- /dev/null +++ b/impl_core/src/main/java/io/opencensus/implcore/tags/propagation/TagPropagationComponentImpl.java @@ -0,0 +1,34 @@ +/* + * Copyright 2017, OpenCensus 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.opencensus.implcore.tags.propagation; + +import io.opencensus.implcore.tags.CurrentTaggingState; +import io.opencensus.tags.propagation.TagContextBinarySerializer; +import io.opencensus.tags.propagation.TagPropagationComponent; + +public final class TagPropagationComponentImpl extends TagPropagationComponent { + private final TagContextBinarySerializer tagContextBinarySerializer; + + public TagPropagationComponentImpl(CurrentTaggingState state) { + tagContextBinarySerializer = new TagContextBinarySerializerImpl(state); + } + + @Override + public TagContextBinarySerializer getBinarySerializer() { + return tagContextBinarySerializer; + } +} |