apiStrategy.go 15.4 KB
Newer Older
Y
Your Name 已提交
1
package console_sqlite3
E
eoLinker API Management 已提交
2 3

import (
Y
Your Name 已提交
4
	"database/sql"
E
eoLinker API Management 已提交
5 6 7 8 9
	"fmt"
	"strconv"
	"strings"
	"time"

Y
Your Name 已提交
10
	"github.com/eolinker/goku-api-gateway/server/dao"
E
eoLinker API Management 已提交
11 12
)

Y
Your Name 已提交
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
//APIStrategyDao APIStrategyDao
type APIStrategyDao struct {
	db *sql.DB
}

//NewAPIStrategyDao new APIStrategyDao
func NewAPIStrategyDao() *APIStrategyDao {
	return &APIStrategyDao{}
}

//Create create
func (d *APIStrategyDao) Create(db *sql.DB) (interface{}, error) {
	d.db = db
	var i dao.APIStrategyDao = d
	return &i, nil
}

Y
Your Name 已提交
30
//AddAPIToStrategy 将接口加入策略组
Y
Your Name 已提交
31 32
func (d *APIStrategyDao) AddAPIToStrategy(apiList []string, strategyID string) (bool, string, error) {
	db := d.db
E
eoLinker API Management 已提交
33 34 35 36 37 38 39 40
	now := time.Now().Format("2006-01-02 15:04:05")
	sql2 := "SELECT apiID FROM goku_conn_strategy_api WHERE apiID = ? AND strategyID = ?"
	sql1 := "SELECT apiID FROM goku_gateway_api WHERE apiID = ?"
	sql3 := "INSERT INTO goku_conn_strategy_api (apiID,strategyID,updateTime) VALUES (?,?,?)"
	Tx, _ := db.Begin()
	stmt1, _ := Tx.Prepare(sql1)
	stmt2, _ := Tx.Prepare(sql2)
	stmt3, _ := Tx.Prepare(sql3)
41 42 43
	defer stmt1.Close()
	defer stmt2.Close()
	defer stmt3.Close()
E
eoLinker API Management 已提交
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79

	for _, apiID := range apiList {
		id, err := strconv.Atoi(apiID)
		if err != nil {
			continue
		}
		// 查询ID是否存在,若不存在,则跳过

		var aID int
		err = stmt1.QueryRow(apiID).Scan(&aID)
		if err != nil {
			continue
		}
		// 查询此接口是否被加入策略组

		err = stmt2.QueryRow(apiID, strategyID).Scan(&aID)
		if err == nil {
			continue
		}
		_, err = stmt3.Exec(id, strategyID, now)
		if err != nil {
			Tx.Rollback()
			return false, "[ERROR]Failed to insert data!", err
		}
	}
	// 更新策略修改时间
	sql4 := "UPDATE goku_gateway_strategy SET updateTime = ? WHERE strategyID = ?"
	_, err := Tx.Exec(sql4, now, strategyID)
	if err != nil {
		Tx.Rollback()
		return false, "[ERROR]Failed to update data!", err
	}
	Tx.Commit()
	return true, "", nil
}

Y
Your Name 已提交
80
// SetAPITargetOfStrategy 重定向接口负载
Y
Your Name 已提交
81 82
func (d *APIStrategyDao) SetAPITargetOfStrategy(apiID int, strategyID string, target string) (bool, string, error) {
	db := d.db
E
eoLinker API Management 已提交
83 84 85 86 87
	sql := "UPDATE goku_conn_strategy_api SET `target` = ? where apiID = ? AND strategyID = ? "
	stmt, err := db.Prepare(sql)
	if err != nil {
		return false, err.Error(), err
	}
88
	defer stmt.Close()
Y
Your Name 已提交
89
	_, e := stmt.Exec(target, apiID, strategyID)
E
eoLinker API Management 已提交
90 91 92 93 94 95 96 97

	if e != nil {
		return false, e.Error(), e
	}

	return true, "", nil
}

Y
Your Name 已提交
98
// BatchSetAPITargetOfStrategy 批量重定向接口负载
Y
Your Name 已提交
99
func (d *APIStrategyDao) BatchSetAPITargetOfStrategy(apiIds []int, strategyID string, target string) (bool, string, error) {
E
eoLinker API Management 已提交
100 101 102 103 104 105 106 107 108 109 110
	idLen := len(apiIds)
	s := make([]interface{}, 0, idLen+2)
	c := ""
	s = append(s, target, strategyID)
	for i, id := range apiIds {
		c += "?"
		if i < idLen-1 {
			c += ","
		}
		s = append(s, id)
	}
Y
Your Name 已提交
111
	db := d.db
E
eoLinker API Management 已提交
112 113 114 115 116
	sql := fmt.Sprintf("UPDATE goku_conn_strategy_api SET `target` = ? where strategyID = ? AND apiID IN (%s) ", c)
	stmt, err := db.Prepare(sql)
	if err != nil {
		return false, err.Error(), err
	}
117
	defer stmt.Close()
E
eoLinker API Management 已提交
118 119 120 121 122 123 124 125 126
	_, e := stmt.Exec(s...)

	if e != nil {
		return false, e.Error(), e
	}

	return true, "", nil
}

Y
Your Name 已提交
127
func (d *APIStrategyDao) getAPIOfStrategyRule(condition int, balanceNames []string, ids []int) []string {
E
eoLinker API Management 已提交
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
	rule := make([]string, 0, 2)
	switch condition {
	case 1, 2:
		{
			balenceNameLen := len(balanceNames)
			nameType := "A.balanceName"
			if condition == 2 {
				nameType = "S.`target`"
			}
			nameStr := ""
			for i := 0; i < balenceNameLen; i++ {
				nameStr += fmt.Sprintf("'%s'", balanceNames[i])
				if i < balenceNameLen-1 {
					nameStr += ","
				}
			}
			rule = append(rule, fmt.Sprintf("%s IN (%s)", nameType, nameStr))
		}
	case 3, 4:
		{
			idsStr := ""
			idLen := len(ids)
			if len(ids) < 1 {
				break
			}
			for i, id := range ids {
				idsStr += strconv.Itoa(id)
				if i < idLen-1 {
					idsStr += ","
				}
			}
			if condition == 3 {
				rule = append(rule, fmt.Sprintf("A.managerID IN (%s)", idsStr))
			} else if condition == 4 {
				rule = append(rule, fmt.Sprintf("A.lastUpdateUserID IN (%s)", idsStr))
			}
		}
	}
	return rule
}

// GetAPIIDListFromStrategy 获取策略组接口列表
Y
Your Name 已提交
170
func (d *APIStrategyDao) GetAPIIDListFromStrategy(strategyID, keyword string, condition int, ids []int, balanceNames []string) (bool, []int, error) {
E
eoLinker API Management 已提交
171 172 173 174 175 176 177 178 179
	rule := make([]string, 0, 10)

	rule = append(rule, fmt.Sprintf("S.strategyID = '%s'", strategyID))
	if keyword != "" {
		searchRule := "(A.apiName LIKE '%" + keyword + "%' OR A.requestURL LIKE '%" + keyword + "%' "
		searchRule += " OR IFNULL(A.balanceName,'') LIKE '%" + keyword + "%' OR A.targetURL LIKE '%" + keyword + "%' OR S.`target` LIKE '%" + keyword + "%')"
		rule = append(rule, searchRule)
	}
	if condition > 0 {
Y
Your Name 已提交
180
		rule = append(rule, d.getAPIOfStrategyRule(condition, balanceNames, ids)...)
E
eoLinker API Management 已提交
181 182 183 184 185 186
	}
	ruleStr := ""
	if len(rule) > 0 {
		ruleStr += "WHERE " + strings.Join(rule, " AND ")
	}
	sql := fmt.Sprintf("SELECT A.`apiID` FROM `goku_gateway_api` A INNER JOIN `goku_conn_strategy_api` S ON S.`apiID` = A.`apiID` %s", ruleStr)
Y
Your Name 已提交
187
	rows, err := d.db.Query(sql)
E
eoLinker API Management 已提交
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206
	if err != nil {
		return false, make([]int, 0), err
	}
	defer rows.Close()

	//获取记录列
	apiIDList := make([]int, 0)
	for rows.Next() {
		var apiID int
		err = rows.Scan(&apiID)
		if err != nil {
			return false, make([]int, 0), err
		}
		apiIDList = append(apiIDList, apiID)
	}
	return true, apiIDList, nil
}

// GetAPIListFromStrategy 获取策略组接口列表
Y
Your Name 已提交
207
func (d *APIStrategyDao) GetAPIListFromStrategy(strategyID, keyword string, condition, page, pageSize int, ids []int, balanceNames []string) (bool, []map[string]interface{}, int, error) {
E
eoLinker API Management 已提交
208 209 210 211 212 213 214 215 216
	rule := make([]string, 0, 2)

	rule = append(rule, fmt.Sprintf("S.strategyID = '%s'", strategyID))
	if keyword != "" {
		searchRule := "(A.apiName LIKE '%" + keyword + "%' OR A.requestURL LIKE '%" + keyword + "%' "
		searchRule += " OR IFNULL(A.balanceName,'') LIKE '%" + keyword + "%' OR A.targetURL LIKE '%" + keyword + "%' OR S.`target` LIKE '%" + keyword + "%')"
		rule = append(rule, searchRule)
	}
	if condition > 0 {
Y
Your Name 已提交
217
		rule = append(rule, d.getAPIOfStrategyRule(condition, balanceNames, ids)...)
E
eoLinker API Management 已提交
218 219 220 221 222
	}
	ruleStr := ""
	if len(rule) > 0 {
		ruleStr += "WHERE " + strings.Join(rule, " AND ")
	}
Y
Your Name 已提交
223 224

	sql := fmt.Sprintf("SELECT A.`apiID`, A.`apiName`, A.`requestURL`,A.`requestMethod`,CASE WHEN A.`apiType`=0 THEN A.`targetURL` ELSE '' END,A.apiType,IFNULL(A.`targetMethod`,''), A.`isFollow`, IFNULL(A.`updateTime`,'') AS updateTime, A.`lastUpdateUserID`, A.`managerID`, IFNULL(A.`balanceName`,'') As `target`, IFNULL(S.`target`,'') as `rewriteTarget`,  CASE WHEN AD.`remark` is null or AD.`remark` = '' THEN AD.`loginCall` ELSE AD.`remark` END AS managerName, CASE WHEN AD2.`remark` is null or AD2.`remark` = '' THEN AD2.`loginCall` ELSE AD2.`remark` END AS updaterName  FROM `goku_gateway_api` A INNER JOIN `goku_conn_strategy_api` S ON S.`apiID` = A.`apiID` LEFT JOIN `goku_admin` AD ON A.`managerID` = AD.`userID` LEFT JOIN `goku_admin` AD2 ON A.`lastUpdateUserID` = AD2.`userID` %s", ruleStr)
Y
Your Name 已提交
225 226
	count := getCountSQL(d.db, sql)
	rows, err := getPageSQL(d.db, sql, "S.`connID`", "DESC", page, pageSize)
E
eoLinker API Management 已提交
227 228 229 230 231 232 233 234
	if err != nil {
		return false, make([]map[string]interface{}, 0), 0, err
	}
	defer rows.Close()

	//获取记录列
	apiList := make([]map[string]interface{}, 0)
	for rows.Next() {
Y
Your Name 已提交
235
		var apiID, updaterID, managerID, apiType int
E
eoLinker API Management 已提交
236 237
		var apiName, requestURL, updateTime, updaterName, managerName, target, targetURL, rewriteTarget, requestMethod, targetMethod string
		var isFollow bool
Y
Your Name 已提交
238
		err = rows.Scan(&apiID, &apiName, &requestURL, &requestMethod, &targetURL, &apiType, &targetMethod, &isFollow, &updateTime, &updaterID, &managerID, &target, &rewriteTarget, &managerName, &updaterName)
E
eoLinker API Management 已提交
239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254
		if err != nil {
			return false, make([]map[string]interface{}, 0), 0, err
		}
		apiInfo := map[string]interface{}{
			"apiID":         apiID,
			"apiName":       apiName,
			"requestURL":    requestURL,
			"updateTime":    updateTime,
			"updaterName":   updaterName,
			"managerName":   managerName,
			"target":        target,
			"targetURL":     targetURL,
			"rewriteTarget": rewriteTarget,
			"requestMethod": strings.ToUpper(requestMethod),
			"targetMethod":  strings.ToUpper(targetMethod),
			"isFollow":      isFollow,
Y
Your Name 已提交
255
			"apiType":       apiType,
E
eoLinker API Management 已提交
256 257 258 259 260 261
		}
		apiList = append(apiList, apiInfo)
	}
	return true, apiList, count, nil
}

Y
Your Name 已提交
262
// CheckIsExistAPIInStrategy 检查插件是否添加进策略组
Y
Your Name 已提交
263 264
func (d *APIStrategyDao) CheckIsExistAPIInStrategy(apiID int, strategyID string) (bool, string, error) {
	db := d.db
E
eoLinker API Management 已提交
265 266 267 268 269 270 271 272 273 274
	var id int
	sql := "SELECT connID FROM goku_conn_strategy_api WHERE apiID = ? AND strategyID = ?"
	err := db.QueryRow(sql, apiID, strategyID).Scan(&id)
	if err != nil {
		return false, "", err
	}
	return true, "", nil
}

// 获取策略绑定的简易接口列表
Y
Your Name 已提交
275 276
func (d *APIStrategyDao) getSimpleAPIListInStrategy(strategyID string, projectID int) map[string]string {
	db := d.db
E
eoLinker API Management 已提交
277 278 279
	sql := "SELECT goku_gateway_api.requestURL,GROUP_CONCAT(DISTINCT goku_gateway_api.requestMethod) AS requestMethod FROM goku_gateway_api INNER JOIN goku_conn_strategy_api ON goku_gateway_api.apiID = goku_conn_strategy_api.apiID where goku_conn_strategy_api.strategyID = ? AND goku_gateway_api.projectID = ? GROUP BY requestURL"
	rows, err := db.Query(sql, strategyID, projectID)
	if err != nil {
Y
Your Name 已提交
280
		return nil
E
eoLinker API Management 已提交
281 282 283 284 285 286 287
	}
	defer rows.Close()
	simpleMap := make(map[string]string)
	for rows.Next() {
		var requestURL, requestMethod string
		err = rows.Scan(&requestURL, &requestMethod)
		if err != nil {
Y
Your Name 已提交
288
			return nil
E
eoLinker API Management 已提交
289 290 291 292 293 294
		}
		simpleMap[requestURL] = requestMethod
	}
	return simpleMap
}

Y
Your Name 已提交
295
// GetAPIIDListNotInStrategy 获取未被该策略组绑定的接口ID列表(通过项目)
Y
Your Name 已提交
296 297
func (d *APIStrategyDao) GetAPIIDListNotInStrategy(strategyID string, projectID, groupID int, keyword string) (bool, []int, error) {
	requestMap := d.getSimpleAPIListInStrategy(strategyID, projectID)
E
eoLinker API Management 已提交
298 299 300 301 302 303 304 305 306
	rule := make([]string, 0, 3)

	rule = append(rule, fmt.Sprintf("A.projectID = %d", projectID))
	rule = append(rule, fmt.Sprintf("A.apiID NOT IN (SELECT apiID FROM goku_conn_strategy_api WHERE strategyID = '%s')", strategyID))
	if keyword != "" {
		searchRule := "(A.apiName LIKE '%" + keyword + "%' OR A.requestURL LIKE '%" + keyword + "%'"
		searchRule += " OR IFNULL(A.balanceName,'') LIKE '%" + keyword + "%' OR A.targetURL LIKE '%" + keyword + "%')"
		rule = append(rule, searchRule)
	}
Y
Your Name 已提交
307
	groupRule, err := d.getAPIGroupRule(projectID, groupID)
E
eoLinker API Management 已提交
308 309 310 311 312 313 314 315 316 317 318 319
	if err != nil {
		return false, make([]int, 0), err
	}
	if groupRule != "" {
		rule = append(rule, groupRule)
	}
	ruleStr := ""
	if len(rule) > 0 {
		ruleStr += "WHERE " + strings.Join(rule, " AND ")
	}

	sql := fmt.Sprintf("SELECT A.apiID,A.requestURL,A.requestMethod FROM goku_gateway_api A %s", ruleStr)
Y
Your Name 已提交
320
	rows, err := d.db.Query(sql)
E
eoLinker API Management 已提交
321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343
	if err != nil {
		return false, make([]int, 0), err
	}
	defer rows.Close()
	apiIDList := make([]int, 0)
	//获取记录列
	for rows.Next() {
		var apiID int
		var requestURL, requestMethod string
		err = rows.Scan(&apiID, &requestURL, &requestMethod)
		if err != nil {
			return false, make([]int, 0), err
		}
		if value, ok := requestMap[requestURL]; ok {
			if strings.Contains(strings.ToUpper(value), strings.ToUpper(requestMethod)) {
				continue
			}
		}
		apiIDList = append(apiIDList, apiID)
	}
	return true, apiIDList, nil
}

Y
Your Name 已提交
344 345
func (d *APIStrategyDao) getAPIGroupRule(projectID, groupID int) (string, error) {
	db := d.db
E
eoLinker API Management 已提交
346 347 348 349 350 351 352
	if groupID < 1 {
		if groupID == 0 {
			groupRule := fmt.Sprintf("A.groupID = %d", groupID)
			return groupRule, nil
		}
		return "", nil
	}
Y
Your Name 已提交
353 354 355 356 357 358 359 360 361 362 363 364 365 366
	var groupPath string
	sql := "SELECT groupPath FROM goku_gateway_api_group WHERE groupID = ?;"
	err := db.QueryRow(sql, groupID).Scan(&groupPath)
	if err != nil {
		return "", err
	}
	// 获取分组ID列表
	sql = "SELECT GROUP_CONCAT(DISTINCT groupID) AS groupID FROM goku_gateway_api_group WHERE projectID = ? AND groupPath LIKE ?;"
	groupIDList := ""
	err = db.QueryRow(sql, projectID, groupPath+"%").Scan(&groupIDList)
	if err != nil {
		return "", err
	}
	return fmt.Sprintf("A.groupID IN (%s)", groupIDList), nil
E
eoLinker API Management 已提交
367 368 369
}

// GetAPIListNotInStrategy 获取未被该策略组绑定的接口列表(通过项目)
Y
Your Name 已提交
370 371
func (d *APIStrategyDao) GetAPIListNotInStrategy(strategyID string, projectID, groupID, page, pageSize int, keyword string) (bool, []map[string]interface{}, int, error) {
	requestMap := d.getSimpleAPIListInStrategy(strategyID, projectID)
E
eoLinker API Management 已提交
372 373 374 375 376 377 378 379 380 381
	rule := make([]string, 0, 3)

	rule = append(rule, fmt.Sprintf("A.projectID = %d", projectID))
	rule = append(rule, fmt.Sprintf("A.apiID NOT IN (SELECT apiID FROM goku_conn_strategy_api WHERE strategyID = '%s')", strategyID))
	if keyword != "" {
		searchRule := "(A.apiName LIKE '%" + keyword + "%' OR A.requestURL LIKE '%" + keyword + "%'"
		searchRule += " OR IFNULL(A.balanceName,'') LIKE '%" + keyword + "%' OR A.targetURL LIKE '%" + keyword + "%')"
		rule = append(rule, searchRule)
	}

Y
Your Name 已提交
382
	groupRule, err := d.getAPIGroupRule(projectID, groupID)
E
eoLinker API Management 已提交
383 384 385 386 387 388 389 390 391 392 393
	if err != nil {
		return false, make([]map[string]interface{}, 0), 0, err
	}
	if groupRule != "" {
		rule = append(rule, groupRule)
	}

	ruleStr := ""
	if len(rule) > 0 {
		ruleStr += "WHERE " + strings.Join(rule, " AND ")
	}
Y
Your Name 已提交
394
	sql := fmt.Sprintf("SELECT A.apiID,A.apiName,A.requestURL,A.requestMethod,IFNULL(A.balanceName,''),CASE WHEN A.apiType=0 THEN A.targetURL ELSE '' END,A.apiType,IFNULL(A.`targetMethod`,''), A.`isFollow`,A.groupID,IFNULL(G.groupPath,A.groupID) FROM goku_gateway_api A LEFT JOIN goku_gateway_api_group G ON G.groupID = A.groupID  %s", ruleStr)
Y
Your Name 已提交
395 396
	count := getCountSQL(d.db, sql)
	rows, err := getPageSQL(d.db, sql, "A.`updateTime`", "DESC", page, pageSize)
E
eoLinker API Management 已提交
397 398 399 400 401 402 403
	if err != nil {
		return false, make([]map[string]interface{}, 0), 0, err
	}
	defer rows.Close()
	apiList := make([]map[string]interface{}, 0)
	//获取记录列
	for rows.Next() {
Y
Your Name 已提交
404
		var apiID, groupID, apiType int
E
eoLinker API Management 已提交
405 406
		var apiName, requestURL, requestMethod, targetServer, groupPath, targetURL, targetMethod string
		var isFollow bool
Y
Your Name 已提交
407
		err = rows.Scan(&apiID, &apiName, &requestURL, &requestMethod, &targetServer, &targetURL, &apiType, &targetMethod, &isFollow, &groupID, &groupPath)
E
eoLinker API Management 已提交
408 409 410 411 412
		if err != nil {
			return false, make([]map[string]interface{}, 0), 0, err
		}
		if value, ok := requestMap[requestURL]; ok {
			if strings.Contains(strings.ToUpper(value), strings.ToUpper(requestMethod)) {
Y
Your Name 已提交
413
				count = count - 1
E
eoLinker API Management 已提交
414 415 416 417 418 419 420 421 422 423 424 425 426 427
				continue
			}
		}
		apiInfo := map[string]interface{}{
			"apiID":         apiID,
			"apiName":       apiName,
			"requestURL":    requestURL,
			"requestMethod": strings.ToUpper(requestMethod),
			"target":        targetServer,
			"targetURL":     targetURL,
			"groupID":       groupID,
			"groupPath":     groupPath,
			"targetMethod":  strings.ToUpper(targetMethod),
			"isFollow":      isFollow,
Y
Your Name 已提交
428
			"apiType":       apiType,
E
eoLinker API Management 已提交
429 430 431 432 433 434
		}
		apiList = append(apiList, apiInfo)
	}
	return true, apiList, count, nil
}

Y
Your Name 已提交
435
//BatchDeleteAPIInStrategy 批量删除策略组接口
Y
Your Name 已提交
436 437
func (d *APIStrategyDao) BatchDeleteAPIInStrategy(apiIDList, strategyID string) (bool, string, error) {
	db := d.db
E
eoLinker API Management 已提交
438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461
	now := time.Now().Format("2006-01-02 15:04:05")
	Tx, _ := db.Begin()
	sql := "DELETE FROM goku_conn_strategy_api WHERE strategyID = ? AND apiID IN (" + apiIDList + ")"
	_, err := Tx.Exec(sql, strategyID)
	if err != nil {
		Tx.Rollback()
		return false, "[ERROR]Fail to excute SQL statement!", err
	}
	sql = "DELETE FROM goku_conn_plugin_api WHERE strategyID = ? AND apiID IN (" + apiIDList + ")"
	_, err = Tx.Exec(sql, strategyID)
	if err != nil {
		Tx.Rollback()
		return false, "[ERROR]Fail to excute SQL statement!", err
	}

	sql = "UPDATE goku_gateway_strategy SET updateTime = ? WHERE strategyID = ?"
	_, err = Tx.Exec(sql, now, strategyID)
	if err != nil {
		Tx.Rollback()
		return false, "[ERROR]Failed to update data!", err
	}
	Tx.Commit()
	return true, "", nil
}