Home | History | Annotate | Download | only in propagation
      1 /*
      2  * Copyright 2017, OpenCensus Authors
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *     http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package io.opencensus.trace.propagation;
     18 
     19 import io.opencensus.internal.Utils;
     20 import io.opencensus.trace.SpanContext;
     21 import java.text.ParseException;
     22 
     23 /**
     24  * This is a helper class for {@link SpanContext} propagation on the wire using binary encoding.
     25  *
     26  * <p>Example of usage on the client:
     27  *
     28  * <pre>{@code
     29  * private static final Tracer tracer = Tracing.getTracer();
     30  * private static final BinaryFormat binaryFormat =
     31  *     Tracing.getPropagationComponent().getBinaryFormat();
     32  * void onSendRequest() {
     33  *   try (Scope ss = tracer.spanBuilder("Sent.MyRequest").startScopedSpan()) {
     34  *     byte[] binaryValue = binaryFormat.toByteArray(tracer.getCurrentContext().context());
     35  *     // Send the request including the binaryValue and wait for the response.
     36  *   }
     37  * }
     38  * }</pre>
     39  *
     40  * <p>Example of usage on the server:
     41  *
     42  * <pre>{@code
     43  * private static final Tracer tracer = Tracing.getTracer();
     44  * private static final BinaryFormat binaryFormat =
     45  *     Tracing.getPropagationComponent().getBinaryFormat();
     46  * void onRequestReceived() {
     47  *   // Get the binaryValue from the request.
     48  *   SpanContext spanContext = SpanContext.INVALID;
     49  *   try {
     50  *     if (binaryValue != null) {
     51  *       spanContext = binaryFormat.fromByteArray(binaryValue);
     52  *     }
     53  *   } catch (SpanContextParseException e) {
     54  *     // Maybe log the exception.
     55  *   }
     56  *   try (Scope ss =
     57  *            tracer.spanBuilderWithRemoteParent("Recv.MyRequest", spanContext).startScopedSpan()) {
     58  *     // Handle request and send response back.
     59  *   }
     60  * }
     61  * }</pre>
     62  *
     63  * @since 0.5
     64  */
     65 public abstract class BinaryFormat {
     66   static final NoopBinaryFormat NOOP_BINARY_FORMAT = new NoopBinaryFormat();
     67 
     68   /**
     69    * Serializes a {@link SpanContext} into a byte array using the binary format.
     70    *
     71    * @deprecated use {@link #toByteArray(SpanContext)}.
     72    * @param spanContext the {@code SpanContext} to serialize.
     73    * @return the serialized binary value.
     74    * @throws NullPointerException if the {@code spanContext} is {@code null}.
     75    * @since 0.5
     76    */
     77   @Deprecated
     78   public byte[] toBinaryValue(SpanContext spanContext) {
     79     return toByteArray(spanContext);
     80   }
     81 
     82   /**
     83    * Serializes a {@link SpanContext} into a byte array using the binary format.
     84    *
     85    * @param spanContext the {@code SpanContext} to serialize.
     86    * @return the serialized binary value.
     87    * @throws NullPointerException if the {@code spanContext} is {@code null}.
     88    * @since 0.7
     89    */
     90   public byte[] toByteArray(SpanContext spanContext) {
     91     // Implementation must override this method.
     92     return toBinaryValue(spanContext);
     93   }
     94 
     95   /**
     96    * Parses the {@link SpanContext} from a byte array using the binary format.
     97    *
     98    * @deprecated use {@link #fromByteArray(byte[])}.
     99    * @param bytes a binary encoded buffer from which the {@code SpanContext} will be parsed.
    100    * @return the parsed {@code SpanContext}.
    101    * @throws NullPointerException if the {@code input} is {@code null}.
    102    * @throws ParseException if the version is not supported or the input is invalid
    103    * @since 0.5
    104    */
    105   @Deprecated
    106   public SpanContext fromBinaryValue(byte[] bytes) throws ParseException {
    107     try {
    108       return fromByteArray(bytes);
    109     } catch (SpanContextParseException e) {
    110       throw new ParseException(e.toString(), 0);
    111     }
    112   }
    113 
    114   /**
    115    * Parses the {@link SpanContext} from a byte array using the binary format.
    116    *
    117    * @param bytes a binary encoded buffer from which the {@code SpanContext} will be parsed.
    118    * @return the parsed {@code SpanContext}.
    119    * @throws NullPointerException if the {@code input} is {@code null}.
    120    * @throws SpanContextParseException if the version is not supported or the input is invalid
    121    * @since 0.7
    122    */
    123   public SpanContext fromByteArray(byte[] bytes) throws SpanContextParseException {
    124     // Implementation must override this method. If it doesn't, the below will StackOverflowError.
    125     try {
    126       return fromBinaryValue(bytes);
    127     } catch (ParseException e) {
    128       throw new SpanContextParseException("Error while parsing.", e);
    129     }
    130   }
    131 
    132   /**
    133    * Returns the no-op implementation of the {@code BinaryFormat}.
    134    *
    135    * @return the no-op implementation of the {@code BinaryFormat}.
    136    */
    137   static BinaryFormat getNoopBinaryFormat() {
    138     return NOOP_BINARY_FORMAT;
    139   }
    140 
    141   private static final class NoopBinaryFormat extends BinaryFormat {
    142     @Override
    143     public byte[] toByteArray(SpanContext spanContext) {
    144       Utils.checkNotNull(spanContext, "spanContext");
    145       return new byte[0];
    146     }
    147 
    148     @Override
    149     public SpanContext fromByteArray(byte[] bytes) {
    150       Utils.checkNotNull(bytes, "bytes");
    151       return SpanContext.INVALID;
    152     }
    153 
    154     private NoopBinaryFormat() {}
    155   }
    156 }
    157