Uploaded image for project: 'Thrift'
  1. Thrift
  2. THRIFT-5104

Forwarding callContext into methods of handler as very last parameter

    XMLWordPrintableJSON

    Details

    • Type: Improvement
    • Status: Open
    • Priority: Major
    • Resolution: Unresolved
    • Affects Version/s: None
    • Fix Version/s: None
    • Labels:
      None

      Description

      I faced with common issue: I want be able to check if sender is a authorized user and to know who she/he is. I Decided to provide some heads to every single call by Injecting authorization token. For this purpose i made a ProtocolWrapper that do stuff like the following:

      uint32_t ProtocolWrapper ::writeMessageBegin_virt(const std::string& name, const MessageType type, const int32_t seqid)
      {
        auto size = TProtocolDecorator::writeMessageBegin_virt(name, type, seqid);
        if (type == MessageType::T_CALL || type == MessageType::T_ONEWAY)
          size += TProtocolDecorator::writeString(token);
        
        return size;
      }
      

       

      Then It's needed to process request , take out this authorization token, change it on user information and provide access to it inside methods of a heandler.

      Taking out authorization token from data stream is pretty easy to do. For instance TMultiplexProcessor does the same stuff. Or there is even a better way - providing a ProcessorEventHandler which operates callContext which can do this work.

      But the accessing taken data inside methods of a handler appeared a very difficult thing because callContext CAN NOT really influence on a method call or method arguments!

      So, the idea is to generate a handler interface which can take callContext of Processor for it's direct access.

       

      For example from this thrift service definition

       

      service SomeService {
        void someMethod(),
        void anotherMethod(
         1: int value,
        ),
      }
      

      would generate the following code:

       

       

      class SomeServiceIf {
      public:
        virtual ~SomeServiceIf() {}
      
        virtual void someMethod() = 0;             // usual
        virtual void anotherMethod(int value) = 0; // methods
      
        // virtual methods but
        // with default implementation
        // for backward compatibility
        virtual void someMethod(void* ctx) {
          someMethod();
        }
        virtual void anotherMethod(int value, void* ctx) {
           anotherMethod(value);
        }
      }
      

       

       

      This requires small change in a SomeServiceProcessor. It should call method with context.

      But this change wont break an existing code because of forwarding calls to non-context methods by default.

      Does it make any sense or there is a better way to do what I want?

       

      you can look at prototype of this change in my fork

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                Unassigned
                Reporter:
                rapotkinnik Nikolay Rapotkin
              • Votes:
                0 Vote for this issue
                Watchers:
                1 Start watching this issue

                Dates

                • Created:
                  Updated:

                  Time Tracking

                  Estimated:
                  Original Estimate - Not Specified
                  Not Specified
                  Remaining:
                  Remaining Estimate - 0h
                  0h
                  Logged:
                  Time Spent - 10m
                  10m