github.com/erda-project/erda-infra@v1.0.9/providers/component-protocol/provider.go (about)

     1  // Copyright (c) 2021 Terminus, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package componentprotocol
    16  
    17  import (
    18  	"net/http"
    19  	"reflect"
    20  
    21  	jsi "github.com/json-iterator/go"
    22  	"github.com/sirupsen/logrus"
    23  
    24  	"github.com/erda-project/erda-infra/base/logs"
    25  	"github.com/erda-project/erda-infra/base/servicehub"
    26  	"github.com/erda-project/erda-infra/pkg/transport"
    27  	transhttp "github.com/erda-project/erda-infra/pkg/transport/http"
    28  	"github.com/erda-project/erda-infra/providers/component-protocol/protobuf/proto-go/cp/pb"
    29  	"github.com/erda-project/erda-infra/providers/i18n"
    30  )
    31  
    32  type config struct {
    33  }
    34  
    35  // +provider
    36  type provider struct {
    37  	Cfg      *config
    38  	Log      logs.Logger
    39  	Register transport.Register
    40  
    41  	tran             i18n.I18n
    42  	customContextKVs map[interface{}]interface{}
    43  
    44  	protocolService *protocolService
    45  	// internalTran    i18n.Translator `translator:"18n-cp-internal"`
    46  }
    47  
    48  // Init .
    49  func (p *provider) Init(ctx servicehub.Context) error {
    50  	p.customContextKVs = make(map[interface{}]interface{})
    51  	p.protocolService = &protocolService{p: p}
    52  	if p.Register != nil {
    53  		pb.RegisterCPServiceImp(p.Register, p.protocolService, transport.WithHTTPOptions(
    54  			transhttp.WithEncoder(encoder),
    55  			transhttp.WithErrorEncoder(errorEncoder),
    56  		))
    57  	}
    58  	return nil
    59  }
    60  
    61  // Error .
    62  type Error interface {
    63  	HTTPStatus() int
    64  }
    65  
    66  func encoder(rw http.ResponseWriter, r *http.Request, obj interface{}) error {
    67  	if obj == nil {
    68  		return nil
    69  	}
    70  	renderResp, ok := obj.(*pb.RenderResponse)
    71  	if !ok {
    72  		logrus.Errorf("response obj is not *pb.RenderResponse type")
    73  		return nil
    74  	}
    75  	rw.Header().Set("Content-Type", "application/json")
    76  	if renderResp.Protocol != nil && renderResp.Protocol.GlobalState != nil &&
    77  		renderResp.Protocol.GlobalState["_userIDs_"] != nil {
    78  		rw.Header().Set("X-Need-User-Info", "true")
    79  	}
    80  	resp := map[string]interface{}{
    81  		"success": true,
    82  		"data":    renderResp,
    83  		"err": map[string]interface{}{
    84  			"code": "",
    85  			"msg":  "",
    86  			"ctx":  nil,
    87  		},
    88  	}
    89  	logrus.Infof("[DEBUG] start marshal in encoder")
    90  	data, err := jsi.Marshal(resp)
    91  	if err != nil {
    92  		return err
    93  	}
    94  	logrus.Infof("[DEBUG] end marshal in encoder")
    95  	if _, err = rw.Write(data); err != nil {
    96  		return err
    97  	}
    98  	return nil
    99  }
   100  
   101  func errorEncoder(rw http.ResponseWriter, request *http.Request, err error) {
   102  	var status int
   103  	if e, ok := err.(Error); ok {
   104  		status = e.HTTPStatus()
   105  	} else {
   106  		status = http.StatusInternalServerError
   107  	}
   108  	rw.Header().Set("Content-Type", "application/json")
   109  	rw.WriteHeader(status)
   110  	byts, _ := jsi.Marshal(map[string]interface{}{
   111  		"success": false,
   112  		"err": map[string]interface{}{
   113  			"code": status,
   114  			"msg":  err.Error(),
   115  		},
   116  	})
   117  	rw.Write(byts)
   118  }
   119  
   120  // Provide .
   121  func (p *provider) Provide(ctx servicehub.DependencyContext, args ...interface{}) interface{} {
   122  	return p
   123  }
   124  
   125  func init() {
   126  	interfaceType := reflect.TypeOf((*Interface)(nil)).Elem()
   127  	servicehub.Register("component-protocol", &servicehub.Spec{
   128  		Services:             pb.ServiceNames(),
   129  		Types:                append(pb.Types(), interfaceType),
   130  		OptionalDependencies: []string{"service-register"},
   131  		Description:          "",
   132  		ConfigFunc: func() interface{} {
   133  			return &config{}
   134  		},
   135  		Creator: func() servicehub.Provider {
   136  			return &provider{}
   137  		},
   138  	})
   139  }