2 * Copyright 2020 Huawei Technologies Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
29 "github.com/apache/servicecomb-service-center/pkg/log"
30 "github.com/apache/servicecomb-service-center/pkg/rest"
31 "github.com/apache/servicecomb-service-center/pkg/util"
32 "github.com/apache/servicecomb-service-center/server/core"
33 "github.com/apache/servicecomb-service-center/server/core/backend"
34 "github.com/apache/servicecomb-service-center/server/core/proto"
35 svcerror "github.com/apache/servicecomb-service-center/server/error"
36 "github.com/apache/servicecomb-service-center/server/plugin/pkg/registry"
37 "github.com/apache/servicecomb-service-center/server/rest/controller"
38 svcutil "github.com/apache/servicecomb-service-center/server/service/util"
41 func InfoToProperties(properties map[string]string, key string, value string) {
43 properties[key] = value
47 func JsonTextToObj(jsonText string) (interface{}, error) {
48 data := []byte(jsonText)
49 var jsonMap interface{}
50 decoder := json.NewDecoder(bytes.NewReader(data))
51 err := decoder.Decode(&jsonMap)
58 func GetHostPort(uri string) (string, int) {
59 idx := strings.LastIndex(uri, ":")
64 port, err = strconv.Atoi(uri[idx+1:])
73 func GetHTTPTags(r *http.Request) (url.Values, []string) {
75 query := r.URL.Query()
76 keys := query.Get("tags")
78 ids = strings.Split(keys, ",")
84 func GetFindParam(r *http.Request) (context.Context, *proto.FindInstancesRequest, url.Values) {
86 query, ids := GetHTTPTags(r)
88 req := &proto.FindInstancesRequest{
89 ConsumerServiceId: r.Header.Get("X-ConsumerId"),
90 AppId: query.Get("instance_id"),
91 ServiceName: query.Get("ser_name"),
92 VersionRule: query.Get("version"),
93 Environment: query.Get("env"),
100 if req.VersionRule == "" {
101 req.VersionRule = "latest"
103 ctx := util.SetTargetDomainProject(r.Context(), r.Header.Get("X-Domain-Name"), query.Get(":project"))
104 return ctx, req, query
108 func WriteHTTPResponse(w http.ResponseWriter, resp *proto.Response, obj interface{}) {
109 if resp != nil && resp.GetCode() != proto.Response_SUCCESS {
110 controller.WriteError(w, resp.GetCode(), resp.GetMessage())
114 w.Header().Set(rest.HEADER_RESPONSE_STATUS, strconv.Itoa(http.StatusOK))
115 w.Header().Set(rest.HEADER_CONTENT_TYPE, rest.CONTENT_TYPE_TEXT)
116 w.WriteHeader(http.StatusOK)
120 objJSON, err := json.Marshal(obj)
122 controller.WriteError(w, svcerror.ErrInternal, err.Error())
125 w.Header().Set(rest.HEADER_RESPONSE_STATUS, strconv.Itoa(http.StatusOK))
126 w.Header().Set(rest.HEADER_CONTENT_TYPE, rest.CONTENT_TYPE_JSON)
127 w.WriteHeader(http.StatusCreated)
128 _, err = fmt.Fprintln(w, util.BytesToStringWithNoCopy(objJSON))
134 func WriteResponse(w http.ResponseWriter, resp *proto.Response, obj interface{}) {
135 if resp != nil && resp.GetCode() != proto.Response_SUCCESS {
136 controller.WriteError(w, resp.GetCode(), resp.GetMessage())
140 w.Header().Set(rest.HEADER_RESPONSE_STATUS, strconv.Itoa(http.StatusOK))
141 w.Header().Set(rest.HEADER_CONTENT_TYPE, rest.CONTENT_TYPE_TEXT)
142 w.WriteHeader(http.StatusOK)
146 objJSON, err := json.Marshal(obj)
148 controller.WriteError(w, svcerror.ErrInternal, err.Error())
151 w.Header().Set(rest.HEADER_RESPONSE_STATUS, strconv.Itoa(http.StatusOK))
152 w.Header().Set(rest.HEADER_CONTENT_TYPE, rest.CONTENT_TYPE_JSON)
153 w.WriteHeader(http.StatusOK)
154 _, err = fmt.Fprintln(w, util.BytesToStringWithNoCopy(objJSON))
160 func HttpErrResponse(w http.ResponseWriter, statusCode int, obj interface{}) {
162 w.Header().Set(rest.HEADER_RESPONSE_STATUS, strconv.Itoa(statusCode))
163 w.Header().Set(rest.HEADER_CONTENT_TYPE, rest.CONTENT_TYPE_TEXT)
164 w.WriteHeader(statusCode)
168 objJSON, err := json.Marshal(obj)
170 log.Errorf(err, "json marshal object fail")
173 w.Header().Set(rest.HEADER_RESPONSE_STATUS, strconv.Itoa(http.StatusOK))
174 w.Header().Set(rest.HEADER_CONTENT_TYPE, rest.CONTENT_TYPE_JSON)
175 w.WriteHeader(statusCode)
176 _, err = fmt.Fprintln(w, util.BytesToStringWithNoCopy(objJSON))
178 log.Errorf(err, "send http response fail")
182 // heartbeat use put to update a service register info
183 func Heartbeat(ctx context.Context, mp1SvcId string) error {
184 serviceID := mp1SvcId[:len(mp1SvcId)/2]
185 instanceID := mp1SvcId[len(mp1SvcId)/2:]
186 req := &proto.HeartbeatRequest{
187 ServiceId: serviceID,
188 InstanceId: instanceID,
190 _, err := core.InstanceAPI.Heartbeat(ctx, req)
194 func GetServiceInstance(ctx context.Context, serviceId string) (*proto.MicroServiceInstance, error) {
195 domainProjet := util.ParseDomainProject(ctx)
196 serviceID := serviceId[:len(serviceId)/2]
197 instanceID := serviceId[len(serviceId)/2:]
198 instance, err := svcutil.GetInstance(ctx, domainProjet, serviceID, instanceID)
203 err = fmt.Errorf("domainProjet %s sservice Id %s not exist", domainProjet, serviceID)
208 func FindInstanceByKey(result url.Values) (*proto.FindInstancesResponse, error) {
209 serCategoryId := result.Get("ser_category_id")
210 scopeOfLocality := result.Get("scope_of_locality")
211 consumedLocalOnly := result.Get("consumed_local_only")
212 isLocal := result.Get("is_local")
213 isQueryAllSvc := serCategoryId == "" && scopeOfLocality == "" && consumedLocalOnly == "" && isLocal == ""
215 opts := []registry.PluginOp{
216 registry.OpGet(registry.WithStrKey("/cse-sr/inst/files///"), registry.WithPrefix()),
218 resp, err := backend.Registry().TxnWithCmp(context.Background(), opts, nil, nil)
220 return nil, fmt.Errorf("query from etch error")
222 var findResp []*proto.MicroServiceInstance
223 for _, value := range resp.Kvs {
224 var instance map[string]interface{}
225 err = json.Unmarshal(value.Value, &instance)
227 return nil, fmt.Errorf("string convert to instance failed")
229 dci := &proto.DataCenterInfo{Name: "", Region: "", AvailableZone: ""}
230 instance["datacenterinfo"] = dci
232 message, err = json.Marshal(&instance)
234 log.Errorf(err, "Instance convert to string failed!")
236 var ins *proto.MicroServiceInstance
237 err = json.Unmarshal(message, &ins)
239 log.Errorf(err, "String convert to MicroServiceInstance failed!")
241 property := ins.Properties
242 if isQueryAllSvc && property != nil {
243 findResp = append(findResp, ins)
244 } else if strings.EqualFold(property["serCategory/id"], serCategoryId) ||
245 strings.EqualFold(property["ConsumedLocalOnly"], consumedLocalOnly) ||
246 strings.EqualFold(property["ScopeOfLocality"], scopeOfLocality) ||
247 strings.EqualFold(property["IsLocal"], isLocal) {
248 findResp = append(findResp, ins)
251 if len(findResp) == 0 {
252 return nil, fmt.Errorf("service not found")
254 response := &proto.Response{Code: 0, Message: ""}
255 ret := &proto.FindInstancesResponse{Response: response, Instances: findResp}
259 func SetMapValue(theMap map[string]interface{}, key string, val interface{}) {
260 mapValue, ok := theMap[key]
261 if !ok || mapValue == nil {