github.com/swiftstack/ProxyFS@v0.0.0-20210203235616-4017c267d62f/pfsagentd/jrpc.go (about)

     1  // Copyright (c) 2015-2021, NVIDIA CORPORATION.
     2  // SPDX-License-Identifier: Apache-2.0
     3  
     4  package main
     5  
     6  import (
     7  	"encoding/json"
     8  	"fmt"
     9  )
    10  
    11  type jrpcRequestMethodAndIDStruct struct {
    12  	Method string `json:"method"`
    13  	ID     uint64 `json:"id"`
    14  }
    15  
    16  type jrpcRequestStruct struct {
    17  	JSONrpc string         `json:"jsonrpc"`
    18  	Method  string         `json:"method"`
    19  	ID      uint64         `json:"id"`
    20  	Params  [1]interface{} `json:"params"`
    21  }
    22  
    23  type jrpcResponseIDStruct struct {
    24  	ID uint64 `json:"id"`
    25  }
    26  
    27  type jrpcResponseIDAndErrorStruct struct {
    28  	ID    uint64 `json:"id"`
    29  	Error string `json:"error"`
    30  }
    31  
    32  type jrpcResponseNoErrorStruct struct {
    33  	ID     uint64      `json:"id"`
    34  	Result interface{} `json:"result"`
    35  }
    36  
    37  type jrpcResponseWithErrorStruct struct {
    38  	ID     uint64      `json:"id"`
    39  	Error  string      `json:"error"`
    40  	Result interface{} `json:"result"`
    41  }
    42  
    43  func jrpcMarshalRequest(requestMethod string, request interface{}) (requestID uint64, requestBuf []byte, marshalErr error) {
    44  	var (
    45  		jrpcRequest *jrpcRequestStruct
    46  	)
    47  
    48  	globals.Lock()
    49  	requestID = globals.jrpcLastID + 1
    50  	globals.jrpcLastID = requestID
    51  	globals.Unlock()
    52  
    53  	jrpcRequest = &jrpcRequestStruct{
    54  		JSONrpc: "2.0",
    55  		Method:  requestMethod,
    56  		ID:      requestID,
    57  		Params:  [1]interface{}{request},
    58  	}
    59  
    60  	requestBuf, marshalErr = json.Marshal(jrpcRequest)
    61  
    62  	return
    63  }
    64  
    65  func jrpcMarshalResponse(requestID uint64, responseError error, response interface{}) (responseBuf []byte, marshalErr error) {
    66  	var (
    67  		jrpcResponse interface{}
    68  	)
    69  
    70  	if nil == responseError {
    71  		if nil == response {
    72  			jrpcResponse = &jrpcResponseIDStruct{
    73  				ID: requestID,
    74  			}
    75  		} else {
    76  			jrpcResponse = &jrpcResponseNoErrorStruct{
    77  				ID:     requestID,
    78  				Result: response,
    79  			}
    80  		}
    81  	} else {
    82  		if nil == response {
    83  			jrpcResponse = &jrpcResponseIDAndErrorStruct{
    84  				ID:    requestID,
    85  				Error: responseError.Error(),
    86  			}
    87  		} else {
    88  			jrpcResponse = &jrpcResponseWithErrorStruct{
    89  				ID:     requestID,
    90  				Error:  responseError.Error(),
    91  				Result: response,
    92  			}
    93  		}
    94  	}
    95  
    96  	responseBuf, marshalErr = json.Marshal(jrpcResponse)
    97  
    98  	return
    99  }
   100  
   101  func jrpcUnmarshalRequestForMethodAndID(requestBuf []byte) (requestMethod string, requestID uint64, unmarshalErr error) {
   102  	var (
   103  		jrpcRequest *jrpcRequestMethodAndIDStruct
   104  	)
   105  
   106  	jrpcRequest = &jrpcRequestMethodAndIDStruct{}
   107  
   108  	unmarshalErr = json.Unmarshal(requestBuf, jrpcRequest)
   109  
   110  	if nil == unmarshalErr {
   111  		requestMethod = jrpcRequest.Method
   112  		requestID = jrpcRequest.ID
   113  	}
   114  
   115  	return
   116  }
   117  
   118  func jrpcUnmarshalRequest(requestID uint64, requestBuf []byte, request interface{}) (unmarshalErr error) {
   119  	var (
   120  		jrpcRequest *jrpcRequestStruct
   121  	)
   122  
   123  	jrpcRequest = &jrpcRequestStruct{
   124  		Params: [1]interface{}{request},
   125  	}
   126  
   127  	unmarshalErr = json.Unmarshal(requestBuf, jrpcRequest)
   128  
   129  	if (nil == unmarshalErr) && (requestID != jrpcRequest.ID) {
   130  		unmarshalErr = fmt.Errorf("requestID mismatch")
   131  	}
   132  
   133  	return
   134  }
   135  
   136  func jrpcUnmarshalResponseForIDAndError(responseBuf []byte) (requestID uint64, responseErr error, unmarshalErr error) {
   137  	var (
   138  		jrpcResponse *jrpcResponseIDAndErrorStruct
   139  	)
   140  
   141  	jrpcResponse = &jrpcResponseIDAndErrorStruct{}
   142  
   143  	unmarshalErr = json.Unmarshal(responseBuf, jrpcResponse)
   144  
   145  	if nil == unmarshalErr {
   146  		requestID = jrpcResponse.ID
   147  		if "" == jrpcResponse.Error {
   148  			responseErr = nil
   149  		} else {
   150  			responseErr = fmt.Errorf("%s", jrpcResponse.Error)
   151  		}
   152  	}
   153  
   154  	return
   155  }
   156  
   157  func jrpcUnmarshalResponse(requestID uint64, responseBuf []byte, response interface{}) (unmarshalErr error) {
   158  	var (
   159  		jrpcResponse *jrpcResponseWithErrorStruct
   160  	)
   161  
   162  	jrpcResponse = &jrpcResponseWithErrorStruct{
   163  		Result: response,
   164  	}
   165  
   166  	unmarshalErr = json.Unmarshal(responseBuf, jrpcResponse)
   167  
   168  	if (nil == unmarshalErr) && (requestID != jrpcResponse.ID) {
   169  		unmarshalErr = fmt.Errorf("requestID mismatch")
   170  	}
   171  
   172  	return
   173  }