140 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			140 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
/**
 | 
						|
 * Copyright (c) 2021 OceanBase
 | 
						|
 * OceanBase CE is licensed under Mulan PubL v2.
 | 
						|
 * You can use this software according to the terms and conditions of the Mulan PubL v2.
 | 
						|
 * You may obtain a copy of Mulan PubL v2 at:
 | 
						|
 *          http://license.coscl.org.cn/MulanPubL-2.0
 | 
						|
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 | 
						|
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 | 
						|
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 | 
						|
 * See the Mulan PubL v2 for more details.
 | 
						|
 */
 | 
						|
 | 
						|
package server
 | 
						|
 | 
						|
import (
 | 
						|
	"context"
 | 
						|
	"fmt"
 | 
						|
	"strconv"
 | 
						|
	"sync"
 | 
						|
 | 
						|
	"github.com/gin-gonic/gin"
 | 
						|
	"github.com/pkg/errors"
 | 
						|
	// log "github.com/sirupsen/logrus"
 | 
						|
 | 
						|
	"github.com/oceanbase/configserver/model"
 | 
						|
)
 | 
						|
 | 
						|
const (
 | 
						|
	CONFIG_URL_FORMAT = "%s/services?Action=ObRootServiceInfo&ObCluster=%s"
 | 
						|
)
 | 
						|
 | 
						|
var obProxyConfigOnce sync.Once
 | 
						|
var obProxyConfigFunc func(*gin.Context)
 | 
						|
var obProxyConfigWithTemplateOnce sync.Once
 | 
						|
var obProxyConfigWithTemplateFunc func(*gin.Context)
 | 
						|
 | 
						|
func getObProxyConfigFunc() func(*gin.Context) {
 | 
						|
	obProxyConfigOnce.Do(func() {
 | 
						|
		obProxyConfigFunc = handlerFunctionWrapper(getObProxyConfig)
 | 
						|
	})
 | 
						|
	return obProxyConfigFunc
 | 
						|
}
 | 
						|
 | 
						|
func getObProxyConfigWithTemplateFunc() func(*gin.Context) {
 | 
						|
	obProxyConfigWithTemplateOnce.Do(func() {
 | 
						|
		obProxyConfigWithTemplateFunc = handlerFunctionWrapper(getObProxyConfigWithTemplate)
 | 
						|
	})
 | 
						|
	return obProxyConfigWithTemplateFunc
 | 
						|
}
 | 
						|
 | 
						|
func getServiceAddress() string {
 | 
						|
	return fmt.Sprintf("http://%s:%d", GetConfigServer().Config.Vip.Address, GetConfigServer().Config.Vip.Port)
 | 
						|
}
 | 
						|
 | 
						|
func isVersionOnly(c *gin.Context) (bool, error) {
 | 
						|
	ret := false
 | 
						|
	var err error
 | 
						|
	versionOnly, ok := c.GetQuery("VersionOnly")
 | 
						|
	if ok {
 | 
						|
		ret, err = strconv.ParseBool(versionOnly)
 | 
						|
	}
 | 
						|
	return ret, err
 | 
						|
}
 | 
						|
 | 
						|
func getObProxyConfig(ctxlog context.Context, c *gin.Context) *ApiResponse {
 | 
						|
	var response *ApiResponse
 | 
						|
	client := GetConfigServer().Client
 | 
						|
 | 
						|
	versionOnly, err := isVersionOnly(c)
 | 
						|
	if err != nil {
 | 
						|
		return NewIllegalArgumentResponse(errors.Wrap(err, "invalid parameter, failed to parse versiononly"))
 | 
						|
	}
 | 
						|
 | 
						|
	rootServiceInfoUrlMap := make(map[string]*model.RootServiceInfoUrl)
 | 
						|
	clusters, err := client.ObCluster.Query().All(context.Background())
 | 
						|
	if err != nil {
 | 
						|
		return NewErrorResponse(errors.Wrap(err, "query ob clusters"))
 | 
						|
	}
 | 
						|
 | 
						|
	for _, cluster := range clusters {
 | 
						|
		rootServiceInfoUrlMap[cluster.Name] = &model.RootServiceInfoUrl{
 | 
						|
			ObCluster: cluster.Name,
 | 
						|
			Url:       fmt.Sprintf(CONFIG_URL_FORMAT, getServiceAddress(), cluster.Name),
 | 
						|
		}
 | 
						|
	}
 | 
						|
	rootServiceInfoUrls := make([]*model.RootServiceInfoUrl, 0, len(rootServiceInfoUrlMap))
 | 
						|
	for _, info := range rootServiceInfoUrlMap {
 | 
						|
		rootServiceInfoUrls = append(rootServiceInfoUrls, info)
 | 
						|
	}
 | 
						|
	obProxyConfig, err := model.NewObProxyConfig(getServiceAddress(), rootServiceInfoUrls)
 | 
						|
	if err != nil {
 | 
						|
		response = NewErrorResponse(errors.Wrap(err, "generate obproxy config"))
 | 
						|
	} else {
 | 
						|
		if versionOnly {
 | 
						|
			response = NewSuccessResponse(model.NewObProxyConfigVersionOnly(obProxyConfig.Version))
 | 
						|
		} else {
 | 
						|
			response = NewSuccessResponse(obProxyConfig)
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return response
 | 
						|
}
 | 
						|
 | 
						|
func getObProxyConfigWithTemplate(ctxlog context.Context, c *gin.Context) *ApiResponse {
 | 
						|
	var response *ApiResponse
 | 
						|
	client := GetConfigServer().Client
 | 
						|
 | 
						|
	versionOnly, err := isVersionOnly(c)
 | 
						|
	if err != nil {
 | 
						|
		return NewIllegalArgumentResponse(errors.Wrap(err, "invalid parameter, failed to parse versiononly"))
 | 
						|
	}
 | 
						|
 | 
						|
	clusterMap := make(map[string]interface{})
 | 
						|
	clusters, err := client.ObCluster.Query().All(context.Background())
 | 
						|
 | 
						|
	if err != nil {
 | 
						|
		return NewErrorResponse(errors.Wrap(err, "query ob clusters"))
 | 
						|
	}
 | 
						|
 | 
						|
	for _, cluster := range clusters {
 | 
						|
		clusterMap[cluster.Name] = nil
 | 
						|
	}
 | 
						|
	clusterNames := make([]string, 0, len(clusterMap))
 | 
						|
	for clusterName := range clusterMap {
 | 
						|
		clusterNames = append(clusterNames, clusterName)
 | 
						|
	}
 | 
						|
 | 
						|
	obProxyConfigWithTemplate, err := model.NewObProxyConfigWithTemplate(getServiceAddress(), clusterNames)
 | 
						|
 | 
						|
	if err != nil {
 | 
						|
		response = NewErrorResponse(errors.Wrap(err, "generate obproxy config with template"))
 | 
						|
	} else {
 | 
						|
		if versionOnly {
 | 
						|
			response = NewSuccessResponse(model.NewObProxyConfigVersionOnly(obProxyConfigWithTemplate.Version))
 | 
						|
		} else {
 | 
						|
			response = NewSuccessResponse(obProxyConfigWithTemplate)
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return response
 | 
						|
}
 |