2 * Copyright (c) 2018 ZTE Corporation.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * and the Apache License 2.0 which both accompany this distribution,
6 * and are available at http://www.eclipse.org/legal/epl-v10.html
7 * and http://www.apache.org/licenses/LICENSE-2.0
10 * ZTE - initial Project
23 istioModel "istio.io/istio/pilot/pkg/model"
27 cachedServices []*models.MsbService
31 routerulePrefix = "msbcustom."
34 func SyncMsbData(newServices []*models.MsbService) {
35 if len(cachedServices) == 0 {
38 log.Log.Debug("sync msb rewrite rule to pilot")
39 createServices, updateServices, deleteServices := compareServices(cachedServices, newServices)
41 saveService(OperationCreate, createServices)
42 saveService(OperationUpdate, updateServices)
43 saveService(OperationDelete, deleteServices)
45 cachedServices = newServices
48 func saveService(operation Operation, services []*models.MsbService) {
49 if len(services) == 0 {
52 configs, err := parseServiceToConfig(services)
54 log.Log.Error("param parse error", err)
57 fails := Save(operation, configs)
58 log.Log.Debug("%d services need to %s, %d fails. \n", len(services), operation, len(fails))
61 func deleteAllMsbRules() {
62 log.Log.Informational("delete all msb rules")
63 configs, err := List("route-rule", "")
69 deleteList := msbRuleFilter(configs)
71 Save(OperationDelete, deleteList)
74 func msbRuleFilter(configs []istioModel.Config) []istioModel.Config {
75 res := make([]istioModel.Config, 0, len(configs))
77 for _, config := range configs {
78 if strings.HasPrefix(config.Name, routerulePrefix) {
79 res = append(res, config)
86 func compareServices(oldServices, newServices []*models.MsbService) (createServices, updateServices, deleteServices []*models.MsbService) {
87 oldServiceMap := toServiceMap(oldServices)
88 newServiceMap := toServiceMap(newServices)
90 for key, newService := range newServiceMap {
91 if oldService, exist := oldServiceMap[key]; exist {
92 // service exist: check whether need to update
93 if oldService.ModifyIndex != newService.ModifyIndex {
94 updateServices = append(updateServices, newService)
97 // service not exist: add
98 createServices = append(createServices, newService)
101 delete(oldServiceMap, key)
104 for _, service := range oldServiceMap {
105 deleteServices = append(deleteServices, service)
111 func toServiceMap(services []*models.MsbService) map[string]*models.MsbService {
112 serviceMap := make(map[string]*models.MsbService)
114 for _, service := range services {
115 serviceMap[service.ServiceName] = service
121 func parseServiceToConfig(services []*models.MsbService) ([]istioModel.Config, error) {
122 publishServices := getPublishServiceMap()
123 apiGateway := os.Getenv(models.EnvApiGatewayName)
125 for _, service := range services {
126 if publishService, exist := publishServices[getPublishServiceKey(service)]; exist {
128 if service.ConsulLabels.BaseInfo != nil {
129 rule := createRouteRule(apiGateway, publishService.PublishUrl, service.ServiceName, service.ConsulLabels.BaseInfo.Url)
130 buf.WriteString(rule)
134 return ParseParam(buf.String())
137 func getPublishServiceKey(svc *models.MsbService) string {
138 res := svc.ServiceName
140 if svc.ConsulLabels.BaseInfo != nil {
141 res += svc.ConsulLabels.BaseInfo.Version
144 if svc.ConsulLabels.NameSpace != nil {
145 res += svc.ConsulLabels.NameSpace.NameSpace
151 func getPublishServiceMap() map[string]*models.PublishService {
152 publishServices := msb.GetAllPublishServices()
154 res := make(map[string]*models.PublishService)
156 for _, svc := range publishServices {
157 key := svc.ServiceName + svc.Version + svc.NameSpace
164 func createRouteRule(sourceService, sourcePath, targetService, targetPath string) string {
165 if sourcePath == "" {
168 if targetPath == "" {
171 // rule name must consist of lower case alphanuberic charactoers, '-' or '.'. and must start and end with an alphanumberic charactore
172 r := regexp.MustCompile("[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*")
173 strs := r.FindAllString(targetService, -1)
174 name := routerulePrefix + strings.Join(strs, "")
175 name = strings.ToLower(name)
178 "apiVersion": "config.istio.io/v1alpha2",
181 "name": "` + name + `"
185 "name":"` + sourceService + `"
191 "prefix": "` + sourcePath + `"
197 "uri": "` + targetPath + `"
202 "name":"` + targetService + `"