The static `BaggageContext` API provides the following:
The Tracing Plane provides a static API `brown.tracingplane.Baggage` for manipulating `BaggageContext` instances. This static API is the main entry point for manipulating contexts directly. Supported methods are:
* Enables registration of a `BaggageProvider` class using the `baggage.provider` property
* Provides static methods in the `brown.tracingplane.Baggage` class that proxy to the configured `BaggageProvider`.
*`newInstance()` -- creates a new, empty `BaggageContext`; possibly a `null` value
*`branch(BaggageContext)` -- creates a duplicate `BaggageContext`. Typically this just creates a copy. Changes made to the branched `BaggageContext` will not be visible in the original, and vice versa.
*`join(BaggageContext, BaggageContext)` -- merges the values of two `BaggageContext` instances. If there is no conflicting data within the `BaggageContexts`, this resembles a union of their contents. However, if they both contain, e.g., values mapped to the same key, and those values differ, then the `BaggageProvider` must implement some sort of conflict resolution.
*`serialize(BaggageContext)` -- serializes the `BaggageContext` to a binary representation. For a string-based representation, either use a `BaggageProvider`-specified representation, or `base64` encode the binary representation
*`trim` -- trim is a special operation, that is exposed as `serialize(BaggageContext, maximumSerializedLength)`. `BaggageProvider` is expected to provide a serialization method that drops data if it exceeds a certain length threshold.
By default, `baggage.provider` will not be set; if this is the case, a No-Op provider will be used that simply ignores all baggage.
\ No newline at end of file
Example usage in code is, for example, to pass a `BaggageContext` to a new thread:
BaggageContext currentContext;
MyThread newThread = new MyThread(Baggage.branch(currentContext));
Or to serialize a context for inclusion in network calls:
BaggageContext currentContext;
out.write(Baggage.serialize(currentContext));
The Tracing Plane also provides an `ActiveBaggage` API that mirrors these method calls.
Use of the `Baggage` static API depends on a `BaggageProvider` being configured. Typically, this is done automatically by the Tracing Plane distribution that you use. If this is not the case, or if you wish to override the `BaggageProvider` implementation being used, then you can set the `baggage.provider` property to the `BaggageProviderFactory` of your choice, e.g.,
The Tracing Plane provides an out-of-the-box context propagation library called the "Transit Layer". The Transit Layer uses thread-local storage to store `BaggageContext` instances for threads, and provides a static API in `brown.tracingplane.ActiveBaggage` that invokes transit layer methods. `ActiveBaggage` provides methods as follows:
*`set(BaggageContext)` -- set the active `BaggageContext` for this thread
*`get()` -- get the active `BaggageContext` for this thread
*`take()` -- remove and return the active `BaggageContext` for this thread
*`takeBytes()` -- remove, return, and serialize the active `BaggageContext` for this thread
*`discard()` -- discard the active `BaggageContext` for this thread
In addition to methods for manipulating the active baggage, the Transit Layer and `ActiveBaggage` interface provides methods mirroring those in the `Baggage` and `BaggageProvider` interfaces, to implicitly manipulate the current context:
*`branch()` -- creates and returns a duplicate of the currently active `BaggageContext`.
*`join(BaggageContext)` -- merges the values of some `BaggageContext` object into the active context.
The Transit Layer is configurable, and alternative implementations can be used other than the out-of-the-box thread-local implementation. To provide a different implementation, simply implement the `TransitLayer` and `TransitLayerFactory` interfaces, then configure the factory class using the `baggage.transit` property, e.g.:
log.warn("No TransitLayerFactory has been configured using baggage.transit -- baggage propagation using the ActiveBaggage interface will be disabled");
log.error("Unable to instantiate TransitLayerFactory specified by baggage.transit "+
transitLayerClass,e);
}
}catch(ConfigException.WrongTypee){
Objectv=config.getAnyRef("baggage.transit");
log.error("Invalid baggage.transit has been configured -- baggage propagation using the ActiveBaggage interface will be disabled. Expected a string for baggage.provider, found "+
v.getClass().getName()+": "+v);
}
}
if(factory==null){
this.factory=newNoOpTransitLayerFactory();
this.transitlayer=this.factory.transitlayer();
}else{
this.factory=factory;
this.transitlayer=this.factory.transitlayer();
}
}
privatestaticDefaultTransitLayerinstance=null;
privatestaticDefaultTransitLayerinstance(){
if(instance==null){
synchronized(DefaultTransitLayer.class){
if(instance==null){
instance=newDefaultTransitLayer();
}
}
}
returninstance;
}
/**
* @return the configured {@link TransitLayer} instance. The default transit layer can be set using
* -Dbaggage.transit. If no instance has been configured, this method will return a
* {@link ThreadLocalTransitLayer} that uses simple thread-local storage to store baggage contexts.