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 }