All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.netflix.server.context.BiDirectional Maven / Gradle / Ivy

There is a newer version: 0.5.1
Show newest version
/*
 * Copyright 2014 Netflix, Inc.
 *
 * 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 com.netflix.server.context;

import io.reactivex.netty.contexts.ContextKeySupplier;
import io.reactivex.netty.contexts.ContextsContainer;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Any contexts added to {@link ContextsContainer#addContext(String, Object, ContextSerializer)} is unidirectional i.e.
 * it always flows down the call chain, eg: In the below call graph
 
        Service A ---> Service B ---> Service C
                                |
                                 ---> Service D

 ------------------ Context X Flows through the call graph ----------------->
 
* Any changes to Context "X" (which gets added by Service A) in Service B will only be available to Service C & D but not * service A.
* This interface addresses the use-case where the update in context X must be available to Service A.
* * By annotating their class with this annotation, the context implementers can guarantee that the context changes, * flow bi-directionally in the call graph i.e. any code invoked after the change will get the updated context.
* These updates will be effective iff, the following steps are taken: *
  • Whenever the context gets updated, update the same with {@link ContextsContainer} by calling {@link ContextsContainer#addContext(String, Object, ContextSerializer)}. Implementation may batch these updates if such a batch can be made reliably.
  • Before returning a response from the service, get the updated bidirectional contexts via {@link ContextsContainer#getModifiedBidirectionalContexts()} and add it as response headers.
  • On receiving a response, read & update bidirectional contexts by calling {@link ContextsContainer#consumeBidirectionalContextsFromResponse(ContextKeySupplier)}
* * NIWS infrastructure does the last two steps transparently. If you (or your dependencies) are not using NIWS you may * have to do either one or both of these yourselves based on whether you are using client side, server side or none * of the NIWS components. * *

Mergeable contexts

* The infrastructure always over-writes the existing context when writing back a bi-directional context to the current * thread. In the above example, when service B returns, it reads back the bi-directional context & update the context * in Service A, at this point the default behavior is to over-write the existing context. However, in some cases, it * may be desirable to merge the two contexts. If so, is the case with your context, you must implement the interface * {@link MergeableContext} to indicate that the old context must be merged into the new context.
* For such a context, the infrastructure will call {@link MergeableContext#merge(MergeableContext)} on the old context * with the new context as the argument. * *

New Contexts added in Child service

* Any bi-directional contexts added fresh in a child service also flows back in the response. * * @author Nitesh Kant */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface BiDirectional { }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy