From d0c69ff4d87ab6d4370a5e3fb1da67eb73e6d044 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sat, 18 Jan 2020 15:55:37 +0800 Subject: [PATCH] =?UTF-8?q?3.1.3=E7=89=88=E6=9C=AC=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 192 ++--- config/config.go | 46 +- console/account/account-default.go | 48 ++ console/controller/account/guest.go | 21 +- console/controller/account/user.go | 78 +-- console/controller/api/api-balance-batch.go | 10 +- console/controller/api/api.go | 136 ++-- console/controller/api/apiGroup.go | 38 +- console/controller/api/apiPlugin.go | 121 +--- console/controller/api/import.go | 41 +- console/controller/auth/auth.go | 35 +- console/controller/balance/add.go | 8 +- console/controller/balance/delete.go | 12 +- console/controller/balance/get.go | 8 +- console/controller/balance/handle.go | 31 + console/controller/balance/list.go | 8 +- console/controller/balance/save.go | 8 +- console/controller/balance/simple.go | 8 +- console/controller/cluster/cluster.go | 54 +- console/controller/cluster/version.go | 75 +- console/controller/config-log/access.go | 37 +- console/controller/config-log/handle.go | 35 +- console/controller/config-log/log.go | 46 +- console/controller/discovery/add.go | 11 +- console/controller/discovery/default.go | 11 +- console/controller/discovery/delete.go | 17 +- console/controller/discovery/driver.go | 8 +- console/controller/discovery/edit.go | 12 +- console/controller/discovery/get.go | 8 +- console/controller/discovery/handle.go | 39 +- console/controller/discovery/list.go | 7 +- console/controller/discovery/simple.go | 7 +- console/controller/gateway/gateway.go | 24 +- console/controller/monitor/module.go | 39 +- console/controller/node/node.go | 142 ++-- console/controller/node/nodeGroup.go | 44 +- console/controller/plugin/plugin.go | 122 +--- console/controller/project/project.go | 55 +- console/controller/reg.go | 4 + console/controller/strategy/apiStrategy.go | 112 ++- console/controller/strategy/strategy.go | 116 +-- console/controller/strategy/strategyGroup.go | 39 +- console/controller/strategy/strategyPlugin.go | 66 +- console/controller/utils.go | 57 +- console/module/account/guest.go | 33 +- console/module/account/user.go | 24 +- console/module/api/api.go | 30 +- console/module/api/apiGroup.go | 12 +- console/module/api/apiPlugin.go | 26 +- console/module/api/apiStrategy.go | 22 +- console/module/api/dao.go | 18 + console/module/api/import.go | 7 +- console/module/auth/auth.go | 15 +- console/module/balance/balance.go | 39 +- console/module/balance/param.go | 2 + console/module/balance/update.go | 13 +- console/module/cluster/cluster.go | 25 +- console/module/config-log/dao.go | 14 + console/module/config-log/get.go | 5 +- console/module/config-log/set.go | 3 +- console/module/gateway/gateway.go | 37 +- console/module/monitor/module.go | 69 +- console/module/node/Locker_test.go | 14 +- console/module/node/dao.go | 15 + console/module/node/node.go | 74 +- console/module/node/nodeGroup.go | 18 +- console/module/node/status.go | 59 +- console/module/plugin/plugin.go | 35 +- console/module/project/project.go | 25 +- console/module/service/module.go | 27 +- console/module/service/service.go | 2 +- console/module/strategy/dao.go | 17 + console/module/strategy/strategy.go | 43 +- console/module/strategy/strategyGroup.go | 14 +- console/module/strategy/strategyPlugin.go | 22 +- console/module/updater/check.go | 13 +- console/module/versionConfig/load.go | 161 +++-- console/module/versionConfig/version.go | 81 ++- diting/diting.go | 12 +- diting/internal/id.go | 2 +- diting/manager.go | 8 +- diting/opt.go | 6 +- diting/proxy-summary.go | 3 +- diting/utils.go | 4 +- go.mod | 6 +- go.sum | 13 + goku-handler/account.go | 63 ++ goku-handler/handler.go | 47 ++ goku-handler/user.go | 31 + goku-handler/utils.go | 34 + goku-labels/labels.go | 62 +- goku-node/common/body-request.go | 5 +- goku-node/common/request-reader.go | 4 +- goku-node/redis-plugin-proxy/redis.go | 4 +- goku-observe/histogram.go | 105 +-- goku-observe/histogram_test.go | 13 +- goku-observe/observe.go | 11 +- goku-service/application/application.go | 3 +- goku-service/application/org.go | 5 +- goku-service/application/r.go | 15 +- goku-service/application/request.go | 44 +- goku-service/application/service.go | 5 +- goku-service/discovery/config.go | 1 - goku-service/driver/static/static-node.go | 14 +- goku-service/driver/static/staticSources.go | 4 +- ksitigarbha/export.go | 46 ++ ksitigarbha/factory.go | 8 +- ksitigarbha/module.go | 58 +- ksitigarbha/register.go | 13 + module/graphite/config/config.go | 20 +- module/graphite/count.go | 4 +- module/graphite/histogram.go | 108 +-- module/graphite/metrics.go | 12 +- module/httprouter/.travis.yml | 18 + module/httprouter/LICENSE | 24 + module/httprouter/README.md | 269 +++++++ module/httprouter/params_go17.go | 38 + module/httprouter/params_legacy.go | 16 + module/httprouter/path.go | 123 ++++ module/httprouter/router.go | 399 +++++++++++ module/httprouter/tree.go | 661 ++++++++++++++++++ module/manager.go | 2 + module/prometheus/config/config.go | 6 +- module/prometheus/prometheus.go | 2 +- module/status.go | 3 +- node/admin/handler.go | 2 +- node/console/console.go | 35 +- node/gateway/api.go | 8 +- node/gateway/application/backend/backend.go | 2 - node/gateway/application/backend/filter.go | 22 +- node/gateway/application/backend/layer.go | 14 +- node/gateway/application/backend/proxy.go | 21 +- .../application/interpreter/analysis.go | 7 +- node/gateway/application/layer.go | 13 +- node/gateway/application/proxy.go | 7 +- node/gateway/application/static-response.go | 6 +- node/gateway/befor.go | 1 + node/gateway/const.go | 4 +- node/gateway/http.go | 8 +- node/gateway/plugin-executor/executor.go | 83 ++- node/gateway/plugin.go | 5 +- node/gateway/response/decode.go | 31 +- node/gateway/response/decoder.go | 27 +- node/gateway/response/encode.go | 35 +- node/gateway/response/node.go | 156 ++--- node/gateway/response/response.go | 131 ++-- node/gateway/router.go | 23 +- node/gateway/strategy.go | 64 +- node/monitor/collector.go | 30 +- node/monitor/monitor.go | 15 +- node/plugin-loader/pluginload.go | 35 +- node/router/httprouter/router.go | 3 +- node/routerRule/internal/rule.go | 7 + node/routerRule/manager.go | 95 +++ node/routerRule/sort.go | 30 + node/server.go | 14 + node/server/admin.go | 21 +- node/server/log.go | 1 + node/server/server.go | 112 ++- server/dao/console-sqlite3/api.go | 108 ++- server/dao/console-sqlite3/apiGroup.go | 46 +- server/dao/console-sqlite3/apiPlugin.go | 73 +- server/dao/console-sqlite3/apiStrategy.go | 82 ++- server/dao/console-sqlite3/auth.go | 37 +- server/dao/console-sqlite3/cluster.go | 74 +- server/dao/console-sqlite3/config-log/log.go | 29 +- .../dao-balance-update/update.go | 39 +- server/dao/console-sqlite3/dao-balance/add.go | 64 +- .../console-sqlite3/dao-balance/balance.go | 41 +- server/dao/console-sqlite3/dao-balance/get.go | 70 +- server/dao/console-sqlite3/dao-service/add.go | 7 +- server/dao/console-sqlite3/dao-service/dao.go | 24 + .../console-sqlite3/dao-service/default.go | 8 +- .../dao/console-sqlite3/dao-service/delete.go | 7 +- server/dao/console-sqlite3/dao-service/get.go | 5 +- .../dao/console-sqlite3/dao-service/list.go | 5 +- .../dao/console-sqlite3/dao-service/save.go | 8 +- .../console-sqlite3/dao-version-config/api.go | 5 +- .../dao-version-config/balance.go | 5 +- .../console-sqlite3/dao-version-config/dao.go | 25 + .../dao-version-config/discovery.go | 6 +- .../dao-version-config/gateway.go | 19 + .../console-sqlite3/dao-version-config/log.go | 6 +- .../dao-version-config/monitorModule.go | 7 +- .../dao-version-config/plugin.go | 39 +- .../dao-version-config/router.go | 37 + .../dao-version-config/strategy.go | 15 +- server/dao/console-sqlite3/gateway.go | 62 +- server/dao/console-sqlite3/guest.go | 32 +- server/dao/console-sqlite3/import.go | 48 +- .../internal/goku311/gokuMonitorModule.go | 24 + .../internal/goku311/gokuNodeInfo.go | 58 ++ .../internal/goku311/gokuTableVersion.go | 23 + .../internal/goku311/update.go | 60 ++ server/dao/console-sqlite3/monitorModule.go | 41 +- server/dao/console-sqlite3/node.go | 244 ++++--- server/dao/console-sqlite3/nodeGroup.go | 49 +- server/dao/console-sqlite3/plugin.go | 156 ++--- server/dao/console-sqlite3/project.go | 55 +- server/dao/console-sqlite3/register.go | 77 ++ server/dao/console-sqlite3/strategy.go | 109 +-- server/dao/console-sqlite3/strategyGroup.go | 42 +- server/dao/console-sqlite3/strategyPlugin.go | 60 +- server/dao/console-sqlite3/updater/check.go | 10 +- server/dao/console-sqlite3/updater/dao.go | 30 + server/dao/console-sqlite3/updater/get.go | 18 +- server/dao/console-sqlite3/user.go | 87 +-- server/dao/console-sqlite3/utils.go | 10 +- server/dao/console-sqlite3/version.go | 76 +- server/dao/dao-balance.go | 41 ++ server/dao/daos.go | 458 ++++++++++++ .../entity/balance-entity-service/balance.go | 1 + server/entity/balance-entity/balance.go | 2 +- server/entity/cluster.go | 40 +- server/entity/console-entity/ams_import.go | 1 + server/entity/console-entity/api.go | 1 + server/entity/console-entity/cluster.go | 47 +- server/entity/console-entity/gateway.go | 10 + server/entity/console-entity/node.go | 19 +- server/entity/console-entity/redis.go | 1 + server/entity/console-entity/strategy.go | 2 + server/entity/redis_config.go | 29 - server/entity/smtp.go | 11 + utils/function.go | 47 +- utils/json.go | 20 + utils/mail.go | 230 +++--- utils/sftp.go | 128 ++++ utils/ssh.go | 13 +- 228 files changed, 6869 insertions(+), 2966 deletions(-) create mode 100644 console/account/account-default.go create mode 100644 console/controller/balance/handle.go create mode 100644 console/controller/reg.go create mode 100644 console/module/api/dao.go create mode 100644 console/module/config-log/dao.go create mode 100644 console/module/node/dao.go create mode 100644 console/module/strategy/dao.go create mode 100644 goku-handler/account.go create mode 100644 goku-handler/handler.go create mode 100644 goku-handler/user.go create mode 100644 goku-handler/utils.go create mode 100644 ksitigarbha/export.go create mode 100644 ksitigarbha/register.go create mode 100644 module/httprouter/.travis.yml create mode 100644 module/httprouter/LICENSE create mode 100644 module/httprouter/README.md create mode 100644 module/httprouter/params_go17.go create mode 100644 module/httprouter/params_legacy.go create mode 100644 module/httprouter/path.go create mode 100644 module/httprouter/router.go create mode 100644 module/httprouter/tree.go create mode 100644 module/manager.go create mode 100644 node/routerRule/internal/rule.go create mode 100644 node/routerRule/manager.go create mode 100644 node/routerRule/sort.go create mode 100644 node/server.go create mode 100644 server/dao/console-sqlite3/dao-service/dao.go create mode 100644 server/dao/console-sqlite3/dao-version-config/dao.go create mode 100644 server/dao/console-sqlite3/dao-version-config/gateway.go create mode 100644 server/dao/console-sqlite3/dao-version-config/router.go create mode 100644 server/dao/console-sqlite3/internal/goku311/gokuMonitorModule.go create mode 100644 server/dao/console-sqlite3/internal/goku311/gokuNodeInfo.go create mode 100644 server/dao/console-sqlite3/internal/goku311/gokuTableVersion.go create mode 100644 server/dao/console-sqlite3/internal/goku311/update.go create mode 100644 server/dao/console-sqlite3/register.go create mode 100644 server/dao/console-sqlite3/updater/dao.go create mode 100644 server/dao/dao-balance.go create mode 100644 server/dao/daos.go create mode 100644 server/entity/console-entity/gateway.go create mode 100644 server/entity/smtp.go create mode 100644 utils/json.go create mode 100644 utils/sftp.go diff --git a/README.md b/README.md index f1d8d7ce..2be28e3b 100644 --- a/README.md +++ b/README.md @@ -1,85 +1,115 @@ -![](https://data.eolinker.com/WJ2lfq217421a961efc420d88a7cb6f59586824a8ea2f84.jpg) - -[![Gitter](https://badges.gitter.im/goku-api-gateway/community.svg)](https://gitter.im/goku-api-gateway/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) [![Go Report Card](https://goreportcard.com/badge/github.com/eolinker/goku-api-gateway)](https://goreportcard.com/report/github.com/eolinker/goku-api-gateway) [![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/3214/badge)](https://bestpractices.coreinfrastructure.org/projects/3214) ![](https://img.shields.io/badge/license-GPL3.0-blue.svg) - -Goku API Gateway is a Golang-based microservice gateway that enables high-performance dynamic routing, multi-tenancy management, API access control, etc. It's also suitable for API management under micro-service system. - -Goku provides graphic interface and plug-in system to make configuration easier and expand more convenient. - -# Summary / [中文介绍](https://github.com/eolinker/goku-api-gateway/blob/master/README_CN.md "中文介绍") - -- [WhyGoku](#WhyGoku "WhyGoku") -- [Features](#Features "Features") -- [Benchmark](#Benchmark "Benchmark") -- [ConsolePreview](#ConsolePreview "ConsolePreview") -- [QuickStart](#QuickStart "QuickStart") -- [EnterpriseSupport](#EnterpriseSupport "EnterpriseSupport") -- [AboutUs](#AboutUs "AboutUs") -- [License](#License "License") - -# Why Goku - -Goku API Gateway is a microservice gateway that runs on the boundaries of enterprise system services. When you build websites, apps, IOT, and even API transactions, Goku API Gateway can help you extract duplicate components from your internal system and place them on the Goku gateway, such as user authorization, access control, traffic monitoring, firewalls, data cache, data conversion and so on. - -Goku API Gateway CE provides comprehensive usage guide and customization guide. Goku is written in pure Go language, with good performance and scalability, and the built-in plug-in system enables enterprises to customize development for their own business. - -Goku API Gateway also can combine with EOLINK API Studio to enhance API Management,API Monitor and Automated test. - -All in all, Goku API Gateway enables enterprise to focus on their business. - -[![Stargazers over time](https://starchart.cc/eolinker/goku-api-gateway.svg)](#) - -# Product Features -- **Dashboard**: Built-in dashboard to configure Goku. -- **Cluster Management**:Goku nodes are stateless and can be expanded horizontally. Also the configuration can be synchronized automatically. -- **Hot Updates**: Continuously updates configurations without restart nodes. -- **Load balancing**: Round-robin load balancing with weight. -- **Service Discovery**: Service discorvery from Consul or Eureka. -- **HTTP(S) Forward Proxy**: Hide real backend services, support Rest API, Webservice. -- **Multi-tenant management**: According to different strategies to regnorize different users. -- **Strategies**: Support different strategies to access different APIs, configure different authentication (anonymous, Apikey, Basic) and so on. -- **API Alert**: Support the webhook and email to alert abnormal services. -- **Flexible transmit rules**: support fuzzy matching request path, support rewriting transmit path, etc. -- **IP Whitelist/Blacklist** -- **Custom plugins**: Allow plugins to be mounted in common phases, such as before match, access, and proxy. -- **CLI**: Start\stop\reload Goku through the command line. -- **Serverless**: Invoke functions in each phase in Goku. -- **Access Log**:Only record the basic content in proxy, customize the record fields and sort order, and automatically clean up the logs periodically. -- **System Log**:Provide running logs of consoles and nodes,only record the error information, adjust the level to INFO, WARN or DEBUG according to the actual situation. -- **Scalability**: plug-in mechanism is easy to extend. -- **High performance**: Performance excels among many gateways. -- **Open API**:Provide OPEN API for users to operate on the gateway for easy integration. - -# Benchmark -![](https://data.eolinker.com/p7NFG6lb4c73b26cc880e838fe45aa31bc037b7415e3770.jpg) -[Benchmark Detail](https://help.eolinker.com/#/tutorial/?groupID=c-362&productID=19#tip7 "Benchmark Detail") - -# Console Preview -[Console Preview Detail](https://github.com/eolinker/goku-api-gateway/blob/master/docs/CONSOLE_PREVIEW.md "See Console Preview") - - -# Quick Start -* [Deployment Tutorial](https://help.eolinker.com/#/tutorial/?groupID=c-351&productID=19 "Deployment Tutorial") -* [Quick Start](https://help.eolinker.com/#/tutorial/?groupID=c-307&productID=19 "Quick Start Tutorial") -* [Source Code Compilation](https://help.eolinker.com/#/tutorial/?groupID=c-350&productID=19 "Source Code Compilation") - -# Enterprise Support -Goku API Gateway EE (Enterprise Version) has more powerful functions, plug-in libraries and professional technical support services. If you want to know more details, you can contact us in the following ways. -- Apply for free trial and demonstration of Enterprise Version:[Appointment trial](https://wj.qq.com/s2/2150032/4b5e "Appointment trial") -- Market Cooperation Mail:market@eolinker.com -- Purchase consultation Mail:sales@eolinker.com -- Help Center:[help.eolinker.com](help.eolinker.com "help.eolinker.com") -- QQ Group: 725853895 - -# About Us -EOLINK is a leading API management service provider, providing professional API research and development management, API automated test service, API monitor service, API gateway and other services for more than 3000 enterprises worldwide. It is the first enterprise to formulate API R&D management industry norms for ITSS. - -Official website :[https://www.eolinker.com](https://www.eolinker.com "EOLINK Official Site") -Free download of PC client :[https://www.eolinker.com/pc](https://www.eolinker.com/pc/ "Free download of PC client") - -# License +![Goku API Gateway 悟空网关](https://data.eolinker.com/course/gBTEV2s29e16630bb4dc553bec35ad33914d19aa410a8bf "Goku API Gateway 悟空网关") + +[![Gitter](https://badges.gitter.im/goku-api-gateway/community.svg)](https://gitter.im/goku-api-gateway/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) [![Go Report Card](https://goreportcard.com/badge/github.com/eolinker/goku-gateway-api-api-gateway)](https://goreportcard.com/report/github.com/eolinker/goku-gateway-api-api-gateway) [![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/3214/badge)](https://bestpractices.coreinfrastructure.org/projects/3214) ![](https://img.shields.io/badge/license-GPL3.0-blue.svg) + +Goku API Gateway (中文名:悟空 API 网关)是一个基于 Golang 开发的微服务网关,能够实现高性能 HTTP API 转发、多租户管理、API 访问权限控制等目的,拥有强大的自定义插件系统可以自行扩展,并且提供友好的图形化配置界面,能够快速帮助企业进行 API 服务治理、提高 API 服务的稳定性和安全性。 + +# 概况 + +- [为什么要使用Goku](#为什么要使用Goku "为什么要使用Goku") +- [产品特性](#产品特性 "产品特性") +- [产品截图](#产品截图 "产品截图") +- [安装使用](#安装使用 "安装使用") +- [企业支持](#企业支持 "企业支持") +- [关于我们](#关于我们 "关于我们") +- [授权协议](#授权协议 "授权协议") + +# 为什么要使用Goku +Goku API Gateway (悟空 API 网关)是运行在企业系统服务边界上的微服务网关。当您构建网站、App、IOT甚至是开放API交易时,Goku API Gateway 能够帮你将内部系统中重复的组件抽取出来并放置在Goku网关上运行,如进行用户授权、访问控制、流量监控、防火墙、静态数据缓存、数据转换等。 + +Goku API Gateway 的社区版本(CE)拥有完善的使用指南和二次开发指南,代码使用纯 Go 语言编写,拥有良好的性能和扩展性,并且内置的插件系统能够让企业针对自身业务进行定制开发。 + +并且 Goku API Gateway 支持与 EOLINKER 旗下的 API Studio 接口管理平台结合,对 API 进行全面的管理、自动化测试、监控和运维。 + +总而言之,Goku API Gateway 能让业务开发团队更加专注地实现业务。 + +# 产品特性 +- **集群管理**:多个 Goku API Gateway 节点,配置信息自动同步,支持多集群部署。 +- **界面管理后台**:通过清晰的UI界面对网关的各项配置进行管理。 +- **负载均衡**:对后端服务器进行负载均衡。 +- **服务发现**:从 Consul、Eureka 等注册中心发现后端服务器。 +- **转发代理**:通过转发请求来隐藏真实后端服务,支持 Rest API、Webservice。 +- **多租户管理**:根据不同的访问终端或用户来判断。 +- **访问鉴权**:Basic、API Key等。 +- **API监控**:请求数据统计。 +- **API告警**:支持通过API、邮件方式对异常的服务进行告警。 +- **健康检查**:动态发现异常的网关节点以及后端节点,自动切断转发流量并转到其他正常后端服务。 +- **异常自动重启**:网关节点异常时会自动尝试重载重启。 +- **灵活的转发规则**:支持模糊匹配请求路径,支持改写转发路径等。 +- **插件系统**:基于 Go 语言的插件系统,可以快速开发高性能的插件。 +- **性能扩展**:网关节点拥有良好的处理性能,支持水平扩展节点数量满足不同的性能需求。 +- **日志**:详细的系统日志、请求日志等。 +- **Open API**:提供 API 对网关进行操作,便于集成。 +- ... + +# 产品截图 +* 【首页】 +首页可以了解网关的基本信息,例如访问策略数、API数等,还可以了解请求和转发的情况,例如成功率等。 + +![](http://data.eolinker.com/course/p8qL49u6c8adce6b345915b3fd77bf5812a40fe7dd0a8a2) + +* 【网关节点】 +网关支持集群化管理,进入不同的集群可以管理相应的节点。 + +![](http://data.eolinker.com/course/wEa9yEI2bf086f3873b55bbdaec32f3b4ce1eb23dfe44ea) + +* 【服务注册方式】 +您可以通过静态或动态的方式来注册(发现)您的后端服务,创建好服务注册方式后,您可以在某个方式的基础上创建一个或多个负载(Upstream)。 + +![](http://data.eolinker.com/course/1elb5mF4d3fd6141919001293e0119557b3d5ef0cea0719) + +* 【负载配置】 +配置API的转发目标服务器(负载后端),创建之后可以设置为 API 的转发地址 / 负载后端(Target / Upstream)。 + +![](http://data.eolinker.com/course/4tHYXR23abc26b914ca763aac4871ed9d60a3aeb819941f) + +* 【接口管理】 +支持创建并管理API文档,并且支持导入API文档项目。 + +![](http://data.eolinker.com/course/WlTJ2kB1cd03ddf839ea1d489890a0bd5b0572efeff6043) + +* 【访问策略】 +您可以给不同的调用方或应用设置访问策略,不同的访问策略可以设置不同的 API 访问权限、鉴权方式以及插件功能等。 + +![](http://data.eolinker.com/course/fUrHmVd0d2d88b7f72d985b0e93e434ed528648d2dd34db) + +* 【告警设置】 +针对异常API可以设置告警提醒,支持邮件和Webhook通知。 + +![](http://data.eolinker.com/course/9eQ3Lmv64e5cedc1ad4745dfa2895f6657441d874f6c7f4) + +* 【扩展插件】 +插件系统除了提供官方插件,也可以添加自定义的网关插件。 + +![](http://data.eolinker.com/course/sQhUflpcebf65dc43cb7e2e838e8d1ecf3e52e9a5a6c566) + +* 【日志设置】 +提供详细的请求日志和系统运行日志,请求日志可以自定义记录字段;运行日志可以根据情况调整记录等级:ERROR、INFO、DEBUG等。 + +![](http://data.eolinker.com/course/iyifFJ2809fe63e27df709ddc1a22f94d983c5ecbf8cc29) + +# 安装使用 +* [部署教程](https://help.eolinker.com/#/tutorial/?groupID=c-351&productID=19 "部署教程") +* [快速入门教程](https://help.eolinker.com/#/tutorial/?groupID=c-307&productID=19 "快速入门教程") +* [源码编译教程](https://help.eolinker.com/#/tutorial/?groupID=c-350&productID=19 "源码编译") + +# 企业支持 +Goku API Gateway EE(企业版本)拥有更强大的功能、插件库以及专业的技术支持服务,如您需要了解可以通过以下方式联系我们。 +- **中国大陆服务支持电话**:400-616-0330 法定工作日(9:30-18:00) +- **申请企业版免费试用及演示**:[预约试用](https://wj.qq.com/s2/2150032/4b5e "预约试用") +- **市场合作邮箱**:market@eolinker.com +- **购买咨询邮箱**:sales@eolinker.com +- **帮助文档**:[help.eolinker.com](help.eolinker.com "help.eolinker.com") + +# 关于我们 +EOLINKER 是领先的 API 管理服务供应商,为全球超过3000家企业提供专业的 API 研发管理、API自动化测试、API监控、API网关等服务。是首家为ITSS(中国电子工业标准化技术协会)制定API研发管理行业规范的企业。 + +官方网站:[https://www.eolinker.com](https://www.eolinker.com "EOLINKER官方网站") +免费下载PC桌面端:[https://www.eolinker.com/pc/](https://www.eolinker.com/pc/ "免费下载PC客户端") + +# 授权协议 ``` -Copyright 2017-2019 Eolink Inc. +Copyright 2017-2019 Eolinker Inc. Licensed under the GNU General Public License v3.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/config/config.go b/config/config.go index 90597c5b..5d6f49e7 100644 --- a/config/config.go +++ b/config/config.go @@ -1,27 +1,42 @@ package config - //GokuConfig goku根配置 type GokuConfig struct { - Version string `json:"version"` - Cluster string `json:"cluster"` - Instance string `json:"instance"` - BindAddress string `json:"bind"` + Version string `json:"version"` + Cluster string `json:"cluster"` + Instance string `json:"instance"` + BindAddress string `json:"bind"` AdminAddress string `json:"admin"` //Port int `json:"port"` DiscoverConfig map[string]*DiscoverConfig `json:"discover,omitempty"` Balance map[string]*BalanceConfig `json:"balance,omitempty"` - Plugins *GatewayPluginConfig `json:"plugins,omitempty"` + Plugins GatewayPluginConfig `json:"plugins,omitempty"` APIS []*APIContent `json:"apis,omitempty"` Strategy []*StrategyConfig `json:"strategy,omitempty"` AnonymousStrategyID string `json:"anonymousStrategyID,omitempty"` AuthPlugin map[string]string `json:"authPlugin,omitempty"` + GatewayBasicInfo *Gateway `json:"gatewayBasicInfo"` + //RouterRule map[string]*RouterRule `json:"routerRule"` + Log *LogConfig `json:"log,omitempty"` + AccessLog *AccessLogConfig `json:"access_log,omitempty"` + Routers []*Router `json:"routers"` + MonitorModules map[string]string `json:"monitor_modules"` + RedisConfig map[string]interface{} `json:"redisConfig"` + ExtendsConfig map[string]interface{} `json:"extends_config"` +} - Log *LogConfig `json:"log,omitempty"` - AccessLog *AccessLogConfig `json:"access_log,omitempty"` +//Router 路由 +type Router struct { + Rules string `json:"routerRules"` + Target string `json:"target"` + Priority int `json:"priority"` +} - MonitorModules map[string]string `json:"monitor_modules"` +//RouterRule 路由规则 +type RouterRule struct { + Host string `json:"host"` + StrategyID string `json:"strategyID"` } //AccessLogConfig access日志配置 @@ -82,12 +97,15 @@ type PluginConfig struct { IsStop bool `json:"stop"` Config string `json:"config"` UpdateTag string `json:"updateTag"` + IsAuth bool `json:"isAuth"` } //APIContent api详情 type APIContent struct { - ID int `json:"id"` - Name string `json:"name"` + ID int `json:"id"` + Name string `json:"name"` + Alias string `json:"alias"` + OutPutEncoder string `json:"output"` RequestURL string `json:"requestUrl"` Methods []string `json:"methods"` @@ -177,6 +195,11 @@ type StrategyConfig struct { Plugins []*PluginConfig `json:"plugins"` } +//Gateway 网关配置 +type Gateway struct { + SkipCertificate int `json:"skipCertificate"` +} + //APIOfStrategy 策略接口配置 type APIOfStrategy struct { ID int `json:"id"` @@ -193,6 +216,7 @@ type VersionConfig struct { CreateTime string `json:"createTime"` PublishStatus int `json:"publishStatus"` PublishTime string `json:"publishTime"` + Publisher string `json:"publisher"` } //Project 项目 diff --git a/console/account/account-default.go b/console/account/account-default.go new file mode 100644 index 00000000..0bfe3d0a --- /dev/null +++ b/console/account/account-default.go @@ -0,0 +1,48 @@ +package account + +import ( + "errors" + "net/http" + "strconv" + + "github.com/eolinker/goku-api-gateway/console/module/account" +) + +//DefaultAccount default +type DefaultAccount struct { +} + +//NewDefaultAccount new defaultAccount +func NewDefaultAccount() *DefaultAccount { + return &DefaultAccount{} +} + +//CheckLogin 判断是否登录 +func (d *DefaultAccount) CheckLogin(r *http.Request) (int, error) { + + userIDCookie, idErr := r.Cookie("userID") + userCookie, userErr := r.Cookie("userToken") + if idErr != nil || userErr != nil { + e := errors.New("user not logged in") + return 0, e + } + userID, err := strconv.Atoi(userIDCookie.Value) + if err != nil { + return 0, err + } + flag := account.CheckLogin(userCookie.Value, userID) + if !flag { + e := errors.New("illegal users") + return userID, e + } + + return userID, nil +} + +//CheckPermission 检查操作权限 +func (d *DefaultAccount) CheckPermission(pre string, isEdit bool, userID int) (bool, error) { + if isEdit { + return true, nil + } + return true, nil +} diff --git a/console/controller/account/guest.go b/console/controller/account/guest.go index 03e05632..4c91c486 100644 --- a/console/controller/account/guest.go +++ b/console/controller/account/guest.go @@ -2,6 +2,9 @@ package account import ( "errors" + + goku_handler "github.com/eolinker/goku-api-gateway/goku-handler" + "net/http" "strconv" @@ -10,6 +13,22 @@ import ( "github.com/eolinker/goku-api-gateway/utils" ) +//Account 账号类 +type Account struct { +} + +//Handlers 处理器 +func (c *Account) Handlers(factory *goku_handler.AccountHandlerFactory) map[string]http.Handler { + return map[string]http.Handler{ + "/login": http.HandlerFunc(Login), + } +} + +//NewAccountController 新建账号控制类 +func NewAccountController() *Account { + return &Account{} +} + //Login 用户登录 func Login(httpResponse http.ResponseWriter, httpRequest *http.Request) { @@ -24,7 +43,7 @@ func Login(httpResponse http.ResponseWriter, httpRequest *http.Request) { "100000", "guest", "[ERROR]Wrong username or password!", - errors.New("Wrong username or password")) + errors.New("wrong username or password")) return } diff --git a/console/controller/account/user.go b/console/controller/account/user.go index fceecd98..6bab0d14 100644 --- a/console/controller/account/user.go +++ b/console/controller/account/user.go @@ -6,11 +6,38 @@ import ( "regexp" "strconv" + goku_handler "github.com/eolinker/goku-api-gateway/goku-handler" + "github.com/eolinker/goku-api-gateway/console/controller" "github.com/eolinker/goku-api-gateway/console/module/account" "github.com/eolinker/goku-api-gateway/utils" ) +//OperationUser 用户权限 +const OperationUser = "user" + +//UserController 用户控制器 +type UserController struct { +} + +//NewUserController 新建用户控制器 +func NewUserController() *UserController { + return &UserController{} +} + +//Handlers 处理类 +func (u *UserController) Handlers(factory *goku_handler.AccountHandlerFactory) map[string]http.Handler { + + return map[string]http.Handler{ + "/logout": factory.NewAccountHandleFunction(OperationUser, false, Logout), + "/password/edit": factory.NewAccountHandleFunction(OperationUser, false, EditPassword), + "/getInfo": factory.NewAccountHandleFunction(OperationUser, false, GetUserInfo), + "/getUserType": factory.NewAccountHandleFunction(OperationUser, false, GetUserType), + "/checkIsAdmin": factory.NewAccountHandleFunction(OperationUser, false, CheckUserIsAdmin), + "/checkIsSuperAdmin": factory.NewAccountHandleFunction(OperationUser, false, CheckUserIsSuperAdmin), + } +} + //Logout 用户注销 func Logout(httpResponse http.ResponseWriter, httpRequest *http.Request) { @@ -25,10 +52,6 @@ func Logout(httpResponse http.ResponseWriter, httpRequest *http.Request) { //EditPassword 修改账户信息 func EditPassword(httpResponse http.ResponseWriter, httpRequest *http.Request) { - userID, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNone, controller.OperationEDIT) - if e != nil { - return - } oldPassword := httpRequest.PostFormValue("oldPassword") newPassword := httpRequest.PostFormValue("newPassword") @@ -50,6 +73,7 @@ func EditPassword(httpResponse http.ResponseWriter, httpRequest *http.Request) { errors.New("[ERROR]Illegal newPassword")) return } + userID := goku_handler.UserIDFromRequest(httpRequest) flag, result, err := account.EditPassword(oldPassword, newPassword, userID) if !flag { controller.WriteError(httpResponse, @@ -72,10 +96,7 @@ func EditPassword(httpResponse http.ResponseWriter, httpRequest *http.Request) { //GetUserInfo 获取用户信息 func GetUserInfo(httpResponse http.ResponseWriter, httpRequest *http.Request) { - userID, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNone, controller.OperationEDIT) - if e != nil { - return - } + userID := goku_handler.UserIDFromRequest(httpRequest) flag, result, err := account.GetUserInfo(userID) if !flag { @@ -91,11 +112,8 @@ func GetUserInfo(httpResponse http.ResponseWriter, httpRequest *http.Request) { //GetUserType 获取用户类型 func GetUserType(httpResponse http.ResponseWriter, httpRequest *http.Request) { - userID, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNone, controller.OperationEDIT) - if e != nil { - return - } + userID := goku_handler.UserIDFromRequest(httpRequest) flag, result, err := account.GetUserType(userID) if !flag { @@ -109,10 +127,7 @@ func GetUserType(httpResponse http.ResponseWriter, httpRequest *http.Request) { //CheckUserIsAdmin 判断是否是管理员 func CheckUserIsAdmin(httpResponse http.ResponseWriter, httpRequest *http.Request) { - userID, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNone, controller.OperationEDIT) - if e != nil { - return - } + userID := goku_handler.UserIDFromRequest(httpRequest) flag, _, err := account.CheckUserIsAdmin(userID) if !flag { @@ -132,10 +147,7 @@ func CheckUserIsAdmin(httpResponse http.ResponseWriter, httpRequest *http.Reques //CheckUserIsSuperAdmin 判断是否是超级管理员 func CheckUserIsSuperAdmin(httpResponse http.ResponseWriter, httpRequest *http.Request) { - userID, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNone, controller.OperationEDIT) - if e != nil { - return - } + userID := goku_handler.UserIDFromRequest(httpRequest) flag, _, err := account.CheckUserIsSuperAdmin(userID) @@ -153,29 +165,3 @@ func CheckUserIsSuperAdmin(httpResponse http.ResponseWriter, httpRequest *http.R controller.WriteResultInfo(httpResponse, "user", "", nil) return } - -//CheckUserPermission 检查用户权限 -func CheckUserPermission(httpResponse http.ResponseWriter, httpRequest *http.Request) { - userID, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNone, controller.OperationEDIT) - if e != nil { - return - } - - operationType := httpRequest.PostFormValue("operationType") - operation := httpRequest.PostFormValue("operation") - flag, result, err := account.CheckUserPermission(operationType, operation, userID) - - if !flag { - - controller.WriteError(httpResponse, - "110000", - "user", - result, - err) - return - - } - - controller.WriteResultInfo(httpResponse, "user", "", nil) - return -} diff --git a/console/controller/api/api-balance-batch.go b/console/controller/api/api-balance-batch.go index 2d46593f..e817326b 100644 --- a/console/controller/api/api-balance-batch.go +++ b/console/controller/api/api-balance-batch.go @@ -1,19 +1,15 @@ package api import ( - "net/http" - "strings" - "github.com/eolinker/goku-api-gateway/console/controller" "github.com/eolinker/goku-api-gateway/console/module/api" + "net/http" + "strings" ) //BatchSetBalanceAPI 批量设置接口负载 func BatchSetBalanceAPI(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationEDIT) - if e != nil { - return - } + apiIDList := httpRequest.PostFormValue("apiIDList") balanceName := httpRequest.PostFormValue("balance") diff --git a/console/controller/api/api.go b/console/controller/api/api.go index 22c96218..a97573ca 100644 --- a/console/controller/api/api.go +++ b/console/controller/api/api.go @@ -6,19 +6,47 @@ import ( "strconv" "strings" + "github.com/eolinker/goku-api-gateway/utils" + + "github.com/pkg/errors" + + goku_handler "github.com/eolinker/goku-api-gateway/goku-handler" + "github.com/eolinker/goku-api-gateway/console/controller" - "github.com/eolinker/goku-api-gateway/console/module/account" "github.com/eolinker/goku-api-gateway/console/module/api" ) +const operationAPI = "apiManagement" + +//Handlers handlers +type Handlers struct { +} + +//Handlers handlers +func (h *Handlers) Handlers(factory *goku_handler.AccountHandlerFactory) map[string]http.Handler { + return map[string]http.Handler{ + "/add": factory.NewAccountHandleFunction(operationAPI, true, AddAPI), + "/edit": factory.NewAccountHandleFunction(operationAPI, true, EditAPI), + "/copy": factory.NewAccountHandleFunction(operationAPI, true, CopyAPI), + "/getInfo": factory.NewAccountHandleFunction(operationAPI, false, GetAPIInfo), + "/getList": factory.NewAccountHandleFunction(operationAPI, false, GetAPIList), + "/id/getList": factory.NewAccountHandleFunction(operationAPI, false, GetAPIIDList), + "/batchEditGroup": factory.NewAccountHandleFunction(operationAPI, true, BatchEditAPIGroup), + "/batchDelete": factory.NewAccountHandleFunction(operationAPI, true, BatchDeleteAPI), + "/batchEditBalance": factory.NewAccountHandleFunction(operationAPI, true, BatchSetBalanceAPI), + } +} + +//NewAPIHandlers API处理器 +func NewAPIHandlers() *Handlers { + return &Handlers{} +} + //AddAPI 新增接口 func AddAPI(httpResponse http.ResponseWriter, httpRequest *http.Request) { - userID, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationEDIT) - if e != nil { - return - } apiName := httpRequest.PostFormValue("apiName") + alias := httpRequest.PostFormValue("alias") requestURL := httpRequest.PostFormValue("requestURL") requestMethod := httpRequest.PostFormValue("requestMethod") protocol := httpRequest.PostFormValue("protocol") @@ -36,7 +64,7 @@ func AddAPI(httpResponse http.ResponseWriter, httpRequest *http.Request) { linkApis := httpRequest.PostFormValue("linkApis") staticResponse := httpRequest.PostFormValue("staticResponse") responseDataType := httpRequest.PostFormValue("responseDataType") - + userID := goku_handler.UserIDFromRequest(httpRequest) if apiName == "" { controller.WriteError(httpResponse, "190002", "api", "[ERROR]Illegal apiName!", nil) return @@ -55,6 +83,15 @@ func AddAPI(httpResponse http.ResponseWriter, httpRequest *http.Request) { controller.WriteError(httpResponse, "190012", "api", "[ERROR]Illegal apiType!", err) return } + + if !utils.ValidateURL(requestURL) { + controller.WriteError(httpResponse, "190021", "api", "[ERROR]Illegal requestURL!", nil) + return + } + if aType == 1 && !utils.ValidateURL(targetURL) { + controller.WriteError(httpResponse, "190022", "api", "[ERROR]Illegal requestURL!", nil) + return + } if responseDataType != "origin" && responseDataType != "json" && responseDataType != "xml" { controller.WriteError(httpResponse, "190013", "api", "[ERROR]Illegal responseDataType!", err) return @@ -102,8 +139,13 @@ func AddAPI(httpResponse http.ResponseWriter, httpRequest *http.Request) { if managerID == "" { mgID = userID } + if api.CheckAliasIsExist(0, alias) { + errInfo := "[ERROR]duplicate alias!" + controller.WriteError(httpResponse, "190020", "api", errInfo, errors.New(errInfo)) + return + } - flag, id, err := api.AddAPI(apiName, requestURL, targetURL, requestMethod, targetMethod, isFollow, linkApis, staticResponse, responseDataType, balanceName, protocol, pjID, gID, t, count, apiValve, mgID, userID, aType) + flag, id, err := api.AddAPI(apiName, alias, requestURL, targetURL, requestMethod, targetMethod, isFollow, linkApis, staticResponse, responseDataType, balanceName, protocol, pjID, gID, t, count, apiValve, mgID, userID, aType) if !flag { controller.WriteError(httpResponse, @@ -117,13 +159,10 @@ func AddAPI(httpResponse http.ResponseWriter, httpRequest *http.Request) { //EditAPI 编辑接口 func EditAPI(httpResponse http.ResponseWriter, httpRequest *http.Request) { - userID, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationEDIT) - if e != nil { - return - } apiID := httpRequest.PostFormValue("apiID") apiName := httpRequest.PostFormValue("apiName") + alias := httpRequest.PostFormValue("alias") requestURL := httpRequest.PostFormValue("requestURL") targetURL := httpRequest.PostFormValue("targetURL") requestMethod := httpRequest.PostFormValue("requestMethod") @@ -140,6 +179,8 @@ func EditAPI(httpResponse http.ResponseWriter, httpRequest *http.Request) { linkApis := httpRequest.PostFormValue("linkApis") staticResponse := httpRequest.PostFormValue("staticResponse") responseDataType := httpRequest.PostFormValue("responseDataType") + userID := goku_handler.UserIDFromRequest(httpRequest) + if apiName == "" { controller.WriteError(httpResponse, "190002", "api", "[ERROR]Illegal apiName!", nil) return @@ -207,8 +248,13 @@ func EditAPI(httpResponse http.ResponseWriter, httpRequest *http.Request) { if managerID == "" { mgID = userID } + if api.CheckAliasIsExist(aID, alias) { + errInfo := "[ERROR]duplicate alias!" + controller.WriteError(httpResponse, "190020", "api", errInfo, errors.New(errInfo)) + return + } - flag, err := api.EditAPI(apiName, requestURL, targetURL, requestMethod, targetMethod, isFollow, linkApis, staticResponse, responseDataType, balanceName, protocol, pjID, gID, t, count, apiValve, aID, mgID, userID) + flag, err := api.EditAPI(apiName, alias, requestURL, targetURL, requestMethod, targetMethod, isFollow, linkApis, staticResponse, responseDataType, balanceName, protocol, pjID, gID, t, count, apiValve, aID, mgID, userID) if !flag { controller.WriteError(httpResponse, "190000", "api", "[ERROR]apiID does not exist!", err) @@ -223,10 +269,6 @@ func EditAPI(httpResponse http.ResponseWriter, httpRequest *http.Request) { //GetAPIInfo 获取接口信息 func GetAPIInfo(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationREAD) - if e != nil { - return - } apiID := httpRequest.PostFormValue("apiID") @@ -249,10 +291,6 @@ func GetAPIInfo(httpResponse http.ResponseWriter, httpRequest *http.Request) { // GetAPIIDList 获取接口ID列表 func GetAPIIDList(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationREAD) - if e != nil { - return - } httpRequest.ParseForm() projectID := httpRequest.Form.Get("projectID") @@ -284,8 +322,11 @@ func GetAPIIDList(httpResponse http.ResponseWriter, httpRequest *http.Request) { ids := make([]int, 0) json.Unmarshal([]byte(idsStr), &ids) - _, result, _ := api.GetAPIIDList(pjID, gID, keyword, op, ids) - + _, result, err := api.GetAPIIDList(pjID, gID, keyword, op, ids) + if err != nil { + controller.WriteError(httpResponse, "190020", "api", "[ERROR]db error!", err) + return + } // controller.WriteResultInfo(httpResponse, "api", "apiList", result) controller.WriteResultInfoWithPage(httpResponse, "api", "apiIDList", result, &controller.PageInfo{ ItemNum: len(result), @@ -296,10 +337,6 @@ func GetAPIIDList(httpResponse http.ResponseWriter, httpRequest *http.Request) { //GetAPIList 获取接口列表 func GetAPIList(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationREAD) - if e != nil { - return - } httpRequest.ParseForm() projectID := httpRequest.Form.Get("projectID") @@ -343,8 +380,11 @@ func GetAPIList(httpResponse http.ResponseWriter, httpRequest *http.Request) { ids := make([]int, 0) json.Unmarshal([]byte(idsStr), &ids) - _, result, count, _ := api.GetAPIList(pjID, gID, keyword, op, p, pSize, ids) - + _, result, count, err := api.GetAPIList(pjID, gID, keyword, op, p, pSize, ids) + if err != nil { + controller.WriteError(httpResponse, "190019", "api", "[Error]db error", err) + return + } // controller.WriteResultInfo(httpResponse, "api", "apiList", result) controller.WriteResultInfoWithPage(httpResponse, "api", "apiList", result, &controller.PageInfo{ ItemNum: len(result), @@ -357,10 +397,6 @@ func GetAPIList(httpResponse http.ResponseWriter, httpRequest *http.Request) { // BatchEditAPIGroup 批量修改接口分组 func BatchEditAPIGroup(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationEDIT) - if e != nil { - return - } apiIDList := httpRequest.PostFormValue("apiIDList") groupID := httpRequest.PostFormValue("groupID") @@ -381,10 +417,6 @@ func BatchEditAPIGroup(httpResponse http.ResponseWriter, httpRequest *http.Reque //BatchDeleteAPI 批量删除接口 func BatchDeleteAPI(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationEDIT) - if e != nil { - return - } apiIDList := httpRequest.PostFormValue("apiIDList") @@ -400,30 +432,11 @@ func BatchDeleteAPI(httpResponse http.ResponseWriter, httpRequest *http.Request) return } -//GetAPIManagerList 获取接口负责人列表 -func GetAPIManagerList(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationREAD) - if e != nil { - return - } - - flag, result, err := account.GetUserListWithPermission("apiManagement", "edit") - if !flag { - controller.WriteError(httpResponse, "190000", "api", err.Error(), err) - return - } - controller.WriteResultInfo(httpResponse, "api", "userList", result) - return -} - //CopyAPI 复制接口 func CopyAPI(httpResponse http.ResponseWriter, httpRequest *http.Request) { - userID, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationEDIT) - if e != nil { - return - } apiID := httpRequest.PostFormValue("apiID") + alisa := httpRequest.PostFormValue("alisa") apiName := httpRequest.PostFormValue("apiName") requestURL := httpRequest.PostFormValue("requestURL") targetURL := httpRequest.PostFormValue("targetURL") @@ -434,6 +447,7 @@ func CopyAPI(httpResponse http.ResponseWriter, httpRequest *http.Request) { isFollow := httpRequest.PostFormValue("isFollow") groupID := httpRequest.PostFormValue("groupID") projectID := httpRequest.PostFormValue("projectID") + userID := goku_handler.UserIDFromRequest(httpRequest) if apiName == "" { controller.WriteError(httpResponse, "190002", "api", "[ERROR]Illegal apiName!", nil) return @@ -465,13 +479,21 @@ func CopyAPI(httpResponse http.ResponseWriter, httpRequest *http.Request) { return } + if !utils.ValidateURL(requestURL) { + controller.WriteError(httpResponse, "190021", "api", "[ERROR]Illegal requestURL!", nil) + return + } flag, apiInfo, err := api.GetAPIInfo(aID) if !flag { controller.WriteError(httpResponse, "190000", "api", "[ERROR]apiID does not exist!", nil) return } + if apiInfo.APIType == 1 && !utils.ValidateURL(targetURL) { + controller.WriteError(httpResponse, "190022", "api", "[ERROR]Illegal targetURL!", nil) + return + } linkApis, _ := json.Marshal(apiInfo.LinkAPIs) - flag, id, err := api.AddAPI(apiName, requestURL, targetURL, requestMethod, targetMethod, isFollow, string(linkApis), apiInfo.StaticResponse, apiInfo.ResponseDataType, balanceName, protocol, pjID, gID, apiInfo.Timeout, apiInfo.RetryConut, apiInfo.Valve, apiInfo.ManagerID, userID, apiInfo.APIType) + flag, id, err := api.AddAPI(apiName, alisa, requestURL, targetURL, requestMethod, targetMethod, isFollow, string(linkApis), apiInfo.StaticResponse, apiInfo.ResponseDataType, balanceName, protocol, pjID, gID, apiInfo.Timeout, apiInfo.RetryConut, apiInfo.Valve, apiInfo.ManagerID, userID, apiInfo.APIType) if !flag { controller.WriteError(httpResponse, "190000", "api", "[ERROR]Fail to add api!", err) return diff --git a/console/controller/api/apiGroup.go b/console/controller/api/apiGroup.go index 1b7942f6..607242f3 100644 --- a/console/controller/api/apiGroup.go +++ b/console/controller/api/apiGroup.go @@ -7,14 +7,32 @@ import ( "github.com/eolinker/goku-api-gateway/console/controller" "github.com/eolinker/goku-api-gateway/console/module/api" "github.com/eolinker/goku-api-gateway/console/module/project" + goku_handler "github.com/eolinker/goku-api-gateway/goku-handler" ) +const operationAPIGroup = "apiManagement" + +//GroupHandlers 接口分组处理器 +type GroupHandlers struct { +} + +//Handlers 处理器 +func (g *GroupHandlers) Handlers(factory *goku_handler.AccountHandlerFactory) map[string]http.Handler { + return map[string]http.Handler{ + "/add": factory.NewAccountHandleFunction(operationAPIGroup, true, AddAPIGroup), + "/edit": factory.NewAccountHandleFunction(operationAPIGroup, true, EditAPIGroup), + "/delete": factory.NewAccountHandleFunction(operationAPIGroup, true, DeleteAPIGroup), + "/getList": factory.NewAccountHandleFunction(operationAPIGroup, false, GetAPIGroupList), + } +} + +//NewGroupHandlers new 接口分组处理器 +func NewGroupHandlers() *GroupHandlers { + return &GroupHandlers{} +} + //AddAPIGroup 新建接口分组 func AddAPIGroup(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationEDIT) - if e != nil { - return - } groupName := httpRequest.PostFormValue("groupName") projectID := httpRequest.PostFormValue("projectID") @@ -68,10 +86,6 @@ func AddAPIGroup(httpResponse http.ResponseWriter, httpRequest *http.Request) { //EditAPIGroup 修改接口分组 func EditAPIGroup(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationEDIT) - if e != nil { - return - } groupName := httpRequest.PostFormValue("groupName") groupID := httpRequest.PostFormValue("groupID") @@ -120,10 +134,6 @@ func EditAPIGroup(httpResponse http.ResponseWriter, httpRequest *http.Request) { //DeleteAPIGroup 删除接口分组 func DeleteAPIGroup(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationEDIT) - if e != nil { - return - } groupID := httpRequest.PostFormValue("groupID") projectID := httpRequest.PostFormValue("projectID") @@ -158,10 +168,6 @@ func DeleteAPIGroup(httpResponse http.ResponseWriter, httpRequest *http.Request) //GetAPIGroupList 获取接口分组列表 func GetAPIGroupList(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationREAD) - if e != nil { - return - } projectID := httpRequest.PostFormValue("projectID") pjID, err := strconv.Atoi(projectID) diff --git a/console/controller/api/apiPlugin.go b/console/controller/api/apiPlugin.go index c11e1412..eaab20ad 100644 --- a/console/controller/api/apiPlugin.go +++ b/console/controller/api/apiPlugin.go @@ -10,20 +10,44 @@ import ( "github.com/eolinker/goku-api-gateway/console/module/plugin" plugin_config "github.com/eolinker/goku-api-gateway/console/module/plugin/plugin-config" "github.com/eolinker/goku-api-gateway/console/module/strategy" + goku_handler "github.com/eolinker/goku-api-gateway/goku-handler" ) +const operationAPIPlugin = "strategyManagement" + +//PluginHandlers 插件处理器 +type PluginHandlers struct { +} + +//Handlers handlers +func (p *PluginHandlers) Handlers(factory *goku_handler.AccountHandlerFactory) map[string]http.Handler { + return map[string]http.Handler{ + "/addPluginToApi": factory.NewAccountHandleFunction(operationAPIPlugin, true, AddPluginToAPI), + "/edit": factory.NewAccountHandleFunction(operationAPIPlugin, true, EditAPIPluginConfig), + "/getInfo": factory.NewAccountHandleFunction(operationAPIPlugin, false, GetAPIPluginConfig), + "/getList": factory.NewAccountHandleFunction(operationAPIPlugin, false, GetAPIPluginList), + "/getListByStrategy": factory.NewAccountHandleFunction(operationAPIPlugin, false, GetAllAPIPluginInStrategy), + "/batchStart": factory.NewAccountHandleFunction(operationAPIPlugin, true, BatchStartAPIPlugin), + "/batchStop": factory.NewAccountHandleFunction(operationAPIPlugin, true, BatchStopAPIPlugin), + "/batchDelete": factory.NewAccountHandleFunction(operationAPIPlugin, true, BatchDeleteAPIPlugin), + "/notAssign/getList": factory.NewAccountHandleFunction(operationAPIPlugin, false, GetAPIPluginListWithNotAssignAPIList), + } +} + +//NewPluginHandlers new插件处理器 +func NewPluginHandlers() *PluginHandlers { + return &PluginHandlers{} + +} + //AddPluginToAPI 新增插件到接口 func AddPluginToAPI(httpResponse http.ResponseWriter, httpRequest *http.Request) { - userID, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationEDIT) - if e != nil { - return - } pluginName := httpRequest.PostFormValue("pluginName") pluginConfig := httpRequest.PostFormValue("pluginConfig") strategyID := httpRequest.PostFormValue("strategyID") apiID := httpRequest.PostFormValue("apiID") - + userID := goku_handler.UserIDFromRequest(httpRequest) aID, err := strconv.Atoi(apiID) if err != nil { controller.WriteError(httpResponse, "240002", "apiPlugin", "[ERROR]Illegal apiID!", err) @@ -81,15 +105,13 @@ func AddPluginToAPI(httpResponse http.ResponseWriter, httpRequest *http.Request) //EditAPIPluginConfig 修改接口插件 func EditAPIPluginConfig(httpResponse http.ResponseWriter, httpRequest *http.Request) { - userID, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationEDIT) - if e != nil { - return - } pluginName := httpRequest.PostFormValue("pluginName") pluginConfig := httpRequest.PostFormValue("pluginConfig") strategyID := httpRequest.PostFormValue("strategyID") apiID := httpRequest.PostFormValue("apiID") + userID := goku_handler.UserIDFromRequest(httpRequest) + flag, err := plugin_config.CheckConfig(pluginName, []byte(pluginConfig)) if !flag { controller.WriteError(httpResponse, "500000", "apiPlugin", "[ERROR]插件配置无效:"+err.Error(), err) @@ -153,10 +175,6 @@ func EditAPIPluginConfig(httpResponse http.ResponseWriter, httpRequest *http.Req //GetAPIPluginConfig 获取接口插件配置 func GetAPIPluginConfig(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationREAD) - if e != nil { - return - } pluginName := httpRequest.PostFormValue("pluginName") strategyID := httpRequest.PostFormValue("strategyID") @@ -198,10 +216,6 @@ func GetAPIPluginConfig(httpResponse http.ResponseWriter, httpRequest *http.Requ //GetAPIPluginList 获取接口插件配置 func GetAPIPluginList(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationREAD) - if e != nil { - return - } strategyID := httpRequest.PostFormValue("strategyID") apiID := httpRequest.PostFormValue("apiID") @@ -230,60 +244,8 @@ func GetAPIPluginList(httpResponse http.ResponseWriter, httpRequest *http.Reques return } -// GetAPIPluginInStrategyByAPIID 获取策略组中所有接口插件列表 -func GetAPIPluginInStrategyByAPIID(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationREAD) - if e != nil { - return - } - httpRequest.ParseForm() - strategyID := httpRequest.Form.Get("strategyID") - apiID := httpRequest.Form.Get("apiID") - keyword := httpRequest.Form.Get("keyword") - condition := httpRequest.Form.Get("condition") - - aID, err := strconv.Atoi(apiID) - if err != nil { - controller.WriteError(httpResponse, "240002", "apiPlugin", "[ERROR]Illegal condition!", err) - return - } - op, err := strconv.Atoi(condition) - if err != nil && condition != "" { - controller.WriteError(httpResponse, "270006", "apiPlugin", "[ERROR]Illegal condition!", err) - return - } - - flag, pluginList, apiInfo, err := api.GetAPIPluginInStrategyByAPIID(strategyID, aID, keyword, op) - if !flag { - controller.WriteError(httpResponse, - "240000", - "apiPlugin", - "[ERROR]Empty api plugin list!", - err) - return - - } - result := map[string]interface{}{ - "statusCode": "000000", - "type": "apiPlugin", - "resultDesc": "", - "apiPluginList": pluginList, - "apiInfo": apiInfo, - "page": controller.PageInfo{ - ItemNum: len(pluginList), - }, - } - resultStr, _ := json.Marshal(result) - httpResponse.Write(resultStr) - // controller.WriteResultInfo(httpResponse, "apiPlugin", "apiPluginList", result) -} - //GetAllAPIPluginInStrategy 获取策略组中所有接口插件列表 func GetAllAPIPluginInStrategy(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationREAD) - if e != nil { - return - } strategyID := httpRequest.PostFormValue("strategyID") @@ -305,13 +267,11 @@ func GetAllAPIPluginInStrategy(httpResponse http.ResponseWriter, httpRequest *ht //BatchStartAPIPlugin 批量修改策略组插件状态 func BatchStartAPIPlugin(httpResponse http.ResponseWriter, httpRequest *http.Request) { - userID, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationEDIT) - if e != nil { - return - } strategyID := httpRequest.PostFormValue("strategyID") connIDList := httpRequest.PostFormValue("connIDList") + userID := goku_handler.UserIDFromRequest(httpRequest) + if connIDList == "" { controller.WriteError(httpResponse, "240001", @@ -338,13 +298,11 @@ func BatchStartAPIPlugin(httpResponse http.ResponseWriter, httpRequest *http.Req //BatchStopAPIPlugin 批量修改策略组插件状态 func BatchStopAPIPlugin(httpResponse http.ResponseWriter, httpRequest *http.Request) { - userID, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationEDIT) - if e != nil { - return - } strategyID := httpRequest.PostFormValue("strategyID") connIDList := httpRequest.PostFormValue("connIDList") + userID := goku_handler.UserIDFromRequest(httpRequest) + if connIDList == "" { controller.WriteError(httpResponse, "240001", @@ -371,13 +329,10 @@ func BatchStopAPIPlugin(httpResponse http.ResponseWriter, httpRequest *http.Requ //BatchDeleteAPIPlugin 批量删除策略组插件 func BatchDeleteAPIPlugin(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationEDIT) - if e != nil { - return - } strategyID := httpRequest.PostFormValue("strategyID") connIDList := httpRequest.PostFormValue("connIDList") + if connIDList == "" { controller.WriteError(httpResponse, "240001", @@ -401,10 +356,6 @@ func BatchDeleteAPIPlugin(httpResponse http.ResponseWriter, httpRequest *http.Re //GetAPIPluginListWithNotAssignAPIList 获取没有分配接口插件的接口列表 func GetAPIPluginListWithNotAssignAPIList(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationREAD) - if e != nil { - return - } strategyID := httpRequest.PostFormValue("strategyID") if strategyID == "" { diff --git a/console/controller/api/import.go b/console/controller/api/import.go index c2d9e8e7..fec2a76a 100644 --- a/console/controller/api/import.go +++ b/console/controller/api/import.go @@ -2,6 +2,7 @@ package api import ( "encoding/json" + "fmt" "io/ioutil" "net/http" "strconv" @@ -9,18 +10,36 @@ import ( "github.com/eolinker/goku-api-gateway/console/controller" "github.com/eolinker/goku-api-gateway/console/module/api" + goku_handler "github.com/eolinker/goku-api-gateway/goku-handler" entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" ) +const operationImportAMS = "apiManagement" + +//ImportHandlers 导入handlers +type ImportHandlers struct { +} + +//Handlers handler +func (i *ImportHandlers) Handlers(factory *goku_handler.AccountHandlerFactory) map[string]http.Handler { + + return map[string]http.Handler{ + "/api": factory.NewAccountHandleFunction(operationImportAMS, true, ImportAPIFromAms), + "/group": factory.NewAccountHandleFunction(operationImportAMS, true, ImportAPIGroupFromAms), + "/project": factory.NewAccountHandleFunction(operationImportAMS, true, ImportProjectFromAms), + } +} + +//NewImportHandlers new导入处理器 +func NewImportHandlers() *ImportHandlers { + return &ImportHandlers{} +} + //ImportAPIGroupFromAms 导入分组 func ImportAPIGroupFromAms(httpResponse http.ResponseWriter, httpRequest *http.Request) { - userID, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationEDIT) - if e != nil { - return - } contentType := httpRequest.Header.Get("Content-Type") - + userID := goku_handler.UserIDFromRequest(httpRequest) if !strings.Contains(contentType, "multipart/form-data") { controller.WriteError(httpResponse, "310001", @@ -98,13 +117,9 @@ func ImportAPIGroupFromAms(httpResponse http.ResponseWriter, httpRequest *http.R //ImportProjectFromAms 导入项目 func ImportProjectFromAms(httpResponse http.ResponseWriter, httpRequest *http.Request) { - userID, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationEDIT) - if e != nil { - return - } contentType := httpRequest.Header.Get("Content-Type") - + userID := goku_handler.UserIDFromRequest(httpRequest) if !strings.Contains(contentType, "multipart/form-data") { controller.WriteError(httpResponse, "310001", @@ -170,12 +185,9 @@ func ImportProjectFromAms(httpResponse http.ResponseWriter, httpRequest *http.Re //ImportAPIFromAms 导入接口 func ImportAPIFromAms(httpResponse http.ResponseWriter, httpRequest *http.Request) { - userID, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationEDIT) - if e != nil { - return - } contentType := httpRequest.Header.Get("Content-Type") + userID := goku_handler.UserIDFromRequest(httpRequest) if !strings.Contains(contentType, "multipart/form-data") { controller.WriteError(httpResponse, "310001", @@ -229,6 +241,7 @@ func ImportAPIFromAms(httpResponse http.ResponseWriter, httpRequest *http.Reques } apiList := make([]entity.AmsAPIInfo, 0) + fmt.Println(string(body)) err = json.Unmarshal(body, &apiList) if err != nil { controller.WriteError(httpResponse, diff --git a/console/controller/auth/auth.go b/console/controller/auth/auth.go index 37af6dd5..62c42aff 100644 --- a/console/controller/auth/auth.go +++ b/console/controller/auth/auth.go @@ -5,23 +5,40 @@ import ( "net/http" "strings" + goku_handler "github.com/eolinker/goku-api-gateway/goku-handler" + "github.com/eolinker/goku-api-gateway/console/controller" "github.com/eolinker/goku-api-gateway/console/module/auth" log "github.com/eolinker/goku-api-gateway/goku-log" ) +const operationAuth = "strategyManagement" + +//Handlers handlers +type Handlers struct { +} + +//Handlers handlers +func (h *Handlers) Handlers(factory *goku_handler.AccountHandlerFactory) map[string]http.Handler { + return map[string]http.Handler{ + "/getStatus": factory.NewAccountHandleFunction(operationAuth, true, GetAuthStatus), + "/getInfo": factory.NewAccountHandleFunction(operationAuth, true, GetAuthInfo), + "/editInfo": factory.NewAccountHandleFunction(operationAuth, true, EditAuthInfo), + } +} + +//NewHandlers new handlers +func NewHandlers() *Handlers { + return &Handlers{} +} + //GetAuthStatus 获取认证状态 func GetAuthStatus(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNone, controller.OperationREAD) - if e != nil { - return - } strategyID := httpRequest.PostFormValue("strategyID") flag, result, err := auth.GetAuthStatus(strategyID) if !flag { - controller.WriteError(httpResponse, "250000", "auth", "[ERROR]The auth info of the strategy does not exist!", err) return } @@ -37,10 +54,6 @@ func GetAuthStatus(httpResponse http.ResponseWriter, httpRequest *http.Request) //GetAuthInfo 获取认证信息 func GetAuthInfo(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNone, controller.OperationREAD) - if e != nil { - return - } strategyID := httpRequest.PostFormValue("strategyID") @@ -64,10 +77,6 @@ func GetAuthInfo(httpResponse http.ResponseWriter, httpRequest *http.Request) { //EditAuthInfo 编辑认证信息 func EditAuthInfo(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNone, controller.OperationEDIT) - if e != nil { - return - } strategyID := httpRequest.PostFormValue("strategyID") strategyName := httpRequest.PostFormValue("strategyName") diff --git a/console/controller/balance/add.go b/console/controller/balance/add.go index ef948742..a78211d4 100644 --- a/console/controller/balance/add.go +++ b/console/controller/balance/add.go @@ -2,10 +2,11 @@ package balance import ( "fmt" + "github.com/eolinker/goku-api-gateway/console/controller" + "net/http" "github.com/eolinker/goku-api-gateway/common/auto-form" - "github.com/eolinker/goku-api-gateway/console/controller" "github.com/eolinker/goku-api-gateway/console/module/balance" "github.com/go-sql-driver/mysql" ) @@ -13,10 +14,7 @@ import ( //AddBalance 新增负载配置 func AddBalance(w http.ResponseWriter, r *http.Request) { - _, e := controller.CheckLogin(w, r, controller.OperationLoadBalance, controller.OperationEDIT) - if e != nil { - return - } + if err := r.ParseForm(); err != nil { controller.WriteError(w, "260000", diff --git a/console/controller/balance/delete.go b/console/controller/balance/delete.go index 0fac567e..5dd1787e 100644 --- a/console/controller/balance/delete.go +++ b/console/controller/balance/delete.go @@ -1,19 +1,16 @@ package balance import ( + "github.com/eolinker/goku-api-gateway/console/controller" "net/http" "strings" - "github.com/eolinker/goku-api-gateway/console/controller" "github.com/eolinker/goku-api-gateway/console/module/balance" ) //DeleteBalance 删除负载配置 func DeleteBalance(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationLoadBalance, controller.OperationEDIT) - if e != nil { - return - } + if err := httpRequest.ParseForm(); err != nil { controller.WriteError(httpResponse, "260000", "data", "[param_check] Parse form body error | 解析form表单参数错误", err) @@ -37,10 +34,7 @@ func DeleteBalance(httpResponse http.ResponseWriter, httpRequest *http.Request) //BatchDeleteBalance 批量删除负载 func BatchDeleteBalance(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationLoadBalance, controller.OperationEDIT) - if e != nil { - return - } + balanceNames := httpRequest.PostFormValue("balanceNames") result, err := balance.BatchDeleteBalance(strings.Split(balanceNames, ",")) if err != nil { diff --git a/console/controller/balance/get.go b/console/controller/balance/get.go index a726bf08..03528954 100644 --- a/console/controller/balance/get.go +++ b/console/controller/balance/get.go @@ -1,18 +1,14 @@ package balance import ( - "net/http" - "github.com/eolinker/goku-api-gateway/console/controller" "github.com/eolinker/goku-api-gateway/console/module/balance" + "net/http" ) //GetBalanceInfo 获取负载信息 func GetBalanceInfo(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationLoadBalance, controller.OperationREAD) - if e != nil { - return - } + if err := httpRequest.ParseForm(); err != nil { controller.WriteError(httpResponse, "501", "balance", "[ERROR]参数解析错误t!", err) return diff --git a/console/controller/balance/handle.go b/console/controller/balance/handle.go new file mode 100644 index 00000000..dd6a839e --- /dev/null +++ b/console/controller/balance/handle.go @@ -0,0 +1,31 @@ +package balance + +import ( + "net/http" + + goku_handler "github.com/eolinker/goku-api-gateway/goku-handler" +) + +const operationBalance = "balanceManagement" + +//Handlers handlers +type Handlers struct { +} + +//Handlers handlers +func (h *Handlers) Handlers(factory *goku_handler.AccountHandlerFactory) map[string]http.Handler { + return map[string]http.Handler{ + "/add": factory.NewAccountHandleFunction(operationBalance, true, AddBalance), + "/edit": factory.NewAccountHandleFunction(operationBalance, true, SaveBalance), + "/delete": factory.NewAccountHandleFunction(operationBalance, true, DeleteBalance), + "/getInfo": factory.NewAccountHandleFunction(operationBalance, false, GetBalanceInfo), + "/getList": factory.NewAccountHandleFunction(operationBalance, false, GetBalanceList), + "/batchDelete": factory.NewAccountHandleFunction(operationBalance, true, BatchDeleteBalance), + "/simple": factory.NewAccountHandleFunction(operationBalance, true, GetSimpleList), + } +} + +//NewHandlers new handlers +func NewHandlers() *Handlers { + return &Handlers{} +} diff --git a/console/controller/balance/list.go b/console/controller/balance/list.go index a581df98..d3334f1d 100644 --- a/console/controller/balance/list.go +++ b/console/controller/balance/list.go @@ -2,18 +2,14 @@ package balance import ( "fmt" - "net/http" - "github.com/eolinker/goku-api-gateway/console/controller" "github.com/eolinker/goku-api-gateway/console/module/balance" + "net/http" ) //GetBalanceList 获取负载列表 func GetBalanceList(w http.ResponseWriter, r *http.Request) { - _, e := controller.CheckLogin(w, r, controller.OperationLoadBalance, controller.OperationREAD) - if e != nil { - return - } + _ = r.ParseForm() keyword := r.FormValue("keyword") diff --git a/console/controller/balance/save.go b/console/controller/balance/save.go index 8ec187f8..1dc9b9bc 100644 --- a/console/controller/balance/save.go +++ b/console/controller/balance/save.go @@ -2,21 +2,17 @@ package balance import ( "fmt" - "net/http" - "github.com/eolinker/goku-api-gateway/common/auto-form" "github.com/eolinker/goku-api-gateway/console/controller" "github.com/eolinker/goku-api-gateway/console/module/balance" "github.com/go-sql-driver/mysql" + "net/http" ) //SaveBalance 新增负载配置 func SaveBalance(w http.ResponseWriter, r *http.Request) { - _, e := controller.CheckLogin(w, r, controller.OperationLoadBalance, controller.OperationEDIT) - if e != nil { - return - } + if err := r.ParseForm(); err != nil { controller.WriteError(w, "260000", "data", "[param_check] Parse form body error | 解析form表单参数错误", err) diff --git a/console/controller/balance/simple.go b/console/controller/balance/simple.go index 43de34aa..28c5183f 100644 --- a/console/controller/balance/simple.go +++ b/console/controller/balance/simple.go @@ -1,18 +1,14 @@ package balance import ( - "net/http" - "github.com/eolinker/goku-api-gateway/console/controller" "github.com/eolinker/goku-api-gateway/console/module/balance" + "net/http" ) //GetSimpleList 获取简易列表 func GetSimpleList(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationLoadBalance, controller.OperationREAD) - if e != nil { - return - } + flag, result, err := balance.GetBalancNames() diff --git a/console/controller/cluster/cluster.go b/console/controller/cluster/cluster.go index 6f9d0ab1..f5750548 100644 --- a/console/controller/cluster/cluster.go +++ b/console/controller/cluster/cluster.go @@ -4,18 +4,39 @@ import ( "net/http" "regexp" + goku_handler "github.com/eolinker/goku-api-gateway/goku-handler" + "github.com/pkg/errors" "github.com/eolinker/goku-api-gateway/console/controller" "github.com/eolinker/goku-api-gateway/console/module/cluster" ) +const operationCluster = "nodeManagement" + +//Handlers handlers +type Handlers struct { +} + +//Handlers handlers +func (h *Handlers) Handlers(factory *goku_handler.AccountHandlerFactory) map[string]http.Handler { + return map[string]http.Handler{ + "/add": factory.NewAccountHandleFunction(operationCluster, true, AddCluster), + "/edit": factory.NewAccountHandleFunction(operationCluster, true, EditCluster), + "/delete": factory.NewAccountHandleFunction(operationCluster, true, DeleteCluster), + "/list": factory.NewAccountHandleFunction(operationCluster, false, GetClusterInfoList), + "/simpleList": factory.NewAccountHandleFunction(operationCluster, false, GetClusterList), + } +} + +//NewHandlers new handlers +func NewHandlers() *Handlers { + return &Handlers{} +} + //GetClusterList 获取集群列表 func GetClusterList(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNone, controller.OperationREAD) - if e != nil { - return - } + list, _ := cluster.GetClusters() controller.WriteResultInfo(httpResponse, @@ -26,10 +47,7 @@ func GetClusterList(httpResponse http.ResponseWriter, httpRequest *http.Request) //GetCluster 获取集群信息 func GetCluster(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNone, controller.OperationREAD) - if e != nil { - return - } + httpRequest.ParseForm() name := httpRequest.Form.Get("name") @@ -47,10 +65,7 @@ func GetCluster(httpResponse http.ResponseWriter, httpRequest *http.Request) { //AddCluster 新增集群 func AddCluster(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNone, controller.OperationREAD) - if e != nil { - return - } + httpRequest.ParseForm() name := httpRequest.Form.Get("name") title := httpRequest.Form.Get("title") @@ -78,10 +93,7 @@ func AddCluster(httpResponse http.ResponseWriter, httpRequest *http.Request) { //EditCluster 新增集群 func EditCluster(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNone, controller.OperationREAD) - if e != nil { - return - } + httpRequest.ParseForm() name := httpRequest.Form.Get("name") title := httpRequest.Form.Get("title") @@ -105,10 +117,7 @@ func EditCluster(httpResponse http.ResponseWriter, httpRequest *http.Request) { //DeleteCluster 新增集群 func DeleteCluster(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNone, controller.OperationREAD) - if e != nil { - return - } + httpRequest.ParseForm() name := httpRequest.Form.Get("name") match, err := regexp.MatchString(`^[a-zA-Z][a-zA-z0-9_]*$`, name) @@ -135,10 +144,7 @@ func DeleteCluster(httpResponse http.ResponseWriter, httpRequest *http.Request) //GetClusterInfoList 获取集群信息列表 func GetClusterInfoList(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNone, controller.OperationREAD) - if e != nil { - return - } + result, _ := cluster.GetClusters() controller.WriteResultInfo(httpResponse, diff --git a/console/controller/cluster/version.go b/console/controller/cluster/version.go index e40735b1..a9bb52d0 100644 --- a/console/controller/cluster/version.go +++ b/console/controller/cluster/version.go @@ -6,17 +6,38 @@ import ( "strconv" "time" + goku_handler "github.com/eolinker/goku-api-gateway/goku-handler" + "github.com/eolinker/goku-api-gateway/console/module/versionConfig" "github.com/eolinker/goku-api-gateway/console/controller" ) +const operationVersion = "versionManagement" + +//VersionHandlers 版本处理器 +type VersionHandlers struct { +} + +//Handlers handlers +func (h *VersionHandlers) Handlers(factory *goku_handler.AccountHandlerFactory) map[string]http.Handler { + return map[string]http.Handler{ + "/add": factory.NewAccountHandleFunction(operationVersion, true, AddVersionConfig), + "/basic/edit": factory.NewAccountHandleFunction(operationVersion, true, EditVersionBasicConfig), + "/delete": factory.NewAccountHandleFunction(operationVersion, true, BatchDeleteVersionConfig), + "/getList": factory.NewAccountHandleFunction(operationVersion, false, GetVersionList), + "/publish": factory.NewAccountHandleFunction(operationVersion, true, PublishVersion), + } +} + +//NewVersionHandlers new versionHandlers +func NewVersionHandlers() *VersionHandlers { + return &VersionHandlers{} +} + //GetVersionList 获取版本列表 func GetVersionList(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNone, controller.OperationREAD) - if e != nil { - return - } + httpRequest.ParseForm() keyword := httpRequest.Form.Get("keyword") result, _ := versionConfig.GetVersionList(keyword) @@ -28,10 +49,7 @@ func GetVersionList(httpResponse http.ResponseWriter, httpRequest *http.Request) //AddVersionConfig 新增版本配置 func AddVersionConfig(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNone, controller.OperationREAD) - if e != nil { - return - } + httpRequest.ParseForm() name := httpRequest.Form.Get("name") version := httpRequest.Form.Get("version") @@ -44,14 +62,15 @@ func AddVersionConfig(httpResponse http.ResponseWriter, httpRequest *http.Reques } //count := cluster.GetVersionConfigCount() now := time.Now().Format("2006-01-02 15:04:05") - id, err := versionConfig.AddVersionConfig(name, version, remark, now) + userID := goku_handler.UserIDFromRequest(httpRequest) + id, err := versionConfig.AddVersionConfig(name, version, remark, now, userID) if err != nil { controller.WriteError(httpResponse, "380000", "versionConfig", err.Error(), err) return } if p == 1 { - versionConfig.PublishVersion(id, now) + versionConfig.PublishVersion(id, userID, now) } controller.WriteResultInfo(httpResponse, "versionConfig", @@ -60,12 +79,37 @@ func AddVersionConfig(httpResponse http.ResponseWriter, httpRequest *http.Reques return } -//BatchDeleteVersionConfig 批量删除版本配置 -func BatchDeleteVersionConfig(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNone, controller.OperationREAD) - if e != nil { +//EditVersionBasicConfig 新增版本配置 +func EditVersionBasicConfig(httpResponse http.ResponseWriter, httpRequest *http.Request) { + + httpRequest.ParseForm() + name := httpRequest.Form.Get("name") + version := httpRequest.Form.Get("version") + remark := httpRequest.Form.Get("remark") + versionID := httpRequest.Form.Get("versionID") + id, err := strconv.Atoi(versionID) + if err != nil { + controller.WriteError(httpResponse, "380000", "versionConfig", err.Error(), err) return } + + userID := goku_handler.UserIDFromRequest(httpRequest) + err = versionConfig.EditVersionBasicConfig(name, version, remark, userID, id) + if err != nil { + controller.WriteError(httpResponse, "380000", "versionConfig", err.Error(), err) + return + } + + controller.WriteResultInfo(httpResponse, + "versionConfig", + "", + nil) + return +} + +//BatchDeleteVersionConfig 批量删除版本配置 +func BatchDeleteVersionConfig(httpResponse http.ResponseWriter, httpRequest *http.Request) { + httpRequest.ParseForm() ids := httpRequest.Form.Get("ids") idList := make([]int, 0, 10) @@ -93,13 +137,14 @@ func BatchDeleteVersionConfig(httpResponse http.ResponseWriter, httpRequest *htt func PublishVersion(httpResponse http.ResponseWriter, httpRequest *http.Request) { httpRequest.ParseForm() versionID := httpRequest.Form.Get("versionID") + userID := goku_handler.UserIDFromRequest(httpRequest) id, err := strconv.Atoi(versionID) if err != nil { controller.WriteError(httpResponse, "380002", "versionConfig", "[ERROR]Illegal versionID", err) return } now := time.Now().Format("2006-01-02 15:04:05") - err = versionConfig.PublishVersion(id, now) + err = versionConfig.PublishVersion(id, userID, now) if err != nil { controller.WriteError(httpResponse, "380000", "versionConfig", err.Error(), err) return diff --git a/console/controller/config-log/access.go b/console/controller/config-log/access.go index acd43af1..492a2561 100644 --- a/console/controller/config-log/access.go +++ b/console/controller/config-log/access.go @@ -4,39 +4,38 @@ import ( "fmt" "net/http" + goku_handler "github.com/eolinker/goku-api-gateway/goku-handler" + "github.com/eolinker/goku-api-gateway/common/auto-form" "github.com/eolinker/goku-api-gateway/console/controller" module "github.com/eolinker/goku-api-gateway/console/module/config-log" ) -//AccessLogHandler access日志处理器 -type AccessLogHandler struct { +//LogHandler access日志处理器 +type LogHandler struct { + getHandler http.Handler + setHandler http.Handler } -func (h *AccessLogHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { - _, err := controller.CheckLogin(w, r, controller.OperationGatewayConfig, controller.OperationEDIT) - if err != nil { - return - } +func (h *LogHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { switch r.Method { case http.MethodGet: { - h.get(w, r) - + h.getHandler.ServeHTTP(w, r) } case http.MethodPut: { - h.set(w, r) - + h.setHandler.ServeHTTP(w, r) } default: w.WriteHeader(404) } } -func (h *AccessLogHandler) get(w http.ResponseWriter, r *http.Request) { +//AccessLogGet 获取access日志配置 +func AccessLogGet(w http.ResponseWriter, r *http.Request) { config, e := module.GetAccess() if e = r.ParseForm(); e != nil { controller.WriteError(w, "270000", "data", "[Get]未知错误:"+e.Error(), e) @@ -49,7 +48,9 @@ func (h *AccessLogHandler) get(w http.ResponseWriter, r *http.Request) { config) } -func (h *AccessLogHandler) set(w http.ResponseWriter, r *http.Request) { + +//AccessLogSet 设置access日志内容 +func AccessLogSet(w http.ResponseWriter, r *http.Request) { err := r.ParseForm() if err = r.ParseForm(); err != nil { controller.WriteError(w, "260000", "data", "[param_check] Parse form body error | 解析form表单参数错误", err) @@ -82,7 +83,7 @@ func (h *AccessLogHandler) set(w http.ResponseWriter, r *http.Request) { err = module.Set(module.AccessLog, paramBase) if err != nil { - controller.WriteError(w, "260000", "data", fmt.Sprintf("[mysql_error] %s", err.Error()), err) + controller.WriteError(w, "260000", "data", fmt.Sprintf("[db_error] %s", err.Error()), err) return } controller.WriteResultInfo(w, @@ -90,3 +91,11 @@ func (h *AccessLogHandler) set(w http.ResponseWriter, r *http.Request) { "", nil) } + +//NewAccessHandler accessHandler +func NewAccessHandler(factory *goku_handler.AccountHandlerFactory) http.Handler { + return &LogHandler{ + getHandler: factory.NewAccountHandleFunction(operationLog, false, AccessLogGet), + setHandler: factory.NewAccountHandleFunction(operationLog, true, AccessLogSet), + } +} diff --git a/console/controller/config-log/handle.go b/console/controller/config-log/handle.go index 6ab955aa..2063c0ec 100644 --- a/console/controller/config-log/handle.go +++ b/console/controller/config-log/handle.go @@ -1,32 +1,27 @@ package config_log import ( - "fmt" "net/http" - "strings" - module "github.com/eolinker/goku-api-gateway/console/module/config-log" + goku_handler "github.com/eolinker/goku-api-gateway/goku-handler" ) -//Handle handle -func Handle(prefix string) http.Handler { +const operationLog = "logManagement" - pre := strings.TrimSuffix(prefix, "/") - serveMux := http.NewServeMux() - consoleLogHandler := &LogHandler{ - name: module.ConsoleLog, - } +//Handlers handlers +type Handlers struct { +} - serveMux.Handle(fmt.Sprintf("%s/%s", pre, "console"), consoleLogHandler) - nodeLogHandler := &LogHandler{ - name: module.NodeLog, +//Handlers handlers +func (h *Handlers) Handlers(factory *goku_handler.AccountHandlerFactory) map[string]http.Handler { + return map[string]http.Handler{ + "/console": NewLogHandler("console", factory), + "/node": NewLogHandler("node", factory), + "/access": NewAccessHandler(factory), } - serveMux.Handle(fmt.Sprintf("%s/%s", pre, "node"), nodeLogHandler) - - accessLogHandler := &AccessLogHandler{} - - serveMux.Handle(fmt.Sprintf("%s/%s", pre, "access"), accessLogHandler) - - return serveMux +} +//NewHandlers new handlers +func NewHandlers() *Handlers { + return &Handlers{} } diff --git a/console/controller/config-log/log.go b/console/controller/config-log/log.go index 55ec5b7b..312e483f 100644 --- a/console/controller/config-log/log.go +++ b/console/controller/config-log/log.go @@ -4,39 +4,20 @@ import ( "fmt" "net/http" + goku_handler "github.com/eolinker/goku-api-gateway/goku-handler" + "github.com/eolinker/goku-api-gateway/common/auto-form" "github.com/eolinker/goku-api-gateway/console/controller" module "github.com/eolinker/goku-api-gateway/console/module/config-log" ) -//LogHandler 日志处理器 -type LogHandler struct { +//LogHandlerGet 日志配置获取处理器 +type LogHandlerGet struct { name string } -func (h *LogHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { - _, err := controller.CheckLogin(w, r, controller.OperationGatewayConfig, controller.OperationEDIT) - if err != nil { - return - } - - switch r.Method { - case http.MethodGet: - { - h.get(w, r) - - } +func (h *LogHandlerGet) ServeHTTP(w http.ResponseWriter, r *http.Request) { - case http.MethodPut: - { - h.set(w, r) - - } - default: - w.WriteHeader(404) - } -} -func (h *LogHandler) get(w http.ResponseWriter, r *http.Request) { config, e := module.Get(h.name) if e = r.ParseForm(); e != nil { controller.WriteError(w, "270000", "data", "[Get]未知错误:"+e.Error(), e) @@ -50,7 +31,12 @@ func (h *LogHandler) get(w http.ResponseWriter, r *http.Request) { } -func (h *LogHandler) set(w http.ResponseWriter, r *http.Request) { +//LogHandlerSet 设置日志处理器 +type LogHandlerSet struct { + name string +} + +func (h *LogHandlerSet) ServeHTTP(w http.ResponseWriter, r *http.Request) { err := r.ParseForm() if err = r.ParseForm(); err != nil { @@ -83,7 +69,7 @@ func (h *LogHandler) set(w http.ResponseWriter, r *http.Request) { } err = module.Set(h.name, paramBase) if err != nil { - controller.WriteError(w, "260000", "data", fmt.Sprintf("[mysql_error] %s", err.Error()), err) + controller.WriteError(w, "260000", "data", fmt.Sprintf("[db_error] %s", err.Error()), err) return } controller.WriteResultInfo(w, @@ -91,3 +77,11 @@ func (h *LogHandler) set(w http.ResponseWriter, r *http.Request) { "", nil) } + +//NewLogHandler 日志handler +func NewLogHandler(name string, factory *goku_handler.AccountHandlerFactory) http.Handler { + return &LogHandler{ + getHandler: factory.NewAccountHandler(operationLog, false, &LogHandlerGet{name: name}), + setHandler: factory.NewAccountHandler(operationLog, true, &LogHandlerSet{name: name}), + } +} diff --git a/console/controller/discovery/add.go b/console/controller/discovery/add.go index b8544102..584101ba 100644 --- a/console/controller/discovery/add.go +++ b/console/controller/discovery/add.go @@ -2,27 +2,24 @@ package discovery import ( "fmt" + "github.com/eolinker/goku-api-gateway/console/controller" "net/http" "github.com/eolinker/goku-api-gateway/common/auto-form" - "github.com/eolinker/goku-api-gateway/console/controller" "github.com/eolinker/goku-api-gateway/console/module/service" driver2 "github.com/eolinker/goku-api-gateway/server/driver" ) func add(w http.ResponseWriter, r *http.Request) { - _, err := controller.CheckLogin(w, r, controller.OperationLoadBalance, controller.OperationEDIT) - if err != nil { - return - } - if err = r.ParseForm(); err != nil { + + if err := r.ParseForm(); err != nil { controller.WriteError(w, "260000", "data", "[param_check] Parse form body error | 解析form表单参数错误", err) return } param := new(service.AddParam) - err = auto.SetValues(r.PostForm, param) + err := auto.SetValues(r.PostForm, param) if err != nil { controller.WriteError(w, "260000", "data", fmt.Sprintf("[param_check] %s", err.Error()), err) return diff --git a/console/controller/discovery/default.go b/console/controller/discovery/default.go index 8f34d6fc..64db9bfe 100644 --- a/console/controller/discovery/default.go +++ b/console/controller/discovery/default.go @@ -2,19 +2,16 @@ package discovery import ( "fmt" + "github.com/eolinker/goku-api-gateway/console/controller" "net/http" - "github.com/eolinker/goku-api-gateway/console/controller" "github.com/eolinker/goku-api-gateway/console/module/service" ) func setDefault(w http.ResponseWriter, r *http.Request) { - _, err := controller.CheckLogin(w, r, controller.OperationLoadBalance, controller.OperationEDIT) - if err != nil { - return - } - if err != r.ParseForm() { + + if err := r.ParseForm() ; err!= nil{ controller.WriteError(w, "260000", "data", "[param_check] Parse form body error | 解析form表单参数错误", err) return } @@ -24,7 +21,7 @@ func setDefault(w http.ResponseWriter, r *http.Request) { return } - err = service.SetDefaut(name) + err := service.SetDefaut(name) if err != nil { controller.WriteError(w, "260000", "data", fmt.Sprintf("[error] %s", err.Error()), err) return diff --git a/console/controller/discovery/delete.go b/console/controller/discovery/delete.go index 8522856d..bdebea13 100644 --- a/console/controller/discovery/delete.go +++ b/console/controller/discovery/delete.go @@ -2,21 +2,16 @@ package discovery import ( "fmt" - "net/http" - "strings" - - dao_service2 "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3/dao-service" - "github.com/eolinker/goku-api-gateway/console/controller" "github.com/eolinker/goku-api-gateway/console/module/service" + dao_service2 "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3/dao-service" + "net/http" + "strings" ) func delete(w http.ResponseWriter, r *http.Request) { - _, err := controller.CheckLogin(w, r, controller.OperationLoadBalance, controller.OperationEDIT) - if err != nil { - return - } - if err != r.ParseForm() { + + if err := r.ParseForm() ; err!= nil{ controller.WriteError(w, "260000", "serviceDiscovery", "[param_check] Parse form body error | 解析form表单参数错误", err) return } @@ -24,7 +19,7 @@ func delete(w http.ResponseWriter, r *http.Request) { names := strings.Split(nameStr, ",") - err = service.Delete(names) + err := service.Delete(names) if err != nil { if en, ok := err.(dao_service2.DeleteError); ok { diff --git a/console/controller/discovery/driver.go b/console/controller/discovery/driver.go index 440255ed..277ce2df 100644 --- a/console/controller/discovery/driver.go +++ b/console/controller/discovery/driver.go @@ -1,20 +1,14 @@ package discovery import ( - "net/http" - "github.com/eolinker/goku-api-gateway/console/controller" driver2 "github.com/eolinker/goku-api-gateway/server/driver" + "net/http" ) func getDrivices(w http.ResponseWriter, r *http.Request) { ds := driver2.GetByType(driver2.Discovery) - _, err := controller.CheckLogin(w, r, controller.OperationLoadBalance, controller.OperationREAD) - if err != nil { - return - } - controller.WriteResultInfo(w, "serviceDiscovery", "data", ds) } diff --git a/console/controller/discovery/edit.go b/console/controller/discovery/edit.go index 74f17bc8..11e9bd0a 100644 --- a/console/controller/discovery/edit.go +++ b/console/controller/discovery/edit.go @@ -2,26 +2,22 @@ package discovery import ( "fmt" - "net/http" - "github.com/eolinker/goku-api-gateway/common/auto-form" "github.com/eolinker/goku-api-gateway/console/controller" "github.com/eolinker/goku-api-gateway/console/module/service" driver2 "github.com/eolinker/goku-api-gateway/server/driver" + "net/http" ) func edit(w http.ResponseWriter, r *http.Request) { - _, err := controller.CheckLogin(w, r, controller.OperationLoadBalance, controller.OperationEDIT) - if err != nil { - return - } - if err != r.ParseForm() { + + if err := r.ParseForm() ; err!= nil{ controller.WriteError(w, "260000", "serviceDiscovery", "[param_check] Parse form body error | 解析form表单参数错误", err) return } param := new(service.AddParam) - err = auto.SetValues(r.PostForm, param) + err := auto.SetValues(r.PostForm, param) if err != nil { controller.WriteError(w, "260000", "data", fmt.Sprintf("[param_check] %s", err.Error()), err) return diff --git a/console/controller/discovery/get.go b/console/controller/discovery/get.go index d55efa92..6b9237e2 100644 --- a/console/controller/discovery/get.go +++ b/console/controller/discovery/get.go @@ -2,17 +2,13 @@ package discovery import ( "fmt" - "net/http" - "github.com/eolinker/goku-api-gateway/console/controller" "github.com/eolinker/goku-api-gateway/console/module/service" + "net/http" ) func getInfo(w http.ResponseWriter, r *http.Request) { - _, err := controller.CheckLogin(w, r, controller.OperationLoadBalance, controller.OperationREAD) - if err != nil { - return - } + name := r.URL.Query().Get("name") if !service.ValidateName(name) { diff --git a/console/controller/discovery/handle.go b/console/controller/discovery/handle.go index 79703c85..e8b0ca4c 100644 --- a/console/controller/discovery/handle.go +++ b/console/controller/discovery/handle.go @@ -2,24 +2,31 @@ package discovery import ( "net/http" -) - -//Handle 服务发现处理器 -func Handle(prefix string) http.Handler { - - serveMux := http.NewServeMux() - serveMux.HandleFunc("/drivers", getDrivices) - - serveMux.HandleFunc("/add", add) - serveMux.HandleFunc("/delete", delete) - serveMux.HandleFunc("/save", edit) - serveMux.HandleFunc("/info", getInfo) - serveMux.HandleFunc("/simple", simple) - serveMux.HandleFunc("/list", list) + goku_handler "github.com/eolinker/goku-api-gateway/goku-handler" +) - serveMux.HandleFunc("/default", setDefault) +//Handlers handlers +type Handlers struct { +} - return http.StripPrefix(prefix, serveMux) +//Handlers handlers +func (h *Handlers) Handlers(factory *goku_handler.AccountHandlerFactory) map[string]http.Handler { + return map[string]http.Handler{ + "/add": factory.NewAccountHandleFunction(operationDiscovery, true, add), + "/save": factory.NewAccountHandleFunction(operationDiscovery, true, edit), + "/delete": factory.NewAccountHandleFunction(operationDiscovery, true, delete), + "/info": factory.NewAccountHandleFunction(operationDiscovery, false, getInfo), + "/list": factory.NewAccountHandleFunction(operationDiscovery, false, list), + "/default": factory.NewAccountHandleFunction(operationDiscovery, true, setDefault), + "/drivers": factory.NewAccountHandleFunction(operationDiscovery, false, getDrivices), + "/simple": factory.NewAccountHandleFunction(operationDiscovery, false, simple), + } +} +//NewHandlers new handlers +func NewHandlers() *Handlers { + return &Handlers{} } + +const operationDiscovery = "balanceManagement" diff --git a/console/controller/discovery/list.go b/console/controller/discovery/list.go index 24cc84a8..16a86167 100644 --- a/console/controller/discovery/list.go +++ b/console/controller/discovery/list.go @@ -1,17 +1,12 @@ package discovery import ( - "net/http" - "github.com/eolinker/goku-api-gateway/console/controller" "github.com/eolinker/goku-api-gateway/console/module/service" + "net/http" ) func list(w http.ResponseWriter, r *http.Request) { - _, err := controller.CheckLogin(w, r, controller.OperationLoadBalance, controller.OperationREAD) - if err != nil { - return - } _ = r.ParseForm() diff --git a/console/controller/discovery/simple.go b/console/controller/discovery/simple.go index c80a7644..d1ecd95d 100644 --- a/console/controller/discovery/simple.go +++ b/console/controller/discovery/simple.go @@ -1,17 +1,14 @@ package discovery import ( + "github.com/eolinker/goku-api-gateway/console/controller" "net/http" - "github.com/eolinker/goku-api-gateway/console/controller" "github.com/eolinker/goku-api-gateway/console/module/service" ) func simple(w http.ResponseWriter, r *http.Request) { - _, err := controller.CheckLogin(w, r, controller.OperationLoadBalance, controller.OperationREAD) - if err != nil { - return - } + vs, def, err := service.SimpleList() if err != nil { diff --git a/console/controller/gateway/gateway.go b/console/controller/gateway/gateway.go index 6a62cab5..6427eece 100644 --- a/console/controller/gateway/gateway.go +++ b/console/controller/gateway/gateway.go @@ -4,16 +4,32 @@ import ( "encoding/json" "net/http" + goku_handler "github.com/eolinker/goku-api-gateway/goku-handler" + "github.com/eolinker/goku-api-gateway/console/controller" "github.com/eolinker/goku-api-gateway/console/module/gateway" ) +const operationGateway = "gateway" + +//Handlers hendlers +type Handlers struct { +} + +//Handlers handlers +func (h *Handlers) Handlers(factory *goku_handler.AccountHandlerFactory) map[string]http.Handler { + return map[string]http.Handler{ + "/getSummaryInfo": factory.NewAccountHandleFunction(operationGateway, false, GetGatewayBasicInfo), + } +} + +//NewHandlers new handlers +func NewHandlers() *Handlers { + return &Handlers{} +} + //GetGatewayBasicInfo 获取网关基本信息 func GetGatewayBasicInfo(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNone, controller.OperationREAD) - if e != nil { - return - } flag, result, err := gateway.GetGatewayMonitorSummaryByPeriod() if !flag { diff --git a/console/controller/monitor/module.go b/console/controller/monitor/module.go index c469c198..787642cc 100644 --- a/console/controller/monitor/module.go +++ b/console/controller/monitor/module.go @@ -4,19 +4,36 @@ import ( "net/http" "strconv" + goku_handler "github.com/eolinker/goku-api-gateway/goku-handler" + "github.com/eolinker/goku-api-gateway/ksitigarbha" + "github.com/pkg/errors" "github.com/eolinker/goku-api-gateway/console/controller" "github.com/eolinker/goku-api-gateway/console/module/monitor" ) -//GetMonitorModules 获取监控模块列表 -func GetMonitorModules(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNone, controller.OperationREAD) - if e != nil { - return +const operationMonitorModule = "monitorModuleManagement" + +//Handlers handlers +type Handlers struct { +} + +//Handlers handlers +func (h *Handlers) Handlers(factory *goku_handler.AccountHandlerFactory) map[string]http.Handler { + return map[string]http.Handler{ + "/get": factory.NewAccountHandleFunction(operationMonitorModule, false, GetMonitorModules), + "/set": factory.NewAccountHandleFunction(operationMonitorModule, true, SetMonitorModule), } +} +//NewHandlers new handlers +func NewHandlers() *Handlers { + return &Handlers{} +} + +//GetMonitorModules 获取监控模块列表 +func GetMonitorModules(httpResponse http.ResponseWriter, httpRequest *http.Request) { result, err := monitor.GetMonitorModules() if err != nil { controller.WriteError(httpResponse, @@ -25,18 +42,14 @@ func GetMonitorModules(httpResponse http.ResponseWriter, httpRequest *http.Reque err.Error(), err) return - } controller.WriteResultInfo(httpResponse, "monitorModule", "moduleList", result) return } +//SetMonitorModule 设置监控模块 func SetMonitorModule(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNone, controller.OperationREAD) - if e != nil { - return - } httpRequest.ParseForm() moduleName := httpRequest.Form.Get("moduleName") moduleStatus := httpRequest.Form.Get("moduleStatus") @@ -62,7 +75,11 @@ func SetMonitorModule(httpResponse http.ResponseWriter, httpRequest *http.Reques err) return } - + if status == 1 { + ksitigarbha.Open(moduleName, config) + } else { + ksitigarbha.Close(moduleName) + } controller.WriteResultInfo(httpResponse, "monitorModule", "", nil) return } diff --git a/console/controller/node/node.go b/console/controller/node/node.go index f1979306..e584a728 100644 --- a/console/controller/node/node.go +++ b/console/controller/node/node.go @@ -3,8 +3,10 @@ package node import ( "encoding/json" "errors" - "github.com/eolinker/goku-api-gateway/common/auto-form" + goku_handler "github.com/eolinker/goku-api-gateway/goku-handler" + + "github.com/eolinker/goku-api-gateway/common/auto-form" "github.com/eolinker/goku-api-gateway/console/module/cluster" log "github.com/eolinker/goku-api-gateway/goku-log" @@ -17,13 +19,32 @@ import ( "github.com/eolinker/goku-api-gateway/utils" ) -//AddNode 新增节点信息 -func AddNode(httpResponse http.ResponseWriter, httpRequest *http.Request) { +const operationNode = "nodeManagement" - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNode, controller.OperationEDIT) - if e != nil { - return +//Handlers Handlers +type Handlers struct { +} + +//Handlers handlers +func (h *Handlers) Handlers(factory *goku_handler.AccountHandlerFactory) map[string]http.Handler { + return map[string]http.Handler{ + "/add": factory.NewAccountHandleFunction(operationNode, true, AddNode), + "/edit": factory.NewAccountHandleFunction(operationNode, true, EditNode), + "/delete": factory.NewAccountHandleFunction(operationNode, true, DeleteNode), + "/getInfo": factory.NewAccountHandleFunction(operationNode, false, GetNodeInfo), + "/getList": factory.NewAccountHandleFunction(operationNode, false, GetNodeList), + "/batchEditGroup": factory.NewAccountHandleFunction(operationNode, true, BatchEditNodeGroup), + "/batchDelete": factory.NewAccountHandleFunction(operationNode, true, BatchDeleteNode), } +} + +//NewNodeHandlers new nodeHandlers +func NewNodeHandlers() *Handlers { + return &Handlers{} +} + +//AddNode 新增节点信息 +func AddNode(httpResponse http.ResponseWriter, httpRequest *http.Request) { cluserName := httpRequest.PostFormValue("cluster") @@ -35,27 +56,16 @@ func AddNode(httpResponse http.ResponseWriter, httpRequest *http.Request) { //nodeNumber := rsa.CertConf["nodeNumber"].(int) type NodeParam struct { - NodeName string `opt:"nodeName,require"` + NodeName string `opt:"nodeName,require"` ListenAddress string `opt:"listenAddress,require"` - AdminAddress string `opt:"adminAddress,require"` - GroupID int `opt:"groupID,require"` - Path string `opt:"gatewayPath"` + AdminAddress string `opt:"adminAddress,require"` + GroupID int `opt:"groupID,require"` + Path string `opt:"gatewayPath"` } - // - //nodeName := httpRequest.PostFormValue("nodeName") - //listenAddress := httpRequest.PostFormValue("listenAddress") - //adminAddress := httpRequest.PostFormValue("adminAddress") - //groupID := httpRequest.PostFormValue("groupID") - //gatewayPath := httpRequest.PostFormValue("gatewayPath") - // - //gID, err := strconv.Atoi(groupID) - //if err != nil && groupID != "" { - // controller.WriteError(httpResponse, "230015", "", "[ERROR]Illegal groupID!", err) - // return - //} - param:=new(NodeParam) - err:=auto.SetValues(httpRequest.Form,param) - if err!= nil{ + + param := new(NodeParam) + err := auto.SetValues(httpRequest.Form, param) + if err != nil { controller.WriteError(httpResponse, "230015", "", "[ERROR]", err) return } @@ -88,37 +98,32 @@ func AddNode(httpResponse http.ResponseWriter, httpRequest *http.Request) { } } - flag, result, err := node.AddNode(clusterID, param.NodeName, param.ListenAddress, param.AdminAddress, param.Path, param.GroupID) + id, v, result, err := node.AddNode(clusterID, param.NodeName, param.ListenAddress, param.AdminAddress, param.Path, param.GroupID) - if !flag { + if err != nil { controller.WriteError(httpResponse, "330000", "node", - result["error"].(string), + result, err) return } res := map[string]interface{}{ - "nodeID": result["nodeID"], - "version": result["version"], + "nodeID": id, + "version": v, "statusCode": "000000", "type": "node", "resultDesc": "", } data, _ := json.Marshal(res) - _,_=httpResponse.Write(data) + _, _ = httpResponse.Write(data) } //EditNode 修改节点信息 func EditNode(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNode, controller.OperationEDIT) - if e != nil { - return - } - nodeName := httpRequest.PostFormValue("nodeName") listenAddress := httpRequest.PostFormValue("listenAddress") adminAddress := httpRequest.PostFormValue("adminAddress") @@ -170,17 +175,9 @@ func EditNode(httpResponse http.ResponseWriter, httpRequest *http.Request) { } } - //exits := node.CheckIsExistRemoteAddr(id, listenAddress, adminAddress) - //if exits { - // - // controller.WriteError(httpResponse, "230005", "node", "[ERROR]The remote address is existed!", nil) - // return - // - //} + result, err := node.EditNode(nodeName, listenAddress, adminAddress, gatewayPath, id, gID) - flag, result, _ := node.EditNode(nodeName, listenAddress, adminAddress, gatewayPath, id, gID) - - if !flag { + if err != nil { controller.WriteError(httpResponse, "330000", "node", result, nil) return } @@ -192,12 +189,6 @@ func EditNode(httpResponse http.ResponseWriter, httpRequest *http.Request) { //DeleteNode 删除节点信息 func DeleteNode(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNode, controller.OperationEDIT) - if e != nil { - - return - } - nodeID := httpRequest.PostFormValue("nodeID") id, err := strconv.Atoi(nodeID) @@ -210,8 +201,8 @@ func DeleteNode(httpResponse http.ResponseWriter, httpRequest *http.Request) { return } - flag, result, err := node.DeleteNode(id) - if !flag { + result, err := node.DeleteNode(id) + if err != nil { controller.WriteError(httpResponse, "330000", @@ -227,12 +218,8 @@ func DeleteNode(httpResponse http.ResponseWriter, httpRequest *http.Request) { // GetNodeList 获取节点列表 func GetNodeList(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNode, controller.OperationREAD) - if e != nil { - return - } httpRequest.ParseForm() - cluserName := httpRequest.Form.Get("cluster") + clusterName := httpRequest.Form.Get("cluster") groupID := httpRequest.Form.Get("groupID") keyword := httpRequest.Form.Get("keyword") @@ -245,21 +232,20 @@ func GetNodeList(httpResponse http.ResponseWriter, httpRequest *http.Request) { gID = -1 } - clusterID := cluster.GetClusterIDByName(cluserName) + clusterID := cluster.GetClusterIDByName(clusterName) if clusterID == 0 { controller.WriteError(httpResponse, "330003", "node", "[ERROR]The cluster dosen't exist!", nil) return } - flag, result, err := node.GetNodeList(clusterID, gID, keyword) - if !flag { + result, err := node.GetNodeList(clusterID, gID, keyword) + if err != nil { controller.WriteError(httpResponse, "330000", "node", "[ERROR]Empty node list!", err) return - } controller.WriteResultInfo(httpResponse, "node", "nodeList", result) // controller.WriteResultInfo(httpResponse, "nodeList", result) @@ -268,10 +254,6 @@ func GetNodeList(httpResponse http.ResponseWriter, httpRequest *http.Request) { //GetNodeInfo 获取节点信息 func GetNodeInfo(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNode, controller.OperationREAD) - if e != nil { - return - } nodeID := httpRequest.PostFormValue("nodeID") @@ -286,8 +268,8 @@ func GetNodeInfo(httpResponse http.ResponseWriter, httpRequest *http.Request) { err) return } - result, err := node.GetNodeInfo(id) - if err!= nil { + result, err := node.GetNodeInfo(id) + if err != nil { controller.WriteError(httpResponse, "330000", @@ -302,16 +284,8 @@ func GetNodeInfo(httpResponse http.ResponseWriter, httpRequest *http.Request) { return } - - //BatchEditNodeGroup 批量修改节点分组 func BatchEditNodeGroup(httpResponse http.ResponseWriter, httpRequest *http.Request) { - - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNode, controller.OperationEDIT) - if e != nil { - return - } - nodeIDList := httpRequest.PostFormValue("nodeIDList") groupID := httpRequest.PostFormValue("groupID") @@ -325,8 +299,8 @@ func BatchEditNodeGroup(httpResponse http.ResponseWriter, httpRequest *http.Requ return } - flag, result, err := node.BatchEditNodeGroup(nodeIDList, gID) - if !flag { + result, err := node.BatchEditNodeGroup(nodeIDList, gID) + if err != nil { controller.WriteError(httpResponse, "330000", @@ -345,16 +319,10 @@ func BatchEditNodeGroup(httpResponse http.ResponseWriter, httpRequest *http.Requ //BatchDeleteNode 批量删除节点 func BatchDeleteNode(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNode, controller.OperationEDIT) - if e != nil { - - return - } - nodeIDList := httpRequest.PostFormValue("nodeIDList") - flag, result, err := node.BatchDeleteNode(nodeIDList) - if !flag { + result, err := node.BatchDeleteNode(nodeIDList) + if err != nil { if result == "230013" { controller.WriteError(httpResponse, diff --git a/console/controller/node/nodeGroup.go b/console/controller/node/nodeGroup.go index 922f55d5..68a629bd 100644 --- a/console/controller/node/nodeGroup.go +++ b/console/controller/node/nodeGroup.go @@ -4,18 +4,35 @@ import ( "net/http" "strconv" + goku_handler "github.com/eolinker/goku-api-gateway/goku-handler" + "github.com/eolinker/goku-api-gateway/console/controller" "github.com/eolinker/goku-api-gateway/console/module/cluster" "github.com/eolinker/goku-api-gateway/console/module/node" ) -//AddNodeGroup 新增节点分组 -func AddNodeGroup(httpResponse http.ResponseWriter, httpRequest *http.Request) { +//GroupHandlers groupHandlers +type GroupHandlers struct { +} - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNode, controller.OperationEDIT) - if e != nil { - return +//Handlers handlers +func (h *GroupHandlers) Handlers(factory *goku_handler.AccountHandlerFactory) map[string]http.Handler { + return map[string]http.Handler{ + "/add": factory.NewAccountHandleFunction(operationNode, true, AddNodeGroup), + "/edit": factory.NewAccountHandleFunction(operationNode, true, EditNodeGroup), + "/delete": factory.NewAccountHandleFunction(operationNode, true, DeleteNodeGroup), + "/getInfo": factory.NewAccountHandleFunction(operationNode, false, GetNodeGroupInfo), + "/getList": factory.NewAccountHandleFunction(operationNode, false, GetNodeGroupList), } +} + +//NewGroupHandlers new groupHandlers +func NewGroupHandlers() *GroupHandlers { + return &GroupHandlers{} +} + +//AddNodeGroup 新增节点分组 +func AddNodeGroup(httpResponse http.ResponseWriter, httpRequest *http.Request) { cluserName := httpRequest.PostFormValue("cluster") @@ -53,11 +70,6 @@ func AddNodeGroup(httpResponse http.ResponseWriter, httpRequest *http.Request) { //EditNodeGroup 修改节点分组信息 func EditNodeGroup(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNode, controller.OperationEDIT) - if e != nil { - return - } - groupName := httpRequest.PostFormValue("groupName") groupID := httpRequest.PostFormValue("groupID") if groupName == "" { @@ -97,10 +109,6 @@ func EditNodeGroup(httpResponse http.ResponseWriter, httpRequest *http.Request) //DeleteNodeGroup 删除节点分组 func DeleteNodeGroup(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNode, controller.OperationEDIT) - if e != nil { - return - } groupID := httpRequest.PostFormValue("groupID") @@ -149,10 +157,6 @@ func DeleteNodeGroup(httpResponse http.ResponseWriter, httpRequest *http.Request //GetNodeGroupInfo 获取节点分组信息 func GetNodeGroupInfo(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNode, controller.OperationREAD) - if e != nil { - return - } groupID := httpRequest.PostFormValue("groupID") @@ -182,10 +186,6 @@ func GetNodeGroupInfo(httpResponse http.ResponseWriter, httpRequest *http.Reques //GetNodeGroupList 获取节点分组列表 func GetNodeGroupList(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNode, controller.OperationREAD) - if e != nil { - return - } cluserName := httpRequest.FormValue("cluster") clusterID := cluster.GetClusterIDByName(cluserName) diff --git a/console/controller/plugin/plugin.go b/console/controller/plugin/plugin.go index 590ae90e..7075059b 100644 --- a/console/controller/plugin/plugin.go +++ b/console/controller/plugin/plugin.go @@ -4,17 +4,47 @@ import ( "net/http" "strconv" + goku_handler "github.com/eolinker/goku-api-gateway/goku-handler" + "github.com/eolinker/goku-api-gateway/console/controller" "github.com/eolinker/goku-api-gateway/console/module/plugin" plugin_config "github.com/eolinker/goku-api-gateway/console/module/plugin/plugin-config" ) +const operationPlugin = "pluginManagement" + +//Handlers handlers +type Handlers struct { +} + +//Handlers handlers +func (h *Handlers) Handlers(factory *goku_handler.AccountHandlerFactory) map[string]http.Handler { + return map[string]http.Handler{ + "/add": factory.NewAccountHandleFunction(operationPlugin, true, AddPlugin), + "/edit": factory.NewAccountHandleFunction(operationPlugin, true, EditPlugin), + "/delete": factory.NewAccountHandleFunction(operationPlugin, true, DeletePlugin), + "/checkNameIsExist": factory.NewAccountHandleFunction(operationPlugin, false, CheckNameIsExist), + "/checkIndexIsExist": factory.NewAccountHandleFunction(operationPlugin, false, CheckIndexIsExist), + "/getList": factory.NewAccountHandleFunction(operationPlugin, false, GetPluginList), + "/getInfo": factory.NewAccountHandleFunction(operationPlugin, false, GetPluginInfo), + "/getConfig": factory.NewAccountHandleFunction(operationPlugin, false, GetPluginConfig), + "/start": factory.NewAccountHandleFunction(operationPlugin, true, StartPlugin), + "/stop": factory.NewAccountHandleFunction(operationPlugin, true, StopPlugin), + "/getListByType": factory.NewAccountHandleFunction(operationPlugin, false, GetPluginListByPluginType), + "/batchStop": factory.NewAccountHandleFunction(operationPlugin, true, BatchStopPlugin), + "/batchStart": factory.NewAccountHandleFunction(operationPlugin, true, BatchStartPlugin), + "/availiable/check": factory.NewAccountHandleFunction(operationPlugin, false, CheckPluginIsAvailable), + } +} + +//NewHandlers new handlers +func NewHandlers() *Handlers { + return &Handlers{} +} + // GetPluginList 获取插件列表 func GetPluginList(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationPlugin, controller.OperationREAD) - if e != nil { - return - } + httpRequest.ParseForm() keyword := httpRequest.Form.Get("keyword") condition := httpRequest.Form.Get("condition") @@ -40,10 +70,6 @@ func GetPluginList(httpResponse http.ResponseWriter, httpRequest *http.Request) //AddPlugin 新增插件信息 func AddPlugin(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationPlugin, controller.OperationEDIT) - if e != nil { - return - } pluginPriority := httpRequest.PostFormValue("pluginPriority") pluginName := httpRequest.PostFormValue("pluginName") @@ -106,10 +132,6 @@ func AddPlugin(httpResponse http.ResponseWriter, httpRequest *http.Request) { //EditPlugin 修改插件信息 func EditPlugin(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationPlugin, controller.OperationEDIT) - if e != nil { - return - } pluginPriority := httpRequest.PostFormValue("pluginPriority") pluginName := httpRequest.PostFormValue("pluginName") @@ -162,10 +184,6 @@ func EditPlugin(httpResponse http.ResponseWriter, httpRequest *http.Request) { //DeletePlugin 删除插件信息 func DeletePlugin(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationPlugin, controller.OperationEDIT) - if e != nil { - return - } pluginName := httpRequest.PostFormValue("pluginName") flag, err := plugin.CheckNameIsExist(pluginName) @@ -195,10 +213,6 @@ func DeletePlugin(httpResponse http.ResponseWriter, httpRequest *http.Request) { //GetPluginInfo 获取插件信息 func GetPluginInfo(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationPlugin, controller.OperationREAD) - if e != nil { - return - } pluginName := httpRequest.PostFormValue("pluginName") @@ -228,10 +242,6 @@ func GetPluginInfo(httpResponse http.ResponseWriter, httpRequest *http.Request) //GetPluginConfig 获取插件配置 func GetPluginConfig(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationPlugin, controller.OperationREAD) - if e != nil { - return - } pluginName := httpRequest.PostFormValue("pluginName") flag, result, err := plugin.GetPluginConfig(pluginName) @@ -252,10 +262,6 @@ func GetPluginConfig(httpResponse http.ResponseWriter, httpRequest *http.Request //CheckIndexIsExist 判断插件优先级是否存在 func CheckIndexIsExist(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationPlugin, controller.OperationEDIT) - if e != nil { - return - } pluginPriority := httpRequest.PostFormValue("pluginPriority") @@ -286,10 +292,6 @@ func CheckIndexIsExist(httpResponse http.ResponseWriter, httpRequest *http.Reque //CheckNameIsExist 检查插件名称是否存在 func CheckNameIsExist(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationPlugin, controller.OperationEDIT) - if e != nil { - return - } pluginName := httpRequest.PostFormValue("pluginName") @@ -309,10 +311,6 @@ func CheckNameIsExist(httpResponse http.ResponseWriter, httpRequest *http.Reques //StartPlugin 开启插件 func StartPlugin(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationPlugin, controller.OperationEDIT) - if e != nil { - return - } pluginName := httpRequest.PostFormValue("pluginName") @@ -332,10 +330,6 @@ func StartPlugin(httpResponse http.ResponseWriter, httpRequest *http.Request) { //StopPlugin 关闭插件 func StopPlugin(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationPlugin, controller.OperationEDIT) - if e != nil { - return - } pluginName := httpRequest.PostFormValue("pluginName") @@ -354,10 +348,6 @@ func StopPlugin(httpResponse http.ResponseWriter, httpRequest *http.Request) { //GetPluginListByPluginType 获取不同类型的插件列表 func GetPluginListByPluginType(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationPlugin, controller.OperationREAD) - if e != nil { - return - } pluginType := httpRequest.PostFormValue("pluginType") @@ -387,10 +377,6 @@ func GetPluginListByPluginType(httpResponse http.ResponseWriter, httpRequest *ht //BatchStopPlugin 批量关闭插件 func BatchStopPlugin(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationPlugin, controller.OperationEDIT) - if e != nil { - return - } pluginNameList := httpRequest.PostFormValue("pluginNameList") @@ -411,10 +397,6 @@ func BatchStopPlugin(httpResponse http.ResponseWriter, httpRequest *http.Request //BatchStartPlugin 批量关闭插件 func BatchStartPlugin(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationPlugin, controller.OperationEDIT) - if e != nil { - return - } pluginNameList := httpRequest.PostFormValue("pluginNameList") @@ -435,10 +417,6 @@ func BatchStartPlugin(httpResponse http.ResponseWriter, httpRequest *http.Reques //CheckPluginIsAvailable 检测插件 func CheckPluginIsAvailable(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationPlugin, controller.OperationEDIT) - if e != nil { - return - } pluginName := httpRequest.PostFormValue("pluginName") if len(pluginName) < 2 { @@ -449,37 +427,5 @@ func CheckPluginIsAvailable(httpResponse http.ResponseWriter, httpRequest *http. nil) return } - //flag, nodeList, err := node.GetNodeIPList() - //if !flag { - // controller.WriteError(httpResponse, - // "210000", - // "plugin", - // "[ERROR]The Open node list is empty", - // err) - // return - //} - //flag, errPluginList := utils.CheckPluginIsAvailiable(pluginName, nodeList) - //if !flag { - // - // controller.WriteResultInfoWithCode(httpResponse, - // "210000", - // "plugin", - // "errNodeList", - // errPluginList) - // return - //} - //flag, res, _ := plugin.EditPluginCheckStatus(pluginName, 1) - //if !flag { - // - // controller.WriteError(httpResponse, - // "210000", - // "plugin", - // res, - // err) - // return - //} - // - //controller.WriteResultInfo(httpResponse, "plugin", "", nil) - return } diff --git a/console/controller/project/project.go b/console/controller/project/project.go index 675f599d..5ea70380 100644 --- a/console/controller/project/project.go +++ b/console/controller/project/project.go @@ -4,16 +4,38 @@ import ( "net/http" "strconv" + goku_handler "github.com/eolinker/goku-api-gateway/goku-handler" + "github.com/eolinker/goku-api-gateway/console/controller" "github.com/eolinker/goku-api-gateway/console/module/project" ) +const operationProject = "apiManagement" + +//Handlers handlers +type Handlers struct { +} + +//Handlers handlers +func (h *Handlers) Handlers(factory *goku_handler.AccountHandlerFactory) map[string]http.Handler { + return map[string]http.Handler{ + "/add": factory.NewAccountHandleFunction(operationProject, true, AddProject), + "/edit": factory.NewAccountHandleFunction(operationProject, true, EditProject), + "/delete": factory.NewAccountHandleFunction(operationProject, true, DeleteProject), + "/getInfo": factory.NewAccountHandleFunction(operationProject, false, GetProjectInfo), + "/getList": factory.NewAccountHandleFunction(operationProject, false, GetProjectList), + "/strategy/getList": factory.NewAccountHandleFunction(operationProject, false, GetAPIListFromProjectNotInStrategy), + "/batchDelete": factory.NewAccountHandleFunction(operationProject, true, BatchDeleteProject), + } +} + +//NewHandlers new handlers +func NewHandlers() *Handlers { + return &Handlers{} +} + //AddProject 新建项目 func AddProject(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationEDIT) - if e != nil { - return - } projectName := httpRequest.PostFormValue("projectName") if projectName == "" { @@ -43,10 +65,6 @@ func AddProject(httpResponse http.ResponseWriter, httpRequest *http.Request) { //EditProject 修改项目信息 func EditProject(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationEDIT) - if e != nil { - return - } projectName := httpRequest.PostFormValue("projectName") projectID := httpRequest.PostFormValue("projectID") @@ -87,10 +105,6 @@ func EditProject(httpResponse http.ResponseWriter, httpRequest *http.Request) { //DeleteProject 删除项目信息 func DeleteProject(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationEDIT) - if e != nil { - return - } projectID := httpRequest.PostFormValue("projectID") @@ -122,10 +136,6 @@ func DeleteProject(httpResponse http.ResponseWriter, httpRequest *http.Request) //BatchDeleteProject 删除项目信息 func BatchDeleteProject(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationEDIT) - if e != nil { - return - } projectIDList := httpRequest.PostFormValue("projectIDList") @@ -147,10 +157,6 @@ func BatchDeleteProject(httpResponse http.ResponseWriter, httpRequest *http.Requ //GetProjectInfo 获取项目信息 func GetProjectInfo(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationREAD) - if e != nil { - return - } projectID := httpRequest.PostFormValue("projectID") @@ -181,10 +187,7 @@ func GetProjectInfo(httpResponse http.ResponseWriter, httpRequest *http.Request) //GetProjectList 获取项目列表 func GetProjectList(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationREAD) - if e != nil { - return - } + httpRequest.ParseForm() keyword := httpRequest.FormValue("keyword") @@ -207,10 +210,6 @@ func GetProjectList(httpResponse http.ResponseWriter, httpRequest *http.Request) //GetAPIListFromProjectNotInStrategy 获取项目列表中没有被策略组绑定的接口 func GetAPIListFromProjectNotInStrategy(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationREAD) - if e != nil { - return - } flag, result, err := project.GetAPIListFromProjectNotInStrategy() if !flag { diff --git a/console/controller/reg.go b/console/controller/reg.go new file mode 100644 index 00000000..8ca42e8b --- /dev/null +++ b/console/controller/reg.go @@ -0,0 +1,4 @@ +// 控制台模块注册文件 +package controller + + diff --git a/console/controller/strategy/apiStrategy.go b/console/controller/strategy/apiStrategy.go index 424e1c29..e8c19b88 100644 --- a/console/controller/strategy/apiStrategy.go +++ b/console/controller/strategy/apiStrategy.go @@ -6,17 +6,41 @@ import ( "strconv" "strings" + goku_handler "github.com/eolinker/goku-api-gateway/goku-handler" + "github.com/eolinker/goku-api-gateway/console/controller" "github.com/eolinker/goku-api-gateway/console/module/api" "github.com/eolinker/goku-api-gateway/console/module/strategy" ) +const operationAPIStrategy = "strategyManagement" + +//APIStrategyHandlers 接口策略handlers +type APIStrategyHandlers struct { +} + +//Handlers handlers +func (h *APIStrategyHandlers) Handlers(factory *goku_handler.AccountHandlerFactory) map[string]http.Handler { + return map[string]http.Handler{ + "/add": factory.NewAccountHandleFunction(operationAPIStrategy, true, AddAPIToStrategy), + "/target": factory.NewAccountHandleFunction(operationAPIStrategy, true, ResetAPITargetOfStrategy), + "/batchEditTarget": factory.NewAccountHandleFunction(operationAPIStrategy, true, BatchResetAPITargetOfStrategy), + "/getList": factory.NewAccountHandleFunction(operationAPIStrategy, false, GetAPIListFromStrategy), + "/id/getList": factory.NewAccountHandleFunction(operationAPIStrategy, false, GetAPIIDListFromStrategy), + "/getNotInList": factory.NewAccountHandleFunction(operationAPIStrategy, false, GetAPIListNotInStrategy), + "/id/getNotInList": factory.NewAccountHandleFunction(operationAPIStrategy, false, GetAPIIDListNotInStrategyByProject), + "/batchDelete": factory.NewAccountHandleFunction(operationAPIStrategy, true, BatchDeleteAPIInStrategy), + "/plugin/getList": factory.NewAccountHandleFunction(operationAPIStrategy, false, GetAPIPluginInStrategyByAPIID), + } +} + +//NewAPIStrategyHandlers new接口策略处理器 +func NewAPIStrategyHandlers() *APIStrategyHandlers { + return &APIStrategyHandlers{} +} + //AddAPIToStrategy 将接口加入策略组 func AddAPIToStrategy(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationEDIT) - if e != nil { - return - } strategyID := httpRequest.PostFormValue("strategyID") apiID := httpRequest.PostFormValue("apiID") @@ -49,11 +73,6 @@ func AddAPIToStrategy(httpResponse http.ResponseWriter, httpRequest *http.Reques // ResetAPITargetOfStrategy 将接口加入策略组 func ResetAPITargetOfStrategy(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationEDIT) - if e != nil { - return - } - strategyID := httpRequest.PostFormValue("strategyID") target := httpRequest.PostFormValue("target") apiID := httpRequest.PostFormValue("apiID") @@ -93,10 +112,6 @@ func ResetAPITargetOfStrategy(httpResponse http.ResponseWriter, httpRequest *htt // BatchResetAPITargetOfStrategy 将接口加入策略组 func BatchResetAPITargetOfStrategy(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationEDIT) - if e != nil { - return - } strategyID := httpRequest.PostFormValue("strategyID") target := httpRequest.PostFormValue("target") @@ -137,10 +152,6 @@ func BatchResetAPITargetOfStrategy(httpResponse http.ResponseWriter, httpRequest // GetAPIIDListFromStrategy 获取策略组接口ID列表 func GetAPIIDListFromStrategy(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationREAD) - if e != nil { - return - } httpRequest.ParseForm() strategyID := httpRequest.Form.Get("strategyID") @@ -194,10 +205,6 @@ func GetAPIIDListFromStrategy(httpResponse http.ResponseWriter, httpRequest *htt // GetAPIListFromStrategy 获取策略组接口列表 func GetAPIListFromStrategy(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationREAD) - if e != nil { - return - } httpRequest.ParseForm() strategyID := httpRequest.Form.Get("strategyID") @@ -266,10 +273,6 @@ func GetAPIListFromStrategy(httpResponse http.ResponseWriter, httpRequest *http. //CheckIsExistAPIInStrategy 检查插件是否添加进策略组 func CheckIsExistAPIInStrategy(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationEDIT) - if e != nil { - return - } strategyID := httpRequest.PostFormValue("strategyID") apiID := httpRequest.PostFormValue("apiID") @@ -301,10 +304,7 @@ func CheckIsExistAPIInStrategy(httpResponse http.ResponseWriter, httpRequest *ht // GetAPIIDListNotInStrategyByProject 获取未被该策略组绑定的接口ID列表(通过项目) func GetAPIIDListNotInStrategyByProject(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationREAD) - if e != nil { - return - } + httpRequest.ParseForm() strategyID := httpRequest.Form.Get("strategyID") projectID := httpRequest.Form.Get("projectID") @@ -342,10 +342,7 @@ func GetAPIIDListNotInStrategyByProject(httpResponse http.ResponseWriter, httpRe //GetAPIListNotInStrategy 获取未被该策略组绑定的接口列表 func GetAPIListNotInStrategy(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationREAD) - if e != nil { - return - } + httpRequest.ParseForm() strategyID := httpRequest.Form.Get("strategyID") projectID := httpRequest.Form.Get("projectID") @@ -397,10 +394,6 @@ func GetAPIListNotInStrategy(httpResponse http.ResponseWriter, httpRequest *http //BatchDeleteAPIInStrategy 批量删除策略组接口 func BatchDeleteAPIInStrategy(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationEDIT) - if e != nil { - return - } apiIDList := httpRequest.PostFormValue("apiIDList") strategyID := httpRequest.PostFormValue("strategyID") @@ -418,3 +411,48 @@ func BatchDeleteAPIInStrategy(httpResponse http.ResponseWriter, httpRequest *htt } controller.WriteResultInfo(httpResponse, "apiStrategy", "", nil) } + +// GetAPIPluginInStrategyByAPIID 获取策略组中所有接口插件列表 +func GetAPIPluginInStrategyByAPIID(httpResponse http.ResponseWriter, httpRequest *http.Request) { + + httpRequest.ParseForm() + strategyID := httpRequest.Form.Get("strategyID") + apiID := httpRequest.Form.Get("apiID") + keyword := httpRequest.Form.Get("keyword") + condition := httpRequest.Form.Get("condition") + + aID, err := strconv.Atoi(apiID) + if err != nil { + controller.WriteError(httpResponse, "240002", "apiPlugin", "[ERROR]Illegal condition!", err) + return + } + op, err := strconv.Atoi(condition) + if err != nil && condition != "" { + controller.WriteError(httpResponse, "270006", "apiPlugin", "[ERROR]Illegal condition!", err) + return + } + + flag, pluginList, apiInfo, err := api.GetAPIPluginInStrategyByAPIID(strategyID, aID, keyword, op) + if !flag { + controller.WriteError(httpResponse, + "240000", + "apiPlugin", + "[ERROR]Empty api plugin list!", + err) + return + + } + result := map[string]interface{}{ + "statusCode": "000000", + "type": "apiPlugin", + "resultDesc": "", + "apiPluginList": pluginList, + "apiInfo": apiInfo, + "page": controller.PageInfo{ + ItemNum: len(pluginList), + }, + } + resultStr, _ := json.Marshal(result) + httpResponse.Write(resultStr) + // controller.WriteResultInfo(httpResponse, "apiPlugin", "apiPluginList", result) +} diff --git a/console/controller/strategy/strategy.go b/console/controller/strategy/strategy.go index dece7770..cc698afd 100644 --- a/console/controller/strategy/strategy.go +++ b/console/controller/strategy/strategy.go @@ -4,20 +4,47 @@ import ( "net/http" "strconv" + goku_handler "github.com/eolinker/goku-api-gateway/goku-handler" + "github.com/eolinker/goku-api-gateway/console/controller" "github.com/eolinker/goku-api-gateway/console/module/strategy" entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" ) +const operationStrategy = "strategyManagement" + +//Handlers 策略处理器 +type Handlers struct { +} + +//Handlers handlers +func (h *Handlers) Handlers(factory *goku_handler.AccountHandlerFactory) map[string]http.Handler { + return map[string]http.Handler{ + "/add": factory.NewAccountHandleFunction(operationStrategy, true, AddStrategy), + "/edit": factory.NewAccountHandleFunction(operationStrategy, true, EditStrategy), + "/copy": factory.NewAccountHandleFunction(operationStrategy, true, CopyStrategy), + "/delete": factory.NewAccountHandleFunction(operationStrategy, true, DeleteStrategy), + "/getInfo": factory.NewAccountHandleFunction(operationStrategy, false, GetStrategyInfo), + "/getList": factory.NewAccountHandleFunction(operationStrategy, false, GetStrategyList), + "/batchEditGroup": factory.NewAccountHandleFunction(operationStrategy, true, BatchEditStrategyGroup), + "/batchDelete": factory.NewAccountHandleFunction(operationStrategy, true, BatchDeleteStrategy), + "/batchStart": factory.NewAccountHandleFunction(operationStrategy, true, BatchStartStrategy), + "/batchStop": factory.NewAccountHandleFunction(operationStrategy, true, BatchStopStrategy), + "/id/getList": factory.NewAccountHandleFunction(operationStrategy, false, GetStrategyIDList), + } +} + +//NewStrategyHandlers new策略处理器 +func NewStrategyHandlers() *Handlers { + return &Handlers{} +} + //AddStrategy 新增策略组 func AddStrategy(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationEDIT) - if e != nil { - return - } strategyName := httpRequest.PostFormValue("strategyName") groupID := httpRequest.PostFormValue("groupID") + userID := goku_handler.UserIDFromRequest(httpRequest) if strategyName == "" { controller.WriteError(httpResponse, "220006", @@ -37,7 +64,7 @@ func AddStrategy(httpResponse http.ResponseWriter, httpRequest *http.Request) { return } - flag, result, err := strategy.AddStrategy(strategyName, gID) + flag, result, err := strategy.AddStrategy(strategyName, gID, userID) if !flag { controller.WriteError(httpResponse, @@ -54,14 +81,11 @@ func AddStrategy(httpResponse http.ResponseWriter, httpRequest *http.Request) { //EditStrategy 修改策略组信息 func EditStrategy(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationEDIT) - if e != nil { - return - } strategyName := httpRequest.PostFormValue("strategyName") strategyID := httpRequest.PostFormValue("strategyID") groupID := httpRequest.PostFormValue("groupID") + userID := goku_handler.UserIDFromRequest(httpRequest) if strategyName == "" { controller.WriteError(httpResponse, "220006", @@ -80,7 +104,7 @@ func EditStrategy(httpResponse http.ResponseWriter, httpRequest *http.Request) { return } - flag, result, err := strategy.EditStrategy(strategyID, strategyName, gID) + flag, result, err := strategy.EditStrategy(strategyID, strategyName, gID, userID) if !flag { controller.WriteError(httpResponse, "220000", @@ -95,10 +119,6 @@ func EditStrategy(httpResponse http.ResponseWriter, httpRequest *http.Request) { //DeleteStrategy 删除策略组 func DeleteStrategy(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationEDIT) - if e != nil { - return - } strategyID := httpRequest.PostFormValue("strategyID") @@ -116,10 +136,6 @@ func DeleteStrategy(httpResponse http.ResponseWriter, httpRequest *http.Request) // GetOpenStrategy 获取策略组列表 func GetOpenStrategy(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationREAD) - if e != nil { - return - } var flag bool var err error @@ -139,14 +155,22 @@ func GetOpenStrategy(httpResponse http.ResponseWriter, httpRequest *http.Request //GetStrategyList 获取策略组列表 func GetStrategyList(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationREAD) - if e != nil { - return - } + httpRequest.ParseForm() groupID := httpRequest.Form.Get("groupID") keyword := httpRequest.Form.Get("keyword") condition := httpRequest.Form.Get("condition") + page := httpRequest.Form.Get("page") + pageSize := httpRequest.Form.Get("pageSize") + + p, e := strconv.Atoi(page) + if e != nil { + p = 1 + } + pSize, e := strconv.Atoi(pageSize) + if e != nil { + pSize = 15 + } gID, err := strconv.Atoi(groupID) if err != nil { @@ -176,7 +200,7 @@ func GetStrategyList(httpResponse http.ResponseWriter, httpRequest *http.Request var flag bool err = nil result := make([]*entity.Strategy, 0) - flag, result, err = strategy.GetStrategyList(gID, keyword, op) + flag, result, count, err := strategy.GetStrategyList(gID, keyword, op, p, pSize) if !flag { controller.WriteError(httpResponse, "220000", @@ -185,15 +209,18 @@ func GetStrategyList(httpResponse http.ResponseWriter, httpRequest *http.Request err) return } - controller.WriteResultInfo(httpResponse, "strategy", "strategyList", result) + controller.WriteResultInfoWithPage(httpResponse, "strategy", "strategyList", result, &controller.PageInfo{ + ItemNum: len(result), + TotalNum: count, + Page: p, + PageSize: pSize, + }) + return } //GetStrategyIDList 获取策略组列表 func GetStrategyIDList(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationREAD) - if e != nil { - return - } + httpRequest.ParseForm() groupID := httpRequest.Form.Get("groupID") keyword := httpRequest.Form.Get("keyword") @@ -238,10 +265,7 @@ func GetStrategyIDList(httpResponse http.ResponseWriter, httpRequest *http.Reque // GetStrategyInfo 获取策略组信息 func GetStrategyInfo(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationREAD) - if e != nil { - return - } + httpRequest.ParseForm() strategyID := httpRequest.Form.Get("strategyID") @@ -280,10 +304,6 @@ func GetStrategyInfo(httpResponse http.ResponseWriter, httpRequest *http.Request //BatchEditStrategyGroup 批量修改策略组分组 func BatchEditStrategyGroup(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationEDIT) - if e != nil { - return - } strategyIDList := httpRequest.PostFormValue("strategyIDList") groupID := httpRequest.PostFormValue("groupID") @@ -322,10 +342,6 @@ func BatchEditStrategyGroup(httpResponse http.ResponseWriter, httpRequest *http. //BatchDeleteStrategy 批量修改策略组 func BatchDeleteStrategy(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationEDIT) - if e != nil { - return - } strategyIDList := httpRequest.PostFormValue("strategyIDList") if strategyIDList == "" { @@ -351,10 +367,6 @@ func BatchDeleteStrategy(httpResponse http.ResponseWriter, httpRequest *http.Req //BatchStartStrategy 批量开启策略 func BatchStartStrategy(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationEDIT) - if e != nil { - return - } strategyIDList := httpRequest.PostFormValue("strategyIDList") if strategyIDList == "" { @@ -380,10 +392,6 @@ func BatchStartStrategy(httpResponse http.ResponseWriter, httpRequest *http.Requ //BatchStopStrategy 批量关闭策略 func BatchStopStrategy(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationEDIT) - if e != nil { - return - } strategyIDList := httpRequest.PostFormValue("strategyIDList") if strategyIDList == "" { @@ -410,10 +418,7 @@ func BatchStopStrategy(httpResponse http.ResponseWriter, httpRequest *http.Reque // GetBalanceListInStrategy 获取在策略中的负载列表 func GetBalanceListInStrategy(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationEDIT) - if e != nil { - return - } + httpRequest.ParseForm() strategyID := httpRequest.Form.Get("strategyID") balanceType := httpRequest.Form.Get("balanceType") @@ -435,14 +440,11 @@ func GetBalanceListInStrategy(httpResponse http.ResponseWriter, httpRequest *htt // CopyStrategy 复制策略 func CopyStrategy(httpResponse http.ResponseWriter, httpRequest *http.Request) { - userID, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationEDIT) - if e != nil { - return - } strategyName := httpRequest.PostFormValue("strategyName") strategyID := httpRequest.PostFormValue("strategyID") groupID := httpRequest.PostFormValue("groupID") + userID := goku_handler.UserIDFromRequest(httpRequest) if strategyID == "" { controller.WriteError(httpResponse, "220003", @@ -469,7 +471,7 @@ func CopyStrategy(httpResponse http.ResponseWriter, httpRequest *http.Request) { return } - flag, result, err := strategy.AddStrategy(strategyName, gID) + flag, result, err := strategy.AddStrategy(strategyName, gID, userID) if !flag { controller.WriteError(httpResponse, "220000", diff --git a/console/controller/strategy/strategyGroup.go b/console/controller/strategy/strategyGroup.go index c2a8869d..1f8b6b22 100644 --- a/console/controller/strategy/strategyGroup.go +++ b/console/controller/strategy/strategyGroup.go @@ -4,16 +4,35 @@ import ( "net/http" "strconv" + goku_handler "github.com/eolinker/goku-api-gateway/goku-handler" + "github.com/eolinker/goku-api-gateway/console/controller" "github.com/eolinker/goku-api-gateway/console/module/strategy" ) +const operationStrategyGroup = "strategyManagement" + +//GroupHandlers 策略分组处理器 +type GroupHandlers struct { +} + +//Handlers handlers +func (h *GroupHandlers) Handlers(factory *goku_handler.AccountHandlerFactory) map[string]http.Handler { + return map[string]http.Handler{ + "/add": factory.NewAccountHandleFunction(operationStrategyGroup, true, AddStrategyGroup), + "/edit": factory.NewAccountHandleFunction(operationStrategyGroup, true, EditStrategyGroup), + "/delete": factory.NewAccountHandleFunction(operationStrategyGroup, true, DeleteStrategyGroup), + "/getList": factory.NewAccountHandleFunction(operationStrategyGroup, false, GetStrategyGroupList), + } +} + +//NewGroupHandlers new groupHandlers +func NewGroupHandlers() *GroupHandlers { + return &GroupHandlers{} +} + // AddStrategyGroup 新建接口分组 func AddStrategyGroup(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationREAD) - if e != nil { - return - } groupName := httpRequest.PostFormValue("groupName") if groupName == "" { @@ -39,10 +58,6 @@ func AddStrategyGroup(httpResponse http.ResponseWriter, httpRequest *http.Reques // EditStrategyGroup 修改接口分组 func EditStrategyGroup(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationREAD) - if e != nil { - return - } groupName := httpRequest.PostFormValue("groupName") groupID := httpRequest.PostFormValue("groupID") @@ -81,10 +96,6 @@ func EditStrategyGroup(httpResponse http.ResponseWriter, httpRequest *http.Reque // DeleteStrategyGroup 删除接口分组 func DeleteStrategyGroup(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationREAD) - if e != nil { - return - } groupID := httpRequest.PostFormValue("groupID") @@ -113,10 +124,6 @@ func DeleteStrategyGroup(httpResponse http.ResponseWriter, httpRequest *http.Req // GetStrategyGroupList 获取接口分组列表 func GetStrategyGroupList(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationREAD) - if e != nil { - return - } flag, result, err := strategy.GetStrategyGroupList() if !flag { diff --git a/console/controller/strategy/strategyPlugin.go b/console/controller/strategy/strategyPlugin.go index 5c7f2b21..c9c97333 100644 --- a/console/controller/strategy/strategyPlugin.go +++ b/console/controller/strategy/strategyPlugin.go @@ -4,18 +4,43 @@ import ( "net/http" "strconv" + goku_handler "github.com/eolinker/goku-api-gateway/goku-handler" + "github.com/eolinker/goku-api-gateway/console/controller" "github.com/eolinker/goku-api-gateway/console/module/plugin" plugin_config "github.com/eolinker/goku-api-gateway/console/module/plugin/plugin-config" "github.com/eolinker/goku-api-gateway/console/module/strategy" ) +const operationStrategyPlugin = "strategyManagement" + +//PluginHandlers 策略插件处理器 +type PluginHandlers struct { +} + +//Handlers handlers +func (h *PluginHandlers) Handlers(factory *goku_handler.AccountHandlerFactory) map[string]http.Handler { + return map[string]http.Handler{ + "/addPluginToStrategy": factory.NewAccountHandleFunction(operationAPIStrategy, true, AddPluginToStrategy), + "/edit": factory.NewAccountHandleFunction(operationAPIStrategy, true, EditStrategyPluginConfig), + "/getInfo": factory.NewAccountHandleFunction(operationAPIStrategy, false, GetStrategyPluginConfig), + "/getList": factory.NewAccountHandleFunction(operationAPIStrategy, false, GetStrategyPluginList), + "/checkPluginIsExist": factory.NewAccountHandleFunction(operationAPIStrategy, false, CheckPluginIsExistInStrategy), + "/getStatus": factory.NewAccountHandleFunction(operationAPIStrategy, false, GetStrategyPluginStatus), + "/batchStart": factory.NewAccountHandleFunction(operationAPIStrategy, false, BatchStartStrategyPlugin), + "/batchStop": factory.NewAccountHandleFunction(operationAPIStrategy, true, BatchStopStrategyPlugin), + "/batchDelete": factory.NewAccountHandleFunction(operationAPIStrategy, true, BatchDeleteStrategyPlugin), + } + +} + +//NewPluginHandlers new pluginHandlers +func NewPluginHandlers() *PluginHandlers { + return &PluginHandlers{} +} + //AddPluginToStrategy 新增插件到接口 func AddPluginToStrategy(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationEDIT) - if e != nil { - return - } pluginName := httpRequest.PostFormValue("pluginName") pluginConfig := httpRequest.PostFormValue("pluginConfig") @@ -69,10 +94,6 @@ func AddPluginToStrategy(httpResponse http.ResponseWriter, httpRequest *http.Req //EditStrategyPluginConfig 修改插件信息 func EditStrategyPluginConfig(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationEDIT) - if e != nil { - return - } pluginName := httpRequest.PostFormValue("pluginName") pluginConfig := httpRequest.PostFormValue("pluginConfig") @@ -111,10 +132,7 @@ func EditStrategyPluginConfig(httpResponse http.ResponseWriter, httpRequest *htt //GetStrategyPluginList 获取策略组插件列表 func GetStrategyPluginList(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationREAD) - if e != nil { - return - } + httpRequest.ParseForm() strategyID := httpRequest.Form.Get("strategyID") keyword := httpRequest.Form.Get("keyword") @@ -141,10 +159,6 @@ func GetStrategyPluginList(httpResponse http.ResponseWriter, httpRequest *http.R //GetStrategyPluginConfig 获取策略组插件信息 func GetStrategyPluginConfig(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationREAD) - if e != nil { - return - } strategyID := httpRequest.PostFormValue("strategyID") pluginName := httpRequest.PostFormValue("pluginName") @@ -156,10 +170,6 @@ func GetStrategyPluginConfig(httpResponse http.ResponseWriter, httpRequest *http //CheckPluginIsExistInStrategy 检查策略组是否绑定插件 func CheckPluginIsExistInStrategy(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationREAD) - if e != nil { - return - } strategyID := httpRequest.PostFormValue("strategyID") pluginName := httpRequest.PostFormValue("pluginName") @@ -190,10 +200,6 @@ func CheckPluginIsExistInStrategy(httpResponse http.ResponseWriter, httpRequest //GetStrategyPluginStatus 检查策略组插件是否开启 func GetStrategyPluginStatus(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationREAD) - if e != nil { - return - } strategyID := httpRequest.PostFormValue("strategyID") pluginName := httpRequest.PostFormValue("pluginName") @@ -226,10 +232,6 @@ func GetStrategyPluginStatus(httpResponse http.ResponseWriter, httpRequest *http //BatchStartStrategyPlugin 批量开启策略组插件 func BatchStartStrategyPlugin(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationEDIT) - if e != nil { - return - } strategyID := httpRequest.PostFormValue("strategyID") connIDList := httpRequest.PostFormValue("connIDList") @@ -256,10 +258,6 @@ func BatchStartStrategyPlugin(httpResponse http.ResponseWriter, httpRequest *htt //BatchStopStrategyPlugin 批量修改策略组插件状态 func BatchStopStrategyPlugin(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationEDIT) - if e != nil { - return - } strategyID := httpRequest.PostFormValue("strategyID") connIDList := httpRequest.PostFormValue("connIDList") @@ -285,10 +283,6 @@ func BatchStopStrategyPlugin(httpResponse http.ResponseWriter, httpRequest *http //BatchDeleteStrategyPlugin 批量删除策略组插件 func BatchDeleteStrategyPlugin(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationEDIT) - if e != nil { - return - } strategyID := httpRequest.PostFormValue("strategyID") connIDList := httpRequest.PostFormValue("connIDList") diff --git a/console/controller/utils.go b/console/controller/utils.go index 8f0e5d3c..0a51ef77 100644 --- a/console/controller/utils.go +++ b/console/controller/utils.go @@ -2,39 +2,9 @@ package controller import ( "encoding/json" - "errors" + log "github.com/eolinker/goku-api-gateway/goku-log" "net/http" "reflect" - "strconv" - - log "github.com/eolinker/goku-api-gateway/goku-log" - - "github.com/eolinker/goku-api-gateway/console/module/account" -) - -const ( - //OperationEDIT 编辑 - OperationEDIT = "edit" - //OperationREAD 读取 - OperationREAD = "read" -) -const ( - //OperationNone 无操作 - OperationNone = "" - //OperationAPI 接口操作 - OperationAPI = "apiManagement" - //OperationADMIN 管理员 - OperationADMIN = "adminManagement" - //OperationLoadBalance 负载操作 - OperationLoadBalance = "loadBalance" - //OperationStrategy 策略操作 - OperationStrategy = "strategyManagement" - //OperationNode 节点操作 - OperationNode = "nodeManagement" - //OperationPlugin 插件操作 - OperationPlugin = "pluginManagement" - //OperationGatewayConfig 网关配置操作 - OperationGatewayConfig = "gatewayConfig" ) //PageInfo 页码信息 @@ -137,28 +107,3 @@ func WriteError(w http.ResponseWriter, statusCode, resultType, resultDesc string log.WithFields(ret).Debug("write error:", err) } - -//CheckLogin 判断是否登录 -func CheckLogin(w http.ResponseWriter, r *http.Request, operationType, operation string) (int, error) { - - userIDCookie, idErr := r.Cookie("userID") - userCookie, userErr := r.Cookie("userToken") - if idErr != nil || userErr != nil { - e := errors.New("user not logged in") - WriteError(w, "100001", "user", e.Error(), e) - return 0, e - } - userID, err := strconv.Atoi(userIDCookie.Value) - if err != nil { - WriteError(w, "100001", "user", "Illegal user id!", err) - return 0, err - } - flag := account.CheckLogin(userCookie.Value, userID) - if !flag { - e := errors.New("illegal users") - WriteError(w, "100001", "user", "Illegal users!", e) - return userID, e - } - - return userID, nil -} diff --git a/console/module/account/guest.go b/console/module/account/guest.go index aaec7026..9f28f1cf 100644 --- a/console/module/account/guest.go +++ b/console/module/account/guest.go @@ -1,27 +1,42 @@ package account import ( - console_sqlite3 "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3" + "github.com/eolinker/goku-api-gateway/common/pdao" + "github.com/eolinker/goku-api-gateway/server/dao" + +) + +var( + guestDao dao.GuestDao + userDao dao.UserDao ) +func init() { + pdao.Need(&guestDao,&userDao) +} + + //Login 登录 -func Login(loginCall, loginPassword string) (bool, int) { - return console_sqlite3.Login(loginCall, loginPassword) +func Login(loginCall, loginPassword string) (bool, int) { + return guestDao.Login(loginCall, loginPassword) } //CheckLogin 检查用户是否登录 -func CheckLogin(userToken string, userID int) bool { - return console_sqlite3.CheckLogin(userToken, userID) +func CheckLogin(userToken string, userID int) bool { + + return guestDao.CheckLogin(userToken, userID) } //Register 用户注册 -func Register(loginCall, loginPassword string) bool { - return console_sqlite3.Register(loginCall, loginPassword) +func Register(loginCall, loginPassword string) bool { + return guestDao.Register(loginCall, loginPassword) } //CheckSuperAdminCount 获取超级管理员数量 -func CheckSuperAdminCount() (int, error) { - b, err := console_sqlite3.CheckSuperAdminCount() +func CheckSuperAdminCount() (int, error) { + b, err := userDao.CheckSuperAdminCount() return b, err } + + diff --git a/console/module/account/user.go b/console/module/account/user.go index c723957a..25d343e6 100644 --- a/console/module/account/user.go +++ b/console/module/account/user.go @@ -1,40 +1,26 @@ package account -import ( - console_sqlite3 "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3" -) - -//GetUserListWithPermission 获取具有编辑权限的用户列表 -func GetUserListWithPermission(operationType, operation string) (bool, []map[string]interface{}, error) { - return console_sqlite3.GetUserListWithPermission(operationType, operation) -} - //EditPassword 修改账户信息 func EditPassword(oldPassword, newPassword string, userID int) (bool, string, error) { - return console_sqlite3.EditPassword(oldPassword, newPassword, userID) + return userDao.EditPassword(oldPassword, newPassword, userID) } //GetUserInfo 获取账户信息 func GetUserInfo(userID int) (bool, interface{}, error) { - return console_sqlite3.GetUserInfo(userID) + return userDao.GetUserInfo(userID) } //GetUserType 获取用户类型 func GetUserType(userID int) (bool, interface{}, error) { - return console_sqlite3.GetUserType(userID) + return userDao.GetUserType(userID) } //CheckUserIsAdmin 判断是否是管理员 func CheckUserIsAdmin(userID int) (bool, string, error) { - return console_sqlite3.CheckUserIsAdmin(userID) + return userDao.CheckUserIsAdmin(userID) } //CheckUserIsSuperAdmin 判断是否是超级管理员 func CheckUserIsSuperAdmin(userID int) (bool, string, error) { - return console_sqlite3.CheckUserIsSuperAdmin(userID) -} - -//CheckUserPermission 检查用户权限 -func CheckUserPermission(operationType, operation string, userID int) (bool, string, error) { - return console_sqlite3.CheckUserPermission(operationType, operation, userID) + return userDao.CheckUserIsSuperAdmin(userID) } diff --git a/console/module/api/api.go b/console/module/api/api.go index 1d56ec8e..6e8e270b 100644 --- a/console/module/api/api.go +++ b/console/module/api/api.go @@ -1,53 +1,57 @@ package api import ( - console_sqlite3 "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3" entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" ) //AddAPI 新增接口 -func AddAPI(apiName, requestURL, targetURL, requestMethod, targetMethod, isFollow, linkApis, staticResponse, responseDataType, balanceName, protocol string, projectID, groupID, timeout, retryCount, alertValve, managerID, userID, apiType int) (bool, int, error) { +func AddAPI(apiName, alias, requestURL, targetURL, requestMethod, targetMethod, isFollow, linkApis, staticResponse, responseDataType, balanceName, protocol string, projectID, groupID, timeout, retryCount, alertValve, managerID, userID, apiType int) (bool, int, error) { - flag, result, err := console_sqlite3.AddAPI(apiName, requestURL, targetURL, requestMethod, targetMethod, isFollow, linkApis, staticResponse, responseDataType, balanceName, protocol, projectID, groupID, timeout, retryCount, alertValve, managerID, userID, apiType) + flag, result, err := apiDao.AddAPI(apiName, alias, requestURL, targetURL, requestMethod, targetMethod, isFollow, linkApis, staticResponse, responseDataType, balanceName, protocol, projectID, groupID, timeout, retryCount, alertValve, managerID, userID, apiType) return flag, result, err } //EditAPI 新增接口 -func EditAPI(apiName, requestURL, targetURL, requestMethod, targetMethod, isFollow, linkApis, staticResponse, responseDataType, balanceName, protocol string, projectID, groupID, timeout, retryCount, alertValve, apiID, managerID, userID int) (bool, error) { - flag, err := console_sqlite3.EditAPI(apiName, requestURL, targetURL, requestMethod, targetMethod, isFollow, linkApis, staticResponse, responseDataType, balanceName, protocol, projectID, groupID, timeout, retryCount, alertValve, apiID, managerID, userID) +func EditAPI(apiName, alias, requestURL, targetURL, requestMethod, targetMethod, isFollow, linkApis, staticResponse, responseDataType, balanceName, protocol string, projectID, groupID, timeout, retryCount, alertValve, apiID, managerID, userID int) (bool, error) { + flag, err := apiDao.EditAPI(apiName, alias, requestURL, targetURL, requestMethod, targetMethod, isFollow, linkApis, staticResponse, responseDataType, balanceName, protocol, projectID, groupID, timeout, retryCount, alertValve, apiID, managerID, userID) return flag, err } //GetAPIInfo 获取接口信息 func GetAPIInfo(apiID int) (bool, *entity.API, error) { - return console_sqlite3.GetAPIInfo(apiID) + return apiDao.GetAPIInfo(apiID) } // GetAPIIDList 获取接口ID列表 func GetAPIIDList(projectID int, groupID int, keyword string, condition int, ids []int) (bool, []int, error) { - return console_sqlite3.GetAPIIDList(projectID, groupID, keyword, condition, ids) + return apiDao.GetAPIIDList(projectID, groupID, keyword, condition, ids) } // GetAPIList 获取接口列表 func GetAPIList(projectID int, groupID int, keyword string, condition, page, pageSize int, ids []int) (bool, []map[string]interface{}, int, error) { - return console_sqlite3.GetAPIList(projectID, groupID, keyword, condition, page, pageSize, ids) + return apiDao.GetAPIList(projectID, groupID, keyword, condition, page, pageSize, ids) } //CheckURLIsExist 接口路径是否存在 func CheckURLIsExist(requestURL, requestMethod string, projectID, apiID int) bool { - return console_sqlite3.CheckURLIsExist(requestURL, requestMethod, projectID, apiID) + return apiDao.CheckURLIsExist(requestURL, requestMethod, projectID, apiID) } //CheckAPIIsExist 检查接口是否存在 func CheckAPIIsExist(apiID int) (bool, error) { - return console_sqlite3.CheckAPIIsExist(apiID) + return apiDao.CheckAPIIsExist(apiID) +} + +//CheckAliasIsExist 检查接口是否存在 +func CheckAliasIsExist(apiID int, alias string) bool { + return apiDao.CheckAliasIsExist(apiID, alias) } //BatchEditAPIGroup 批量修改接口分组 func BatchEditAPIGroup(apiIDList []string, groupID int) (bool, string, error) { - r, e := console_sqlite3.BatchEditAPIGroup(apiIDList, groupID) + r, e := apiDao.BatchEditAPIGroup(apiIDList, groupID) return e == nil, r, e } @@ -55,7 +59,7 @@ func BatchEditAPIGroup(apiIDList []string, groupID int) (bool, string, error) { //BatchEditAPIBalance 批量修改接口负载 func BatchEditAPIBalance(apiIDList []string, balance string) (string, error) { - r, err := console_sqlite3.BatchEditAPIBalance(apiIDList, balance) + r, err := apiDao.BatchEditAPIBalance(apiIDList, balance) return r, err } @@ -63,7 +67,7 @@ func BatchEditAPIBalance(apiIDList []string, balance string) (string, error) { //BatchDeleteAPI 批量删除接口 func BatchDeleteAPI(apiIDList string) (bool, string, error) { - flag, result, err := console_sqlite3.BatchDeleteAPI(apiIDList) + flag, result, err := apiDao.BatchDeleteAPI(apiIDList) return flag, result, err } diff --git a/console/module/api/apiGroup.go b/console/module/api/apiGroup.go index a7275f9d..bb1fd037 100644 --- a/console/module/api/apiGroup.go +++ b/console/module/api/apiGroup.go @@ -1,27 +1,23 @@ package api -import ( - console_sqlite3 "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3" -) - //AddAPIGroup 新建接口分组 func AddAPIGroup(groupName string, projectID, parentGroupID int) (bool, interface{}, error) { - return console_sqlite3.AddAPIGroup(groupName, projectID, parentGroupID) + return apiGroupDao.AddAPIGroup(groupName, projectID, parentGroupID) } //EditAPIGroup 修改接口分组 func EditAPIGroup(groupName string, groupID, projectID int) (bool, string, error) { - return console_sqlite3.EditAPIGroup(groupName, groupID, projectID) + return apiGroupDao.EditAPIGroup(groupName, groupID, projectID) } //DeleteAPIGroup 删除接口分组 func DeleteAPIGroup(projectID, groupID int) (bool, string, error) { - flag, result, err := console_sqlite3.DeleteAPIGroup(projectID, groupID) + flag, result, err := apiGroupDao.DeleteAPIGroup(projectID, groupID) return flag, result, err } //GetAPIGroupList 获取接口分组列表 func GetAPIGroupList(projectID int) (bool, []map[string]interface{}, error) { - return console_sqlite3.GetAPIGroupList(projectID) + return apiGroupDao.GetAPIGroupList(projectID) } diff --git a/console/module/api/apiPlugin.go b/console/module/api/apiPlugin.go index 3c594c30..b42b7673 100644 --- a/console/module/api/apiPlugin.go +++ b/console/module/api/apiPlugin.go @@ -1,67 +1,63 @@ package api -import ( - console_sqlite3 "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3" -) - //BatchEditAPIPluginStatus BatchEditAPIPluginStatus批量修改接口插件状态 func BatchEditAPIPluginStatus(connIDList, strategyID string, pluginStatus, userID int) (bool, string, error) { - flag, result, err := console_sqlite3.BatchEditAPIPluginStatus(connIDList, strategyID, pluginStatus, userID) + flag, result, err := apiPluginDao.BatchEditAPIPluginStatus(connIDList, strategyID, pluginStatus, userID) return flag, result, err } //BatchDeleteAPIPlugin 批量删除接口插件 func BatchDeleteAPIPlugin(connIDList, strategyID string) (bool, string, error) { - flag, result, err := console_sqlite3.BatchDeleteAPIPlugin(connIDList, strategyID) + flag, result, err := apiPluginDao.BatchDeleteAPIPlugin(connIDList, strategyID) return flag, result, err } //AddPluginToAPI 新增插件到接口 func AddPluginToAPI(pluginName, config, strategyID string, apiID, userID int) (bool, interface{}, error) { - flag, result, err := console_sqlite3.AddPluginToAPI(pluginName, config, strategyID, apiID, userID) + flag, result, err := apiPluginDao.AddPluginToAPI(pluginName, config, strategyID, apiID, userID) return flag, result, err } //EditAPIPluginConfig 修改接口插件配置 func EditAPIPluginConfig(pluginName, config, strategyID string, apiID, userID int) (bool, interface{}, error) { - flag, result, err := console_sqlite3.EditAPIPluginConfig(pluginName, config, strategyID, apiID, userID) + flag, result, err := apiPluginDao.EditAPIPluginConfig(pluginName, config, strategyID, apiID, userID) return flag, result, err } //GetAPIPluginList 获取接口插件列表 func GetAPIPluginList(apiID int, strategyID string) (bool, []map[string]interface{}, error) { - return console_sqlite3.GetAPIPluginList(apiID, strategyID) + return apiPluginDao.GetAPIPluginList(apiID, strategyID) } //GetPluginIndex 获取插件优先级 func GetPluginIndex(pluginName string) (bool, int, error) { - return console_sqlite3.GetPluginIndex(pluginName) + return apiPluginDao.GetPluginIndex(pluginName) } //GetAPIPluginConfig 通过ApiID获取配置信息 func GetAPIPluginConfig(apiID int, strategyID, pluginName string) (bool, map[string]string, error) { - return console_sqlite3.GetAPIPluginConfig(apiID, strategyID, pluginName) + return apiPluginDao.GetAPIPluginConfig(apiID, strategyID, pluginName) } //CheckPluginIsExistInAPI 检查策略组是否绑定插件 func CheckPluginIsExistInAPI(strategyID, pluginName string, apiID int) (bool, error) { - return console_sqlite3.CheckPluginIsExistInAPI(strategyID, pluginName, apiID) + return apiPluginDao.CheckPluginIsExistInAPI(strategyID, pluginName, apiID) } //GetAllAPIPluginInStrategy 获取策略组中所有接口插件列表 func GetAllAPIPluginInStrategy(strategyID string) (bool, []map[string]interface{}, error) { - return console_sqlite3.GetAllAPIPluginInStrategy(strategyID) + return apiPluginDao.GetAllAPIPluginInStrategy(strategyID) } // GetAPIPluginInStrategyByAPIID 获取策略组中所有接口插件列表 func GetAPIPluginInStrategyByAPIID(strategyID string, apiID int, keyword string, condition int) (bool, []map[string]interface{}, map[string]interface{}, error) { - return console_sqlite3.GetAPIPluginInStrategyByAPIID(strategyID, apiID, keyword, condition) + return apiPluginDao.GetAPIPluginInStrategyByAPIID(strategyID, apiID, keyword, condition) } //GetAPIPluginListWithNotAssignAPIList 获取没有绑定插件得接口列表 func GetAPIPluginListWithNotAssignAPIList(strategyID string) (bool, []map[string]interface{}, error) { - return console_sqlite3.GetAPIPluginListWithNotAssignAPIList(strategyID) + return apiPluginDao.GetAPIPluginListWithNotAssignAPIList(strategyID) } diff --git a/console/module/api/apiStrategy.go b/console/module/api/apiStrategy.go index 5bc7ce64..5b383bc9 100644 --- a/console/module/api/apiStrategy.go +++ b/console/module/api/apiStrategy.go @@ -1,58 +1,54 @@ package api -import ( - console_sqlite3 "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3" -) - //AddAPIToStrategy 将接口加入策略组 func AddAPIToStrategy(apiList []string, strategyID string) (bool, string, error) { - flag, result, err := console_sqlite3.AddAPIToStrategy(apiList, strategyID) + flag, result, err := apiStrategyDao.AddAPIToStrategy(apiList, strategyID) return flag, result, err } //SetTarget 重置目标地址 func SetTarget(apiID int, strategyID string, target string) (bool, string, error) { - flag, result, err := console_sqlite3.SetAPITargetOfStrategy(apiID, strategyID, target) + flag, result, err := apiStrategyDao.SetAPITargetOfStrategy(apiID, strategyID, target) return flag, result, err } // BatchSetTarget 批量重置目标地址 func BatchSetTarget(apiIds []int, strategyID string, target string) (bool, string, error) { - flag, result, err := console_sqlite3.BatchSetAPITargetOfStrategy(apiIds, strategyID, target) + flag, result, err := apiStrategyDao.BatchSetAPITargetOfStrategy(apiIds, strategyID, target) return flag, result, err } // GetAPIIDListFromStrategy 获取策略组接口ID列表 func GetAPIIDListFromStrategy(strategyID, keyword string, condition int, ids []int, balanceNames []string) (bool, []int, error) { - return console_sqlite3.GetAPIIDListFromStrategy(strategyID, keyword, condition, ids, balanceNames) + return apiStrategyDao.GetAPIIDListFromStrategy(strategyID, keyword, condition, ids, balanceNames) } // GetAPIListFromStrategy 获取策略组接口列表 func GetAPIListFromStrategy(strategyID, keyword string, condition, page, pageSize int, ids []int, balanceNames []string) (bool, []map[string]interface{}, int, error) { - return console_sqlite3.GetAPIListFromStrategy(strategyID, keyword, condition, page, pageSize, ids, balanceNames) + return apiStrategyDao.GetAPIListFromStrategy(strategyID, keyword, condition, page, pageSize, ids, balanceNames) } //CheckIsExistAPIInStrategy 检查插件是否添加进策略组 func CheckIsExistAPIInStrategy(apiID int, strategyID string) (bool, string, error) { - return console_sqlite3.CheckIsExistAPIInStrategy(apiID, strategyID) + return apiStrategyDao.CheckIsExistAPIInStrategy(apiID, strategyID) } // GetAPIIDListNotInStrategy 获取未被该策略组绑定的接口ID列表(通过项目) func GetAPIIDListNotInStrategy(strategyID string, projectID, groupID int, keyword string) (bool, []int, error) { - return console_sqlite3.GetAPIIDListNotInStrategy(strategyID, projectID, groupID, keyword) + return apiStrategyDao.GetAPIIDListNotInStrategy(strategyID, projectID, groupID, keyword) } // GetAPIListNotInStrategy 获取未被该策略组绑定的接口列表(通过项目) func GetAPIListNotInStrategy(strategyID string, projectID, groupID, page, pageSize int, keyword string) (bool, []map[string]interface{}, int, error) { - return console_sqlite3.GetAPIListNotInStrategy(strategyID, projectID, groupID, page, pageSize, keyword) + return apiStrategyDao.GetAPIListNotInStrategy(strategyID, projectID, groupID, page, pageSize, keyword) } //BatchDeleteAPIInStrategy 批量删除策略组接口 func BatchDeleteAPIInStrategy(apiIDList, strategyID string) (bool, string, error) { - flag, result, err := console_sqlite3.BatchDeleteAPIInStrategy(apiIDList, strategyID) + flag, result, err := apiStrategyDao.BatchDeleteAPIInStrategy(apiIDList, strategyID) return flag, result, err } diff --git a/console/module/api/dao.go b/console/module/api/dao.go new file mode 100644 index 00000000..26dddaef --- /dev/null +++ b/console/module/api/dao.go @@ -0,0 +1,18 @@ +package api + +import ( + "github.com/eolinker/goku-api-gateway/common/pdao" + "github.com/eolinker/goku-api-gateway/server/dao" +) + +var( + apiDao dao.APIDao + apiGroupDao dao.APIGroupDao + apiPluginDao dao.APIPluginDao + apiStrategyDao dao.APIStrategyDao + importDao dao.ImportDao +) + +func init() { + pdao.Need(&apiDao,&apiGroupDao,&apiPluginDao,&apiStrategyDao,&importDao) +} \ No newline at end of file diff --git a/console/module/api/import.go b/console/module/api/import.go index 92484892..917b0a9d 100644 --- a/console/module/api/import.go +++ b/console/module/api/import.go @@ -1,27 +1,26 @@ package api import ( - console_sqlite3 "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3" entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" ) //ImportAPIGroupFromAms 导入接口分组 func ImportAPIGroupFromAms(projectID, userID int, groupInfo entity.AmsGroupInfo) (bool, string, error) { - flag, result, err := console_sqlite3.ImportAPIGroupFromAms(projectID, userID, groupInfo) + flag, result, err := importDao.ImportAPIGroupFromAms(projectID, userID, groupInfo) return flag, result, err } //ImportProjectFromAms 导入项目 func ImportProjectFromAms(userID int, projectInfo entity.AmsProject) (bool, string, error) { - flag, result, err := console_sqlite3.ImportProjectFromAms(userID, projectInfo) + flag, result, err := importDao.ImportProjectFromAms(userID, projectInfo) return flag, result, err } //ImportAPIFromAms 导入接口 func ImportAPIFromAms(projectID, groupID, userID int, apiList []entity.AmsAPIInfo) (bool, string, error) { - flag, result, err := console_sqlite3.ImportAPIFromAms(projectID, groupID, userID, apiList) + flag, result, err := importDao.ImportAPIFromAms(projectID, groupID, userID, apiList) return flag, result, err } diff --git a/console/module/auth/auth.go b/console/module/auth/auth.go index 996c3180..b4380a8c 100644 --- a/console/module/auth/auth.go +++ b/console/module/auth/auth.go @@ -1,22 +1,29 @@ package auth import ( - console_sqlite3 "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3" + "github.com/eolinker/goku-api-gateway/common/pdao" + "github.com/eolinker/goku-api-gateway/server/dao" +) +var ( + authDao dao.AuthDao ) +func init() { + pdao.Need(&authDao) +} //GetAuthStatus 获取认证状态 func GetAuthStatus(strategyID string) (bool, map[string]interface{}, error) { - return console_sqlite3.GetAuthStatus(strategyID) + return authDao.GetAuthStatus(strategyID) } //GetAuthInfo 获取认证信息 func GetAuthInfo(strategyID string) (bool, map[string]interface{}, error) { - return console_sqlite3.GetAuthInfo(strategyID) + return authDao.GetAuthInfo(strategyID) } //EditAuthInfo 编辑认证信息 func EditAuthInfo(strategyID, strategyName, basicAuthList, apikeyList, jwtCredentialList, oauth2CredentialList string, delClientIDList []string) (bool, error) { - flag, err := console_sqlite3.EditAuthInfo(strategyID, strategyName, basicAuthList, apikeyList, + flag, err := authDao.EditAuthInfo(strategyID, strategyName, basicAuthList, apikeyList, jwtCredentialList, oauth2CredentialList, delClientIDList) return flag, err diff --git a/console/module/balance/balance.go b/console/module/balance/balance.go index 075a88fb..16937085 100644 --- a/console/module/balance/balance.go +++ b/console/module/balance/balance.go @@ -5,14 +5,12 @@ import ( "fmt" "time" - dao_balance "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3/dao-balance" - "github.com/eolinker/goku-api-gateway/console/module/service" driver2 "github.com/eolinker/goku-api-gateway/server/driver" entity "github.com/eolinker/goku-api-gateway/server/entity/balance-entity-service" ) -//Add 新增负载 +//RegisterDao 新增负载 func Add(info *Param) (string, error) { serviceInfo, err := service.Get(info.ServiceName) if err != nil { @@ -25,7 +23,7 @@ func Add(info *Param) (string, error) { return "param:static 和 staticCluster 不能同时为空", errors.New("param:static 和 staticCluster 不能同时为空") } now := time.Now().Format("2006-01-02 15:04:05") - result, err := dao_balance.AddStatic(info.Name, info.ServiceName, info.Static, info.StaticCluster, info.Desc, now) + result, err := balanceDao.AddStatic(info.Name, info.ServiceName, info.Static, info.StaticCluster, info.Desc, now) return result, err } @@ -35,7 +33,7 @@ func Add(info *Param) (string, error) { return "param:appName 不能为空", errors.New("param:appName 不能为空") } now := time.Now().Format("2006-01-02 15:04:05") - result, err := dao_balance.AddDiscovery(info.Name, info.ServiceName, info.AppName, info.Desc, now) + result, err := balanceDao.AddDiscovery(info.Name, info.ServiceName, info.AppName, info.Desc, now) return result, err } @@ -58,7 +56,7 @@ func Save(info *Param) (string, error) { return "param:static 和 staticCluster 不能同时为空", errors.New("param:static 和 staticCluster 不能同时为空") } now := time.Now().Format("2006-01-02 15:04:05") - result, err := dao_balance.SaveStatic(info.Name, info.ServiceName, info.Static, info.StaticCluster, info.Desc, now) + result, err := balanceDao.SaveStatic(info.Name, info.ServiceName, info.Static, info.StaticCluster, info.Desc, now) return result, err } @@ -68,7 +66,7 @@ func Save(info *Param) (string, error) { return "param:appName 不能为空", errors.New("param:appName 不能为空") } now := time.Now().Format("2006-01-02 15:04:05") - result, err := dao_balance.SaveDiscover(info.Name, info.ServiceName, info.AppName, info.Desc, now) + result, err := balanceDao.SaveDiscover(info.Name, info.ServiceName, info.AppName, info.Desc, now) return result, err } @@ -80,7 +78,7 @@ func Save(info *Param) (string, error) { //Get 通过负载名称获取负载信息 func Get(name string) (*Info, error) { - b, e := dao_balance.Get(name) + b, e := balanceDao.Get(name) if e != nil { return nil, e } @@ -92,13 +90,13 @@ func Get(name string) (*Info, error) { func Search(keyworkd string) ([]*Info, error) { var entities []*entity.Balance if keyworkd == "" { - es, e := dao_balance.GetAll() + es, e := balanceDao.GetAll() if e != nil { return nil, e } entities = es } else { - es, e := dao_balance.Search(keyworkd) + es, e := balanceDao.Search(keyworkd) if e != nil { return nil, e } @@ -107,7 +105,13 @@ func Search(keyworkd string) ([]*Info, error) { infos := make([]*Info, 0, len(entities)) + useBalances, _ := balanceDao.GetUseBalanceNames() for _, ent := range entities { + if useBalances != nil { + if _, ok := useBalances[ent.Name]; ok { + ent.CanDelete = 0 + } + } infos = append(infos, ReadInfo(ent)) } return infos, nil @@ -116,13 +120,18 @@ func Search(keyworkd string) ([]*Info, error) { //GetAll 获取所有负载列表 func GetAll() ([]*Info, error) { - entities, e := dao_balance.GetAll() + entities, e := balanceDao.GetAll() if e != nil { return nil, e } infos := make([]*Info, 0, len(entities)) - + useBalances, _ := balanceDao.GetUseBalanceNames() for _, ent := range entities { + if useBalances != nil { + if _, ok := useBalances[ent.Name]; ok { + ent.CanDelete = 0 + } + } infos = append(infos, ReadInfo(ent)) } return infos, nil @@ -130,19 +139,19 @@ func GetAll() ([]*Info, error) { //Delete 删除负载 func Delete(name string) (string, error) { - result, err := dao_balance.Delete(name) + result, err := balanceDao.Delete(name) return result, err } //GetBalancNames 获取负载名称列表 func GetBalancNames() (bool, []string, error) { - return dao_balance.GetBalanceNames() + return balanceDao.GetBalanceNames() } //BatchDeleteBalance 批量删除负载 func BatchDeleteBalance(balanceNames []string) (string, error) { - result, err := dao_balance.BatchDelete(balanceNames) + result, err := balanceDao.BatchDelete(balanceNames) return result, err } diff --git a/console/module/balance/param.go b/console/module/balance/param.go index 1de64bce..1f740f73 100644 --- a/console/module/balance/param.go +++ b/console/module/balance/param.go @@ -28,6 +28,7 @@ type Info struct { Desc string `json:"balanceDesc"` CreateTime string `json:"createTime"` UpdateTime string `json:"updateTime"` + CanDelete int `json:"canDelete"` } //ReadInfo 读取负载信息 @@ -43,6 +44,7 @@ func ReadInfo(balance *entity.Balance) *Info { Desc: balance.Desc, CreateTime: balance.CreateTime, UpdateTime: balance.UpdateTime, + CanDelete: balance.CanDelete, } json.Unmarshal([]byte(balance.StaticCluster), &info.StaticCluster) return info diff --git a/console/module/balance/update.go b/console/module/balance/update.go index 083f6142..51dd380c 100644 --- a/console/module/balance/update.go +++ b/console/module/balance/update.go @@ -2,25 +2,30 @@ package balance import ( "encoding/json" + "github.com/eolinker/goku-api-gateway/common/pdao" + "github.com/eolinker/goku-api-gateway/server/dao" "github.com/eolinker/goku-api-gateway/common/general" - dao_balance_update2 "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3/dao-balance-update" entity "github.com/eolinker/goku-api-gateway/server/entity/balance-entity" ) - +var ( + balanceDao dao.BalanceDao + balanceUpdateDao dao.BalanceUpdateDao +) func init() { + pdao.Need(&balanceDao,&balanceUpdateDao) general.RegeditLater(Update) } //Update 将旧负载配置更新为新负载配置 func Update() error { - l, e := dao_balance_update2.GetAllOldVerSion() + l, e := balanceUpdateDao.GetAllOldVerSion() if e != nil { return e } - defStaticServiceName := dao_balance_update2.GetDefaultServiceStatic() + defStaticServiceName := balanceUpdateDao.GetDefaultServiceStatic() for _, e := range l { update(e, defStaticServiceName) } diff --git a/console/module/cluster/cluster.go b/console/module/cluster/cluster.go index beab2bd9..720fd407 100644 --- a/console/module/cluster/cluster.go +++ b/console/module/cluster/cluster.go @@ -1,46 +1,53 @@ package cluster import ( - console_sqlite3 "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3" + "github.com/eolinker/goku-api-gateway/common/pdao" + "github.com/eolinker/goku-api-gateway/server/dao" entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" ) +var ( + clusterDao dao.ClusterDao +) +func init() { + pdao.Need(&clusterDao) +} //AddCluster 新增集群 func AddCluster(name, title, note string) error { - return console_sqlite3.AddCluster(name, title, note) + return clusterDao.AddCluster(name, title, note) } //EditCluster 修改集群信息 func EditCluster(name, title, note string) error { - return console_sqlite3.EditCluster(name, title, note) + return clusterDao.EditCluster(name, title, note) } //DeleteCluster 删除集群 func DeleteCluster(name string) error { - return console_sqlite3.DeleteCluster(name) + return clusterDao.DeleteCluster(name) } //GetClusters 获取集群列表 func GetClusters() ([]*entity.Cluster, error) { - return console_sqlite3.GetClusters() + return clusterDao.GetClusters() } //GetCluster 获取集群信息 func GetCluster(name string) (*entity.Cluster, error) { - return console_sqlite3.GetCluster(name) + return clusterDao.GetCluster(name) } //GetClusterNodeCount 获取集群节点数量 func GetClusterNodeCount(name string) int { - return console_sqlite3.GetClusterNodeCount(name) + return clusterDao.GetClusterNodeCount(name) } //CheckClusterNameIsExist 判断集群名称是否存在 func CheckClusterNameIsExist(name string) bool { - return console_sqlite3.CheckClusterNameIsExist(name) + return clusterDao.CheckClusterNameIsExist(name) } //GetClusterIDByName 获取集群节点数量 func GetClusterIDByName(name string) int { - return console_sqlite3.GetClusterIDByName(name) + return clusterDao.GetClusterIDByName(name) } diff --git a/console/module/config-log/dao.go b/console/module/config-log/dao.go new file mode 100644 index 00000000..4bdab4c1 --- /dev/null +++ b/console/module/config-log/dao.go @@ -0,0 +1,14 @@ +package config_log + +import ( + "github.com/eolinker/goku-api-gateway/common/pdao" + "github.com/eolinker/goku-api-gateway/server/dao" +) + +var ( + configLogDao dao.ConfigLogDao +) + +func init() { + pdao.Need(&configLogDao) +} \ No newline at end of file diff --git a/console/module/config-log/get.go b/console/module/config-log/get.go index 52ed0616..700dcb24 100644 --- a/console/module/config-log/get.go +++ b/console/module/config-log/get.go @@ -5,7 +5,6 @@ import ( "github.com/eolinker/goku-api-gateway/common/auto-form" log "github.com/eolinker/goku-api-gateway/goku-log" - config_log "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3/config-log" ) //Get 获取普通日志配置 @@ -18,7 +17,7 @@ func Get(name string) (*LogConfig, error) { c.Levels = Levels c.Periods = Periods c.Expires = Expires - config, e := config_log.Get(name) + config, e := configLogDao.Get(name) if e != nil || config == nil { auto.SetDefaults(c) @@ -36,7 +35,7 @@ func Get(name string) (*LogConfig, error) { //GetAccess 获取access配置 func GetAccess() (*AccessConfig, error) { - config, e := config_log.Get(AccessLog) + config, e := configLogDao.Get(AccessLog) c := new(AccessConfig) c.Periods = Periods c.Expires = Expires diff --git a/console/module/config-log/set.go b/console/module/config-log/set.go index 3216f1e0..a4d5f0c9 100644 --- a/console/module/config-log/set.go +++ b/console/module/config-log/set.go @@ -4,7 +4,6 @@ import ( "fmt" log "github.com/eolinker/goku-api-gateway/goku-log" - config_log "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3/config-log" entity "github.com/eolinker/goku-api-gateway/server/entity/config-log" ) @@ -27,7 +26,7 @@ func Set(name string, param *Param) error { } c.Fields = param.Fields c.Expire = param.Expire - err := config_log.Set(c) + err := configLogDao.Set(c) if err != nil { return err } diff --git a/console/module/gateway/gateway.go b/console/module/gateway/gateway.go index fbe46549..81aa7ee0 100644 --- a/console/module/gateway/gateway.go +++ b/console/module/gateway/gateway.go @@ -1,10 +1,22 @@ package gateway import ( + "github.com/eolinker/goku-api-gateway/common/pdao" v "github.com/eolinker/goku-api-gateway/common/version" - console_sqlite3 "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3" + "github.com/eolinker/goku-api-gateway/server/dao" + entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" ) +var ( + gatewayDao dao.GatewayDao + pluginDao dao.PluginDao + clusterDao dao.ClusterDao +) + +func init() { + pdao.Need(&gatewayDao, &pluginDao, &clusterDao) +} + //BaseGatewayInfo 网关基本配置 type BaseGatewayInfo struct { NodeCount int `json:"nodeCount"` @@ -25,37 +37,36 @@ type SystemInfo struct { //GetGatewayConfig 获取网关配置 func GetGatewayConfig() (map[string]interface{}, error) { - return console_sqlite3.GetGatewayConfig() + return gatewayDao.GetGatewayConfig() } //EditGatewayBaseConfig 编辑网关基本配置 func EditGatewayBaseConfig(successCode string, nodeUpdatePeriod, monitorUpdatePeriod, timeout int) (bool, string, error) { - flag, result, err := console_sqlite3.EditGatewayBaseConfig(successCode, nodeUpdatePeriod, monitorUpdatePeriod, timeout) - return flag, result, err -} - -//EditGatewayAlarmConfig 编辑网关告警配置 -func EditGatewayAlarmConfig(apiAlertInfo, sender, senderPassword, smtpAddress string, alertStatus, smtpPort, smtpProtocol int) (bool, string, error) { - flag, result, err := console_sqlite3.EditGatewayAlarmConfig(apiAlertInfo, sender, senderPassword, smtpAddress, alertStatus, smtpPort, smtpProtocol) - + config := entity.GatewayBasicConfig{ + SuccessCode: successCode, + NodeUpdatePeriod: nodeUpdatePeriod, + MonitorUpdatePeriod: monitorUpdatePeriod, + MonitorTimeout: timeout, + } + flag, result, err := gatewayDao.EditGatewayBaseConfig(config) return flag, result, err } //GetGatewayMonitorSummaryByPeriod 获取监控summary func GetGatewayMonitorSummaryByPeriod() (bool, *SystemInfo, error) { - nodeStartCount, nodeStopCount, projectCount, apiCount, strategyCount, e := console_sqlite3.GetGatewayInfo() + nodeStartCount, nodeStopCount, projectCount, apiCount, strategyCount, e := gatewayDao.GetGatewayInfo() if e != nil { return false, nil, e } info := new(SystemInfo) - info.BaseInfo.PluginCount = console_sqlite3.GetPluginCount() + info.BaseInfo.PluginCount = pluginDao.GetPluginCount() info.BaseInfo.NodeCount = nodeStartCount + nodeStopCount info.BaseInfo.ProjectCount = projectCount info.BaseInfo.APICount = apiCount info.BaseInfo.StrategyCount = strategyCount info.BaseInfo.Version = v.Version - info.BaseInfo.ClusterCount = console_sqlite3.GetClusterCount() + info.BaseInfo.ClusterCount = clusterDao.GetClusterCount() return true, info, nil diff --git a/console/module/monitor/module.go b/console/module/monitor/module.go index 80b2293b..76f21163 100644 --- a/console/module/monitor/module.go +++ b/console/module/monitor/module.go @@ -1,11 +1,20 @@ package monitor import ( + "github.com/eolinker/goku-api-gateway/common/general" + "github.com/eolinker/goku-api-gateway/common/pdao" "github.com/eolinker/goku-api-gateway/ksitigarbha" - - console_sqlite3 "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3" + "github.com/eolinker/goku-api-gateway/server/dao" "github.com/pkg/errors" ) +var( + monitorModuleDao dao.MonitorModulesDao +) + +func init() { + pdao.Need(&monitorModuleDao) + general.RegeditLater(InitModuleStatus) +} type MonitorModule struct { Name string `json:"moduleName"` @@ -14,31 +23,54 @@ type MonitorModule struct { Desc string `json:"moduleDesc"` Models interface{} `json:"layer"` } +// 初始化监控模块的配置状态 +func InitModuleStatus() error { + modules, err := monitorModuleDao.GetMonitorModules() + if err != nil { + return err + } + + names := ksitigarbha.GetMonitorModuleNames() + + for _, name := range names { + + if m,has:= modules[name];has{ + if m.ModuleStatus == 1{ + ksitigarbha.Open(name,m.Config) + }else{ + ksitigarbha.Close(name) + } + }else{ + ksitigarbha.Close(name) + } + } + return nil +} //GetMonitorModules 获取监控模块列表 func GetMonitorModules() ([]*MonitorModule, error) { - m, err := console_sqlite3.GetMonitorModules() + m, err := monitorModuleDao.GetMonitorModules() if err != nil { - return make([]*MonitorModule, 0), nil + return nil, err } names := ksitigarbha.GetMonitorModuleNames() modules := make([]*MonitorModule, 0, len(names)) for _, name := range names { - model,_ := ksitigarbha.GetMonitorModuleModel(name) - mod :=&MonitorModule{ - Name: name, - Config: model.GetDefaultConfig(), - ModuleStatus: 0, - Desc: model.GetDesc(), - Models: model.GetModel(), - } + model, _ := ksitigarbha.GetMonitorModuleModel(name) + mod := &MonitorModule{ + Name: name, + Config: model.GetDefaultConfig(), + ModuleStatus: 0, + Desc: model.GetDesc(), + Models: model.GetModel(), + } v, ok := m[name] if ok { mod.ModuleStatus = v.ModuleStatus - c ,err := model.Decode(v.Config) + c, err := model.Decode(v.Config) if err == nil { mod.Config = c } @@ -51,22 +83,21 @@ func GetMonitorModules() ([]*MonitorModule, error) { func SetMonitorModule(moduleName string, config string, moduleStatus int) error { - model,has := ksitigarbha.GetMonitorModuleModel(moduleName) + model, has := ksitigarbha.GetMonitorModuleModel(moduleName) if !has { return errors.New("[error]the module does not exist") } - if moduleStatus == 1 { + if moduleStatus == 1 { - _ ,err:= model.Decode(config) - if err != nil{ + _, err := model.Decode(config) + if err != nil { //errInfo := "[error]invalid config" return err } - } - err := console_sqlite3.SetMonitorModule(moduleName, config, moduleStatus) + err := monitorModuleDao.SetMonitorModule(moduleName, config, moduleStatus) if err != nil { return err } diff --git a/console/module/node/Locker_test.go b/console/module/node/Locker_test.go index c2cce1ca..f250801f 100644 --- a/console/module/node/Locker_test.go +++ b/console/module/node/Locker_test.go @@ -4,27 +4,27 @@ import "testing" func Test_InstanceLocker_Lock(t *testing.T) { - l:=newInstanceLocker() - instance:="test" - if !l.Lock(instance){ + l := newInstanceLocker() + instance := "test" + if !l.Lock(instance) { t.Error("should lock true") return } - if l.Lock(instance){ + if l.Lock(instance) { t.Error("should lock false") return } l.UnLock(instance) - if !l.Lock(instance){ + if !l.Lock(instance) { t.Error("should lock true") return } - if l.Lock(instance){ + if l.Lock(instance) { t.Error("should lock false") return } -} \ No newline at end of file +} diff --git a/console/module/node/dao.go b/console/module/node/dao.go new file mode 100644 index 00000000..364f52df --- /dev/null +++ b/console/module/node/dao.go @@ -0,0 +1,15 @@ +package node + +import ( + "github.com/eolinker/goku-api-gateway/common/pdao" + "github.com/eolinker/goku-api-gateway/server/dao" +) + +var ( + nodeDao dao.NodeDao + nodeGroupDao dao.NodeGroupDao +) + +func init() { + pdao.Need(&nodeDao,&nodeGroupDao) +} \ No newline at end of file diff --git a/console/module/node/node.go b/console/module/node/node.go index 1421f338..024f3c14 100644 --- a/console/module/node/node.go +++ b/console/module/node/node.go @@ -3,66 +3,80 @@ package node import ( "time" - console_sqlite3 "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3" entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" "github.com/eolinker/goku-api-gateway/utils" ) //AddNode 新增节点信息 -func AddNode(clusterID int, nodeName, listenAddress, adminAddress, gatewayPath string, groupID int) (bool, map[string]interface{}, error) { +func AddNode(clusterID int, nodeName, listenAddress, adminAddress, gatewayPath string, groupID int) (int64, string, string, error) { now := time.Now().Format("20060102150405") nodeKey := utils.Md5(utils.GetRandomString(16) + now) - return console_sqlite3.AddNode(clusterID, nodeName, nodeKey, listenAddress, adminAddress, gatewayPath, groupID) + return nodeDao.AddNode(clusterID, nodeName, nodeKey, listenAddress, adminAddress, gatewayPath, groupID) } //EditNode 修改节点 -func EditNode(nodeName, listenAddress, adminAddress, gatewayPath string, nodeID, groupID int) (bool, string, error) { - return console_sqlite3.EditNode(nodeName, listenAddress, adminAddress, gatewayPath, nodeID, groupID) +func EditNode(nodeName, listenAddress, adminAddress, gatewayPath string, nodeID, groupID int) (string, error) { + return nodeDao.EditNode(nodeName, listenAddress, adminAddress, gatewayPath, nodeID, groupID) } //DeleteNode 删除节点 -func DeleteNode(nodeID int) (bool, string, error) { - return console_sqlite3.DeleteNode(nodeID) +func DeleteNode(nodeID int) (string, error) { + return nodeDao.DeleteNode(nodeID) } //GetNodeInfo 获取节点信息 -func GetNodeInfo(nodeID int) ( *entity.Node, error) { - node, e := console_sqlite3.GetNodeInfo(nodeID) +func GetNodeInfo(nodeID int) (*entity.Node, error) { + node, e := nodeDao.GetNodeInfo(nodeID) + if e != nil { + return nil, e + } ResetNodeStatus(node) - return node, e + return node, e } //GetNodeInfoByKey 获取节点信息 -func GetNodeInfoByKey(nodeKey string) ( *entity.Node, error) { - node, e := console_sqlite3.GetNodeByKey(nodeKey) +func GetNodeInfoByKey(nodeKey string) (*entity.Node, error) { + node, e := nodeDao.GetNodeByKey(nodeKey) + if e != nil { + return nil, e + } ResetNodeStatus(node) - return node, e + return node, e } + // GetNodeList 获取节点列表 -func GetNodeList(clusterID, groupID int, keyword string) (bool, []*entity.Node, error) { - b, nodes, e := console_sqlite3.GetNodeList(clusterID, groupID, keyword) +func GetNodeList(clusterID, groupID int, keyword string) ([]*entity.Node, error) { + nodes, e := nodeDao.GetNodeList(clusterID, groupID, keyword) + if e != nil { + return nil, e + } ResetNodeStatus(nodes...) - return b, nodes, e + return nodes, e } +//GetAllNode 获取所有节点 +func GetAllNode() ([]*entity.Node, error) { + nodes, e := nodeDao.GetNodeInfoAll() + if e != nil { + return nil, e + } + + return nodes, e +} //BatchDeleteNode 批量删除节点 -func BatchDeleteNode(nodeIDList string) (bool, string, error) { - flag, nodeIDList, err := console_sqlite3.GetAvaliableNodeListFromNodeList(nodeIDList, 0) - if !flag { - return false, err.Error(), err - } else if nodeIDList == "" { - return false, "230013", err +func BatchDeleteNode(nodeIDList string) (string, error) { + nodeIDList, err := nodeDao.GetAvaliableNodeListFromNodeList(nodeIDList, 0) + if err != nil { + return err.Error(), err + } + if nodeIDList == "" { + return "230013", err } - return console_sqlite3.BatchDeleteNode(nodeIDList) + return nodeDao.BatchDeleteNode(nodeIDList) } //BatchEditNodeGroup 批量修改节点分组 -func BatchEditNodeGroup(nodeIDList string, groupID int) (bool, string, error) { - return console_sqlite3.BatchEditNodeGroup(nodeIDList, groupID) +func BatchEditNodeGroup(nodeIDList string, groupID int) (string, error) { + return nodeDao.BatchEditNodeGroup(nodeIDList, groupID) } -// -////GetNodeIPList 获取节点IP列表 -//func GetNodeIPList() (bool, []map[string]interface{}, error) { -// return console_sqlite3.GetNodeIPList() -//} diff --git a/console/module/node/nodeGroup.go b/console/module/node/nodeGroup.go index 33de70e9..cb60cf41 100644 --- a/console/module/node/nodeGroup.go +++ b/console/module/node/nodeGroup.go @@ -1,40 +1,36 @@ package node -import ( - console_sqlite3 "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3" -) - //AddNodeGroup 新建节点分组 func AddNodeGroup(groupName string, clusterID int) (bool, interface{}, error) { - return console_sqlite3.AddNodeGroup(groupName, clusterID) + return nodeGroupDao.AddNodeGroup(groupName, clusterID) } //EditNodeGroup 修改节点分组信息 func EditNodeGroup(groupName string, groupID int) (bool, string, error) { - return console_sqlite3.EditNodeGroup(groupName, groupID) + return nodeGroupDao.EditNodeGroup(groupName, groupID) } //DeleteNodeGroup 删除节点分组 func DeleteNodeGroup(groupID int) (bool, string, error) { - return console_sqlite3.DeleteNodeGroup(groupID) + return nodeGroupDao.DeleteNodeGroup(groupID) } //GetNodeGroupInfo 获取节点分组信息 func GetNodeGroupInfo(groupID int) (bool, map[string]interface{}, error) { - return console_sqlite3.GetNodeGroupInfo(groupID) + return nodeGroupDao.GetNodeGroupInfo(groupID) } //GetNodeGroupList 获取节点分组列表 func GetNodeGroupList(clusterID int) (bool, []map[string]interface{}, error) { - return console_sqlite3.GetNodeGroupList(clusterID) + return nodeGroupDao.GetNodeGroupList(clusterID) } //CheckNodeGroupIsExist 检查节点分组是否存在 func CheckNodeGroupIsExist(groupID int) (bool, error) { - return console_sqlite3.CheckNodeGroupIsExist(groupID) + return nodeGroupDao.CheckNodeGroupIsExist(groupID) } //GetRunningNodeCount 获取分组内启动节点数量 func GetRunningNodeCount(groupID int) (bool, interface{}, error) { - return console_sqlite3.GetRunningNodeCount(groupID) + return nodeGroupDao.GetRunningNodeCount(groupID) } diff --git a/console/module/node/status.go b/console/module/node/status.go index 6a17e9bb..35c4d483 100644 --- a/console/module/node/status.go +++ b/console/module/node/status.go @@ -8,7 +8,7 @@ import ( ) //EXPIRE 心跳检测过期时间 -const EXPIRE = time.Second * 5 +const EXPIRE = time.Second * 10 var ( manager = _StatusManager{ @@ -25,11 +25,16 @@ type _StatusManager struct { func (m *_StatusManager) refresh(id string) { t := time.Now() + //heartBeat, err := nodeDao.GetHeartBeatTime(id) + //if err == nil { + // t = heartBeat + //} m.locker.Lock() m.lastHeartBeat[id] = t m.locker.Unlock() + nodeDao.SetHeartBeatTime(id, time.Now()) } func (m *_StatusManager) stop(id string) { @@ -48,7 +53,7 @@ func (m *_StatusManager) get(id string) (time.Time, bool) { } type _InstanceLocker struct { - locker sync.RWMutex + locker sync.RWMutex instances map[string]bool } @@ -58,22 +63,22 @@ func newInstanceLocker() *_InstanceLocker { instances: make(map[string]bool), } } -func (l * _InstanceLocker)IsLock(key string)bool { +func (l *_InstanceLocker) IsLock(key string) bool { l.locker.RLock() - locked :=l.instances[key] + locked := l.instances[key] l.locker.RUnlock() return locked } -func (l * _InstanceLocker)Lock(key string)bool{ +func (l *_InstanceLocker) Lock(key string) bool { - locked :=l.IsLock(key) - if locked{ + locked := l.IsLock(key) + if locked { return false } l.locker.Lock() - locked =l.instances[key] - if locked{ + locked = l.instances[key] + if locked { l.locker.Unlock() return false } @@ -81,7 +86,7 @@ func (l * _InstanceLocker)Lock(key string)bool{ l.locker.Unlock() return true } -func (l * _InstanceLocker)UnLock(key string){ +func (l *_InstanceLocker) UnLock(key string) { l.locker.Lock() l.instances[key] = false @@ -90,21 +95,29 @@ func (l * _InstanceLocker)UnLock(key string){ //Refresh refresh -func Refresh( instance string) { +func Refresh(instance string) { manager.refresh(instance) } +func GetLastHeartTime(instance string) (time.Time, bool) { + return manager.get(instance) +} + //IsLive 通过ip和端口获取当前节点在线状态 -func IsLive( instance string) bool { +func IsLive(instance string) bool { + + if instanceLocker.IsLock(instance) { + return true + } t, has := manager.get(instance) if !has { return false } - - if time.Now().Sub(t) > EXPIRE { + now := time.Now() + if now.Sub(t) > EXPIRE { return false } return true @@ -113,23 +126,23 @@ func IsLive( instance string) bool { //ResetNodeStatus 重置节点状态 func ResetNodeStatus(nodes ...*entity.Node) { for _, node := range nodes { - - if instanceLocker.IsLock(node.NodeKey) || IsLive(node.NodeKey) { + if instanceLocker.IsLock(node.NodeKey) || IsLive(node.NodeKey) { node.NodeStatus = 1 } else { - node.NodeStatus = 0 + if node.NodeStatus == 1 { + node.NodeStatus = 2 + } else { + node.NodeStatus = 0 + } } } } -func Lock(key string)bool{ +func Lock(key string) bool { return instanceLocker.Lock(key) } -func UnLock(key string) { +func UnLock(key string) { instanceLocker.UnLock(key) Refresh(key) -} -func IsLock(key string)bool{ - return instanceLocker.Lock(key) -} \ No newline at end of file +} diff --git a/console/module/plugin/plugin.go b/console/module/plugin/plugin.go index 9172b195..ac462c18 100644 --- a/console/module/plugin/plugin.go +++ b/console/module/plugin/plugin.go @@ -1,77 +1,84 @@ package plugin import ( - console_sqlite3 "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3" + "github.com/eolinker/goku-api-gateway/common/pdao" + "github.com/eolinker/goku-api-gateway/server/dao" entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" ) +var ( + pluginDao dao.PluginDao +) +func init() { + pdao.Need(&pluginDao) +} //GetPluginInfo 获取插件配置信息 func GetPluginInfo(pluginName string) (bool, *entity.Plugin, error) { - return console_sqlite3.GetPluginInfo(pluginName) + return pluginDao.GetPluginInfo(pluginName) } //GetPluginList 获取插件列表 func GetPluginList(keyword string, condition int) (bool, []*entity.Plugin, error) { - return console_sqlite3.GetPluginList(keyword, condition) + return pluginDao.GetPluginList(keyword, condition) } //AddPlugin 新增插件信息 func AddPlugin(pluginName, pluginConfig, pluginDesc, version string, pluginPriority, isStop, pluginType int) (bool, string, error) { - return console_sqlite3.AddPlugin(pluginName, pluginConfig, pluginDesc, version, pluginPriority, isStop, pluginType) + return pluginDao.AddPlugin(pluginName, pluginConfig, pluginDesc, version, pluginPriority, isStop, pluginType) } //EditPlugin 修改插件信息 func EditPlugin(pluginName, pluginConfig, pluginDesc, version string, pluginPriority, isStop, pluginType int) (bool, string, error) { - return console_sqlite3.EditPlugin(pluginName, pluginConfig, pluginDesc, version, pluginPriority, isStop, pluginType) + return pluginDao.EditPlugin(pluginName, pluginConfig, pluginDesc, version, pluginPriority, isStop, pluginType) } //DeletePlugin 删除插件信息 func DeletePlugin(pluginName string) (bool, string, error) { - return console_sqlite3.DeletePlugin(pluginName) + return pluginDao.DeletePlugin(pluginName) } //CheckIndexIsExist 判断插件ID是否存在 func CheckIndexIsExist(pluginName string, pluginPriority int) (bool, error) { - return console_sqlite3.CheckIndexIsExist(pluginName, pluginPriority) + return pluginDao.CheckIndexIsExist(pluginName, pluginPriority) } //GetPluginConfig 获取插件配置及插件信息 func GetPluginConfig(pluginName string) (bool, string, error) { - return console_sqlite3.GetPluginConfig(pluginName) + return pluginDao.GetPluginConfig(pluginName) } //CheckNameIsExist 检查插件名称是否存在 func CheckNameIsExist(pluginName string) (bool, error) { - return console_sqlite3.CheckNameIsExist(pluginName) + return pluginDao.CheckNameIsExist(pluginName) } //EditPluginStatus 修改插件开启状态 func EditPluginStatus(pluginName string, pluginStatus int) (bool, error) { - flag, err := console_sqlite3.EditPluginStatus(pluginName, pluginStatus) + flag, err := pluginDao.EditPluginStatus(pluginName, pluginStatus) return flag, err } //GetPluginListByPluginType 获取不同类型的插件列表 func GetPluginListByPluginType(pluginType int) (bool, []map[string]interface{}, error) { - return console_sqlite3.GetPluginListByPluginType(pluginType) + return pluginDao.GetPluginListByPluginType(pluginType) } //BatchStopPlugin 批量关闭插件 func BatchStopPlugin(pluginNameList string) (bool, string, error) { - flag, result, err := console_sqlite3.BatchStopPlugin(pluginNameList) + flag, result, err := pluginDao.BatchStopPlugin(pluginNameList) return flag, result, err } //BatchStartPlugin 批量关闭插件 func BatchStartPlugin(pluginNameList string) (bool, string, error) { - flag, result, err := console_sqlite3.BatchStartPlugin(pluginNameList) + flag, result, err := pluginDao.BatchStartPlugin(pluginNameList) return flag, result, err } //EditPluginCheckStatus 更新插件检测状态 func EditPluginCheckStatus(pluginName string, isCheck int) (bool, string, error) { - return console_sqlite3.EditPluginCheckStatus(pluginName, isCheck) + return pluginDao.EditPluginCheckStatus(pluginName, isCheck) } diff --git a/console/module/project/project.go b/console/module/project/project.go index c7363da9..ef655610 100644 --- a/console/module/project/project.go +++ b/console/module/project/project.go @@ -1,49 +1,56 @@ package project import ( - console_sqlite3 "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3" + "github.com/eolinker/goku-api-gateway/common/pdao" + "github.com/eolinker/goku-api-gateway/server/dao" entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" ) +var ( + projectDao dao.ProjectDao +) +func init() { + pdao.Need(&projectDao) +} //AddProject 新建项目 func AddProject(projectName string) (bool, interface{}, error) { - return console_sqlite3.AddProject(projectName) + return projectDao.AddProject(projectName) } //EditProject 修改项目信息 func EditProject(projectName string, projectID int) (bool, string, error) { - return console_sqlite3.EditProject(projectName, projectID) + return projectDao.EditProject(projectName, projectID) } //DeleteProject 修改项目信息 func DeleteProject(projectID int) (bool, string, error) { - flag, result, err := console_sqlite3.DeleteProject(projectID) + flag, result, err := projectDao.DeleteProject(projectID) return flag, result, err } //BatchDeleteProject 批量删除项目 func BatchDeleteProject(projectIDList string) (bool, string, error) { - flag, result, err := console_sqlite3.BatchDeleteProject(projectIDList) + flag, result, err := projectDao.BatchDeleteProject(projectIDList) return flag, result, err } //GetProjectInfo 获取项目信息 func GetProjectInfo(projectID int) (bool, entity.Project, error) { - return console_sqlite3.GetProjectInfo(projectID) + return projectDao.GetProjectInfo(projectID) } //GetProjectList 获取项目列表 func GetProjectList(keyword string) (bool, []*entity.Project, error) { - return console_sqlite3.GetProjectList(keyword) + return projectDao.GetProjectList(keyword) } //CheckProjectIsExist 检查项目是否存在 func CheckProjectIsExist(projectID int) (bool, error) { - return console_sqlite3.CheckProjectIsExist(projectID) + return projectDao.CheckProjectIsExist(projectID) } //GetAPIListFromProjectNotInStrategy 获取项目列表中没有被策略组绑定的接口 func GetAPIListFromProjectNotInStrategy() (bool, []map[string]interface{}, error) { - return console_sqlite3.GetAPIListFromProjectNotInStrategy() + return projectDao.GetAPIListFromProjectNotInStrategy() } diff --git a/console/module/service/module.go b/console/module/service/module.go index f2c26458..fb00ad87 100644 --- a/console/module/service/module.go +++ b/console/module/service/module.go @@ -2,17 +2,24 @@ package service import ( "fmt" + "github.com/eolinker/goku-api-gateway/common/pdao" + "github.com/eolinker/goku-api-gateway/server/dao" - dao_service2 "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3/dao-service" driver2 "github.com/eolinker/goku-api-gateway/server/driver" entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" ) const _TableName = "goku_service_config" +var ( + serviceDao dao.ServiceDao +) -//Add 新增服务发现 +func init() { + pdao.Need(&serviceDao) +} +//RegisterDao 新增服务发现 func Add(param *AddParam) error { - err := dao_service2.Add(param.Name, param.Driver, param.Desc, param.Config, param.ClusterConfig, false, param.HealthCheck, param.HealthCheckPath, param.HealthCheckCode, param.HealthCheckPeriod, param.HealthCheckTimeOut) + err := serviceDao.Add(param.Name, param.Driver, param.Desc, param.Config, param.ClusterConfig, false, param.HealthCheck, param.HealthCheckPath, param.HealthCheckCode, param.HealthCheckPeriod, param.HealthCheckTimeOut) return err } @@ -20,7 +27,7 @@ func Add(param *AddParam) error { //Save 保存服务发现 func Save(param *AddParam) error { - v, e := dao_service2.Get(param.Name) + v, e := serviceDao.Get(param.Name) if e != nil { return e } @@ -29,14 +36,14 @@ func Save(param *AddParam) error { return fmt.Errorf("not allowed change dirver from %s to %s for service", v.Driver, param.Driver) } - err := dao_service2.Save(param.Name, param.Desc, param.Config, param.ClusterConfig, param.HealthCheck, param.HealthCheckPath, param.HealthCheckCode, param.HealthCheckPeriod, param.HealthCheckTimeOut) + err := serviceDao.Save(param.Name, param.Desc, param.Config, param.ClusterConfig, param.HealthCheck, param.HealthCheckPath, param.HealthCheckCode, param.HealthCheckPeriod, param.HealthCheckTimeOut) return err } //Get 通过名称获取服务发现信息 func Get(name string) (*Info, error) { - v, err := dao_service2.Get(name) + v, err := serviceDao.Get(name) if err != nil { return nil, err } @@ -61,12 +68,12 @@ func Delete(names []string) error { } } - return dao_service2.Delete(names) + return serviceDao.Delete(names) } //SetDefaut 设置默认服务发现 func SetDefaut(name string) error { - return dao_service2.SetDefault(name) + return serviceDao.SetDefault(name) } func tran(v *entity.Service) *Service { s := &Service{ @@ -94,7 +101,7 @@ func tran(v *entity.Service) *Service { //List 获取服务发现列表 func List(keyword string) ([]*Service, error) { - vs, e := dao_service2.List(keyword) + vs, e := serviceDao.List(keyword) if e != nil { return nil, e } @@ -110,7 +117,7 @@ func List(keyword string) ([]*Service, error) { //SimpleList 获取简易服务发现列表 func SimpleList() ([]*Simple, string, error) { - vs, e := dao_service2.List("") + vs, e := serviceDao.List("") if e != nil { return nil, "", e } diff --git a/console/module/service/service.go b/console/module/service/service.go index 7579c515..9cb8b1a1 100644 --- a/console/module/service/service.go +++ b/console/module/service/service.go @@ -33,7 +33,7 @@ type Info struct { HealthCheckTimeOut int `json:"healthCheckTimeOut"` } -//Decode 解码 +//Read 解码 func (i *Info) Decode() { json.Unmarshal([]byte(i.ClusterConfig), &i.ClusterConfigObj) } diff --git a/console/module/strategy/dao.go b/console/module/strategy/dao.go new file mode 100644 index 00000000..ea0b8610 --- /dev/null +++ b/console/module/strategy/dao.go @@ -0,0 +1,17 @@ +package strategy + +import ( + "github.com/eolinker/goku-api-gateway/common/pdao" + "github.com/eolinker/goku-api-gateway/server/dao" +) + +var( + strategyDao dao.StrategyDao + strategyGroupDao dao.StrategyGroupDao + strategyPluginDao dao.StrategyPluginDao + +) + +func init() { + pdao.Need(&strategyDao,&strategyGroupDao,&strategyPluginDao) +} \ No newline at end of file diff --git a/console/module/strategy/strategy.go b/console/module/strategy/strategy.go index 4c8b99f0..2169c338 100644 --- a/console/module/strategy/strategy.go +++ b/console/module/strategy/strategy.go @@ -3,95 +3,88 @@ package strategy import ( "errors" - console_sqlite3 "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3" - entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" ) //AddStrategy 新增策略组 -func AddStrategy(strategyName string, groupID int) (bool, string, error) { - flag := console_sqlite3.CheckIsOpenGroup(groupID) +func AddStrategy(strategyName string, groupID, userID int) (bool, string, error) { + flag := strategyGroupDao.CheckIsOpenGroup(groupID) if flag { return false, "[ERROR]The group is an open group", errors.New("[ERROR]The group is an open group") } - flag, result, err := console_sqlite3.AddStrategy(strategyName, groupID) + flag, result, err := strategyDao.AddStrategy(strategyName, groupID, userID) return flag, result, err } //EditStrategy 修改策略组信息 -func EditStrategy(strategyID, strategyName string, groupID int) (bool, string, error) { - return console_sqlite3.EditStrategy(strategyID, strategyName, groupID) +func EditStrategy(strategyID, strategyName string, groupID, userID int) (bool, string, error) { + return strategyDao.EditStrategy(strategyID, strategyName, groupID, userID) } // DeleteStrategy 删除策略组 func DeleteStrategy(strategyID string) (bool, string, error) { - flag := console_sqlite3.CheckIsOpenStrategy(strategyID) + flag := strategyDao.CheckIsOpenStrategy(strategyID) if flag { return false, "[ERROR]The strategy is an open strategy", errors.New("[ERROR]The strategy is an open strategy") } - flag, result, err := console_sqlite3.DeleteStrategy(strategyID) + flag, result, err := strategyDao.DeleteStrategy(strategyID) return flag, result, err } // GetOpenStrategy 获取策略组列表 func GetOpenStrategy() (bool, *entity.Strategy, error) { - return console_sqlite3.GetOpenStrategy() + return strategyDao.GetOpenStrategy() } // GetStrategyList 获取策略组列表 -func GetStrategyList(groupID int, keyword string, condition int) (bool, []*entity.Strategy, error) { - return console_sqlite3.GetStrategyList(groupID, keyword, condition) +func GetStrategyList(groupID int, keyword string, condition, page, pageSize int) (bool, []*entity.Strategy, int, error) { + return strategyDao.GetStrategyList(groupID, keyword, condition, page, pageSize) } // GetStrategyInfo 获取策略组信息 func GetStrategyInfo(strategyID string) (bool, *entity.Strategy, error) { - return console_sqlite3.GetStrategyInfo(strategyID) + return strategyDao.GetStrategyInfo(strategyID) } // CheckStrategyIsExist 检查策略组ID是否存在 func CheckStrategyIsExist(strategyID string) (bool, error) { - return console_sqlite3.CheckStrategyIsExist(strategyID) + return strategyDao.CheckStrategyIsExist(strategyID) } // BatchEditStrategyGroup 批量修改策略组分组 func BatchEditStrategyGroup(strategyIDList string, groupID int) (bool, string, error) { - return console_sqlite3.BatchEditStrategyGroup(strategyIDList, groupID) + return strategyDao.BatchEditStrategyGroup(strategyIDList, groupID) } // BatchDeleteStrategy 批量修改策略组分组 func BatchDeleteStrategy(strategyIDList string) (bool, string, error) { - flag, result, err := console_sqlite3.BatchDeleteStrategy(strategyIDList) + flag, result, err := strategyDao.BatchDeleteStrategy(strategyIDList) return flag, result, err } -//CheckIsOpenStrategy 检查是否是开放策略 -func CheckIsOpenStrategy(strategyID string) bool { - return console_sqlite3.CheckIsOpenStrategy(strategyID) -} - //BatchUpdateStrategyEnableStatus 更新策略启用状态 func BatchUpdateStrategyEnableStatus(strategyIDList string, enableStatus int) (bool, string, error) { - flag, result, err := console_sqlite3.BatchUpdateStrategyEnableStatus(strategyIDList, enableStatus) + flag, result, err := strategyDao.BatchUpdateStrategyEnableStatus(strategyIDList, enableStatus) return flag, result, err } // GetBalanceListInStrategy 获取在策略中的负载列表 func GetBalanceListInStrategy(strategyID string, balanceType int) (bool, []string, error) { - return console_sqlite3.GetBalanceListInStrategy(strategyID, balanceType) + return strategyDao.GetBalanceListInStrategy(strategyID, balanceType) } // CopyStrategy 复制策略 func CopyStrategy(strategyID string, newStrategyID string, userID int) (string, error) { - result, err := console_sqlite3.CopyStrategy(strategyID, newStrategyID, userID) + result, err := strategyDao.CopyStrategy(strategyID, newStrategyID, userID) return result, err } //GetStrategyIDList 获取策略ID列表 func GetStrategyIDList(groupID int, keyword string, condition int) (bool, []string, error) { - return console_sqlite3.GetStrategyIDList(groupID, keyword, condition) + return strategyDao.GetStrategyIDList(groupID, keyword, condition) } diff --git a/console/module/strategy/strategyGroup.go b/console/module/strategy/strategyGroup.go index b0be5e3b..d2e04bdc 100644 --- a/console/module/strategy/strategyGroup.go +++ b/console/module/strategy/strategyGroup.go @@ -2,37 +2,35 @@ package strategy import ( "errors" - - console_sqlite3 "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3" ) //AddStrategyGroup 新建策略组分组 func AddStrategyGroup(groupName string) (bool, interface{}, error) { - return console_sqlite3.AddStrategyGroup(groupName) + return strategyGroupDao.AddStrategyGroup(groupName) } //EditStrategyGroup 修改策略组分组 func EditStrategyGroup(groupName string, groupID int) (bool, string, error) { - return console_sqlite3.EditStrategyGroup(groupName, groupID) + return strategyGroupDao.EditStrategyGroup(groupName, groupID) } // DeleteStrategyGroup 删除策略组分组 func DeleteStrategyGroup(groupID int) (bool, string, error) { - flag := console_sqlite3.CheckIsOpenGroup(groupID) + flag := strategyGroupDao.CheckIsOpenGroup(groupID) if flag { return false, "[ERROR]The group is an open group", errors.New("[ERROR]The group is an open group") } - flag, result, err := console_sqlite3.DeleteStrategyGroup(groupID) + flag, result, err := strategyGroupDao.DeleteStrategyGroup(groupID) return flag, result, err } //GetStrategyGroupList 获取策略组分组列表 func GetStrategyGroupList() (bool, []map[string]interface{}, error) { - return console_sqlite3.GetStrategyGroupList() + return strategyGroupDao.GetStrategyGroupList() } //CheckIsOpenGroup 判断是否是开放分组 func CheckIsOpenGroup(groupID int) bool { - return console_sqlite3.CheckIsOpenGroup(groupID) + return strategyGroupDao.CheckIsOpenGroup(groupID) } diff --git a/console/module/strategy/strategyPlugin.go b/console/module/strategy/strategyPlugin.go index 3410ece0..84118046 100644 --- a/console/module/strategy/strategyPlugin.go +++ b/console/module/strategy/strategyPlugin.go @@ -1,19 +1,15 @@ package strategy -import ( - console_sqlite3 "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3" -) - //AddPluginToStrategy 新增策略组插件 func AddPluginToStrategy(pluginName, config, strategyID string) (bool, interface{}, error) { - flag, result, err := console_sqlite3.AddPluginToStrategy(pluginName, config, strategyID) + flag, result, err := strategyPluginDao.AddPluginToStrategy(pluginName, config, strategyID) return flag, result, err } //EditStrategyPluginConfig 新增策略组插件配置 func EditStrategyPluginConfig(pluginName, config, strategyID string) (bool, string, error) { - flag, result, err := console_sqlite3.EditStrategyPluginConfig(pluginName, config, strategyID) + flag, result, err := strategyPluginDao.EditStrategyPluginConfig(pluginName, config, strategyID) return flag, result, err } @@ -21,39 +17,39 @@ func EditStrategyPluginConfig(pluginName, config, strategyID string) (bool, stri //BatchEditStrategyPluginStatus 批量修改策略组插件状态 func BatchEditStrategyPluginStatus(connIDList, strategyID string, pluginStatus int) (bool, string, error) { - flag, result, err := console_sqlite3.BatchEditStrategyPluginStatus(connIDList, strategyID, pluginStatus) + flag, result, err := strategyPluginDao.BatchEditStrategyPluginStatus(connIDList, strategyID, pluginStatus) return flag, result, err } //BatchDeleteStrategyPlugin 批量删除策略组插件 func BatchDeleteStrategyPlugin(connIDList, strategyID string) (bool, string, error) { - flag, result, err := console_sqlite3.BatchDeleteStrategyPlugin(connIDList, strategyID) + flag, result, err := strategyPluginDao.BatchDeleteStrategyPlugin(connIDList, strategyID) return flag, result, err } // GetStrategyPluginList 获取策略插件列表 func GetStrategyPluginList(strategyID, keyword string, condition int) (bool, []map[string]interface{}, error) { - return console_sqlite3.GetStrategyPluginList(strategyID, keyword, condition) + return strategyPluginDao.GetStrategyPluginList(strategyID, keyword, condition) } //GetStrategyPluginConfig 通过策略组ID获取配置信息 func GetStrategyPluginConfig(strategyID, pluginName string) (bool, string, error) { - return console_sqlite3.GetStrategyPluginConfig(strategyID, pluginName) + return strategyPluginDao.GetStrategyPluginConfig(strategyID, pluginName) } //CheckPluginIsExistInStrategy 检查策略组是否绑定插件 func CheckPluginIsExistInStrategy(strategyID, pluginName string) (bool, error) { - return console_sqlite3.CheckPluginIsExistInStrategy(strategyID, pluginName) + return strategyPluginDao.CheckPluginIsExistInStrategy(strategyID, pluginName) } //GetStrategyPluginStatus 检查策略组插件是否开启 func GetStrategyPluginStatus(strategyID, pluginName string) (bool, error) { - return console_sqlite3.GetStrategyPluginStatus(strategyID, pluginName) + return strategyPluginDao.GetStrategyPluginStatus(strategyID, pluginName) } //GetConnIDFromStrategyPlugin 获取Connid func GetConnIDFromStrategyPlugin(pluginName, strategyID string) (bool, int, error) { - return console_sqlite3.GetConnIDFromStrategyPlugin(pluginName, strategyID) + return strategyPluginDao.GetConnIDFromStrategyPlugin(pluginName, strategyID) } diff --git a/console/module/updater/check.go b/console/module/updater/check.go index 670c0443..dd787024 100644 --- a/console/module/updater/check.go +++ b/console/module/updater/check.go @@ -1,15 +1,22 @@ package updater import ( - "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3/updater" + "github.com/eolinker/goku-api-gateway/common/pdao" + "github.com/eolinker/goku-api-gateway/server/dao" +) +var ( + updaterDao dao.UpdaterDao ) +func init() { + pdao.Need(&updaterDao) +} //IsTableExist 检查table是否存在 func IsTableExist(name string) bool { - return updater.IsTableExist(name) + return updaterDao.IsTableExist(name) } //IsColumnExist 检查列是否存在 func IsColumnExist(name string, column string) bool { - return updater.IsColumnExist(name, column) + return updaterDao.IsColumnExist(name, column) } diff --git a/console/module/versionConfig/load.go b/console/module/versionConfig/load.go index 91490416..64d18062 100644 --- a/console/module/versionConfig/load.go +++ b/console/module/versionConfig/load.go @@ -1,67 +1,88 @@ package versionConfig import ( - "context" "sync" "time" log "github.com/eolinker/goku-api-gateway/goku-log" - console_sqlite3 "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3" - - "github.com/eolinker/goku-api-gateway/common/telegraph" - entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" "github.com/eolinker/goku-api-gateway/config" ) -type versionConfig struct { - config map[string]*telegraph.Telegraph - lock sync.RWMutex -} +type ConfigChangeEventFunc func(conf map[string]*config.GokuConfig) var ( - vc *versionConfig + eventCallback []ConfigChangeEventFunc + lock sync.RWMutex + + lastConf = make(map[string]*config.GokuConfig) ) -func init() { - vc = &versionConfig{ - config: make(map[string]*telegraph.Telegraph), - lock: sync.RWMutex{}, +func AddCallback(f ConfigChangeEventFunc) { + lock.Lock() + eventCallback = append(eventCallback, f) + lock.Unlock() +} +func call() { + lock.RLock() + es := eventCallback + conf := lastConf + lock.RUnlock() + + for _, f := range es { + f(conf) } } -//InitVersionConfig 初始化版本配置 +//type versionConfig struct { +// config map[string]*telegraph.Telegraph +// lock sync.RWMutex +//} +// +//var ( +// vc *versionConfig +//) + +//func init() { +// vc = &versionConfig{ +// config: make(map[string]*telegraph.Telegraph), +// lock: sync.RWMutex{}, +// } +//} + +////InitVersionConfig 初始化版本配置 func InitVersionConfig() { load() } -func (c *versionConfig) GetV(cluster string) *telegraph.Telegraph { - c.lock.RLock() - v, ok := c.config[cluster] - c.lock.RUnlock() - if !ok { - c.lock.Lock() - v, ok = c.config[cluster] - if !ok { - v = telegraph.NewTelegraph("", nil) - c.config[cluster] = v - } - c.lock.Unlock() - } - return v -} -func (c *versionConfig) getConfig(ctx context.Context, cluster string, version string) (*config.GokuConfig, error) { - - v := c.GetV(cluster) - r, err := v.GetWidthContext(ctx, version) - if err != nil { - return nil, err - } - return r.(*config.GokuConfig), err - -} +//func (c *versionConfig) GetV(cluster string) *telegraph.Telegraph { +// c.lock.RLock() +// v, ok := c.config[cluster] +// c.lock.RUnlock() +// if !ok { +// c.lock.Lock() +// v, ok = c.config[cluster] +// if !ok { +// v = telegraph.NewTelegraph("", nil) +// c.config[cluster] = v +// } +// c.lock.Unlock() +// } +// return v +//} +//func (c *versionConfig) getConfig(ctx context.Context, cluster string, version string) (*config.GokuConfig, error) { +// +// v := c.GetV(cluster) +// +// r, err := v.GetWidthContext(ctx, version) +// if err != nil { +// return nil, err +// } +// return r.(*config.GokuConfig), err +// +//} //func (c *versionConfig) getVersion() string { // c.lock.RLock() @@ -69,12 +90,25 @@ func (c *versionConfig) getConfig(ctx context.Context, cluster string, version s // return c.version //} -//GetVersionConfig 获取版本配置 -func GetVersionConfig(ctx context.Context, cluster, version string) (*config.GokuConfig, error) { - return vc.getConfig(ctx, cluster, version) +////GetVersionConfig 获取版本配置 +//func GetVersionConfig(ctx context.Context, cluster, version string) (*config.GokuConfig, error) { +// return vc.getConfig(ctx, cluster, version) +//} + +func GetConfig(cluster string) (*config.GokuConfig, error) { + + lock.RLock() + c, has := lastConf[cluster] + lock.RUnlock() + if !has { + return &config.GokuConfig{}, nil + //return nil, errors.New("no pub config") + } + return c, nil + } -func (c *versionConfig) reset(clusters []*entity.Cluster, gokuConfig *config.GokuConfig, balanceConfig map[string]map[string]*config.BalanceConfig, discoverConfig map[string]map[string]*config.DiscoverConfig) { +func reset(clusters []*entity.Cluster, gokuConfig *config.GokuConfig, balanceConfig map[string]map[string]*config.BalanceConfig, discoverConfig map[string]map[string]*config.DiscoverConfig) { newConfig := make(map[string]*config.GokuConfig) now := time.Now().Format("20060102150405") for _, cl := range clusters { @@ -86,6 +120,12 @@ func (c *versionConfig) reset(clusters []*entity.Cluster, gokuConfig *config.Gok if v, ok := discoverConfig[cl.Name]; ok { df = v } + var redisConfig interface{} = nil + if config, ok := gokuConfig.RedisConfig[cl.Name]; ok { + redisConfig = config + } else { + redisConfig = cl.Redis + } configByte := &config.GokuConfig{ Version: now, Cluster: cl.Name, @@ -99,38 +139,31 @@ func (c *versionConfig) reset(clusters []*entity.Cluster, gokuConfig *config.Gok Log: gokuConfig.Log, AccessLog: gokuConfig.AccessLog, MonitorModules: gokuConfig.MonitorModules, + Routers: gokuConfig.Routers, + GatewayBasicInfo: gokuConfig.GatewayBasicInfo, + ExtendsConfig: map[string]interface{}{ + "redis": redisConfig, + }, } newConfig[cl.Name] = configByte } - c.lock.Lock() + lock.Lock() + + lastConf = newConfig + lock.Unlock() + call() - for name, cf := range vc.config { - if _, has := newConfig[name]; !has { - cf.Close() - delete(vc.config, name) - } - } - for name, cs := range newConfig { - cf, has := vc.config[name] - if !has { - cf = telegraph.NewTelegraph(now, cs) - vc.config[name] = cf - } else { - cf.Set(now, cs) - } - } - c.lock.Unlock() } func load() { - clusters, err := console_sqlite3.GetClusters() + clusters, err := clusterDao.GetClusters() if err != nil { return } - cf, bf, df, err := console_sqlite3.GetVersionConfig() + cf, bf, df, err := versionDao.GetVersionConfig() if err != nil { log.Warn("load config error:", err) return } - vc.reset(clusters, cf, bf, df) + reset(clusters, cf, bf, df) } diff --git a/console/module/versionConfig/version.go b/console/module/versionConfig/version.go index 642dc865..671fc6fc 100644 --- a/console/module/versionConfig/version.go +++ b/console/module/versionConfig/version.go @@ -3,41 +3,54 @@ package versionConfig import ( "encoding/json" - "github.com/eolinker/goku-api-gateway/ksitigarbha" + "github.com/eolinker/goku-api-gateway/common/pdao" + "github.com/eolinker/goku-api-gateway/server/dao" + entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" - console_sqlite3 "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3" - dao_version_config2 "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3/dao-version-config" + "github.com/eolinker/goku-api-gateway/ksitigarbha" "github.com/eolinker/goku-api-gateway/config" ) -var authNames = map[string]string{ - "Oauth2": "goku-oauth2_auth", - "Apikey": "goku-apikey_auth", - "Basic": "goku-basic_auth", - "Jwt": "goku-jwt_auth", +var ( + versionDao dao.VersionDao + versionConfigDao dao.VersionConfigDao + clusterDao dao.ClusterDao + authNames = map[string]string{ + "Oauth2": "goku-oauth2_auth", + "Apikey": "goku-apikey_auth", + "Basic": "goku-basic_auth", + "Jwt": "goku-jwt_auth", + } +) + +func init() { + pdao.Need(&versionConfigDao, &versionDao, &clusterDao) } //GetVersionList 获取版本列表 func GetVersionList(keyword string) ([]config.VersionConfig, error) { - return console_sqlite3.GetVersionList(keyword) + return versionDao.GetVersionList(keyword) } //AddVersionConfig 新增版本配置 -func AddVersionConfig(name, version, remark, now string) (int, error) { +func AddVersionConfig(name, version, remark, now string, userID int) (int, error) { config, balanceConfig, discoverConfig := buildVersionConfig(version) - return console_sqlite3.AddVersionConfig(name, version, remark, config, balanceConfig, discoverConfig, now) + return versionDao.AddVersionConfig(name, version, remark, config, balanceConfig, discoverConfig, now, userID) +} +func EditVersionBasicConfig(name, version, remark string, userID, versionID int) error { + return versionDao.EditVersionBasicConfig(name, version, remark, userID, versionID) } //BatchDeleteVersionConfig 批量删除版本配置 func BatchDeleteVersionConfig(ids []int) error { - publishID := console_sqlite3.GetPublishVersionID() - return console_sqlite3.BatchDeleteVersionConfig(ids, publishID) + publishID := versionDao.GetPublishVersionID() + return versionDao.BatchDeleteVersionConfig(ids, publishID) } //PublishVersion 发布版本 -func PublishVersion(id int, now string) error { - err := console_sqlite3.PublishVersion(id, now) +func PublishVersion(id, userID int, now string) error { + err := versionDao.PublishVersion(id, userID, now) if err == nil { load() } @@ -46,44 +59,55 @@ func PublishVersion(id int, now string) error { //GetVersionConfigCount 获取版本配置数量 func GetVersionConfigCount() int { - return console_sqlite3.GetVersionConfigCount() + return versionDao.GetVersionConfigCount() +} + +func getRedisConfig(clusters []*entity.Cluster) map[string]interface{} { + redisConfig := map[string]interface{}{} + for _, c := range clusters { + redisConfig[c.Name] = c.Redis + } + return redisConfig } func buildVersionConfig(v string) (string, string, string) { - clusters, err := console_sqlite3.GetClusters() + clusters, err := clusterDao.GetClusters() if err != nil { return "", "", "" } - discoverMap, err := dao_version_config2.GetDiscoverConfig(clusters) + discoverMap, err := versionConfigDao.GetDiscoverConfig(clusters) if err != nil { return "", "", "" } - balanceMap, err := dao_version_config2.GetBalances(clusters) + balanceMap, err := versionConfigDao.GetBalances(clusters) if err != nil { return "", "", "" } - openStrategy, strategyConfigs, err := dao_version_config2.GetStrategyConfig() + openStrategy, strategyConfigs, err := versionConfigDao.GetStrategyConfig() if err != nil { return "", "", "" } - apiContents, err := dao_version_config2.GetAPIContent() + apiContents, err := versionConfigDao.GetAPIContent() if err != nil { return "", "", "" } - plugins, err := dao_version_config2.GetGlobalPlugin() + plugins, err := versionConfigDao.GetGlobalPlugin() if err != nil { return "", "", "" } - logCf, accessCf, err := dao_version_config2.GetLogInfo() + logCf, accessCf, err := versionConfigDao.GetLogInfo() if err != nil { return "", "", "" } + + g, _ := versionConfigDao.GetGatewayBasicConfig() + routers, _ := versionConfigDao.GetRouterRules(1) ms := make(map[string]string) - modules, _ := dao_version_config2.GetMonitorModules(1, false) + modules, _ := versionConfigDao.GetMonitorModules(1, false) if modules != nil { for key, config := range modules { - module ,has:= ksitigarbha.GetMonitorModuleModel(key) - if has{ + module, has := ksitigarbha.GetMonitorModuleModel(key) + if has { ms[module.GetName()] = config } } @@ -91,7 +115,7 @@ func buildVersionConfig(v string) (string, string, string) { c := config.GokuConfig{ Version: v, - Plugins: plugins, + Plugins: *plugins, APIS: apiContents, Strategy: strategyConfigs, AnonymousStrategyID: openStrategy, @@ -99,6 +123,9 @@ func buildVersionConfig(v string) (string, string, string) { Log: logCf, AccessLog: accessCf, MonitorModules: ms, + Routers: routers, + GatewayBasicInfo: g, + RedisConfig: getRedisConfig(clusters), } cByte, err := json.Marshal(c) diff --git a/diting/diting.go b/diting/diting.go index e94039c7..dcef19d0 100644 --- a/diting/diting.go +++ b/diting/diting.go @@ -6,25 +6,21 @@ type ConfigHandleFunc func() interface{} //Constructor constructor type Constructor interface { Namespace() string - Create(conf string) (Factory,error) + Create(conf string) (Factory, error) Close() - } //Factory factory type Factory interface { - - NewCounter(opt *CounterOpts) (Counter,error) + NewCounter(opt *CounterOpts) (Counter, error) //NewSummary(opt *SummaryOpts) (Summary,error) - NewHistogram(opt *HistogramOpts) (Histogram,error) - NewGauge(opt *GaugeOpts) (Gauge,error) - + NewHistogram(opt *HistogramOpts) (Histogram, error) + NewGauge(opt *GaugeOpts) (Gauge, error) } //Factories factories type Factories []Factory - //NewCounter new counter func (fs Factories) NewCounter(opt *CounterOpts) (Counters, error) { cs := make(Counters, 0, len(fs)) diff --git a/diting/internal/id.go b/diting/internal/id.go index 37cc512a..d2c5cb25 100644 --- a/diting/internal/id.go +++ b/diting/internal/id.go @@ -18,7 +18,7 @@ func NewIDCreate() *IDCreate { //Next next func (c *IDCreate) Next() uint64 { - var id uint64 = 0 + var id uint64 c.locker.Lock() id = uint64(time.Now().UnixNano()) diff --git a/diting/manager.go b/diting/manager.go index a407924a..122b68dc 100644 --- a/diting/manager.go +++ b/diting/manager.go @@ -30,11 +30,13 @@ func get(namespace string) (Constructor, bool) { func construct(confs map[string]string) Factories { + lives:= make(map[string]int) factories := make(Factories,0,len(confs)) defer func() { // close 关闭不用的模块 - lives := confs + for name,constructor:= range constructorMap{ + if _,has:=lives[name];!has{ constructor.Close() } @@ -44,9 +46,9 @@ func construct(confs map[string]string) Factories { return factories } - for name, conf := range confs { - namespace:=ksitigarbha.GetNameSpaceByName(name) + namespace,_:=ksitigarbha.GetNameSpaceByName(name) + lives[namespace] = 1 constructor, has := get(namespace) if !has { continue diff --git a/diting/opt.go b/diting/opt.go index 6e59e798..4b582c65 100644 --- a/diting/opt.go +++ b/diting/opt.go @@ -54,15 +54,15 @@ type HistogramOpts struct { LabelNames []string // Namespace, Subsystem, and Name are components of the fully-qualified - // name of the Histogram (created by joining these components with + // name of the HistogramObserve (created by joining these components with // "_"). Only Name is mandatory, the others merely help structuring the - // name. Note that the fully-qualified name of the Histogram must be a + // name. Note that the fully-qualified name of the HistogramObserve must be a // valid Prometheus metric name. Namespace string Subsystem string Name string - // Help provides information about this Histogram. + // Help provides information about this HistogramObserve. // // Metrics with the same fully-qualified name must have the same Help // string. diff --git a/diting/proxy-summary.go b/diting/proxy-summary.go index 70543161..e0a00e25 100644 --- a/diting/proxy-summary.go +++ b/diting/proxy-summary.go @@ -1,6 +1,5 @@ package diting - // //type SummariesProxy struct { // ConstLabelsProxy @@ -33,4 +32,4 @@ package diting // s.locker.RUnlock() // summaries.Observe(value,labels) //} -// \ No newline at end of file +// diff --git a/diting/utils.go b/diting/utils.go index 9fa8b0f6..f449bbee 100644 --- a/diting/utils.go +++ b/diting/utils.go @@ -14,7 +14,7 @@ func NewGauge(opt *GaugeOpts) Gauge { return g } -//NewHistogram new Histogram +//NewHistogram new HistogramObserve func NewHistogram(opt *HistogramOpts) Histogram { h := newHistogramProxy(opt) refresher.Add(h) @@ -23,6 +23,6 @@ func NewHistogram(opt *HistogramOpts) Histogram { //func NewSummary(opt *SummaryOpts) Summary { // s:= newSummariesProxy(opt) -// refresher.Add(s) +// refresher.RegisterDao(s) // return s //} diff --git a/go.mod b/go.mod index 4b677cdb..2e441941 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,6 @@ require ( github.com/go-sql-driver/mysql v1.4.1 github.com/hashicorp/consul/api v1.1.0 github.com/json-iterator/go v1.1.7 - github.com/julienschmidt/httprouter v1.2.0 github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect github.com/marpaia/graphite-golang v0.0.0-20190519024811-caf161d2c2b1 github.com/mattn/go-colorable v0.1.4 // indirect @@ -24,7 +23,9 @@ require ( github.com/onsi/gomega v1.7.0 // indirect github.com/peterh/liner v1.1.0 // indirect github.com/pkg/errors v0.8.1 + github.com/pkg/sftp v1.10.1 github.com/prometheus/client_golang v1.2.1 + github.com/robertkrimen/otto v0.0.0-20191219234010-c382bd3c16ff github.com/sirupsen/logrus v1.4.2 github.com/spf13/cobra v0.0.5 // indirect github.com/spf13/pflag v1.0.5 // indirect @@ -34,7 +35,10 @@ require ( golang.org/x/net v0.0.0-20190923162816-aa69164e4478 // indirect golang.org/x/sys v0.0.0-20191024073052-e66fe6eb8e0c // indirect google.golang.org/appengine v1.6.3 // indirect + gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect + gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df + gopkg.in/sourcemap.v1 v1.0.5 // indirect gopkg.in/yaml.v2 v2.2.4 ) diff --git a/go.sum b/go.sum index 46e210e6..a5382255 100644 --- a/go.sum +++ b/go.sum @@ -91,6 +91,8 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGi github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -141,6 +143,8 @@ github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/profile v0.0.0-20170413231811-06b906832ed0/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= +github.com/pkg/sftp v1.10.1 h1:VasscCm72135zRysgrJDKsntdmPN+OuU3+nnHYA9wyc= +github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= @@ -158,6 +162,8 @@ github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.5 h1:3+auTFlqw+ZaQYJARz6ArODtkaIwtvBTx3N2NehQlL8= github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= +github.com/robertkrimen/otto v0.0.0-20191219234010-c382bd3c16ff h1:+6NUiITWwE5q1KO6SAfUX918c+Tab0+tGAM/mtdlUyA= +github.com/robertkrimen/otto v0.0.0-20191219234010-c382bd3c16ff/go.mod h1:xvqspoSXJTIpemEonrMDFq6XzwHYYgToXWj5eRX1OtY= github.com/russross/blackfriday v0.0.0-20180428102519-11635eb403ff/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= @@ -194,6 +200,7 @@ golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392 h1:ACG4HJsFiNMf47Y4PeRoebLNy/2lXT9EtprMuTFWt1M= golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -238,6 +245,8 @@ google.golang.org/appengine v1.6.3 h1:hvZejVcIxAKHR8Pq2gXaDggf6CWT1QEqO+JEBeOKCG google.golang.org/appengine v1.6.3/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk= +gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -245,6 +254,10 @@ gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMy gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= +gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df h1:n7WqCuqOuCbNr617RXOY0AWRXxgwEyPp2z+p0+hgMuE= +gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw= +gopkg.in/sourcemap.v1 v1.0.5 h1:inv58fC9f9J3TK2Y2R1NPntXEn3/wjWHkonhIUODNTI= +gopkg.in/sourcemap.v1 v1.0.5/go.mod h1:2RlvNNSMglmRrcvhfuzp4hQHwOtjxlbjX7UPY/GXb78= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= diff --git a/goku-handler/account.go b/goku-handler/account.go new file mode 100644 index 00000000..bd9af2a9 --- /dev/null +++ b/goku-handler/account.go @@ -0,0 +1,63 @@ +package goku_handler + +import ( + "net/http" +) + +//Account 账号处理器 +type Account interface { + CheckLogin(r *http.Request) (int, error) + CheckPermission(pre string, isEdit bool, userID int) (bool, error) +} + +//AccountHandler 账号处理器 +type AccountHandler struct { + account Account + handler http.Handler + permission string + isEdit bool +} + +func (h *AccountHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + + // 检查登录操作 + userID, err := h.account.CheckLogin(r) + if err != nil { + WriteError(w, "100001", "user", err.Error(), err) + return + } + + // 检查权限操作 + if _, err := h.account.CheckPermission(h.permission, h.isEdit, userID); err != nil { + WriteError(w, "100002", "user", err.Error(), err) + return + } + + r = SetUserIDToRequest(r, userID) + h.handler.ServeHTTP(w, r) +} + +//AccountHandlerFactory 账号处理工厂 +type AccountHandlerFactory struct { + account Account +} + +//NewAccountHandlerFactory new AccountHandlerFactory +func NewAccountHandlerFactory(account Account) *AccountHandlerFactory { + return &AccountHandlerFactory{account: account} +} + +//NewAccountHandler new accountHandler +func (f *AccountHandlerFactory) NewAccountHandler(permission string, isEdit bool, handler http.Handler) http.Handler { + return &AccountHandler{ + account: f.account, + handler: handler, + permission: permission, + isEdit: isEdit, + } +} + +//NewAccountHandleFunction new accountHandleFunction +func (f *AccountHandlerFactory) NewAccountHandleFunction(permission string, isEdit bool, handleFunc func(w http.ResponseWriter, r *http.Request)) http.Handler { + return f.NewAccountHandler(permission, isEdit, http.HandlerFunc(handleFunc)) +} diff --git a/goku-handler/handler.go b/goku-handler/handler.go new file mode 100644 index 00000000..8e5aa683 --- /dev/null +++ b/goku-handler/handler.go @@ -0,0 +1,47 @@ +package goku_handler + +import ( + "fmt" + "net/http" + "strings" +) + +//GokuHandler gokuHandler +type GokuHandler interface { + Handlers(factory *AccountHandlerFactory) map[string]http.Handler +} + +//GokuServer gokuServer +type GokuServer struct { + factory *AccountHandlerFactory + mux *http.ServeMux +} + +func (s *GokuServer) ServeHTTP(w http.ResponseWriter, r *http.Request) { + s.mux.ServeHTTP(w, r) +} + +//NewGokuServer new gokuServer +func NewGokuServer(factory *AccountHandlerFactory) *GokuServer { + return &GokuServer{ + factory: factory, + mux: http.NewServeMux(), + } +} + +//Add add +func (s *GokuServer) Add(pre string, handler GokuHandler) { + handlers := handler.Handlers(s.factory) + + for sub, h := range handlers { + + path := join(pre, sub) + s.mux.Handle(path, h) + } +} + +func join(pre, sub string) string { + + return fmt.Sprint(strings.TrimSuffix(pre, "/"), "/", strings.TrimPrefix(sub, "/")) + +} diff --git a/goku-handler/user.go b/goku-handler/user.go new file mode 100644 index 00000000..294e4140 --- /dev/null +++ b/goku-handler/user.go @@ -0,0 +1,31 @@ +package goku_handler + +import ( + "context" + "fmt" + "net/http" +) + +//ContextKey contextKey +type userIDKey struct { +} + +var _userIDKey = userIDKey{} + +//UserIDFromRequest 从request中读取用户ID +func UserIDFromRequest(req *http.Request) int { + ctx := req.Context() + p, ok := ctx.Value(_userIDKey).(int) + if !ok { + fmt.Println("error") + } + return p +} + +//SetUserIDToRequest 设置userID到request +func SetUserIDToRequest(req *http.Request, userID int) *http.Request { + rctx := req.Context() + rctx = context.WithValue(rctx, _userIDKey, userID) + req = req.WithContext(rctx) + return req +} diff --git a/goku-handler/utils.go b/goku-handler/utils.go new file mode 100644 index 00000000..7f0f10ff --- /dev/null +++ b/goku-handler/utils.go @@ -0,0 +1,34 @@ +package goku_handler + +import ( + "encoding/json" + log "github.com/eolinker/goku-api-gateway/goku-log" + "net/http" +) + + + +//WriteError 返回错误 +func WriteError(w http.ResponseWriter, statusCode, resultType, resultDesc string, resuleErr error) { + + ret := map[string]interface{}{ + "type": resultType, + "statusCode": statusCode, + "resultDesc": resultDesc, + } + + if resuleErr != nil { + log.Info(resuleErr) + } + + data, err := json.Marshal(ret) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + log.WithFields(ret).Debug("write error:", err) + } + + w.Write(data) + log.WithFields(ret).Debug("write error:", err) + +} + diff --git a/goku-labels/labels.go b/goku-labels/labels.go index 82c3c11f..3c36c595 100644 --- a/goku-labels/labels.go +++ b/goku-labels/labels.go @@ -1,23 +1,51 @@ -package goku_labels - -// constlabel +package goku_labels // constlabel +// api labels +// proxy const ( - Cluster = "cluster" + Cluster = "cluster" Instance = "instance" -) + //Namespace 命名空间 + Namespace = "goku" + //Subsystem subSystem + Subsystem = "" + //APIName apiName + APIName = "api" + //ProxyName proxyName + ProxyName = "proxy" -// api labels -const ( - API = "api" + API = "api" Strategy = "strategy" - Status ="status" - + Status = "status" + Proto = "proto" + Method = "method" + Host = "host" + Path = "path" ) -// proxy -const ( - Proto = "proto" - Method = "method" - Host ="host" - Path = "path" -) \ No newline at end of file +var ( + //APIBuckets apiBuckets + APIBuckets = []float64{5, 25, 50, 100, 200, 400, 600, 800, 1000, 2500, 5000} + //ProxyBuckets proxyBuckets + ProxyBuckets = []float64{5, 25, 50, 100, 200, 400, 600, 800, 1000, 2500, 5000} + + //APIDelayLabelNames apiDelayLabelNames + APIDelayLabelNames = []string{ + Cluster, + Instance, + API, + Strategy, + Status, + } + //ProxyDelayLabelNames proxyDelayLabelNames + ProxyDelayLabelNames = []string{ + Cluster, + Instance, + API, + Strategy, + Proto, + Host, + Path, + Method, + Status, + } +) diff --git a/goku-node/common/body-request.go b/goku-node/common/body-request.go index 2153fb69..5f644c2b 100644 --- a/goku-node/common/body-request.go +++ b/goku-node/common/body-request.go @@ -51,13 +51,11 @@ func (b *BodyRequestHandler) Files() (map[string]*goku_plugin.FileHeader, error) //Parse 解析 func (b *BodyRequestHandler) Parse() error { - if b.isInit { return nil } contentType, _, _ := mime.ParseMediaType(b.contentType) - switch contentType { case goku_plugin.JSON: { @@ -123,8 +121,7 @@ func (b *BodyRequestHandler) Parse() error { return err } if b.form == nil { - - b.object = form + b.form = form } else { for k, v := range form { b.form[k] = append(b.form[k], v...) diff --git a/goku-node/common/request-reader.go b/goku-node/common/request-reader.go index 7b1d77c5..8db15538 100644 --- a/goku-node/common/request-reader.go +++ b/goku-node/common/request-reader.go @@ -30,9 +30,9 @@ func NewRequestReader(req *http.Request) *RequestReader { func (r *RequestReader) ParseRequest() { r.Header = NewHeader(r.req.Header) - body ,err:= ioutil.ReadAll(r.req.Body) + body, err := ioutil.ReadAll(r.req.Body) _ = r.req.Body.Close() - if err != nil { + if err != nil { r.BodyRequestHandler = NewBodyRequestHandler(r.req.Header.Get("Content-Type"), nil) } else { r.BodyRequestHandler = NewBodyRequestHandler(r.req.Header.Get("Content-Type"), body) diff --git a/goku-node/redis-plugin-proxy/redis.go b/goku-node/redis-plugin-proxy/redis.go index 04787964..3217bc00 100644 --- a/goku-node/redis-plugin-proxy/redis.go +++ b/goku-node/redis-plugin-proxy/redis.go @@ -7,7 +7,9 @@ import ( //Create 创建RedisManager func Create() goku_plugin.RedisManager { - + if redis_manager.GetConnection() == nil { + return nil + } return &RedisManager{ def: &RedisProxy{ redisClient: redis_manager.GetConnection(), diff --git a/goku-observe/histogram.go b/goku-observe/histogram.go index d62bbda7..3c6c6df9 100644 --- a/goku-observe/histogram.go +++ b/goku-observe/histogram.go @@ -10,69 +10,78 @@ import ( // values int64 //} -type _Histogram struct { - size int - buckets []float64 - values []int64 - max float64 - min float64 - sum float64 - count int - locker sync.Mutex +//Histogram histogram +type Histogram struct { + size int + Values []uint64 + Max float64 + Min float64 + Sum float64 + Count uint64 } -func (h *_Histogram) Observe(value float64) { +//HistogramObserver histogramObserver +type HistogramObserver struct { + Histogram + locker sync.Mutex +} + +//Collapse Collapse +func (h *HistogramObserver) Collapse() (values []uint64, sum, max, min float64, count uint64) { + return h.Values, h.Sum, h.Max, h.Min, h.Count +} + +//Observe Observe +func (h *HistogramObserver) Observe(buckets []float64, value float64) { + h.locker.Lock() if value < 0 { value = 0 } - h.locker.Lock() - h.count++ - h.sum += value - if value> h.max{ - h.max = value + h.Count++ + h.Sum += value + if value > h.Max { + h.Max = value } - if value < h.min{ - h.min= value + if value < h.Min { + h.Min = value } - l:= h.size -1 - for i:=l;i>=0;i--{ - if value >= h.buckets[i]{ + l := h.size - 1 + for i := l; i >= 0; i-- { + if value >= buckets[i] { break } - h.values[i]++ + h.Values[i]++ } h.locker.Unlock() } -//func (h*_Histogram) Reset() { -// h.locker.Lock() -// h.values = make([]int64,len(h.values),len(h.values)) -// h.sum ,h.max ,h.min,h.count = 0,0,math.MaxFloat64,0 -// h.locker.Unlock() -//} -func (h *_Histogram) Collapse() (values []int64, sum ,max,min float64,count int){ - h.locker.Lock() - values,sum,max,min,count = h.values,h.sum,h.max,h.min,h.count - h.locker.Unlock() - return + +//NewHistogram new Histogram +func NewHistogram(size int) *Histogram { + return &Histogram{ + size: size, + Values: make([]uint64, size, size), + Max: 0, + Min: math.MaxFloat64, + Sum: 0, + Count: 0, + } } -func NewHistogram(buckets []float64) *_Histogram { - max:= len(buckets) +1 - h:=&_Histogram{ - size: max, - buckets: make([]float64, 0, max), - values: make([]int64, max, max), - max: 0, - min: math.MaxFloat64, - sum: 0, - count: 0, - locker: sync.Mutex{}, + +//NewHistogramObserve new HistogramObserve +func NewHistogramObserve(size int) HistogramObserve { + + h := &HistogramObserver{ + Histogram: Histogram{ + size: size, + Values: make([]uint64, size, size), + Max: 0, + Min: math.MaxFloat64, + Sum: 0, + Count: 0, + }, + locker: sync.Mutex{}, } - h.buckets = append(h.buckets,buckets...) - h.buckets = append(h.buckets,math.MaxFloat64) - //sort.Float64s(h.buckets) return h } - - diff --git a/goku-observe/histogram_test.go b/goku-observe/histogram_test.go index 469144a3..a1b05236 100644 --- a/goku-observe/histogram_test.go +++ b/goku-observe/histogram_test.go @@ -58,7 +58,7 @@ func TestHistogram_Observe(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - h := &Histogram{ + h := &HistogramObserve{ Buckets: tt.fields.Buckets, Count: tt.fields.Count, } @@ -82,23 +82,22 @@ func TestNewHistogram(t *testing.T) { tests := []struct { name string args args - want *Histogram + want *HistogramObserve }{ - // TODO: Add test cases. + // TODO: RegisterDao test cases. { name: "", args: args{ buckets: []float64{0.1,0.5,1.0}, }, - want: &Histogram{ - Buckets: []float64{0.1,0.5,1.0,math.MaxFloat64}, - Count: []int64{0,0,0,0}, + want: &HistogramObserver{ + }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if got := NewHistogram(tt.args.buckets); !reflect.DeepEqual(got, tt.want) { + if got := NewHistogramObserve(len(tt.args.buckets)); !reflect.DeepEqual(got, tt.want) { t.Errorf("NewHistogram() = %v, want %v", got, tt.want) } }) diff --git a/goku-observe/observe.go b/goku-observe/observe.go index 086855be..d7062a41 100644 --- a/goku-observe/observe.go +++ b/goku-observe/observe.go @@ -1,10 +1,7 @@ package goku_observe -type Observe interface { - Observe(value float64) -} - -type Histogram interface { - Observe - Collapse() (values []int64, sum ,max,min float64,count int) +//HistogramObserve HistogramObserve +type HistogramObserve interface { + Observe(buckets []float64, value float64) + Collapse() (values []uint64, sum, max, min float64, count uint64) } diff --git a/goku-service/application/application.go b/goku-service/application/application.go index 2f0567a6..b06d4e85 100644 --- a/goku-service/application/application.go +++ b/goku-service/application/application.go @@ -1,6 +1,7 @@ package application import ( + goku_plugin "github.com/eolinker/goku-plugin" "net/http" "net/url" "time" @@ -8,5 +9,5 @@ import ( //IHttpApplication iHttpApplication type IHttpApplication interface { - Send(Proto string, method string, path string, querys url.Values, header http.Header, body []byte, timeout time.Duration, retry int) (*http.Response, string, []string, error) + Send(ctx goku_plugin.ContextAccess,Proto string, method string, path string, querys url.Values, header http.Header, body []byte, timeout time.Duration, retry int) (*http.Response, string, []string, error) } diff --git a/goku-service/application/org.go b/goku-service/application/org.go index 469eca13..a118a023 100644 --- a/goku-service/application/org.go +++ b/goku-service/application/org.go @@ -2,6 +2,7 @@ package application import ( "fmt" + goku_plugin "github.com/eolinker/goku-plugin" "net/http" "net/url" "time" @@ -15,7 +16,7 @@ type Org struct { } //Send 请求发送,忽略重试 -func (app *Org) Send(proto string, method string, path string, querys url.Values, header http.Header, body []byte, timeout time.Duration, retry int) (*http.Response, string, []string, error) { +func (app *Org) Send(ctx goku_plugin.ContextAccess,proto string, method string, path string, querys url.Values, header http.Header, body []byte, timeout time.Duration, retry int) (*http.Response, string, []string, error) { var response *http.Response var err error @@ -30,7 +31,7 @@ func (app *Org) Send(proto string, method string, path string, querys url.Values u := fmt.Sprintf("%s://%s/%s", proto, app.server, path) FinalTargetServer = app.server RetryTargetServers = append(RetryTargetServers, FinalTargetServer) - response, err = request(method, u, querys, header, body, timeout) + response, err = request(ctx,method, u, querys, header, body, timeout) if err != nil { continue } else { diff --git a/goku-service/application/r.go b/goku-service/application/r.go index 4b47b28f..65f8c8bd 100644 --- a/goku-service/application/r.go +++ b/goku-service/application/r.go @@ -2,12 +2,13 @@ package application import ( "fmt" + goku_plugin "github.com/eolinker/goku-plugin" "net/http" "net/url" "time" ) -func request(method string, backendDomain string, query url.Values, header http.Header, body []byte, timeout time.Duration) (*http.Response, error) { +func request(ctx goku_plugin.ContextAccess,method string, backendDomain string, query url.Values, header http.Header, body []byte, timeout time.Duration) (*http.Response, error) { if backendDomain == "" { return nil, fmt.Errorf("invaild url") @@ -24,11 +25,11 @@ func request(method string, backendDomain string, query url.Values, header http. return nil, err } - queryDest:= u.Query() - if query!= nil{ - for k,vs:=range query{ - for _,v:=range vs{ - queryDest.Add(k,v) + queryDest := u.Query() + if query != nil { + for k, vs := range query { + for _, v := range vs { + queryDest.Add(k, v) } } } @@ -41,5 +42,5 @@ func request(method string, backendDomain string, query url.Values, header http. if timeout != 0 { req.SetTimeout(timeout) } - return req.Send() + return req.Send(ctx) } diff --git a/goku-service/application/request.go b/goku-service/application/request.go index 63aeb01c..d4373334 100644 --- a/goku-service/application/request.go +++ b/goku-service/application/request.go @@ -2,10 +2,15 @@ package application import ( "bytes" + "crypto/tls" "errors" "io" + "net" "net/http" "net/url" + "strconv" + + goku_plugin "github.com/eolinker/goku-plugin" "github.com/eolinker/goku-api-gateway/diting" goku_labels "github.com/eolinker/goku-api-gateway/goku-labels" @@ -18,6 +23,13 @@ import ( //Version 版本号 var Version = "2.0" +var skipCertificate = 0 + +//SetSkipCertificate 设置跳过证书 +func SetSkipCertificate(skip int) { + skipCertificate = skip +} + //Request request type Request struct { client *http.Client @@ -40,6 +52,14 @@ func NewRequest(method string, URL *url.URL) (*Request, error) { return newRequest(method, URL) } +//URLPath urlPath +func URLPath(url string, query url.Values) string { + if len(query) < 1 { + return url + } + return url + "?" + query.Encode() +} + func newRequest(method string, URL *url.URL) (*Request, error) { var urlPath string queryParams := make(map[string][]string) @@ -47,8 +67,14 @@ func newRequest(method string, URL *url.URL) (*Request, error) { queryParams[key] = values } urlPath = URL.Scheme + "://" + URL.Host + URL.Path + tp := http.DefaultTransport + if skipCertificate == 1 { + tp = &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + } + } r := &Request{ - client: &http.Client{}, + client: &http.Client{Transport: tp}, method: method, URL: urlPath, headers: make(map[string][]string), @@ -95,12 +121,13 @@ func (r *Request) SetTimeout(timeout time.Duration) { //} //Send 发送请求 -func (r *Request) Send() (*http.Response, error) { +func (r *Request) Send(ctx goku_plugin.ContextAccess) (*http.Response, error) { // now := time.Now() req, err := r.parseBody() if err != nil { return nil, err } + status := 0 start := time.Now() defer func() { delay := time.Since(start) @@ -110,6 +137,9 @@ func (r *Request) Send() (*http.Response, error) { labels[goku_labels.Host] = req.Host labels[goku_labels.Path] = req.URL.Path labels[goku_labels.Method] = req.Method + labels[goku_labels.API] = strconv.Itoa(ctx.ApiID()) + labels[goku_labels.Strategy] = ctx.StrategyId() + labels[goku_labels.Status] = strconv.Itoa(status) monitor.ProxyMonitor.Observe(float64(delay/time.Millisecond), labels) }() req.Header.Set("Accept-Encoding", "gzip") @@ -120,8 +150,18 @@ func (r *Request) Send() (*http.Response, error) { httpResponse, err := r.client.Do(req) if err != nil { + if netErr, ok := err.(net.Error); ok { + if netErr.Timeout() { + status = 504 + } else { + status = 503 + } + } else { + status = 503 + } return nil, err } + status = httpResponse.StatusCode return httpResponse, nil } diff --git a/goku-service/application/service.go b/goku-service/application/service.go index 80d69145..00530708 100644 --- a/goku-service/application/service.go +++ b/goku-service/application/service.go @@ -2,6 +2,7 @@ package application import ( "fmt" + goku_plugin "github.com/eolinker/goku-plugin" "net/http" "net/url" "time" @@ -27,7 +28,7 @@ func NewApplication(service *common.Service, healthCheckHandler health.CheckHand } //Send send -func (app *Application) Send(proto string, method string, path string, querys url.Values, header http.Header, body []byte, timeout time.Duration, retry int) (*http.Response, string, []string, error) { +func (app *Application) Send(ctx goku_plugin.ContextAccess,proto string, method string, path string, querys url.Values, header http.Header, body []byte, timeout time.Duration, retry int) (*http.Response, string, []string, error) { var response *http.Response var err error @@ -51,7 +52,7 @@ func (app *Application) Send(proto string, method string, path string, querys ur RetryTargetServers = append(RetryTargetServers, FinalTargetServer) u := fmt.Sprintf("%s://%s/%s", proto, FinalTargetServer, path) - response, err = request(method, u, querys, header, body, timeout) + response, err = request(ctx,method, u, querys, header, body, timeout) if err != nil { if app.healthCheckHandler.IsNeedCheck() { diff --git a/goku-service/discovery/config.go b/goku-service/discovery/config.go index acf42edc..5844159a 100644 --- a/goku-service/discovery/config.go +++ b/goku-service/discovery/config.go @@ -1,2 +1 @@ package discovery - diff --git a/goku-service/driver/static/static-node.go b/goku-service/driver/static/static-node.go index 5856d0ae..7bb01c20 100644 --- a/goku-service/driver/static/static-node.go +++ b/goku-service/driver/static/static-node.go @@ -16,35 +16,35 @@ func (d *Driver) Open(name string, config string) (discovery.ISource, error) { } //StaticDiscovery staticDiscovery -type StaticDiscovery struct { +type Discovery struct { } //SetConfig setConfig -func (d *StaticDiscovery) SetConfig(config string) error { +func (d *Discovery) SetConfig(config string) error { return nil } //Driver driver -func (d *StaticDiscovery) Driver() string { +func (d *Discovery) Driver() string { return DriverName } //SetCallback setCallBack -func (d *StaticDiscovery) SetCallback(callback func(services []*common.Service)) { +func (d *Discovery) SetCallback(callback func(services []*common.Service)) { return } //GetServers getServers -func (d *StaticDiscovery) GetServers() ([]*common.Service, error) { +func (d *Discovery) GetServers() ([]*common.Service, error) { return nil, nil } //Close close -func (d *StaticDiscovery) Close() error { +func (d *Discovery) Close() error { return nil } //Open open -func (d *StaticDiscovery) Open() error { +func (d *Discovery) Open() error { return nil } diff --git a/goku-service/driver/static/staticSources.go b/goku-service/driver/static/staticSources.go index 7df29b8d..23950e14 100644 --- a/goku-service/driver/static/staticSources.go +++ b/goku-service/driver/static/staticSources.go @@ -22,7 +22,7 @@ var ErrorNoInstance = errors.New("no instance") type Sources struct { name string - discovery *StaticDiscovery + discovery *Discovery healthCheckHandler health.CheckHandler instanceFactory *common.InstanceFactory } @@ -74,7 +74,7 @@ func NewStaticSources(name string) *Sources { return &Sources{ name: name, - discovery: new(StaticDiscovery), + discovery: new(Discovery), healthCheckHandler: &health.CheckBox{}, instanceFactory: common.NewInstanceFactory(), } diff --git a/ksitigarbha/export.go b/ksitigarbha/export.go new file mode 100644 index 00000000..cfe4b93c --- /dev/null +++ b/ksitigarbha/export.go @@ -0,0 +1,46 @@ +package ksitigarbha + +import ( + log "github.com/eolinker/goku-api-gateway/goku-log" +) + +var mManager = newModelManager() + +//GetMonitorModuleNames 获取监控模块名称列表 +func GetMonitorModuleNames() []string { + return mManager.getModuleNames() +} + +//GetMonitorModuleModel 获取 +func GetMonitorModuleModel(name string) (IModule, bool) { + return mManager.getModuleModel(name) +} + +//GetNameSpaceByName 获取namespace +func GetNameSpaceByName(name string) (namespace string, has bool) { + return mManager.getNameSpace(name) + +} + +//Register 注册 +func Register(name string, f IModule) { + if f == nil { + log.Panic("register ksitigarbha nil") + } + mManager.add(name, f) +} + +//Close close +func Close(name string) { + mManager.Close(name) +} + +//Open open +func Open(name string, config string) { + mManager.Open(name, config) +} + +//HandlerConfig HandlerConfig +func HandlerConfig(name string, handler ConfigHandler) { + mManager.Handler(name, handler) +} diff --git a/ksitigarbha/factory.go b/ksitigarbha/factory.go index 67f91a1d..3194bb8b 100644 --- a/ksitigarbha/factory.go +++ b/ksitigarbha/factory.go @@ -1,13 +1,13 @@ package ksitigarbha +//IModule IModule type IModule interface { GetModel() []Model GetDesc() string GetName() string - GetNameSpace()string + GetNameSpace() string GetDefaultConfig() interface{} //CheckConfig(interface{}) bool - Decode(config string) (interface{},error) - Encoder(v interface{}) (string,error) - + Decode(config string) (interface{}, error) + Encode(v interface{}) (string, error) } diff --git a/ksitigarbha/module.go b/ksitigarbha/module.go index ba034012..301d5152 100644 --- a/ksitigarbha/module.go +++ b/ksitigarbha/module.go @@ -11,41 +11,46 @@ type modelManager struct { modules map[string]IModule names []string namespaceNames map[string]string + handlers map[string][]ConfigHandler } -func newModelManager() *modelManager { - return &modelManager{ - modules: make(map[string]IModule), - names: make([]string,0,5), - namespaceNames: make(map[string]string), - } +func (m *modelManager) Handler(name string, handler ConfigHandler) { + m.handlers[name] = append(m.handlers[name],handler) } -var mManager = newModelManager() - -//GetMonitorModuleNames 获取监控模块名称列表 -func GetMonitorModuleNames() []string { - return mManager.getModuleNames() +func (m *modelManager) Close(name string) { + namespace,has:= m.getNameSpace(name) + if !has{ + return + } + hs:=m.handlers[name] + for _,handler:=range hs{ + handler.OnClose(namespace,name) + } } -//GetMonitorModuleModel 获取 -func GetMonitorModuleModel(name string) (IModule ,bool){ - return mManager.getModuleModel(name) -} +func (m *modelManager) Open(name string, config string) { + namespace,has:= m.getNameSpace(name) + if !has{ + return + } + hs:=m.handlers[name] -//GetNameSpaceByName 获取namespace -func GetNameSpaceByName(name string) string { - return mManager.getNameSpace(name) -} -//Register 注册 -func Register(name string,f IModule) { - if f==nil { - log.Panic("register ksitigarbha nil") + for _,handler:=range hs{ + handler.OnOpen(namespace,name,config) } - mManager.add(name,f) +} +func newModelManager() *modelManager { + return &modelManager{ + modules: make(map[string]IModule), + names: make([]string,0,5), + namespaceNames: make(map[string]string), + handlers: make(map[string][]ConfigHandler), + } } + func (m *modelManager) add(name string,f IModule) { _,has:=m.modules[name] @@ -73,8 +78,9 @@ func (m *modelManager) isExisted(name string) bool { return ok } -func (m *modelManager) getNameSpace(name string) string { - return m.namespaceNames[name] +func (m *modelManager) getNameSpace(name string) (namespace string,has bool) { + namespace,has = m.namespaceNames[name] + return } func (m *modelManager) getModuleCount() int { count := len(m.modules) diff --git a/ksitigarbha/register.go b/ksitigarbha/register.go new file mode 100644 index 00000000..e31ac384 --- /dev/null +++ b/ksitigarbha/register.go @@ -0,0 +1,13 @@ +package ksitigarbha + +//ConfigHandler configHandler +type ConfigHandler interface { + OnOpen(namespace, name, config string) + OnClose(namespace, name string) +} + +type _H interface { + Handler(namespace string, handler ConfigHandler) + Close(namespace string) + Open(namespace string, config string) +} diff --git a/module/graphite/config/config.go b/module/graphite/config/config.go index c6dafe1e..e9206ef2 100644 --- a/module/graphite/config/config.go +++ b/module/graphite/config/config.go @@ -11,8 +11,8 @@ import ( //ModuleNameSpace 模块空间名称 const ModuleNameSpace = "diting.graphite" const moduleName = "Graphite" -const desc = "API监控模块对接Graphite(udp by minute)" -const addressPattern = `^[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]$` +const desc = "对接Graphite(数据每分钟更新)" +const addressPattern = `^[-A-Za-z0-9\.]+(:\d+)$` const content = `[ { "type": "line", @@ -24,7 +24,7 @@ const content = `[ "name":"accessAddress", "placeholder":"", "required":true, - "pattern":"` + addressPattern + `" + "pattern":"" } ] } @@ -36,13 +36,17 @@ var ( ) func init() { - json.Unmarshal([]byte(content), &mode) + err := json.Unmarshal([]byte(content), &mode) + if err != nil { + panic(err) + } r, err := regexp.Compile(addressPattern) if err != nil { panic("init graphite module error:" + err.Error()) } addressMatcher = r + mode[0].Items[0]["pattern"] = addressPattern } //GraphiteModule 配置 @@ -81,8 +85,8 @@ func (c *GraphiteModule) GetDefaultConfig() interface{} { } } -//Encoder encoder -func (c *GraphiteModule) Encoder(v interface{}) (string, error) { +//Write encoder +func (c *GraphiteModule) Encode(v interface{}) (string, error) { if v == nil { return "", nil } @@ -94,7 +98,7 @@ func (c *GraphiteModule) Encoder(v interface{}) (string, error) { return "", errors.New("illegal config") } -//Decode decode +//Read decode func Decode(config string) (*GraphiteConfig, error) { mc := new(GraphiteConfig) err := json.Unmarshal([]byte(config), &mc) @@ -110,7 +114,7 @@ func Decode(config string) (*GraphiteConfig, error) { return mc, nil } -//Decode decode +//Read decode func (c *GraphiteModule) Decode(config string) (interface{}, error) { return Decode(config) } diff --git a/module/graphite/count.go b/module/graphite/count.go index 95907d2e..a4be6c85 100644 --- a/module/graphite/count.go +++ b/module/graphite/count.go @@ -15,7 +15,7 @@ type Count struct { metricsValuesCount *MetricsValuesCount } -//Add add +//RegisterDao add func (c *Count) Add(value float64, labels diting.Labels) { key := c.metricKey.Key(labels, "count") @@ -61,7 +61,7 @@ func NewMetricsValuesCount() *MetricsValuesCount { } } -//Add add +//RegisterDao add func (m *MetricsValuesCount) Add(key string, value float64) { m.locker.Lock() v := int64(value) diff --git a/module/graphite/histogram.go b/module/graphite/histogram.go index 9d3c8530..63abec03 100644 --- a/module/graphite/histogram.go +++ b/module/graphite/histogram.go @@ -12,59 +12,72 @@ import ( "github.com/marpaia/graphite-golang" ) -//Histogram histogram +//HistogramObserve histogram type Histogram struct { metricKey MetricKey - keyHistogram *_KeyHistogram + buckets []float64 + histograms map[string]observe.HistogramObserve + locker sync.Mutex } //NewHistogram new histogram func NewHistogram(metricKey MetricKey, buckets []float64) *Histogram { return &Histogram{ metricKey: metricKey, - keyHistogram: newKeyHistogram(buckets), + buckets: buckets, + histograms: make(map[string]observe.HistogramObserve), + locker: sync.Mutex{}, } } //Observe observe func (h *Histogram) Observe(value float64, labels diting.Labels) { key := h.metricKey.Key(labels, "") - h.keyHistogram.Observe(key, value) + h.locker.Lock() + + hv, has := h.histograms[key] + if !has { + hv = observe.NewHistogramObserve(len(h.buckets)) + h.histograms[key] = hv + } + + h.locker.Unlock() + hv.Observe(h.buckets,value) } //Metrics metrics func (h *Histogram) Metrics() []graphite.Metric { - all := h.keyHistogram.Collapse() + all := h.Collapse() if len(all) == 0 { return nil } keySize := len(all) - size := keySize * (len(h.keyHistogram.buckets) + 5) + size := keySize * (len(h.buckets) + 5) ms := make([]graphite.Metric, 0, size) t := time.Now().Unix() tmpName := make([]string, 2) tmpBucketName := make([]string, 3) tmpBucketName[0] = "bucket_le" - overIndex := len(h.keyHistogram.buckets) + //overIndex := len(h.keyHistogram.buckets) for k, v := range all { tmpName[0] = k - + values, sum, max, min, count := v.Collapse() tmpName[1] = "count" - ms = append(ms, graphite.NewMetric(strings.Join(tmpName, "."), strconv.Itoa(v.count), t)) + ms = append(ms, graphite.NewMetric(strings.Join(tmpName, "."), strconv.FormatUint(count, 10), t)) tmpName[1] = "max" - ms = append(ms, graphite.NewMetric(strings.Join(tmpName, "."), strconv.FormatFloat(v.max, 'f', 2, 64), t)) + ms = append(ms, graphite.NewMetric(strings.Join(tmpName, "."), strconv.FormatFloat(max, 'f', 2, 64), t)) tmpName[1] = "min" - ms = append(ms, graphite.NewMetric(strings.Join(tmpName, "."), strconv.FormatFloat(v.min, 'f', 2, 64), t)) + ms = append(ms, graphite.NewMetric(strings.Join(tmpName, "."), strconv.FormatFloat(min, 'f', 2, 64), t)) tmpName[1] = "sum" - ms = append(ms, graphite.NewMetric(strings.Join(tmpName, "."), strconv.FormatFloat(v.sum, 'f', 2, 64), t)) + ms = append(ms, graphite.NewMetric(strings.Join(tmpName, "."), strconv.FormatFloat(sum, 'f', 2, 64), t)) tmpName[1] = "bucket_le_inf" - ms = append(ms, graphite.NewMetric(strings.Join(tmpName, "."), strconv.FormatInt(v.list[overIndex], 10), t)) + ms = append(ms, graphite.NewMetric(strings.Join(tmpName, "."), strconv.FormatUint(count, 10), t)) - for i, b := range h.keyHistogram.buckets { + for i, b := range h.buckets { floor := math.Floor(b) tmpBucketName[1] = strconv.FormatInt(int64(floor), 10) if floor-b < 0 { @@ -74,73 +87,22 @@ func (h *Histogram) Metrics() []graphite.Metric { tmpName[1] = strings.Join(tmpBucketName[:2], "_") } - ms = append(ms, graphite.NewMetric(strings.Join(tmpName, "."), strconv.FormatInt(v.list[i], 10), t)) + ms = append(ms, graphite.NewMetric(strings.Join(tmpName, "."), strconv.FormatUint(values[i], 10), t)) } } return ms } -type _KeyHistogram struct { - buckets []float64 - histograms map[string]observe.Histogram - locker sync.Mutex -} - -func newKeyHistogram(buckets []float64) *_KeyHistogram { - return &_KeyHistogram{ - buckets: buckets, - histograms: make(map[string]observe.Histogram), - locker: sync.Mutex{}, - } -} - -//HistogramValue histogramValue -type HistogramValue struct { - list []int64 - max float64 - min float64 - count int - sum float64 -} - //Collapse collapse -func (k *_KeyHistogram) Collapse() map[string]HistogramValue { - - new := make(map[string]observe.Histogram) - k.locker.Lock() - histograms := k.histograms - k.histograms = new - k.locker.Unlock() - - values := make(map[string]HistogramValue) - for k, hm := range histograms { - col, sum, max, min, count := hm.Collapse() - values[k] = HistogramValue{ - list: col, - max: max, - min: min, - count: count, - sum: sum, - } - } +func (h *Histogram) Collapse() map[string]observe.HistogramObserve { - return values -} -func (k *_KeyHistogram) get(key string) observe.Histogram { - k.locker.Lock() + n := make(map[string]observe.HistogramObserve) + h.locker.Lock() + histograms := h.histograms + h.histograms = n + h.locker.Unlock() - h, has := k.histograms[key] - if !has { - h = observe.NewHistogram(k.buckets) - k.histograms[key] = h - } - - k.locker.Unlock() - return h + return histograms } -//Observe observe -func (k *_KeyHistogram) Observe(key string, value float64) { - k.get(key).Observe(value) -} diff --git a/module/graphite/metrics.go b/module/graphite/metrics.go index e7af50c6..1d22a418 100644 --- a/module/graphite/metrics.go +++ b/module/graphite/metrics.go @@ -28,14 +28,13 @@ func NewMetricKey(name string, labelNames []string) MetricKey { return &_MetricKey{name: name, labelNames: labelNames} } - //Key key func (m *_MetricKey) Key(labels diting.Labels, valueType string) string { tmp := make([]string, 0, len(m.labelNames)+2) tmp = append(tmp, m.name) for _, name := range m.labelNames { - labelValue:= labels[name] + labelValue := labels[name] tmp = append(tmp, formatLabelValue(labelValue)) } @@ -45,14 +44,15 @@ func (m *_MetricKey) Key(labels diting.Labels, valueType string) string { return strings.Join(tmp, ".") } -const rep = '_' +const rep = '_' + //formatLabelValue 将label value的所有字母、数字转换成 _ -func formatLabelValue(value string)string { - s:=[]rune(value) +func formatLabelValue(value string) string { + s := []rune(value) for i, r := range s { if !unicode.IsLetter(r) && !unicode.IsNumber(r) { s[i] = rep } } return string(s) -} \ No newline at end of file +} diff --git a/module/httprouter/.travis.yml b/module/httprouter/.travis.yml new file mode 100644 index 00000000..477807dd --- /dev/null +++ b/module/httprouter/.travis.yml @@ -0,0 +1,18 @@ +sudo: false +language: go +go: + - 1.7 + - 1.8 + - 1.9 + - "1.10" + - tip +before_install: + - go get golang.org/x/tools/cmd/cover + - go get github.com/mattn/goveralls + - go get github.com/golang/lint/golint +script: + - go test -v -covermode=count -coverprofile=coverage.out + - go vet ./... + - test -z "$(gofmt -d -s . | tee /dev/stderr)" + - test -z "$(golint ./... | tee /dev/stderr)" + - $HOME/gopath/bin/goveralls -coverprofile=coverage.out -service=travis-ci diff --git a/module/httprouter/LICENSE b/module/httprouter/LICENSE new file mode 100644 index 00000000..b829abc8 --- /dev/null +++ b/module/httprouter/LICENSE @@ -0,0 +1,24 @@ +Copyright (c) 2013 Julien Schmidt. All rights reserved. + + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * The names of the contributors may not be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL JULIEN SCHMIDT BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/module/httprouter/README.md b/module/httprouter/README.md new file mode 100644 index 00000000..c5903103 --- /dev/null +++ b/module/httprouter/README.md @@ -0,0 +1,269 @@ +# HttpRouter [![Build Status](https://travis-ci.org/julienschmidt/httprouter.svg?branch=master)](https://travis-ci.org/julienschmidt/httprouter) [![Coverage Status](https://coveralls.io/repos/github/julienschmidt/httprouter/badge.svg?branch=master)](https://coveralls.io/github/julienschmidt/httprouter?branch=master) [![GoDoc](https://godoc.org/github.com/julienschmidt/httprouter?status.svg)](http://godoc.org/github.com/julienschmidt/httprouter) + +HttpRouter is a lightweight high performance HTTP request router (also called *multiplexer* or just *mux* for short) for [Go](https://golang.org/). + +In contrast to the [default mux](https://golang.org/pkg/net/http/#ServeMux) of Go's `net/http` package, this router supports variables in the routing pattern and matches against the request method. It also scales better. + +The router is optimized for high performance and a small memory footprint. It scales well even with very long paths and a large number of routes. A compressing dynamic trie (radix tree) structure is used for efficient matching. + +## Features + +**Only explicit matches:** With other routers, like [`http.ServeMux`](https://golang.org/pkg/net/http/#ServeMux), a requested URL path could match multiple patterns. Therefore they have some awkward pattern priority rules, like *longest match* or *first registered, first matched*. By design of this router, a request can only match exactly one or no route. As a result, there are also no unintended matches, which makes it great for SEO and improves the user experience. + +**Stop caring about trailing slashes:** Choose the URL style you like, the router automatically redirects the client if a trailing slash is missing or if there is one extra. Of course it only does so, if the new path has a handler. If you don't like it, you can [turn off this behavior](https://godoc.org/github.com/julienschmidt/httprouter#Router.RedirectTrailingSlash). + +**Path auto-correction:** Besides detecting the missing or additional trailing slash at no extra cost, the router can also fix wrong cases and remove superfluous path elements (like `../` or `//`). Is [CAPTAIN CAPS LOCK](http://www.urbandictionary.com/define.php?term=Captain+Caps+Lock) one of your users? HttpRouter can help him by making a case-insensitive look-up and redirecting him to the correct URL. + +**Parameters in your routing pattern:** Stop parsing the requested URL path, just give the path segment a name and the router delivers the dynamic value to you. Because of the design of the router, path parameters are very cheap. + +**Zero Garbage:** The matching and dispatching process generates zero bytes of garbage. The only heap allocations that are made are building the slice of the key-value pairs for path parameters, and building new context and request objects (the latter only in the standard `Handler`/`HandlerFunc` api). In the 3-argument API, if the request path contains no parameters not a single heap allocation is necessary. + +**Best Performance:** [Benchmarks speak for themselves](https://github.com/julienschmidt/go-http-routing-benchmark). See below for technical details of the implementation. + +**No more server crashes:** You can set a [Panic handler](https://godoc.org/github.com/julienschmidt/httprouter#Router.PanicHandler) to deal with panics occurring during handling a HTTP request. The router then recovers and lets the `PanicHandler` log what happened and deliver a nice error page. + +**Perfect for APIs:** The router design encourages to build sensible, hierarchical RESTful APIs. Moreover it has builtin native support for [OPTIONS requests](http://zacstewart.com/2012/04/14/http-options-method.html) and `405 Method Not Allowed` replies. + +Of course you can also set **custom [`NotFound`](https://godoc.org/github.com/julienschmidt/httprouter#Router.NotFound) and [`MethodNotAllowed`](https://godoc.org/github.com/julienschmidt/httprouter#Router.MethodNotAllowed) handlers** and [**serve static files**](https://godoc.org/github.com/julienschmidt/httprouter#Router.ServeFiles). + +## Usage + +This is just a quick introduction, view the [GoDoc](http://godoc.org/github.com/julienschmidt/httprouter) for details. + +Let's start with a trivial example: + +```go +package main + +import ( + "fmt" + "github.com/julienschmidt/httprouter" + "net/http" + "log" +) + +func Index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { + fmt.Fprint(w, "Welcome!\n") +} + +func Hello(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { + fmt.Fprintf(w, "hello, %s!\n", ps.ByName("name")) +} + +func main() { + router := httprouter.New() + router.GET("/", Index) + router.GET("/hello/:name", Hello) + + log.Fatal(http.ListenAndServe(":8080", router)) +} +``` + +### Named parameters + +As you can see, `:name` is a *named parameter*. The values are accessible via `httprouter.Params`, which is just a slice of `httprouter.Param`s. You can get the value of a parameter either by its index in the slice, or by using the `ByName(name)` method: `:name` can be retrived by `ByName("name")`. + +Named parameters only match a single path segment: + +``` +Pattern: /user/:user + + /user/gordon match + /user/you match + /user/gordon/profile no match + /user/ no match +``` + +**Note:** Since this router has only explicit matches, you can not register static routes and parameters for the same path segment. For example you can not register the patterns `/user/new` and `/user/:user` for the same request method at the same time. The routing of different request methods is independent from each other. + +### Catch-All parameters + +The second type are *catch-all* parameters and have the form `*name`. Like the name suggests, they match everything. Therefore they must always be at the **end** of the pattern: + +``` +Pattern: /src/*filepath + + /src/ match + /src/somefile.go match + /src/subdir/somefile.go match +``` + +## How does it work? + +The router relies on a tree structure which makes heavy use of *common prefixes*, it is basically a *compact* [*prefix tree*](https://en.wikipedia.org/wiki/Trie) (or just [*Radix tree*](https://en.wikipedia.org/wiki/Radix_tree)). Nodes with a common prefix also share a common parent. Here is a short example what the routing tree for the `GET` request method could look like: + +``` +Priority Path Handle +9 \ *<1> +3 ├s nil +2 |├earch\ *<2> +1 |└upport\ *<3> +2 ├blog\ *<4> +1 | └:post nil +1 | └\ *<5> +2 ├about-us\ *<6> +1 | └team\ *<7> +1 └contact\ *<8> +``` + +Every `*` represents the memory address of a handler function (a pointer). If you follow a path trough the tree from the root to the leaf, you get the complete route path, e.g `\blog\:post\`, where `:post` is just a placeholder ([*parameter*](#named-parameters)) for an actual post name. Unlike hash-maps, a tree structure also allows us to use dynamic parts like the `:post` parameter, since we actually match against the routing patterns instead of just comparing hashes. [As benchmarks show](https://github.com/julienschmidt/go-http-routing-benchmark), this works very well and efficient. + +Since URL paths have a hierarchical structure and make use only of a limited set of characters (byte values), it is very likely that there are a lot of common prefixes. This allows us to easily reduce the routing into ever smaller problems. Moreover the router manages a separate tree for every request method. For one thing it is more space efficient than holding a method->handle map in every single node, it also allows us to greatly reduce the routing problem before even starting the look-up in the prefix-tree. + +For even better scalability, the child nodes on each tree level are ordered by priority, where the priority is just the number of handles registered in sub nodes (children, grandchildren, and so on..). This helps in two ways: + +1. Nodes which are part of the most routing paths are evaluated first. This helps to make as much routes as possible to be reachable as fast as possible. +2. It is some sort of cost compensation. The longest reachable path (highest cost) can always be evaluated first. The following scheme visualizes the tree structure. Nodes are evaluated from top to bottom and from left to right. + +``` +├------------ +├--------- +├----- +├---- +├-- +├-- +└- +``` + +## Why doesn't this work with `http.Handler`? + +**It does!** The router itself implements the `http.Handler` interface. Moreover the router provides convenient [adapters for `http.Handler`](https://godoc.org/github.com/julienschmidt/httprouter#Router.Handler)s and [`http.HandlerFunc`](https://godoc.org/github.com/julienschmidt/httprouter#Router.HandlerFunc)s which allows them to be used as a [`httprouter.Handle`](https://godoc.org/github.com/julienschmidt/httprouter#Router.Handle) when registering a route. The only disadvantage is, that no parameter values can be retrieved when a `http.Handler` or `http.HandlerFunc` is used, since there is no efficient way to pass the values with the existing function parameters. Therefore [`httprouter.Handle`](https://godoc.org/github.com/julienschmidt/httprouter#Router.Handle) has a third function parameter. + +Just try it out for yourself, the usage of HttpRouter is very straightforward. The package is compact and minimalistic, but also probably one of the easiest routers to set up. + +## Where can I find Middleware *X*? + +This package just provides a very efficient request router with a few extra features. The router is just a [`http.Handler`](https://golang.org/pkg/net/http/#Handler), you can chain any http.Handler compatible middleware before the router, for example the [Gorilla handlers](http://www.gorillatoolkit.org/pkg/handlers). Or you could [just write your own](https://justinas.org/writing-http-middleware-in-go/), it's very easy! + +Alternatively, you could try [a web framework based on HttpRouter](#web-frameworks-based-on-httprouter). + +### Multi-domain / Sub-domains + +Here is a quick example: Does your server serve multiple domains / hosts? +You want to use sub-domains? +Define a router per host! + +```go +// We need an object that implements the http.Handler interface. +// Therefore we need a type for which we implement the ServeHTTP method. +// We just use a map here, in which we map host names (with port) to http.Handlers +type HostSwitch map[string]http.Handler + +// Implement the ServeHTTP method on our new type +func (hs HostSwitch) ServeHTTP(w http.ResponseWriter, r *http.Request) { + // Check if a http.Handler is registered for the given host. + // If yes, use it to handle the request. + if handler := hs[r.Host]; handler != nil { + handler.ServeHTTP(w, r) + } else { + // Handle host names for which no handler is registered + http.Error(w, "Forbidden", 403) // Or Redirect? + } +} + +func main() { + // Initialize a router as usual + router := httprouter.New() + router.GET("/", Index) + router.GET("/hello/:name", Hello) + + // Make a new HostSwitch and insert the router (our http handler) + // for example.com and port 12345 + hs := make(HostSwitch) + hs["example.com:12345"] = router + + // Use the HostSwitch to listen and serve on port 12345 + log.Fatal(http.ListenAndServe(":12345", hs)) +} +``` + +### Basic Authentication + +Another quick example: Basic Authentication (RFC 2617) for handles: + +```go +package main + +import ( + "fmt" + "log" + "net/http" + + "github.com/julienschmidt/httprouter" +) + +func BasicAuth(h httprouter.Handle, requiredUser, requiredPassword string) httprouter.Handle { + return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { + // Get the Basic Authentication credentials + user, password, hasAuth := r.BasicAuth() + + if hasAuth && user == requiredUser && password == requiredPassword { + // Delegate request to the given handle + h(w, r, ps) + } else { + // Request Basic Authentication otherwise + w.Header().Set("WWW-Authenticate", "Basic realm=Restricted") + http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized) + } + } +} + +func Index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { + fmt.Fprint(w, "Not protected!\n") +} + +func Protected(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { + fmt.Fprint(w, "Protected!\n") +} + +func main() { + user := "gordon" + pass := "secret!" + + router := httprouter.New() + router.GET("/", Index) + router.GET("/protected/", BasicAuth(Protected, user, pass)) + + log.Fatal(http.ListenAndServe(":8080", router)) +} +``` + +## Chaining with the NotFound handler + +**NOTE: It might be required to set [`Router.HandleMethodNotAllowed`](https://godoc.org/github.com/julienschmidt/httprouter#Router.HandleMethodNotAllowed) to `false` to avoid problems.** + +You can use another [`http.Handler`](https://golang.org/pkg/net/http/#Handler), for example another router, to handle requests which could not be matched by this router by using the [`Router.NotFound`](https://godoc.org/github.com/julienschmidt/httprouter#Router.NotFound) handler. This allows chaining. + +### Static files + +The `NotFound` handler can for example be used to serve static files from the root path `/` (like an `index.html` file along with other assets): + +```go +// Serve static files from the ./public directory +router.NotFound = http.FileServer(http.Dir("public")) +``` + +But this approach sidesteps the strict core rules of this router to avoid routing problems. A cleaner approach is to use a distinct sub-path for serving files, like `/static/*filepath` or `/files/*filepath`. + +## Web Frameworks based on HttpRouter + +If the HttpRouter is a bit too minimalistic for you, you might try one of the following more high-level 3rd-party web frameworks building upon the HttpRouter package: + +* [Ace](https://github.com/plimble/ace): Blazing fast Go Web Framework +* [api2go](https://github.com/manyminds/api2go): A JSON API Implementation for Go +* [Gin](https://github.com/gin-gonic/gin): Features a martini-like API with much better performance +* [Goat](https://github.com/bahlo/goat): A minimalistic REST API server in Go +* [goMiddlewareChain](https://github.com/TobiEiss/goMiddlewareChain): An express.js-like-middleware-chain +* [Hikaru](https://github.com/najeira/hikaru): Supports standalone and Google AppEngine +* [Hitch](https://github.com/nbio/hitch): Hitch ties httprouter, [httpcontext](https://github.com/nbio/httpcontext), and middleware up in a bow +* [httpway](https://github.com/corneldamian/httpway): Simple middleware extension with context for httprouter and a server with gracefully shutdown support +* [kami](https://github.com/guregu/kami): A tiny web framework using x/net/context +* [Medeina](https://github.com/imdario/medeina): Inspired by Ruby's Roda and Cuba +* [Neko](https://github.com/rocwong/neko): A lightweight web application framework for Golang +* [River](https://github.com/abiosoft/river): River is a simple and lightweight REST server +* [Roxanna](https://github.com/iamthemuffinman/Roxanna): An amalgamation of httprouter, better logging, and hot reload +* [siesta](https://github.com/VividCortex/siesta): Composable HTTP handlers with contexts +* [xmux](https://github.com/rs/xmux): xmux is a httprouter fork on top of xhandler (net/context aware) + +---- +此处对tree.go方法getValue方法进行修改,以适应匹配前缀的需求 \ No newline at end of file diff --git a/module/httprouter/params_go17.go b/module/httprouter/params_go17.go new file mode 100644 index 00000000..abb4209d --- /dev/null +++ b/module/httprouter/params_go17.go @@ -0,0 +1,38 @@ +// +build go1.7 + +package httprouter + +import ( + "context" + "net/http" +) + +type paramsKey struct{} + +// ParamsKey is the request context key under which URL params are stored. +// +// This is only present from go 1.7. +var ParamsKey = paramsKey{} + +// Handler is an adapter which allows the usage of an http.Handler as a +// request handle. With go 1.7+, the Params will be available in the +// request context under ParamsKey. +func (r *Router) Handler(method, path string, handler http.Handler) { + r.Handle(method, path, + func(w http.ResponseWriter, req *http.Request, p Params) { + ctx := req.Context() + ctx = context.WithValue(ctx, ParamsKey, p) + req = req.WithContext(ctx) + handler.ServeHTTP(w, req) + }, + ) +} + +// ParamsFromContext pulls the URL parameters from a request context, +// or returns nil if none are present. +// +// This is only present from go 1.7. +func ParamsFromContext(ctx context.Context) Params { + p, _ := ctx.Value(ParamsKey).(Params) + return p +} diff --git a/module/httprouter/params_legacy.go b/module/httprouter/params_legacy.go new file mode 100644 index 00000000..0278a441 --- /dev/null +++ b/module/httprouter/params_legacy.go @@ -0,0 +1,16 @@ +// +build !go1.7 + +package httprouter + +import "net/http" + +// Handler is an adapter which allows the usage of an http.Handler as a +// request handle. With go 1.7+, the Params will be available in the +// request context under ParamsKey. +func (r *Router) Handler(method, path string, handler http.Handler) { + r.Handle(method, path, + func(w http.ResponseWriter, req *http.Request, _ Params) { + handler.ServeHTTP(w, req) + }, + ) +} diff --git a/module/httprouter/path.go b/module/httprouter/path.go new file mode 100644 index 00000000..0331c7ec --- /dev/null +++ b/module/httprouter/path.go @@ -0,0 +1,123 @@ +// Copyright 2013 Julien Schmidt. All rights reserved. +// Based on the path package, Copyright 2009 The Go Authors. +// Use of this source code is governed by a BSD-style license that can be found +// in the LICENSE file. + +package httprouter + +// CleanPath is the URL version of path.Clean, it returns a canonical URL path +// for p, eliminating . and .. elements. +// +// The following rules are applied iteratively until no further processing can +// be done: +// 1. Replace multiple slashes with a single slash. +// 2. Eliminate each . path name element (the current directory). +// 3. Eliminate each inner .. path name element (the parent directory) +// along with the non-.. element that precedes it. +// 4. Eliminate .. elements that begin a rooted path: +// that is, replace "/.." by "/" at the beginning of a path. +// +// If the result of this process is an empty string, "/" is returned +func CleanPath(p string) string { + // Turn empty string into "/" + if p == "" { + return "/" + } + + n := len(p) + var buf []byte + + // Invariants: + // reading from path; r is index of next byte to process. + // writing to buf; w is index of next byte to write. + + // path must start with '/' + r := 1 + w := 1 + + if p[0] != '/' { + r = 0 + buf = make([]byte, n+1) + buf[0] = '/' + } + + trailing := n > 1 && p[n-1] == '/' + + // A bit more clunky without a 'lazybuf' like the path package, but the loop + // gets completely inlined (bufApp). So in contrast to the path package this + // loop has no expensive function calls (except 1x make) + + for r < n { + switch { + case p[r] == '/': + // empty path element, trailing slash is added after the end + r++ + + case p[r] == '.' && r+1 == n: + trailing = true + r++ + + case p[r] == '.' && p[r+1] == '/': + // . element + r += 2 + + case p[r] == '.' && p[r+1] == '.' && (r+2 == n || p[r+2] == '/'): + // .. element: remove to last / + r += 3 + + if w > 1 { + // can backtrack + w-- + + if buf == nil { + for w > 1 && p[w] != '/' { + w-- + } + } else { + for w > 1 && buf[w] != '/' { + w-- + } + } + } + + default: + // real path element. + // add slash if needed + if w > 1 { + bufApp(&buf, p, w, '/') + w++ + } + + // copy element + for r < n && p[r] != '/' { + bufApp(&buf, p, w, p[r]) + w++ + r++ + } + } + } + + // re-append trailing slash + if trailing && w > 1 { + bufApp(&buf, p, w, '/') + w++ + } + + if buf == nil { + return p[:w] + } + return string(buf[:w]) +} + +// internal helper to lazily create a buffer if necessary +func bufApp(buf *[]byte, s string, w int, c byte) { + if *buf == nil { + if s[w] == c { + return + } + + *buf = make([]byte, len(s)) + copy(*buf, s[:w]) + } + (*buf)[w] = c +} diff --git a/module/httprouter/router.go b/module/httprouter/router.go new file mode 100644 index 00000000..558e1392 --- /dev/null +++ b/module/httprouter/router.go @@ -0,0 +1,399 @@ +// Copyright 2013 Julien Schmidt. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be found +// in the LICENSE file. + +// Package httprouter is a trie based high performance HTTP request router. +// +// A trivial example is: +// +// package main +// +// import ( +// "fmt" +// "github.com/julienschmidt/httprouter" +// "net/http" +// "log" +// ) +// +// func Index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { +// fmt.Fprint(w, "Welcome!\n") +// } +// +// func Hello(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { +// fmt.Fprintf(w, "hello, %s!\n", ps.ByName("name")) +// } +// +// func main() { +// router := httprouter.New() +// router.GET("/", Index) +// router.GET("/hello/:name", Hello) +// +// log.Fatal(http.ListenAndServe(":8080", router)) +// } +// +// The router matches incoming requests by the request method and the path. +// If a handle is registered for this path and method, the router delegates the +// request to that function. +// For the methods GET, POST, PUT, PATCH and DELETE shortcut functions exist to +// register handles, for all other methods router.Handle can be used. +// +// The registered path, against which the router matches incoming requests, can +// contain two types of parameters: +// Syntax Type +// :name named parameter +// *name catch-all parameter +// +// Named parameters are dynamic path segments. They match anything until the +// next '/' or the path end: +// Path: /blog/:category/:post +// +// Requests: +// /blog/go/request-routers match: category="go", post="request-routers" +// /blog/go/request-routers/ no match, but the router would redirect +// /blog/go/ no match +// /blog/go/request-routers/comments no match +// +// Catch-all parameters match anything until the path end, including the +// directory index (the '/' before the catch-all). Since they match anything +// until the end, catch-all parameters must always be the final path element. +// Path: /files/*filepath +// +// Requests: +// /files/ match: filepath="/" +// /files/LICENSE match: filepath="/LICENSE" +// /files/templates/article.html match: filepath="/templates/article.html" +// /files no match, but the router would redirect +// +// The value of parameters is saved as a slice of the Param struct, consisting +// each of a key and a value. The slice is passed to the Handle func as a third +// parameter. +// There are two ways to retrieve the value of a parameter: +// // by the name of the parameter +// user := ps.ByName("user") // defined by :user or *user +// +// // by the index of the parameter. This way you can also get the name (key) +// thirdKey := ps[2].Key // the name of the 3rd parameter +// thirdValue := ps[2].Value // the value of the 3rd parameter +package httprouter + +import ( + "net/http" +) + +// Handle is a function that can be registered to a route to handle HTTP +// requests. Like http.HandlerFunc, but has a third parameter for the values of +// wildcards (variables). +type Handle func(http.ResponseWriter, *http.Request, Params) + +// Param is a single URL parameter, consisting of a key and a value. +type Param struct { + Key string + Value string +} + +// Params is a Param-slice, as returned by the router. +// The slice is ordered, the first URL parameter is also the first slice value. +// It is therefore safe to read values by the index. +type Params []Param + +// ByName returns the value of the first Param which key matches the given name. +// If no matching Param is found, an empty string is returned. +func (ps Params) ByName(name string) string { + for i := range ps { + if ps[i].Key == name { + return ps[i].Value + } + } + return "" +} + +// Router is a http.Handler which can be used to dispatch requests to different +// handler functions via configurable routes +type Router struct { + trees map[string]*node + + // Enables automatic redirection if the current route can't be matched but a + // handler for the path with (without) the trailing slash exists. + // For example if /foo/ is requested but a route only exists for /foo, the + // client is redirected to /foo with http status code 301 for GET requests + // and 307 for all other request methods. + RedirectTrailingSlash bool + + // If enabled, the router tries to fix the current request path, if no + // handle is registered for it. + // First superfluous path elements like ../ or // are removed. + // Afterwards the router does a case-insensitive lookup of the cleaned path. + // If a handle can be found for this route, the router makes a redirection + // to the corrected path with status code 301 for GET requests and 307 for + // all other request methods. + // For example /FOO and /..//Foo could be redirected to /foo. + // RedirectTrailingSlash is independent of this option. + RedirectFixedPath bool + + // If enabled, the router checks if another method is allowed for the + // current route, if the current request can not be routed. + // If this is the case, the request is answered with 'Method Not Allowed' + // and HTTP status code 405. + // If no other Method is allowed, the request is delegated to the NotFound + // handler. + HandleMethodNotAllowed bool + + // If enabled, the router automatically replies to OPTIONS requests. + // Custom OPTIONS handlers take priority over automatic replies. + HandleOPTIONS bool + + // Configurable http.Handler which is called when no matching route is + // found. If it is not set, http.NotFound is used. + NotFound http.Handler + + // Configurable http.Handler which is called when a request + // cannot be routed and HandleMethodNotAllowed is true. + // If it is not set, http.Error with http.StatusMethodNotAllowed is used. + // The "Allow" header with allowed request methods is set before the handler + // is called. + MethodNotAllowed http.Handler + + // Function to handle panics recovered from http handlers. + // It should be used to generate a error page and return the http error code + // 500 (Internal Server Error). + // The handler can be used to keep your server from crashing because of + // unrecovered panics. + PanicHandler func(http.ResponseWriter, *http.Request, interface{}) +} + +// Make sure the Router conforms with the http.Handler interface +var _ http.Handler = New() + +// New returns a new initialized Router. +// Path auto-correction, including trailing slashes, is enabled by default. +func New() *Router { + return &Router{ + RedirectTrailingSlash: true, + RedirectFixedPath: true, + HandleMethodNotAllowed: true, + HandleOPTIONS: true, + } +} + +// GET is a shortcut for router.Handle("GET", path, handle) +func (r *Router) GET(path string, handle Handle) { + r.Handle("GET", path, handle) +} + +// HEAD is a shortcut for router.Handle("HEAD", path, handle) +func (r *Router) HEAD(path string, handle Handle) { + r.Handle("HEAD", path, handle) +} + +// OPTIONS is a shortcut for router.Handle("OPTIONS", path, handle) +func (r *Router) OPTIONS(path string, handle Handle) { + r.Handle("OPTIONS", path, handle) +} + +// POST is a shortcut for router.Handle("POST", path, handle) +func (r *Router) POST(path string, handle Handle) { + r.Handle("POST", path, handle) +} + +// PUT is a shortcut for router.Handle("PUT", path, handle) +func (r *Router) PUT(path string, handle Handle) { + r.Handle("PUT", path, handle) +} + +// PATCH is a shortcut for router.Handle("PATCH", path, handle) +func (r *Router) PATCH(path string, handle Handle) { + r.Handle("PATCH", path, handle) +} + +// DELETE is a shortcut for router.Handle("DELETE", path, handle) +func (r *Router) DELETE(path string, handle Handle) { + r.Handle("DELETE", path, handle) +} + +// Handle registers a new request handle with the given path and method. +// +// For GET, POST, PUT, PATCH and DELETE requests the respective shortcut +// functions can be used. +// +// This function is intended for bulk loading and to allow the usage of less +// frequently used, non-standardized or custom methods (e.g. for internal +// communication with a proxy). +func (r *Router) Handle(method, path string, handle Handle) { + if path[0] != '/' { + panic("path must begin with '/' in path '" + path + "'") + } + + if r.trees == nil { + r.trees = make(map[string]*node) + } + + root := r.trees[method] + if root == nil { + root = new(node) + r.trees[method] = root + } + + root.addRoute(path, handle) +} + +// HandlerFunc is an adapter which allows the usage of an http.HandlerFunc as a +// request handle. +func (r *Router) HandlerFunc(method, path string, handler http.HandlerFunc) { + r.Handler(method, path, handler) +} + +// ServeFiles serves files from the given file system root. +// The path must end with "/*filepath", files are then served from the local +// path /defined/root/dir/*filepath. +// For example if root is "/etc" and *filepath is "passwd", the local file +// "/etc/passwd" would be served. +// Internally a http.FileServer is used, therefore http.NotFound is used instead +// of the Router's NotFound handler. +// To use the operating system's file system implementation, +// use http.Dir: +// router.ServeFiles("/src/*filepath", http.Dir("/var/www")) +func (r *Router) ServeFiles(path string, root http.FileSystem) { + if len(path) < 10 || path[len(path)-10:] != "/*filepath" { + panic("path must end with /*filepath in path '" + path + "'") + } + + fileServer := http.FileServer(root) + + r.GET(path, func(w http.ResponseWriter, req *http.Request, ps Params) { + req.URL.Path = ps.ByName("filepath") + fileServer.ServeHTTP(w, req) + }) +} + +func (r *Router) recv(w http.ResponseWriter, req *http.Request) { + if rcv := recover(); rcv != nil { + r.PanicHandler(w, req, rcv) + } +} + +// Lookup allows the manual lookup of a method + path combo. +// This is e.g. useful to build a framework around this router. +// If the path was found, it returns the handle function and the path parameter +// values. Otherwise the third return value indicates whether a redirection to +// the same path with an extra / without the trailing slash should be performed. +func (r *Router) Lookup(method, path string) (Handle, Params, bool) { + if root := r.trees[method]; root != nil { + return root.getValue(path) + } + return nil, nil, false +} + +func (r *Router) allowed(path, reqMethod string) (allow string) { + if path == "*" { // server-wide + for method := range r.trees { + if method == "OPTIONS" { + continue + } + + // add request method to list of allowed methods + if len(allow) == 0 { + allow = method + } else { + allow += ", " + method + } + } + } else { // specific path + for method := range r.trees { + // Skip the requested method - we already tried this one + if method == reqMethod || method == "OPTIONS" { + continue + } + + handle, _, _ := r.trees[method].getValue(path) + if handle != nil { + // add request method to list of allowed methods + if len(allow) == 0 { + allow = method + } else { + allow += ", " + method + } + } + } + } + if len(allow) > 0 { + allow += ", OPTIONS" + } + return +} + +// ServeHTTP makes the router implement the http.Handler interface. +func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) { + if r.PanicHandler != nil { + defer r.recv(w, req) + } + + path := req.URL.Path + + if root := r.trees[req.Method]; root != nil { + if handle, ps, tsr := root.getValue(path); handle != nil { + handle(w, req, ps) + return + } else if req.Method != "CONNECT" && path != "/" { + code := 301 // Permanent redirect, request with GET method + if req.Method != "GET" { + // Temporary redirect, request with same method + // As of Go 1.3, Go does not support status code 308. + code = 307 + } + + if tsr && r.RedirectTrailingSlash { + if len(path) > 1 && path[len(path)-1] == '/' { + req.URL.Path = path[:len(path)-1] + } else { + req.URL.Path = path + "/" + } + http.Redirect(w, req, req.URL.String(), code) + return + } + + // Try to fix the request path + if r.RedirectFixedPath { + fixedPath, found := root.findCaseInsensitivePath( + CleanPath(path), + r.RedirectTrailingSlash, + ) + if found { + req.URL.Path = string(fixedPath) + http.Redirect(w, req, req.URL.String(), code) + return + } + } + } + } + + if req.Method == "OPTIONS" && r.HandleOPTIONS { + // Handle OPTIONS requests + if allow := r.allowed(path, req.Method); len(allow) > 0 { + w.Header().Set("Allow", allow) + return + } + } else { + // Handle 405 + if r.HandleMethodNotAllowed { + if allow := r.allowed(path, req.Method); len(allow) > 0 { + w.Header().Set("Allow", allow) + if r.MethodNotAllowed != nil { + r.MethodNotAllowed.ServeHTTP(w, req) + } else { + http.Error(w, + http.StatusText(http.StatusMethodNotAllowed), + http.StatusMethodNotAllowed, + ) + } + return + } + } + } + + // Handle 404 + if r.NotFound != nil { + r.NotFound.ServeHTTP(w, req) + } else { + http.NotFound(w, req) + } +} diff --git a/module/httprouter/tree.go b/module/httprouter/tree.go new file mode 100644 index 00000000..89676c3e --- /dev/null +++ b/module/httprouter/tree.go @@ -0,0 +1,661 @@ +// Copyright 2013 Julien Schmidt. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be found +// in the LICENSE file. +// 此处对getValue方法进行部分修改,以适应匹配前缀的需求 + +package httprouter + +import ( + "strings" + "unicode" + "unicode/utf8" +) + +func min(a, b int) int { + if a <= b { + return a + } + return b +} + +func countParams(path string) uint8 { + var n uint + for i := 0; i < len(path); i++ { + if path[i] != ':' && path[i] != '*' { + continue + } + n++ + } + if n >= 255 { + return 255 + } + return uint8(n) +} + +type nodeType uint8 + +const ( + static nodeType = iota // default + root + param + catchAll +) + +type node struct { + path string + wildChild bool + nType nodeType + maxParams uint8 + indices string + children []*node + handle Handle + priority uint32 +} + +// increments priority of the given child and reorders if necessary +func (n *node) incrementChildPrio(pos int) int { + n.children[pos].priority++ + prio := n.children[pos].priority + + // adjust position (move to front) + newPos := pos + for newPos > 0 && n.children[newPos-1].priority < prio { + // swap node positions + n.children[newPos-1], n.children[newPos] = n.children[newPos], n.children[newPos-1] + + newPos-- + } + + // build new index char string + if newPos != pos { + n.indices = n.indices[:newPos] + // unchanged prefix, might be empty + n.indices[pos:pos+1] + // the index char we move + n.indices[newPos:pos] + n.indices[pos+1:] // rest without char at 'pos' + } + + return newPos +} + +// addRoute adds a node with the given handle to the path. +// Not concurrency-safe! +func (n *node) addRoute(path string, handle Handle) { + fullPath := path + n.priority++ + numParams := countParams(path) + + // non-empty tree + if len(n.path) > 0 || len(n.children) > 0 { + walk: + for { + // Update maxParams of the current node + if numParams > n.maxParams { + n.maxParams = numParams + } + + // Find the longest common prefix. + // This also implies that the common prefix contains no ':' or '*' + // since the existing key can't contain those chars. + i := 0 + max := min(len(path), len(n.path)) + for i < max && path[i] == n.path[i] { + i++ + } + + // Split edge + if i < len(n.path) { + child := node{ + path: n.path[i:], + wildChild: n.wildChild, + nType: static, + indices: n.indices, + children: n.children, + handle: n.handle, + priority: n.priority - 1, + } + + // Update maxParams (max of all children) + for i := range child.children { + if child.children[i].maxParams > child.maxParams { + child.maxParams = child.children[i].maxParams + } + } + + n.children = []*node{&child} + // []byte for proper unicode char conversion, see #65 + n.indices = string([]byte{n.path[i]}) + n.path = path[:i] + n.handle = nil + n.wildChild = false + } + + // Make new node a child of this node + if i < len(path) { + path = path[i:] + + if n.wildChild { + n = n.children[0] + n.priority++ + + // Update maxParams of the child node + if numParams > n.maxParams { + n.maxParams = numParams + } + numParams-- + + // Check if the wildcard matches + if len(path) >= len(n.path) && n.path == path[:len(n.path)] && + // Check for longer wildcard, e.g. :name and :names + (len(n.path) >= len(path) || path[len(n.path)] == '/') { + continue walk + } else { + // Wildcard conflict + var pathSeg string + if n.nType == catchAll { + pathSeg = path + } else { + pathSeg = strings.SplitN(path, "/", 2)[0] + } + prefix := fullPath[:strings.Index(fullPath, pathSeg)] + n.path + panic("'" + pathSeg + + "' in new path '" + fullPath + + "' conflicts with existing wildcard '" + n.path + + "' in existing prefix '" + prefix + + "'") + } + } + + c := path[0] + + // slash after param + if n.nType == param && c == '/' && len(n.children) == 1 { + n = n.children[0] + n.priority++ + continue walk + } + + // Check if a child with the next path byte exists + for i := 0; i < len(n.indices); i++ { + if c == n.indices[i] { + i = n.incrementChildPrio(i) + n = n.children[i] + continue walk + } + } + + // Otherwise insert it + if c != ':' && c != '*' { + // []byte for proper unicode char conversion, see #65 + n.indices += string([]byte{c}) + child := &node{ + maxParams: numParams, + } + n.children = append(n.children, child) + n.incrementChildPrio(len(n.indices) - 1) + n = child + } + n.insertChild(numParams, path, fullPath, handle) + return + + } else if i == len(path) { // Make node a (in-path) leaf + if n.handle != nil { + panic("a handle is already registered for path '" + fullPath + "'") + } + n.handle = handle + } + return + } + } else { // Empty tree + n.insertChild(numParams, path, fullPath, handle) + n.nType = root + } +} + +func (n *node) insertChild(numParams uint8, path, fullPath string, handle Handle) { + var offset int // already handled bytes of the path + + // find prefix until first wildcard (beginning with ':'' or '*'') + for i, max := 0, len(path); numParams > 0; i++ { + c := path[i] + if c != ':' && c != '*' { + continue + } + + // find wildcard end (either '/' or path end) + end := i + 1 + for end < max && path[end] != '/' { + switch path[end] { + // the wildcard name must not contain ':' and '*' + case ':', '*': + panic("only one wildcard per path segment is allowed, has: '" + + path[i:] + "' in path '" + fullPath + "'") + default: + end++ + } + } + + // check if this Node existing children which would be + // unreachable if we insert the wildcard here + if len(n.children) > 0 { + panic("wildcard route '" + path[i:end] + + "' conflicts with existing children in path '" + fullPath + "'") + } + + // check if the wildcard has a name + if end-i < 2 { + panic("wildcards must be named with a non-empty name in path '" + fullPath + "'") + } + + if c == ':' { // param + // split path at the beginning of the wildcard + if i > 0 { + n.path = path[offset:i] + offset = i + } + + child := &node{ + nType: param, + maxParams: numParams, + } + n.children = []*node{child} + n.wildChild = true + n = child + n.priority++ + numParams-- + + // if the path doesn't end with the wildcard, then there + // will be another non-wildcard subpath starting with '/' + if end < max { + n.path = path[offset:end] + offset = end + + child := &node{ + maxParams: numParams, + priority: 1, + } + n.children = []*node{child} + n = child + } + + } else { // catchAll + if end != max || numParams > 1 { + panic("catch-all routes are only allowed at the end of the path in path '" + fullPath + "'") + } + + if len(n.path) > 0 && n.path[len(n.path)-1] == '/' { + panic("catch-all conflicts with existing handle for the path segment root in path '" + fullPath + "'") + } + + // currently fixed width 1 for '/' + i-- + if path[i] != '/' { + panic("no / before catch-all in path '" + fullPath + "'") + } + + n.path = path[offset:i] + + // first node: catchAll node with empty path + child := &node{ + wildChild: true, + nType: catchAll, + maxParams: 1, + } + n.children = []*node{child} + n.indices = string(path[i]) + n = child + n.priority++ + + // second node: node holding the variable + child = &node{ + path: path[i:], + nType: catchAll, + maxParams: 1, + handle: handle, + priority: 1, + } + n.children = []*node{child} + + return + } + } + + // insert remaining path part and handle to the leaf + n.path = path[offset:] + n.handle = handle +} + +// Returns the handle registered with the given path (key). The values of +// wildcards are saved to a map. +// If no handle can be found, a TSR (trailing slash redirect) recommendation is +// made if a handle exists with an extra (without the) trailing slash for the +// given path. +func (n *node) getValue(path string) (handle Handle, p Params, tsr bool) { +walk: // outer loop for walking the tree + for { + if len(path) > len(n.path) { + if path[:len(n.path)] == n.path { + path = path[len(n.path):] + // If this node does not have a wildcard (param or catchAll) + // child, we can just look up the next child node and continue + // to walk down the tree + if !n.wildChild { + c := path[0] + for i := 0; i < len(n.indices); i++ { + if c == n.indices[i] { + n = n.children[i] + continue walk + } + } + // 此处对getValue方法进行部分修改,以适应匹配前缀的需求 + handle = n.handle + pathLen := len(path) + tsr = string(path[pathLen-1]) == "/" && n.handle != nil + // Nothing found. + // We can recommend to redirect to the same URL without a + // trailing slash if a leaf exists for that path. + + //tsr = (path == "/" && n.handle != nil) + return + + } + + // handle wildcard child + n = n.children[0] + switch n.nType { + case param: + // find param end (either '/' or path end) + end := 0 + for end < len(path) && path[end] != '/' { + end++ + } + + // save param value + if p == nil { + // lazy allocation + p = make(Params, 0, n.maxParams) + } + i := len(p) + p = p[:i+1] // expand slice within preallocated capacity + p[i].Key = n.path[1:] + p[i].Value = path[:end] + + // we need to go deeper! + if end < len(path) { + if len(n.children) > 0 { + path = path[end:] + n = n.children[0] + continue walk + } + + // ... but we can't + tsr = (len(path) == end+1) + return + } + + if handle = n.handle; handle != nil { + return + } else if len(n.children) == 1 { + // No handle found. Check if a handle for this path + a + // trailing slash exists for TSR recommendation + n = n.children[0] + tsr = (n.path == "/" && n.handle != nil) + } + + return + + case catchAll: + // save param value + if p == nil { + // lazy allocation + p = make(Params, 0, n.maxParams) + } + i := len(p) + p = p[:i+1] // expand slice within preallocated capacity + p[i].Key = n.path[2:] + p[i].Value = path + + handle = n.handle + return + + default: + panic("invalid node type") + } + } + } else if path == n.path { + // We should have reached the node containing the handle. + // Check if this node has a handle registered. + if handle = n.handle; handle != nil { + return + } + + if path == "/" && n.wildChild && n.nType != root { + tsr = true + return + } + + // No handle found. Check if a handle for this path + a + // trailing slash exists for trailing slash recommendation + for i := 0; i < len(n.indices); i++ { + if n.indices[i] == '/' { + n = n.children[i] + tsr = (len(n.path) == 1 && n.handle != nil) || + (n.nType == catchAll && n.children[0].handle != nil) + return + } + } + + return + } + + // Nothing found. We can recommend to redirect to the same URL with an + // extra trailing slash if a leaf exists for that path + tsr = (path == "/") || + (len(n.path) == len(path)+1 && n.path[len(path)] == '/' && + path == n.path[:len(n.path)-1] && n.handle != nil) + return + } +} + +// Makes a case-insensitive lookup of the given path and tries to find a handler. +// It can optionally also fix trailing slashes. +// It returns the case-corrected path and a bool indicating whether the lookup +// was successful. +func (n *node) findCaseInsensitivePath(path string, fixTrailingSlash bool) (ciPath []byte, found bool) { + return n.findCaseInsensitivePathRec( + path, + strings.ToLower(path), + make([]byte, 0, len(path)+1), // preallocate enough memory for new path + [4]byte{}, // empty rune buffer + fixTrailingSlash, + ) +} + +// shift bytes in array by n bytes left +func shiftNRuneBytes(rb [4]byte, n int) [4]byte { + switch n { + case 0: + return rb + case 1: + return [4]byte{rb[1], rb[2], rb[3], 0} + case 2: + return [4]byte{rb[2], rb[3]} + case 3: + return [4]byte{rb[3]} + default: + return [4]byte{} + } +} + +// recursive case-insensitive lookup function used by n.findCaseInsensitivePath +func (n *node) findCaseInsensitivePathRec(path, loPath string, ciPath []byte, rb [4]byte, fixTrailingSlash bool) ([]byte, bool) { + loNPath := strings.ToLower(n.path) + +walk: // outer loop for walking the tree + for len(loPath) >= len(loNPath) && (len(loNPath) == 0 || loPath[1:len(loNPath)] == loNPath[1:]) { + // add common path to result + ciPath = append(ciPath, n.path...) + + if path = path[len(n.path):]; len(path) > 0 { + loOld := loPath + loPath = loPath[len(loNPath):] + + // If this node does not have a wildcard (param or catchAll) child, + // we can just look up the next child node and continue to walk down + // the tree + if !n.wildChild { + // skip rune bytes already processed + rb = shiftNRuneBytes(rb, len(loNPath)) + + if rb[0] != 0 { + // old rune not finished + for i := 0; i < len(n.indices); i++ { + if n.indices[i] == rb[0] { + // continue with child node + n = n.children[i] + loNPath = strings.ToLower(n.path) + continue walk + } + } + } else { + // process a new rune + var rv rune + + // find rune start + // runes are up to 4 byte long, + // -4 would definitely be another rune + var off int + for max := min(len(loNPath), 3); off < max; off++ { + if i := len(loNPath) - off; utf8.RuneStart(loOld[i]) { + // read rune from cached lowercase path + rv, _ = utf8.DecodeRuneInString(loOld[i:]) + break + } + } + + // calculate lowercase bytes of current rune + utf8.EncodeRune(rb[:], rv) + // skipp already processed bytes + rb = shiftNRuneBytes(rb, off) + + for i := 0; i < len(n.indices); i++ { + // lowercase matches + if n.indices[i] == rb[0] { + // must use a recursive approach since both the + // uppercase byte and the lowercase byte might exist + // as an index + if out, found := n.children[i].findCaseInsensitivePathRec( + path, loPath, ciPath, rb, fixTrailingSlash, + ); found { + return out, true + } + break + } + } + + // same for uppercase rune, if it differs + if up := unicode.ToUpper(rv); up != rv { + utf8.EncodeRune(rb[:], up) + rb = shiftNRuneBytes(rb, off) + + for i := 0; i < len(n.indices); i++ { + // uppercase matches + if n.indices[i] == rb[0] { + // continue with child node + n = n.children[i] + loNPath = strings.ToLower(n.path) + continue walk + } + } + } + } + + // Nothing found. We can recommend to redirect to the same URL + // without a trailing slash if a leaf exists for that path + return ciPath, (fixTrailingSlash && path == "/" && n.handle != nil) + } + + n = n.children[0] + switch n.nType { + case param: + // find param end (either '/' or path end) + k := 0 + for k < len(path) && path[k] != '/' { + k++ + } + + // add param value to case insensitive path + ciPath = append(ciPath, path[:k]...) + + // we need to go deeper! + if k < len(path) { + if len(n.children) > 0 { + // continue with child node + n = n.children[0] + loNPath = strings.ToLower(n.path) + loPath = loPath[k:] + path = path[k:] + continue + } + + // ... but we can't + if fixTrailingSlash && len(path) == k+1 { + return ciPath, true + } + return ciPath, false + } + + if n.handle != nil { + return ciPath, true + } else if fixTrailingSlash && len(n.children) == 1 { + // No handle found. Check if a handle for this path + a + // trailing slash exists + n = n.children[0] + if n.path == "/" && n.handle != nil { + return append(ciPath, '/'), true + } + } + return ciPath, false + + case catchAll: + return append(ciPath, path...), true + + default: + panic("invalid node type") + } + } else { + // We should have reached the node containing the handle. + // Check if this node has a handle registered. + if n.handle != nil { + return ciPath, true + } + + // No handle found. + // Try to fix the path by adding a trailing slash + if fixTrailingSlash { + for i := 0; i < len(n.indices); i++ { + if n.indices[i] == '/' { + n = n.children[i] + if (len(n.path) == 1 && n.handle != nil) || + (n.nType == catchAll && n.children[0].handle != nil) { + return append(ciPath, '/'), true + } + return ciPath, false + } + } + } + return ciPath, false + } + } + + // Nothing found. + // Try to fix the path by adding / removing a trailing slash + if fixTrailingSlash { + if path == "/" { + return ciPath, true + } + if len(loPath)+1 == len(loNPath) && loNPath[len(loPath)] == '/' && + loPath[1:] == loNPath[1:len(loPath)] && n.handle != nil { + return append(ciPath, n.path...), true + } + } + return ciPath, false +} diff --git a/module/manager.go b/module/manager.go new file mode 100644 index 00000000..4b6d790c --- /dev/null +++ b/module/manager.go @@ -0,0 +1,2 @@ +package module + diff --git a/module/prometheus/config/config.go b/module/prometheus/config/config.go index fbe24efb..984fa41d 100644 --- a/module/prometheus/config/config.go +++ b/module/prometheus/config/config.go @@ -12,7 +12,7 @@ const moduleName = "Prometheus" //Pattern 请求路径 const Pattern = "/prometheus/metrics" -const desc = "API监控模块对接Prometheus" +const desc = "对接Prometheus" const content = `[ { "type": "line", @@ -43,8 +43,8 @@ func (c *PrometheusModule) GetNameSpace() string { return ModuleNameSpace } -//Encoder encode -func (c *PrometheusModule) Encoder(v interface{}) (string, error) { +//Encode encode +func (c *PrometheusModule) Encode(v interface{}) (string, error) { return "", nil } diff --git a/module/prometheus/prometheus.go b/module/prometheus/prometheus.go index 3582f4ff..b2dc19aa 100644 --- a/module/prometheus/prometheus.go +++ b/module/prometheus/prometheus.go @@ -92,7 +92,7 @@ func (p *Prometheus) NewCounter(opts *diting.CounterOpts) (diting.Counter, error return newCounter(c), nil } -//NewHistogram new Histogram +//NewHistogram new HistogramObserve func (p *Prometheus) NewHistogram(opts *diting.HistogramOpts) (diting.Histogram, error) { h := prometheus.NewHistogramVec(ReadHistogramOpts(opts), opts.LabelNames) err := p.registry.Register(h) diff --git a/module/status.go b/module/status.go index cbb7fa88..5cd59129 100644 --- a/module/status.go +++ b/module/status.go @@ -47,7 +47,6 @@ func Open(name string) { m.locker.Lock() m.modules[name] = true m.locker.Unlock() - } //Refresh refresh @@ -59,5 +58,5 @@ func Refresh(States []State) { m.modules[s.name] = s.isOpen } m.locker.Unlock() - } + diff --git a/node/admin/handler.go b/node/admin/handler.go index 1eee7224..47b61b46 100644 --- a/node/admin/handler.go +++ b/node/admin/handler.go @@ -71,7 +71,7 @@ func Handler() http.Handler { return handler } -//Add add +//Add( add func Add(name string, pattern string, h http.Handler) { handler.Add(name, pattern, h) } diff --git a/node/console/console.go b/node/console/console.go index 616cc633..2822054c 100644 --- a/node/console/console.go +++ b/node/console/console.go @@ -1,32 +1,17 @@ package console import ( - "context" - "sync" + "github.com/eolinker/goku-api-gateway/config" ) -//Console console -type Console struct { - adminHost string - instance string - ctx context.Context - cancel context.CancelFunc - lastVersion int - once sync.Once +//ConfigConsole configConsole +type ConfigConsole interface { + Close() + AddListen(callback ConfigCallbackFunc) + GetConfig() (*config.GokuConfig, error) + RegisterToConsole() (*config.GokuConfig, error) + Listen() } -//Close close -func (c *Console) Close() { - c.once.Do(c.cancel) -} - -//NewConsole newConsole -func NewConsole(instance string, adminHost string) *Console { - ctx, cancel := context.WithCancel(context.Background()) - return &Console{ - instance: instance, - adminHost: adminHost, - ctx: ctx, - cancel: cancel, - } -} +//ConfigCallbackFunc configCallbackFunc +type ConfigCallbackFunc func(conf *config.GokuConfig) diff --git a/node/gateway/api.go b/node/gateway/api.go index 91740dc1..6880001b 100644 --- a/node/gateway/api.go +++ b/node/gateway/api.go @@ -50,9 +50,10 @@ func (h *API) Router(ctx *common.Context) { func (h *API) accessFlow(ctx *common.Context) bool { for _, handler := range h.pluginAccess { - - flag, _ := handler.Execute(ctx) - + flag, err := handler.Execute(ctx) + if err != nil { + fmt.Println(err) + } if flag == false && handler.IsStop() { return false @@ -70,7 +71,6 @@ func (h *API) accessGlobalFlow(ctx *common.Context) { func (h *API) proxyFlow(ctx *common.Context) bool { for _, handler := range h.pluginProxies { - flag, _ := handler.Execute(ctx) if flag == false && handler.IsStop() { diff --git a/node/gateway/application/backend/backend.go b/node/gateway/application/backend/backend.go index 73b3b18d..24809436 100644 --- a/node/gateway/application/backend/backend.go +++ b/node/gateway/application/backend/backend.go @@ -1,3 +1 @@ package backend - - diff --git a/node/gateway/application/backend/filter.go b/node/gateway/application/backend/filter.go index 2eb17859..b6ab383c 100644 --- a/node/gateway/application/backend/filter.go +++ b/node/gateway/application/backend/filter.go @@ -6,23 +6,23 @@ import ( ) func genFilter(blackList, whiteList []string, acs []*config.ActionConfig) action.Filter { - size:=len(blackList)+1 + len(acs) + size := len(blackList) + 1 + len(acs) - filters:= make(action.Filters,0,size) + filters := make(action.Filters, 0, size) - for _,b:=range blackList{ - filters = append(filters,action.Blacklist(b)) + for _, b := range blackList { + filters = append(filters, action.Blacklist(b)) } - if len(whiteList)>0{ - filters = append(filters,action.GenWhite(whiteList)) + if len(whiteList) > 0 { + filters = append(filters, action.GenWhite(whiteList)) } - for _,ac:=range acs{ + for _, ac := range acs { - f:=action.GenByconfig(ac) - if f!= nil{ - filters = append(filters,f) + f := action.GenByconfig(ac) + if f != nil { + filters = append(filters, f) } } return filters -} \ No newline at end of file +} diff --git a/node/gateway/application/backend/layer.go b/node/gateway/application/backend/layer.go index fac80c20..3c5faeb9 100644 --- a/node/gateway/application/backend/layer.go +++ b/node/gateway/application/backend/layer.go @@ -1,6 +1,7 @@ package backend import ( + "compress/gzip" "context" "io/ioutil" "strings" @@ -41,7 +42,7 @@ func (b *Layer) Send(deadline context.Context, ctx *common.Context, variables *i body := b.Body.Execution(variables) method := b.Method - r, finalTargetServer, retryTargetServers, err := b.Balance.Send(b.Protocol, method, path, ctx.ProxyRequest.Querys(), ctx.ProxyRequest.Headers(), []byte(body), b.TimeOut, b.Retry) + r, finalTargetServer, retryTargetServers, err := b.Balance.Send(ctx, b.Protocol, method, path, ctx.ProxyRequest.Querys(), ctx.ProxyRequest.Headers(), []byte(body), b.TimeOut, b.Retry) if err != nil { return nil, err @@ -57,7 +58,13 @@ func (b *Layer) Send(deadline context.Context, ctx *common.Context, variables *i } defer r.Body.Close() - backendResponse.BodyOrg, err = ioutil.ReadAll(r.Body) + bd := r.Body + if r.Header.Get("Content-Encoding") == "gzip" { + bd, _ = gzip.NewReader(r.Body) + r.Header.Del("Content-Encoding") + } + + backendResponse.BodyOrg, err = ioutil.ReadAll(bd) if err != nil { return backendResponse, nil } @@ -76,6 +83,7 @@ func (b *Layer) Send(deadline context.Context, ctx *common.Context, variables *i if len(b.Group) > 0 { rp.Group(b.Group) } + backendResponse.Body = rp.Data return backendResponse, nil } @@ -95,7 +103,7 @@ func NewLayer(step *config.APIStepConfig) *Layer { Target: step.Target, Group: nil, TimeOut: time.Duration(step.TimeOut) * time.Millisecond, - Body: interpreter.Gen(step.Body), + Body: interpreter.Gen(step.Body, step.Encode), Retry: step.Retry, } if step.Group != "" { diff --git a/node/gateway/application/backend/proxy.go b/node/gateway/application/backend/proxy.go index d58bbd8a..a18185ce 100644 --- a/node/gateway/application/backend/proxy.go +++ b/node/gateway/application/backend/proxy.go @@ -1,6 +1,7 @@ package backend import ( + "compress/gzip" "fmt" "io/ioutil" "strings" @@ -67,18 +68,20 @@ func (b *Proxy) Send(ctx *common.Context, variables *interpreter.Variables) (*Ba // 不是restful时,将匹配路由之后对url拼接到path之后 if len(variables.Restful) == 0 { - orgRequestURL := ctx.RequestOrg.URL().RawPath + orgRequestURL := ctx.RequestOrg.URL().Path lessPath := strings.TrimPrefix(orgRequestURL, b.RequestPath) lessPath = strings.TrimPrefix(lessPath, "/") - path = strings.TrimSuffix(path, "/") - path = fmt.Sprint(path, "/", lessPath) + if lessPath != "" { + path = strings.TrimSuffix(path, "/") + path = fmt.Sprint(path, "/", lessPath) + } } method := b.Method if method == "FOLLOW" { method = ctx.ProxyRequest.Method } - r, finalTargetServer, retryTargetServers, err := b.Balance.Send(b.Protocol, method, path, ctx.ProxyRequest.Querys(), ctx.ProxyRequest.Headers(), variables.Org, b.TimeOut, b.Retry) + r, finalTargetServer, retryTargetServers, err := b.Balance.Send(ctx, b.Protocol, method, path, ctx.ProxyRequest.Querys(), ctx.ProxyRequest.Headers(), variables.Org, b.TimeOut, b.Retry) backendResponse := &BackendResponse{ Method: method, @@ -89,15 +92,21 @@ func (b *Proxy) Send(ctx *common.Context, variables *interpreter.Variables) (*Ba TargetURL: path, FinalTargetServer: finalTargetServer, RetryTargetServers: retryTargetServers, - Header: r.Header, + //Cookies:r.Cookies(), } if err != nil { backendResponse.StatusCode, backendResponse.Status = 503, "503" return backendResponse, err } + backendResponse.Header = r.Header defer r.Body.Close() - backendResponse.BodyOrg, err = ioutil.ReadAll(r.Body) + bd := r.Body + if r.Header.Get("Content-Encoding") == "gzip" { + bd, _ = gzip.NewReader(r.Body) + r.Header.Del("Content-Encoding") + } + backendResponse.BodyOrg, err = ioutil.ReadAll(bd) if err != nil { return backendResponse, nil } diff --git a/node/gateway/application/interpreter/analysis.go b/node/gateway/application/interpreter/analysis.go index cf8b7fb0..8d2ac828 100644 --- a/node/gateway/application/interpreter/analysis.go +++ b/node/gateway/application/interpreter/analysis.go @@ -17,7 +17,12 @@ var ( ) //Gen gen -func Gen(tpl string) Interpreter { +func Gen(tpl string, encode string) Interpreter { + if encode == "origin" { + exe := make(_Executor, 1, 1) + exe[0] = new(_OrgReader) + return exe + } tpl = strings.TrimSpace(tpl) i, err := Parse(tpl) if err != nil { diff --git a/node/gateway/application/layer.go b/node/gateway/application/layer.go index 7c6abf15..46e37ce3 100644 --- a/node/gateway/application/layer.go +++ b/node/gateway/application/layer.go @@ -2,6 +2,7 @@ package application import ( "context" + "fmt" "time" "github.com/eolinker/goku-api-gateway/config" @@ -54,8 +55,8 @@ func (app *LayerApplication) Execute(ctx *common.Context) { ctx.SetBody([]byte("[ERROR]timeout!")) // 超时 return - case <-errC: - + case e := <-errC: + fmt.Println(e) cancelFunc() ctx.SetStatus(504, "504") ctx.SetBody([]byte("[ERROR]Fail to get response after proxy!")) @@ -74,7 +75,13 @@ func (app *LayerApplication) Execute(ctx *common.Context) { log.Warn("encode response error:", e) return } - + //if headers.Get("Content-Encoding") == "gzip" { + // var b bytes.Buffer + // wb := gzip.NewWriter(&b) + // wb.Write(body) + // wb.Flush() + // body, _ = ioutil.ReadAll(&b) + //} ctx.SetProxyResponseHandler(common.NewResponseReader(headers, 200, "200", body)) } diff --git a/node/gateway/application/proxy.go b/node/gateway/application/proxy.go index f19605c0..271d3045 100644 --- a/node/gateway/application/proxy.go +++ b/node/gateway/application/proxy.go @@ -4,6 +4,8 @@ import ( "fmt" "strings" + "github.com/eolinker/goku-api-gateway/goku-service/application" + "github.com/eolinker/goku-api-gateway/config" log "github.com/eolinker/goku-api-gateway/goku-log" "github.com/eolinker/goku-api-gateway/goku-node/common" @@ -64,11 +66,12 @@ func (app *DefaultApplication) Execute(ctx *common.Context) { ctx.LogFields[access_field.FinallyServer] = ctx.FinalTargetServer() ctx.LogFields[access_field.Retry] = ctx.RetryTargetServers() - ctx.LogFields[access_field.Proxy] = fmt.Sprintf("\"%s %s %s\"", r.Method, r.TargetURL, r.Protocol) + ctx.LogFields[access_field.Proxy] = fmt.Sprintf("\"%s %s %s\"", r.Method, application.URLPath(r.TargetURL, ctx.ProxyRequest.Querys()), r.Protocol) } if err != nil { - + ctx.SetStatus(504, "504") + ctx.SetBody([]byte("[ERROR]Fail to get response after proxy!")) log.Warn(err) return } diff --git a/node/gateway/application/static-response.go b/node/gateway/application/static-response.go index a5b7d04e..4a9fc124 100644 --- a/node/gateway/application/static-response.go +++ b/node/gateway/application/static-response.go @@ -6,7 +6,7 @@ import ( ) type staticeResponse struct { - body []byte + body []byte strategy config.StaticResponseStrategy } @@ -16,5 +16,5 @@ func newStaticeResponse(body string, strategy config.StaticResponseStrategy) *st func (sp *staticeResponse) Do(ctx *common.Context) { ctx.SetBody(sp.body) - ctx.SetStatus(200,"200") -} \ No newline at end of file + ctx.SetStatus(200, "200") +} diff --git a/node/gateway/befor.go b/node/gateway/befor.go index 69d255ad..f21653fb 100644 --- a/node/gateway/befor.go +++ b/node/gateway/befor.go @@ -61,6 +61,7 @@ func (r *Before) BeforeMatch(ctx *common.Context) bool { func (r *Before) rout(w http.ResponseWriter, req *http.Request, ctx *common.Context) { strategyID := utils.GetStrateyID(ctx) + if strategyID == "" { // 没有策略id if r.anonymousStrategy == "" { diff --git a/node/gateway/const.go b/node/gateway/const.go index 6c6a2346..d9283aa0 100644 --- a/node/gateway/const.go +++ b/node/gateway/const.go @@ -1,10 +1,10 @@ package gateway -var( +var ( authNames = map[string]string{ "Oauth2": "goku-oauth2_auth", "Apikey": "goku-apikey_auth", "Basic": "goku-basic_auth", "Jwt": "goku-jwt_auth", } -) \ No newline at end of file +) diff --git a/node/gateway/http.go b/node/gateway/http.go index 119c50f3..b9043e96 100644 --- a/node/gateway/http.go +++ b/node/gateway/http.go @@ -17,7 +17,7 @@ import ( fields "github.com/eolinker/goku-api-gateway/server/access-field" ) -var systemRequestPath = []string{"/oauth2/token", "/oauth2/authorize", "/oauth2/verify"} +var systemRequestPath = map[string]bool{"/oauth2/token": true, "/oauth2/authorize": true, "/oauth2/verify": true} //HTTPHandler httpHandler type HTTPHandler struct { @@ -61,12 +61,16 @@ func (h *HTTPHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { ctx.LogFields[fields.HTTPUserAgent] = fmt.Sprint("\"", req.UserAgent(), "\"") ctx.LogFields[fields.HTTPReferer] = req.Referer() ctx.LogFields[fields.RequestTime] = delay - ctx.LogFields[fields.Request] = fmt.Sprint("\"", req.Method, " ", req.URL.Path, " ", req.Proto, "\"") + ctx.LogFields[fields.Request] = fmt.Sprint("\"", req.Method, " ", req.URL.String(), " ", req.Proto, "\"") ctx.LogFields[fields.BodyBytesSent] = n ctx.LogFields[fields.Host] = req.Host access_log.Log(ctx.LogFields) log.WithFields(ctx.LogFields).Info() + // /oauth2的path不参与统计 + if systemRequestPath[req.URL.Path] { + return + } // 监控计数 labels := make(diting.Labels) diff --git a/node/gateway/plugin-executor/executor.go b/node/gateway/plugin-executor/executor.go index bb75ca13..7094c9f5 100644 --- a/node/gateway/plugin-executor/executor.go +++ b/node/gateway/plugin-executor/executor.go @@ -1,82 +1,93 @@ package plugin_executor import ( - goku_plugin "github.com/eolinker/goku-plugin" + "time" + "github.com/eolinker/goku-api-gateway/config" log "github.com/eolinker/goku-api-gateway/goku-log" "github.com/eolinker/goku-api-gateway/goku-node/common" - "time" + goku_plugin "github.com/eolinker/goku-plugin" ) +//Executor executor type Executor interface { - Execute(ctx *common.Context)(isContinue bool, e error) - IsStop()bool + Execute(ctx *common.Context) (isContinue bool, e error) + IsStop() bool + IsAuth() bool } type executorInfo struct { - Name string + Name string isStop bool + isAuth bool } +func (ex *executorInfo) IsStop() bool { + return ex.isStop +} - -func (ex*executorInfo) IsStop() bool { - return ex.isStop +func (ex *executorInfo) IsAuth() bool { + return ex.isAuth } func genExecutor(cfg *config.PluginConfig) executorInfo { return executorInfo{ - Name:cfg.Name, - isStop:cfg.IsStop, + Name: cfg.Name, + isStop: cfg.IsStop, + isAuth: cfg.IsAuth, } } + type beforeExecutor struct { executorInfo plugin goku_plugin.PluginBeforeMatch - } -func (ex*beforeExecutor) Execute(ctx *common.Context) (isContinue bool, e error) { - requestId:=ctx.RequestId() +//Execute execute +func (ex *beforeExecutor) Execute(ctx *common.Context) (isContinue bool, e error) { + requestID := ctx.RequestId() ctx.SetPlugin(ex.Name) - log.Debug(requestId, " before plugin :", ex.Name, " start") + log.Debug(requestID, " before plugin :", ex.Name, " start") now := time.Now() isContinue, err := ex.plugin.BeforeMatch(ctx) - log.Debug(requestId, " before plugin :", ex.Name, " Duration:", time.Since(now)) - log.Debug(requestId, " before plugin :", ex.Name, " end") + log.Debug(requestID, " before plugin :", ex.Name, " Duration:", time.Since(now)) + log.Debug(requestID, " before plugin :", ex.Name, " end") if err != nil { - log.Warn(requestId, " before plugin:", ex.Name, " error:", err) + log.Warn(requestID, " before plugin:", ex.Name, " error:", err) } - return isContinue,err + return isContinue, err } -func NewBeforeExecutor(cfg *config.PluginConfig,p goku_plugin.PluginBeforeMatch ) *beforeExecutor { +//NewBeforeExecutor 创建before阶段执行器 +func NewBeforeExecutor(cfg *config.PluginConfig, p goku_plugin.PluginBeforeMatch) *beforeExecutor { return &beforeExecutor{ executorInfo: genExecutor(cfg), plugin: p, } } + type accessExecutor struct { executorInfo plugin goku_plugin.PluginAccess } func (ex *accessExecutor) Execute(ctx *common.Context) (isContinue bool, e error) { - requestId:=ctx.RequestId() + requestID := ctx.RequestId() ctx.SetPlugin(ex.Name) - log.Debug(requestId, " access plugin :", ex.Name, " start") + log.Debug(requestID, " access plugin :", ex.Name, " start") now := time.Now() isContinue, err := ex.plugin.Access(ctx) - log.Debug(requestId, " access plugin :", ex.Name, " Duration:", time.Since(now)) - log.Debug(requestId, " access plugin :", ex.Name, " end") + log.Debug(requestID, " access plugin :", ex.Name, " Duration:", time.Since(now)) + log.Debug(requestID, " access plugin :", ex.Name, " end") if err != nil { - log.Warn(requestId, " access plugin:", ex.Name, " error:", err) + log.Warn(requestID, " access plugin:", ex.Name, " error:", err) } - return isContinue,err + return isContinue, err } -func NewAccessExecutor(cfg *config.PluginConfig,p goku_plugin.PluginAccess ) *accessExecutor { +//NewAccessExecutor 创建access阶段执行器 +func NewAccessExecutor(cfg *config.PluginConfig, p goku_plugin.PluginAccess) *accessExecutor { return &accessExecutor{ executorInfo: genExecutor(cfg), plugin: p, @@ -88,24 +99,26 @@ type proxyExecutor struct { plugin goku_plugin.PluginProxy } -func (ex*proxyExecutor) Execute(ctx *common.Context) (isContinue bool, e error) { - requestId:=ctx.RequestId() +//Execute execute +func (ex *proxyExecutor) Execute(ctx *common.Context) (isContinue bool, e error) { + requestID := ctx.RequestId() ctx.SetPlugin(ex.Name) - log.Debug(requestId, " proxy plugin :", ex.Name, " start") + log.Debug(requestID, " proxy plugin :", ex.Name, " start") now := time.Now() isContinue, err := ex.plugin.Proxy(ctx) - log.Debug(requestId, " proxy plugin :", ex.Name, " Duration:", time.Since(now)) - log.Debug(requestId, " proxy plugin :", ex.Name, " end") + log.Debug(requestID, " proxy plugin :", ex.Name, " Duration:", time.Since(now)) + log.Debug(requestID, " proxy plugin :", ex.Name, " end") if err != nil { - log.Warn(requestId, " proxy plugin:", ex.Name, " error:", err) + log.Warn(requestID, " proxy plugin:", ex.Name, " error:", err) } - return isContinue,err + return isContinue, err } -func NewProxyExecutor(cfg *config.PluginConfig,p goku_plugin.PluginProxy ) *proxyExecutor { +//NewProxyExecutor 创建proxy阶段执行器 +func NewProxyExecutor(cfg *config.PluginConfig, p goku_plugin.PluginProxy) *proxyExecutor { return &proxyExecutor{ executorInfo: genExecutor(cfg), plugin: p, } -} \ No newline at end of file +} diff --git a/node/gateway/plugin.go b/node/gateway/plugin.go index 4427e802..946933db 100644 --- a/node/gateway/plugin.go +++ b/node/gateway/plugin.go @@ -2,6 +2,7 @@ package gateway import ( "reflect" + "strings" "github.com/eolinker/goku-api-gateway/config" plugin_executor "github.com/eolinker/goku-api-gateway/node/gateway/plugin-executor" @@ -32,7 +33,6 @@ func genPlugins(cfgs []*config.PluginConfig, cluster string, strategyID string, psBefor := make([]plugin_executor.Executor, 0, len(cfgs)) psAccess := make([]plugin_executor.Executor, 0, len(cfgs)) psProxy := make([]plugin_executor.Executor, 0, len(cfgs)) - for _, cfg := range cfgs { factory, e := plugin.LoadPlugin(cfg.Name) @@ -48,6 +48,9 @@ func genPlugins(cfgs []*config.PluginConfig, cluster string, strategyID string, psBefor = append(psBefor, plugin_executor.NewBeforeExecutor(cfg, obj.BeforeMatch)) } if obj.Access != nil && !reflect.ValueOf(obj.Access).IsNil() { + if strings.Contains(cfg.Name, "_auth") { + cfg.IsAuth = true + } psAccess = append(psAccess, plugin_executor.NewAccessExecutor(cfg, obj.Access)) } if obj.Proxy != nil && !reflect.ValueOf(obj.Proxy).IsNil() { diff --git a/node/gateway/response/decode.go b/node/gateway/response/decode.go index b96844fd..70d36168 100644 --- a/node/gateway/response/decode.go +++ b/node/gateway/response/decode.go @@ -3,26 +3,45 @@ package response import ( "encoding/json" "strings" + + "github.com/eolinker/goku-api-gateway/utils" ) -const( - JSON ="json" + +const ( + //JSON json + JSON = "json" + //XML xml XML = "xml" + //String string String = "string" + //JSONNoQuote 非标准json(key不带双引号) + JSONNoQuote = "json-noquote" ) + var ( - jsonDecoder = func(data []byte, v interface{}) error { - err:=json.Unmarshal(data,v) + jsonDecoder = func(data []byte, v interface{}) error { + err := json.Unmarshal(data, v) + return err + } + jsonNoQuoteDecoder = func(data []byte, v interface{}) error { + d, err := utils.JSObjectToJSON(string(data)) + if err != nil { + return err + } + err = json.Unmarshal(d, v) return err } - ) + +//GetDecoder getDecoder func GetDecoder(decoder string) DecodeHandle { switch strings.ToLower(decoder) { case JSON: return jsonDecoder + case JSONNoQuote: + return jsonNoQuoteDecoder } return nil } - diff --git a/node/gateway/response/decoder.go b/node/gateway/response/decoder.go index f4e1ef4d..fafab207 100644 --- a/node/gateway/response/decoder.go +++ b/node/gateway/response/decoder.go @@ -3,29 +3,36 @@ package response import "errors" var ( + //ErrorInvalidDecoder 非法Decoder ErrorInvalidDecoder = errors.New("invalid decoder") ) + +//DecodeHandle 解码器 type DecodeHandle func(data []byte, v interface{}) error -type EncodeHandle func (v interface{},org []byte)([]byte,error) +//EncodeHandle 解码处理器 +type EncodeHandle func(v interface{}, org []byte) ([]byte, error) + +//Encoder 解码器 type Encoder interface { - Encode(v interface{},org []byte)([]byte,error) - ContentType()string + Encode(v interface{}, org []byte) ([]byte, error) + ContentType() string } -func Decode(data []byte,handle DecodeHandle) (*Response,error) { +//Decode 解码 +func Decode(data []byte, handle DecodeHandle) (*Response, error) { - if handle == nil{ - return nil,ErrorInvalidDecoder + if handle == nil { + return nil, ErrorInvalidDecoder } var v interface{} - err:=handle(data,&v) - if err!=nil{ - return nil,err + err := handle(data, &v) + if err != nil { + return nil, err } return &Response{ Data: v, - },nil + }, nil } diff --git a/node/gateway/response/encode.go b/node/gateway/response/encode.go index b452fadf..65020ddb 100644 --- a/node/gateway/response/encode.go +++ b/node/gateway/response/encode.go @@ -8,47 +8,50 @@ import ( ) var ( - - jsonEncoder =& EncoderH{ - contentType:"application/json", - handleFunc:func(v interface{},org []byte)([]byte,error){ + jsonEncoder = &EncoderH{ + contentType: "application/json", + handleFunc: func(v interface{}, org []byte) ([]byte, error) { return json.Marshal(v) }, } - xmlEncoder =&EncoderH{ - contentType:"text/xml; charset=utf-8", - handleFunc:func(v interface{},org []byte) ([]byte,error){ + xmlEncoder = &EncoderH{ + contentType: "text/xml; charset=utf-8", + handleFunc: func(v interface{}, org []byte) ([]byte, error) { return xml.Marshal(v) }, } - stringEncoder =&EncoderH{ - contentType:"text/plain", - handleFunc: func(v interface{},org []byte)([]byte,error) { + stringEncoder = &EncoderH{ + contentType: "text/plain", + handleFunc: func(v interface{}, org []byte) ([]byte, error) { - return org,nil + return org, nil }, } notEncoder = &EncoderH{ contentType: "", handleFunc: func(v interface{}, org []byte) (bytes []byte, e error) { - return org,nil + return org, nil }, } ) +//EncoderH encodeH type EncoderH struct { contentType string - handleFunc EncodeHandle + handleFunc EncodeHandle } -func (e *EncoderH) Encode(v interface{},org []byte) ([]byte, error) { - return e.handleFunc(v,org) +//Encode encode +func (e *EncoderH) Encode(v interface{}, org []byte) ([]byte, error) { + return e.handleFunc(v, org) } +//ContentType contentType func (e *EncoderH) ContentType() string { return e.contentType } +//GetEncoder 获取编码器 func GetEncoder(encoder string) Encoder { switch strings.ToLower(encoder) { @@ -60,4 +63,4 @@ func GetEncoder(encoder string) Encoder { return stringEncoder } return notEncoder -} \ No newline at end of file +} diff --git a/node/gateway/response/node.go b/node/gateway/response/node.go index 1b412345..defbcb33 100644 --- a/node/gateway/response/node.go +++ b/node/gateway/response/node.go @@ -6,44 +6,42 @@ import ( ) type _Node struct { - data interface{} + data interface{} parent *_Node - index int - key string + index int + key string } -func (node *_Node)Set(v interface{}) { - if node.parent == nil{ +func (node *_Node) Set(v interface{}) { + if node.parent == nil { return } } - - -func (node*_Node)child(key string,callback func(*_Node))bool { +func (node *_Node) child(key string, callback func(*_Node)) bool { return false } -func (node *_Node)get(key string)*_Node{ +func (node *_Node) get(key string) *_Node { - if key == ""{ + if key == "" { return nil } - if key == "*"{ + if key == "*" { return node } switch node.data.(type) { case []interface{}: { - sl:=node.data.([]interface{}) - if i,e:= strconv.Atoi(key);e==nil{ - if i< len(sl){ - n:=&_Node{ - data:sl[i], - parent:node, - index:i, + sl := node.data.([]interface{}) + if i, e := strconv.Atoi(key); e == nil { + if i < len(sl) { + n := &_Node{ + data: sl[i], + parent: node, + index: i, } return n } @@ -52,9 +50,9 @@ func (node *_Node)get(key string)*_Node{ } case map[string]interface{}: { - sm :=node.data.(map[string]interface{}) - if v,has:=sm[key];has{ - n:=&_Node{ + sm := node.data.(map[string]interface{}) + if v, has := sm[key]; has { + n := &_Node{ data: v, parent: node, key: key, @@ -68,89 +66,89 @@ func (node *_Node)get(key string)*_Node{ return nil } -func (node*_Node)Make(path []string) { +func (node *_Node) Make(path []string) { - if node.data == nil{ + if node.data == nil { node.data = make(map[string]interface{}) } - makePath(node.data,path) + makePath(node.data, path) } -func makePath(data interface{},path[]string) { - if len(path) == 0{ +func makePath(data interface{}, path []string) { + if len(path) == 0 { return } - k:=path[0] - next:=path[1:] - switch data.(type){ + k := path[0] + next := path[1:] + switch data.(type) { case []interface{}: - dl:=data.([]interface{}) + dl := data.([]interface{}) if k == "*" { - for _,d:=range dl{ - makePath(d,next) + for _, d := range dl { + makePath(d, next) } - }else if i,err:=strconv.Atoi(k);err!=nil{ - if i0 ; key = spiltKey(key){ + for key := pattern; len(key) > 0; key = spiltKey(key) { - next:=next(pattern,key) - if key == "*" { - data:= node.data + next := next(pattern, key) + if key == "*" { + data := node.data switch data.(type) { case []interface{}: { sl := data.([]interface{}) - - for i, s := range sl { - n := &_Node{ - data: s, - parent: node, - index: i, - } - match, isBreak := n.Pattern(next, callback) - if isBreak { - return true,true - } - isMatch = isMatch || match + for i, s := range sl { + n := &_Node{ + data: s, + parent: node, + index: i, } + match, isBreak := n.Pattern(next, callback) + if isBreak { + return true, true + } + isMatch = isMatch || match + } } case map[string]interface{}: { - sm :=data.(map[string]interface{}) + sm := data.(map[string]interface{}) - if len(sm) > 0{ - for k,s:=range sm { + if len(sm) > 0 { + for k, s := range sm { n := &_Node{ data: s, parent: node, @@ -162,7 +160,7 @@ func (node *_Node) Pattern(pattern string,callback func(*_Node)bool)( match bool } isMatch = isMatch || match } - }else{ + } else { n := &_Node{ data: nil, parent: node, @@ -178,36 +176,36 @@ func (node *_Node) Pattern(pattern string,callback func(*_Node)bool)( match bool } } - }else{ + } else { - child:= node.get(key) + child := node.get(key) if child != nil { - match, isBreak :=child.Pattern(next,callback) + match, isBreak := child.Pattern(next, callback) if isBreak { return true, true } isMatch = match } } - if isMatch{ - return true,false + if isMatch { + return true, false } } - return false,false + return false, false } -func next(pattern ,key string) string{ +func next(pattern, key string) string { - l:=len(key) + l := len(key) - if len(pattern)>l{ + if len(pattern) > l { return pattern[l+1:] } return "" } func spiltKey(key string) string { - if index:=strings.LastIndex(key,".");index!= -1{ + if index := strings.LastIndex(key, "."); index != -1 { return key[:index] } return "" -} \ No newline at end of file +} diff --git a/node/gateway/response/response.go b/node/gateway/response/response.go index 3bb39295..ffae19b9 100644 --- a/node/gateway/response/response.go +++ b/node/gateway/response/response.go @@ -8,63 +8,65 @@ type Response struct { Data interface{} } +//Delete delete func (r *Response) Delete(pattern string) *Response { - if pattern == ""{ + if pattern == "" { return r } - root:=_Node{ - data:r.Data, + root := _Node{ + data: r.Data, } - root.Pattern(pattern, func(node *_Node)bool { - if node.parent ==nil { + root.Pattern(pattern, func(node *_Node) bool { + if node.parent == nil { return false } - parent:= node.parent + parent := node.parent switch parent.data.(type) { case []interface{}: - index:= node.index - sl:= parent.data.([]interface{}) + index := node.index + sl := parent.data.([]interface{}) - nl:=sl[:index] - sl=append(nl,sl[index+1]) + nl := sl[:index] + sl = append(nl, sl[index+1]) parent.data = sl case map[string]interface{}: - mp:=parent.data.(map[string]interface{}) - delete(mp,node.key) + mp := parent.data.(map[string]interface{}) + delete(mp, node.key) } return false }) return r } + //SetValue 设置目标值,如果目标不存在,会对路径进行创建 -func (r *Response) SetValue(pattern string,value interface{}) { - if pattern == ""{ +func (r *Response) SetValue(pattern string, value interface{}) { + if pattern == "" { r.Data = value return } - root:=_Node{ - data:r.Data, + root := _Node{ + data: r.Data, } - root.Make(strings.Split(pattern,".")) + root.Make(strings.Split(pattern, ".")) - root.Pattern(pattern, func(node *_Node)bool { + root.Pattern(pattern, func(node *_Node) bool { - if node.parent ==nil { + if node.parent == nil { return false } - parent:= node.parent + parent := node.parent switch parent.data.(type) { case []interface{}: - sl:= parent.data.([]interface{}) - index:= node.index + sl := parent.data.([]interface{}) + index := node.index sl[index] = value parent.data = sl case map[string]interface{}: - mp:=parent.data.(map[string]interface{}) - mp[node.key]=value + mp := parent.data.(map[string]interface{}) + mp[node.key] = value } return false }) @@ -73,11 +75,11 @@ func (r *Response) SetValue(pattern string,value interface{}) { //ReTarget 选择目标重新设置为root func (r *Response) ReTarget(pattern string) { - if pattern == ""{ + if pattern == "" { return } - root:=_Node{ - data:r.Data, + root := _Node{ + data: r.Data, } match, _ := root.Pattern(pattern, func(node *_Node) bool { @@ -85,25 +87,26 @@ func (r *Response) ReTarget(pattern string) { return true }) - if !match{ + if !match { r.Data = make(map[string]interface{}) } return } -//Group + +//Group group func (r *Response) Group(path []string) { - l:=len(path) - if l==0{ + l := len(path) + if l == 0 { return } root := make(map[string]interface{}) - node:=root + node := root lastKey := path[l-1] - if l>1{ - for _,key:=range path[:l-1]{ + if l > 1 { + for _, key := range path[:l-1] { v := make(map[string]interface{}) - node[key]=v + node[key] = v node = v } } @@ -111,72 +114,74 @@ func (r *Response) Group(path []string) { node[lastKey] = r.Data r.Data = root } + //ReName 重命名 -func (r *Response)ReName(pattern string,newName string) { - if pattern == ""{ +func (r *Response) ReName(pattern string, newName string) { + if pattern == "" { return } - root:=_Node{ - data:r.Data, + root := _Node{ + data: r.Data, } root.Pattern(pattern, func(node *_Node) bool { - if node.parent ==nil { + if node.parent == nil { return false } - parent:= node.parent + parent := node.parent switch parent.data.(type) { case []interface{}: return false case map[string]interface{}: - mp:=parent.data.(map[string]interface{}) - delete(mp,node.key) - mp[newName]=node.data + mp := parent.data.(map[string]interface{}) + delete(mp, node.key) + mp[newName] = node.data return false } return false }) } -func (r *Response)Move(source ,target string) { +//Move move +func (r *Response) Move(source, target string) { - if strings.Index(source,"*") != -1{ + if strings.Index(source, "*") != -1 { return } - if strings.Index(target,"*") != -1{ + if strings.Index(target, "*") != -1 { return } - root:=_Node{ - data:r.Data, + root := _Node{ + data: r.Data, } var oldValues *_Node - match,_:=root.Pattern(source, func(node *_Node) bool { + match, _ := root.Pattern(source, func(node *_Node) bool { oldValues = node - if node.parent ==nil { + if node.parent == nil { return false } - parent:= node.parent + parent := node.parent switch parent.data.(type) { case []interface{}: - index:= node.index - sl:= parent.data.([]interface{}) + index := node.index + sl := parent.data.([]interface{}) - nl:=sl[:index] - sl=append(nl,sl[index+1]) + nl := sl[:index] + sl = append(nl, sl[index+1]) parent.data = sl case map[string]interface{}: - mp:=parent.data.(map[string]interface{}) - delete(mp,node.key) + mp := parent.data.(map[string]interface{}) + delete(mp, node.key) } return false }) - if match{ - r.SetValue(target,oldValues.data) - }else{ - r.SetValue(target,nil) + if match { + r.SetValue(target, oldValues.data) + } else { + r.SetValue(target, nil) } -} \ No newline at end of file +} diff --git a/node/gateway/router.go b/node/gateway/router.go index d05527ac..cef0e2c2 100644 --- a/node/gateway/router.go +++ b/node/gateway/router.go @@ -2,6 +2,7 @@ package gateway import ( "errors" + "fmt" "net/http" "reflect" "strings" @@ -69,7 +70,7 @@ func (f *_RootFactory) createStrategy() map[string]*Strategy { // 构造策略 func (f *_RootFactory) genStrategy(cfg *config.StrategyConfig) *Strategy { - _, accesses, _ := genPlugins(cfg.Plugins, f.cluster, cfg.ID, 0) + _, accesses, proxies := genPlugins(cfg.Plugins, f.cluster, cfg.ID, 0) s := &Strategy{ ID: cfg.ID, @@ -100,20 +101,23 @@ func (f *_RootFactory) genStrategy(cfg *config.StrategyConfig) *Strategy { } if pluginObj.Access != nil && !reflect.ValueOf(pluginObj.Access).IsNil() { + if cfg.ID == "68YAY7" { + fmt.Println(authKey, pluginName) + } s.authPlugin[authKey] = plugin_executor.NewAccessExecutor(&config.PluginConfig{ Name: pluginName, IsStop: true, Config: authCfg, + IsAuth: true, }, pluginObj.Access) } } } factory := newAPIFactory(f, s.ID) - for _, apiCfg := range cfg.APIS { - iRouter, apiContent := factory.genAPIRouter(apiCfg) + iRouter, apiContent := factory.genAPIRouter(apiCfg, proxies) if iRouter == nil { continue } @@ -137,7 +141,7 @@ func newAPIFactory(root *_RootFactory, strategyID string) *_ApiFactory { strategyID: strategyID, } } -func (f *_ApiFactory) genAPIRouter(cfg *config.APIOfStrategy) (router.IRouter, *config.APIContent) { +func (f *_ApiFactory) genAPIRouter(cfg *config.APIOfStrategy, proxies []plugin_executor.Executor) (router.IRouter, *config.APIContent) { apiContend, has := f.root.apis[cfg.ID] if !has { @@ -149,13 +153,16 @@ func (f *_ApiFactory) genAPIRouter(cfg *config.APIOfStrategy) (router.IRouter, * return nil, nil } _, pluginAccesses, pluginProxies := genPlugins(cfg.Plugins, f.root.cluster, f.strategyID, cfg.ID) + pro := make([]plugin_executor.Executor, 0, len(proxies)+len(pluginProxies)) + pro = append(pro, proxies...) + pro = append(pro, pluginProxies...) return &API{ strategyID: f.strategyID, - apiID: cfg.ID, + apiID: cfg.ID, app: app, pluginAccess: pluginAccesses, - pluginProxies: pluginProxies, + pluginProxies: pro, pluginAccessGlobal: f.root.gAccesses, pluginProxiesGlobal: f.root.gProxies, }, apiContend @@ -169,7 +176,6 @@ func genFactory(cfg *config.GokuConfig, factory router.Factory) *_RootFactory { beforePlugin := genBeforPlugin(cfg.Plugins.BeforePlugins, cfg.Cluster) gBefores, gAccesses, gProxies := genPlugins(cfg.Plugins.GlobalPlugins, cfg.Cluster, "", 0) - apis := toMap(cfg.APIS) return &_RootFactory{ beforePlugin: beforePlugin, @@ -188,6 +194,9 @@ func genFactory(cfg *config.GokuConfig, factory router.Factory) *_RootFactory { func toMap(cfgs []*config.APIContent) map[int]*config.APIContent { m := make(map[int]*config.APIContent) for _, cfg := range cfgs { + //if cfg.ID == 1880 { + // fmt.Println(cfg) + //} m[cfg.ID] = cfg } return m diff --git a/node/gateway/strategy.go b/node/gateway/strategy.go index a08a23e8..a86d5a6c 100644 --- a/node/gateway/strategy.go +++ b/node/gateway/strategy.go @@ -4,6 +4,8 @@ import ( "fmt" "net/http" + "github.com/pkg/errors" + log "github.com/eolinker/goku-api-gateway/goku-log" "github.com/eolinker/goku-api-gateway/goku-node/common" plugin_executor "github.com/eolinker/goku-api-gateway/node/gateway/plugin-executor" @@ -45,50 +47,75 @@ func (r *Strategy) Router(w http.ResponseWriter, req *http.Request, ctx *common. if r.isNeedAuth { // 需要校验 - if !r.auth(ctx) { + ok, err := r.auth(ctx) + if err != nil { // 校验失败 ctx.SetStatus(403, "403") - ctx.SetBody([]byte("[ERROR]Illegal authorization type!")) + //ctx.SetBody([]byte("[ERROR]Illegal authorization type!")) + ctx.SetBody([]byte(err.Error())) + return + } + if !ok { + return + } + } + for _, strategyAccess := range r.accessPlugin { + if strategyAccess.IsAuth() { + continue + } + fmt.Println(strategyAccess.IsAuth()) + isContinued, err := strategyAccess.Execute(ctx) + if isContinued { + continue + } + if err != nil { + ctx.SetStatus(403, "403") + ctx.SetBody([]byte(err.Error())) return } } - r.apiRouter.ServeHTTP(w, req, ctx) } -func (r *Strategy) auth(ctx *common.Context) bool { +func (r *Strategy) auth(ctx *common.Context) (bool, error) { requestID := ctx.RequestId() authType := ctx.Request().GetHeader("Authorization-Type") authPlugin, has := r.authPlugin[authType] if !has { - log.Warn(requestID, " Illegal authorization type:", authType) - return false + errInfo := errors.New(" Illegal authorization type:" + authType) + log.Warn(requestID, errInfo.Error()) + return false, errInfo } isContinue, err := authPlugin.Execute(ctx) if isContinue == false { pluginName := authNames[authType] + + var errInfo error // 校验失败 if err != nil { - log.Warn(requestID, " access auth:[", pluginName, "] error:", err) + errInfo = errors.New(" access auth:[" + pluginName + "] error:" + err.Error()) + log.Warn(requestID, errInfo.Error()) + return false, errInfo } log.Info(requestID, " auth [", pluginName, "] refuse") - return false + return false, nil } log.Debug(requestID, " auth [", authType, "] pass") - return true + return true, nil } -func (r *Strategy) accessFlow(ctx *common.Context) { +func (r *Strategy) accessFlow(ctx *common.Context) bool { for _, handler := range r.accessPlugin { flag, _ := handler.Execute(ctx) if flag == false && handler.IsStop() { - return + return false } } + return true } func (r *Strategy) accessGlobalFlow(ctx *common.Context) { @@ -103,11 +130,18 @@ func (r *Strategy) accessGlobalFlow(ctx *common.Context) { func (r *Strategy) HandlerAPINotFound(ctx *common.Context) { // 未匹配到api // 执行策略access 插件 - r.accessFlow(ctx) + if !r.accessFlow(ctx) { + r.accessGlobalFlow(ctx) + return + } // 执行全局access 插件 r.accessGlobalFlow(ctx) - log.Info(ctx.RequestId(), " URL dose not exist!") - ctx.SetStatus(404, "404") - ctx.SetBody([]byte("[ERROR]URL dose not exist!")) + if ctx.StatusCode() == 0 { + // 插件可能会设置状态码 + log.Info(ctx.RequestId(), " URL dose not exist!") + ctx.SetStatus(404, "404") + ctx.SetBody([]byte("[ERROR]URL dose not exist!")) + } + } diff --git a/node/monitor/collector.go b/node/monitor/collector.go index 244414e0..12873eef 100644 --- a/node/monitor/collector.go +++ b/node/monitor/collector.go @@ -6,12 +6,13 @@ import ( ) var ( - //APICount diting.Counter + //APIMonitor diting.APIMonitor APIMonitor diting.Histogram + //ProxyMonitor diting.Histogram ProxyMonitor diting.Histogram ) -func initCollector(constLabels diting.Labels) { +func initCollector(constLabels diting.Labels) { //apiLabelNames := []string{ // goku_labels.Cluster, // goku_labels.Instance, @@ -22,29 +23,10 @@ func initCollector(constLabels diting.Labels) { //apiCounterOpt:= diting.NewCounterOpts("goku","api","count","api 请求计数",constLabels,apiLabelNames) //APICount = diting.NewCounter(apiCounterOpt) - buckets:=[]float64{5, 25, 50, 100, 200,400, 600,800,1000, 2500,5000} - //buckets:=[]float64{.005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10} - apiDelayLabelNames := []string{ - goku_labels.Cluster, - goku_labels.Instance, - goku_labels.API, - goku_labels.Strategy, - goku_labels.Status, - } - apiHistogramOpt := diting.NewHistogramOpts("goku","","api","api整体请求统计",constLabels,apiDelayLabelNames,buckets) + apiHistogramOpt := diting.NewHistogramOpts(goku_labels.Namespace, goku_labels.Subsystem, goku_labels.APIName, "api整体请求统计", constLabels, goku_labels.APIDelayLabelNames, goku_labels.APIBuckets) APIMonitor = diting.NewHistogram(apiHistogramOpt) - - proxyDelayLabelNames := []string{ - goku_labels.Cluster, - goku_labels.Instance, - goku_labels.Proto, - goku_labels.Host, - goku_labels.Path, - goku_labels.Method, - } - - proxyMonitorOpt := diting.NewHistogramOpts("goku","","proxy","转发统计",constLabels,proxyDelayLabelNames,buckets) + proxyMonitorOpt := diting.NewHistogramOpts(goku_labels.Namespace, goku_labels.Subsystem, goku_labels.ProxyName, "转发统计", constLabels, goku_labels.ProxyDelayLabelNames, goku_labels.ProxyBuckets) ProxyMonitor = diting.NewHistogram(proxyMonitorOpt) -} \ No newline at end of file +} diff --git a/node/monitor/monitor.go b/node/monitor/monitor.go index 153aaf03..ca2a11f3 100644 --- a/node/monitor/monitor.go +++ b/node/monitor/monitor.go @@ -1,26 +1,25 @@ package monitor import ( - "github.com/eolinker/goku-api-gateway/diting" - "github.com/eolinker/goku-api-gateway/goku-labels" "strings" "sync" -) + "github.com/eolinker/goku-api-gateway/diting" + goku_labels "github.com/eolinker/goku-api-gateway/goku-labels" +) var ( - once =sync.Once{} - + once = sync.Once{} ) -func Init(cluster string,instance string) { +//Init init +func Init(cluster string, instance string) { once.Do(func() { constLabels := make(diting.Labels) constLabels[goku_labels.Cluster] = cluster - constLabels[goku_labels.Instance] = strings.ReplaceAll(instance,".","_") + constLabels[goku_labels.Instance] = strings.ReplaceAll(instance, ".", "_") initCollector(constLabels) }) } - diff --git a/node/plugin-loader/pluginload.go b/node/plugin-loader/pluginload.go index 27c63cc3..7260bf09 100644 --- a/node/plugin-loader/pluginload.go +++ b/node/plugin-loader/pluginload.go @@ -33,7 +33,7 @@ func (m *_GlodPluginManager) check(name string) (int, error) { return code, err } - _, e, errorCode := m.loadPlugin(name) + _, errorCode, e := m.loadPlugin(name) return errorCode, e } @@ -56,34 +56,31 @@ func (m *_GlodPluginManager) getPluginHandle(name string) (goku_plugin.PluginFac return p, has } -func LoadPlugin(name string)(goku_plugin.PluginFactory ,error) { - factory, err, _ := globalPluginManager.loadPlugin(name) +//LoadPlugin 加载插件 +func LoadPlugin(name string) (goku_plugin.PluginFactory, error) { + factory, _, err := globalPluginManager.loadPlugin(name) - return factory,err + return factory, err } // 加载动态库 -func (m *_GlodPluginManager) loadPlugin(name string) (goku_plugin.PluginFactory, error, int) { +func (m *_GlodPluginManager) loadPlugin(name string) (goku_plugin.PluginFactory, int, error) { handle, has := m.getPluginHandle(name) if has { - return handle, nil, LoadOk + return handle, LoadOk, nil } m.gloadPluginLocker.Lock() defer m.gloadPluginLocker.Unlock() - handle, has = m.gloadPlugin[name] - if has { - return handle, nil, LoadOk - } - path, _ := filepath.Abs(fmt.Sprintf("plugin/%s.so", name)) + pdll, err := plugin.Open(path) if err != nil { - e := fmt.Errorf("The plugin file named '%s.so' can not be found in plugin:%s ", name, err.Error()) + e := fmt.Errorf("plugin:%s ", name, err.Error()) m.errors[name] = e m.errorCodes[name] = LoadFileError - return nil, e, LoadFileError + return nil, LoadFileError, e } //structName := strings.Replace(name, "-", "_", -1) @@ -93,11 +90,10 @@ func (m *_GlodPluginManager) loadPlugin(name string) (goku_plugin.PluginFactory, v, err := pdll.Lookup("Builder") if err != nil { - e := fmt.Errorf("The Builder can not be found in plugin/%s.so ", name) + e := fmt.Errorf("The Builder can not be found in plugin/%s.so ", name) m.errors[name] = e m.errorCodes[name] = LoadLookupError - - return nil, e, LoadLookupError + return nil, LoadLookupError, e } vp, ok := v.(func() goku_plugin.PluginFactory) @@ -105,18 +101,19 @@ func (m *_GlodPluginManager) loadPlugin(name string) (goku_plugin.PluginFactory, e := fmt.Errorf("The builder func can not implemented interface named goku_plugin.PluginFactory:%s ", name) m.errors[name] = e m.errorCodes[name] = LoadInterFaceError - return nil, e, LoadInterFaceError + return nil, LoadInterFaceError, e } factory := vp() if factory == nil || reflect.ValueOf(factory).IsNil() { e := fmt.Errorf("The builder result is nil:%s ", name) m.errors[name] = e m.errorCodes[name] = LoadInterFaceError - return nil, e, LoadInterFaceError + fmt.Println(e) + return nil, LoadInterFaceError, e } m.gloadPlugin[name] = factory m.errorCodes[name] = LoadOk m.errors[name] = nil - return factory, nil, LoadOk + return factory, LoadOk, nil } diff --git a/node/router/httprouter/router.go b/node/router/httprouter/router.go index df3cf7fc..207fa78c 100644 --- a/node/router/httprouter/router.go +++ b/node/router/httprouter/router.go @@ -4,8 +4,8 @@ import ( "net/http" "github.com/eolinker/goku-api-gateway/goku-node/common" + "github.com/eolinker/goku-api-gateway/module/httprouter" "github.com/eolinker/goku-api-gateway/node/router" - "github.com/julienschmidt/httprouter" ) //HTTPRouter httpRouter @@ -29,6 +29,7 @@ type Engine struct { //AddRouter addRouter func (r *Engine) AddRouter(method, path string, router router.IRouter) { + r.router.Handle(method, path, func(w http.ResponseWriter, req *http.Request, params httprouter.Params) { ctx := ContextFromRequest(req) diff --git a/node/routerRule/internal/rule.go b/node/routerRule/internal/rule.go new file mode 100644 index 00000000..04123989 --- /dev/null +++ b/node/routerRule/internal/rule.go @@ -0,0 +1,7 @@ +package internal + +//RouterRule RouterRule +type RouterRule interface { + GetTargets() []int + Match(arg ...string) bool +} diff --git a/node/routerRule/manager.go b/node/routerRule/manager.go new file mode 100644 index 00000000..020259d5 --- /dev/null +++ b/node/routerRule/manager.go @@ -0,0 +1,95 @@ +package routerRule + +import ( + "encoding/json" + "sort" + "strings" + + "github.com/eolinker/goku-api-gateway/config" + "github.com/eolinker/goku-api-gateway/utils" +) + +//Router router +type Router struct { + Host string `json:"host"` + StrategyID string `json:"strategyID"` + ID string `json:"id"` +} + +//Match match +func (r *Router) Match(c *config.RouterRule) (bool, string) { + if r.Host != "" && !matchHost(r.Host, c.Host) { + return false, "" + } + + if r.StrategyID != "" && r.StrategyID != c.StrategyID { + return false, "" + } + return true, r.ID +} + +var router = make([]*Router, 0) + +func newRouter(rs []*config.Router) []*Router { + newRs := make([]*Router, 0, len(rs)) + if rs == nil { + return newRs + } + for _, r := range rs { + rls := make([]*config.RouterRule, 0) + err := json.Unmarshal([]byte(r.Rules), &rls) + if err != nil { + continue + } + ts := make([]int, 0, 2) + err = json.Unmarshal([]byte(r.Target), &ts) + if err != nil { + continue + } + if len(ts) == 1 && ts[0] == 0 { + // 指标只有策略ID + newRs = append(newRs, &Router{Host: "", StrategyID: ""}) + continue + } + commonRs := make([]*Router, 0, len(rls)) + for _, rl := range rls { + var host, strategyID string + if strings.Contains(r.Target, "0") { + // 指标包括策略ID + strategyID = rl.StrategyID + } + if strings.Contains(r.Target, "1") { + // 指标包括Host + host = rl.Host + } + commonRs = append(commonRs, &Router{Host: host, StrategyID: strategyID, ID: rl.StrategyID}) + } + sort.Sort(Routers(commonRs)) + newRs = append(newRs, commonRs...) + } + return newRs +} + +//Load load +func Load(rs []*config.Router) { + router = newRouter(rs) +} + +//Get get +func Get() []*Router { + return router +} + +func matchHost(org, match string) bool { + if org == "*" || org == match { + return true + } + + _, o := utils.Intercept(org, ".") + _, m := utils.Intercept(match, ".") + if o == m && string(org[0]) == "*" { + return true + } + + return false +} diff --git a/node/routerRule/sort.go b/node/routerRule/sort.go new file mode 100644 index 00000000..5541b595 --- /dev/null +++ b/node/routerRule/sort.go @@ -0,0 +1,30 @@ +package routerRule + +import "strings" + +//Routers Routers +type Routers []*Router + +func (p Routers) Len() int { + return len(p) +} + +func (p Routers) Less(i, j int) bool { + if p[i].Host == "*" { + return false + } + if p[j].Host == "*" { + return true + } + if strings.Contains(p[i].Host, "*") { + return false + } + if strings.Contains(p[j].Host, "*") { + return true + } + return false +} + +func (p Routers) Swap(i, j int) { + p[i], p[j] = p[j], p[i] +} diff --git a/node/server.go b/node/server.go new file mode 100644 index 00000000..8948864f --- /dev/null +++ b/node/server.go @@ -0,0 +1,14 @@ +package node + +import ( + log "github.com/eolinker/goku-api-gateway/goku-log" + + redis_plugin_proxy "github.com/eolinker/goku-api-gateway/goku-node/redis-plugin-proxy" + goku_plugin "github.com/eolinker/goku-plugin" +) + +func InitPluginUtils() { + goku_plugin.SetRedisManager(redis_plugin_proxy.Create()) + goku_plugin.InitLog(log.GetLogger()) + //goku_plugin.SetLog(new(log_plugin_proxy.LoggerGeneral)) +} diff --git a/node/server/admin.go b/node/server/admin.go index 44e34197..7ecbe029 100644 --- a/node/server/admin.go +++ b/node/server/admin.go @@ -1,19 +1,26 @@ package server import ( - "github.com/eolinker/goku-api-gateway/common/endless" - "github.com/eolinker/goku-api-gateway/node/admin" "log" "sync" -) -var (adminOnce = sync.Once{}) -func StartAdmin(address string) { + "github.com/eolinker/goku-api-gateway/common/endless" + + "github.com/eolinker/goku-api-gateway/node/admin" +) +var ( + adminOnce = sync.Once{} +) +//StartAdmin 启动节点管理端 +func StartAdmin(address string) { go adminOnce.Do(func() { - err :=endless.ListenAndServe(address,admin.Handler()) - if err!=nil{ + server := endless.NewServer(address, admin.Handler()) + endless.SetAdminServer(server) + err := server.ListenAndServe() + //err := http.ListenAndServe(address, admin.Handler()) + if err != nil { log.Fatal(err) } }) diff --git a/node/server/log.go b/node/server/log.go index 4dd7686f..aea36e2f 100644 --- a/node/server/log.go +++ b/node/server/log.go @@ -67,6 +67,7 @@ func defaultAccessLogConfig() *config.AccessLogConfig { Dir: "work/logs/", File: "access.log", Period: "hour", + Expire: 3, Fields: nil, } } diff --git a/node/server/server.go b/node/server/server.go index b1c1b8db..e447e0db 100644 --- a/node/server/server.go +++ b/node/server/server.go @@ -2,13 +2,25 @@ package server import ( "errors" + "fmt" + "net/http" + "runtime/debug" + + "github.com/eolinker/goku-api-gateway/common/endless" + + "github.com/eolinker/goku-api-gateway/goku-service/application" + + "github.com/eolinker/goku-api-gateway/node/routerRule" + + redis_manager "github.com/eolinker/goku-api-gateway/common/redis-manager" + "github.com/eolinker/goku-api-gateway/node" + "github.com/eolinker/goku-api-gateway/diting" "github.com/eolinker/goku-api-gateway/module" "github.com/eolinker/goku-api-gateway/node/admin" "github.com/eolinker/goku-api-gateway/node/monitor" - "net/http" + entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" - "github.com/eolinker/goku-api-gateway/common/endless" "github.com/eolinker/goku-api-gateway/config" log "github.com/eolinker/goku-api-gateway/goku-log" "github.com/eolinker/goku-api-gateway/node/console" @@ -20,7 +32,7 @@ import ( type Server struct { //port int //console *console.Console - router http.Handler + router http.Handler } //NewServer newServer @@ -28,7 +40,7 @@ func NewServer() *Server { return &Server{ //port: port, //console: nil, - router: nil, + router: nil, } } @@ -38,72 +50,115 @@ func (s *Server) SetRouter(r http.Handler) error { return nil } - -//Server server -func (s *Server) ServerWidthConsole(console *console.Console ) error { - if console == nil { +//ServerWidthConsole 开启节点监听服务 +func (s *Server) ServerWidthConsole(console console.ConfigConsole) error { + if console == nil { return errors.New("can not start server widthout router and console") } if console != nil { - conf, err := console.GetConfig() + conf, err := console.RegisterToConsole() if err != nil { return err } console.AddListen(s.FlushRouter) console.AddListen(s.FlushModule) - return s.ServerWidthConfig(conf) + console.AddListen(s.FlushRedisConfig) + console.AddListen(s.FlushRouterRule) + console.AddListen(s.FlushGatewayBasicConfig) + + console.Listen() + + return s.ServerWidthConfig(conf) } - return errors.New("can not start server widthout router and console") + return errors.New("can not start server widthout router and console") } -func (s *Server)ServerWidthConfig(conf *config.GokuConfig)error { +//ServerWidthConfig 处理配置 +func (s *Server) ServerWidthConfig(conf *config.GokuConfig) error { - if conf == nil{ + if conf == nil { return errors.New("can not start server width out config") } - + s.FlushRedisConfig(conf) r, err := gateway.Parse(conf, httprouter.Factory()) if err != nil { log.Panic("parse config error:", err) } + if conf.GatewayBasicInfo != nil { + application.SetSkipCertificate(conf.GatewayBasicInfo.SkipCertificate) + } e := s.SetRouter(r) if e != nil { return e } + routerRule.Load(conf.Routers) + // 初始化监控模块 - monitor.Init(conf.Cluster,conf.Instance) + monitor.Init(conf.Cluster, conf.Instance) s.FlushModule(conf) - if conf.BindAddress == ""{ + if conf.BindAddress == "" { log.Panic("invalid bind address") } - //if conf.AdminAddress == ""{ - // log.Panic("invalid admin address") - //} + // 启用管理接口 - if conf.AdminAddress != ""{ + if conf.AdminAddress != "" { StartAdmin(conf.AdminAddress) } return endless.ListenAndServe(conf.BindAddress, s) + //return http.ListenAndServe(conf.BindAddress, s) } + //FlushRouter flushConfig func (s *Server) FlushRouter(config *config.GokuConfig) { + r, err := gateway.Parse(config, httprouter.Factory()) + if err != nil { + log.Error("parse config error:", err) + return + } + _ = s.SetRouter(r) +} +//FlushRouterRule flushConfig +func (s *Server) FlushRouterRule(config *config.GokuConfig) { + routerRule.Load(config.Routers) +} - r, err := gateway.Parse(config, httprouter.Factory()) - if err != nil { - log.Error("parse config error:", err) +//FlushGatewayBasicConfig 刷新网关基础配置 +func (s *Server) FlushGatewayBasicConfig(config *config.GokuConfig) { + if config.GatewayBasicInfo != nil { + application.SetSkipCertificate(config.GatewayBasicInfo.SkipCertificate) + } +} + +//FlushRedisConfig 刷新redis配置 +func (s *Server) FlushRedisConfig(config *config.GokuConfig) { + if r, ok := config.ExtendsConfig["redis"]; ok { + if r == nil { return } - _=s.SetRouter(r) + rr := r.(map[string]interface{}) + rdsConfig := &entity.ClusterRedis{ + Addrs: rr["addrs"].(string), + DbIndex: int(rr["dbIndex"].(float64)), + Masters: rr["masters"].(string), + Mode: rr["mode"].(string), + Password: rr["password"].(string), + } + rds := redis_manager.Create(rdsConfig) + log.Info(rdsConfig) + redis_manager.SetDefault(rds) + node.InitPluginUtils() + } } -//FlushRouter flushConfig + +//FlushModule 刷新模块配置 func (s *Server) FlushModule(conf *config.GokuConfig) { SetLog(conf.Log) SetAccessLog(conf.AccessLog) @@ -119,6 +174,13 @@ func (s *Server) FlushModule(conf *config.GokuConfig) { } func (s *Server) ServeHTTP(w http.ResponseWriter, req *http.Request) { + defer func() { + if err := recover(); err != nil { + fmt.Println(err) + print(err) + debug.PrintStack() + } + }() if s.router == nil { w.WriteHeader(404) return diff --git a/server/dao/console-sqlite3/api.go b/server/dao/console-sqlite3/api.go index aebfdb01..4da2032f 100644 --- a/server/dao/console-sqlite3/api.go +++ b/server/dao/console-sqlite3/api.go @@ -8,16 +8,34 @@ import ( "strings" "time" - database2 "github.com/eolinker/goku-api-gateway/common/database" + "github.com/eolinker/goku-api-gateway/server/dao" + entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" ) +//APIDao APIDao +type APIDao struct { + db *SQL.DB +} + +//NewAPIDao new APIDao +func NewAPIDao() *APIDao { + return &APIDao{} +} + +//Create create +func (d *APIDao) Create(db *SQL.DB) (interface{}, error) { + d.db = db + var i dao.APIDao = d + return &i, nil +} + // AddAPI 新增接口 -func AddAPI(apiName, requestURL, targetURL, requestMethod, targetMethod, isFollow, linkAPIs, staticResponse, responseDataType, balanceName, protocol string, projectID, groupID, timeout, retryCount, alertValve, managerID, userID, apiType int) (bool, int, error) { - db := database2.GetConnection() +func (d *APIDao) AddAPI(apiName, alias, requestURL, targetURL, requestMethod, targetMethod, isFollow, linkAPIs, staticResponse, responseDataType, balanceName, protocol string, projectID, groupID, timeout, retryCount, alertValve, managerID, userID, apiType int) (bool, int, error) { + db := d.db now := time.Now().Format("2006-01-02 15:04:05") Tx, _ := db.Begin() - res, err := Tx.Exec("INSERT INTO goku_gateway_api (projectID,groupID,apiName,requestURL,targetURL,requestMethod,targetMethod,protocol,linkAPIs,staticResponse,responseDataType,balanceName,isFollow,timeout,retryCount,alertValve,createTime,updateTime,managerID,lastUpdateUserID,createUserID,apiType) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);", projectID, groupID, apiName, requestURL, targetURL, requestMethod, targetMethod, protocol, linkAPIs, staticResponse, responseDataType, balanceName, isFollow, timeout, retryCount, alertValve, now, now, managerID, userID, userID, apiType) + res, err := Tx.Exec("INSERT INTO goku_gateway_api (projectID,groupID,apiName,alias,requestURL,targetURL,requestMethod,targetMethod,protocol,linkAPIs,staticResponse,responseDataType,balanceName,isFollow,timeout,retryCount,alertValve,createTime,updateTime,managerID,lastUpdateUserID,createUserID,apiType) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);", projectID, groupID, apiName, alias, requestURL, targetURL, requestMethod, targetMethod, protocol, linkAPIs, staticResponse, responseDataType, balanceName, isFollow, timeout, retryCount, alertValve, now, now, managerID, userID, userID, apiType) if err != nil { Tx.Rollback() @@ -35,11 +53,11 @@ func AddAPI(apiName, requestURL, targetURL, requestMethod, targetMethod, isFollo } // EditAPI 修改接口 -func EditAPI(apiName, requestURL, targetURL, requestMethod, targetMethod, isFollow, linkAPIs, staticResponse, responseDataType, balanceName, protocol string, projectID, groupID, timeout, retryCount, alertValve, apiID, managerID, userID int) (bool, error) { - db := database2.GetConnection() +func (d *APIDao) EditAPI(apiName, alias, requestURL, targetURL, requestMethod, targetMethod, isFollow, linkAPIs, staticResponse, responseDataType, balanceName, protocol string, projectID, groupID, timeout, retryCount, alertValve, apiID, managerID, userID int) (bool, error) { + db := d.db now := time.Now().Format("2006-01-02 15:04:05") Tx, _ := db.Begin() - _, err := Tx.Exec("UPDATE goku_gateway_api SET projectID = ?,groupID = ?,apiName = ?,requestURL = ?,targetURL = ?,requestMethod = ?,protocol = ?,balanceName = ?,targetMethod = ?,isFollow = ?,linkAPIs = ?,staticResponse = ?,responseDataType = ?,timeout = ?,retryCount = ?,alertValve = ?,updateTime = ?,managerID = ?,lastUpdateUserID = ? WHERE apiID = ?", projectID, groupID, apiName, requestURL, targetURL, requestMethod, protocol, balanceName, targetMethod, isFollow, linkAPIs, staticResponse, responseDataType, timeout, retryCount, alertValve, now, managerID, userID, apiID) + _, err := Tx.Exec("UPDATE goku_gateway_api SET projectID = ?,groupID = ?,apiName = ?,alias = ?,requestURL = ?,targetURL = ?,requestMethod = ?,protocol = ?,balanceName = ?,targetMethod = ?,isFollow = ?,linkAPIs = ?,staticResponse = ?,responseDataType = ?,timeout = ?,retryCount = ?,alertValve = ?,updateTime = ?,managerID = ?,lastUpdateUserID = ? WHERE apiID = ?", projectID, groupID, apiName, alias, requestURL, targetURL, requestMethod, protocol, balanceName, targetMethod, isFollow, linkAPIs, staticResponse, responseDataType, timeout, retryCount, alertValve, now, managerID, userID, apiID) if err != nil { Tx.Rollback() @@ -56,9 +74,9 @@ func EditAPI(apiName, requestURL, targetURL, requestMethod, targetMethod, isFoll } // GetAPIInfo 获取接口信息 -func GetAPIInfo(apiID int) (bool, *entity.API, error) { - db := database2.GetConnection() - sql := `SELECT goku_gateway_api.apiID,goku_gateway_api.groupID,goku_gateway_api.apiName,goku_gateway_api.requestURL,goku_gateway_api.targetURL,goku_gateway_api.requestMethod,goku_gateway_api.targetMethod,IFNULL(goku_gateway_api.protocol,"http"),IFNULL(goku_gateway_api.balanceName,""),goku_gateway_api.isFollow,goku_gateway_api.timeout,goku_gateway_api.retryCount,goku_gateway_api.alertValve,goku_gateway_api.createTime,goku_gateway_api.updateTime,goku_gateway_api.managerID,goku_gateway_api.lastUpdateUserID,goku_gateway_api.createUserID,IFNULL(goku_gateway_api_group.groupPath,"0"),goku_gateway_api.apiType,IFNULL(goku_gateway_api.linkAPIs,''),IFNULL(goku_gateway_api.staticResponse,''),IFNULL(goku_gateway_api.responseDataType,'origin') FROM goku_gateway_api LEFT JOIN goku_gateway_api_group ON goku_gateway_api.groupID = goku_gateway_api_group.groupID WHERE goku_gateway_api.apiID = ?` +func (d *APIDao) GetAPIInfo(apiID int) (bool, *entity.API, error) { + db := d.db + sql := `SELECT A.apiID,A.groupID,A.apiName,A.requestURL,A.targetURL,A.requestMethod,A.targetMethod,IFNULL(A.protocol,"http"),IFNULL(A.balanceName,""),A.isFollow,A.timeout,A.retryCount,A.alertValve,A.createTime,A.updateTime,A.managerID,A.lastUpdateUserID,A.createUserID,IFNULL(goku_gateway_api_group.groupPath,"0"),A.apiType,IFNULL(A.linkAPIs,''),IFNULL(A.staticResponse,''),IFNULL(A.responseDataType,'origin') FROM goku_gateway_api A LEFT JOIN goku_gateway_api_group ON A.groupID = goku_gateway_api_group.groupID WHERE A.apiID = ?` api := &entity.API{} var managerInfo entity.ManagerInfo var linkAPIs string @@ -93,10 +111,10 @@ func GetAPIInfo(apiID int) (bool, *entity.API, error) { } //GetAPIListByGroupList 通过分组列表获取接口列表 -func GetAPIListByGroupList(projectID int, groupIDList string) (bool, []map[string]interface{}, error) { - db := database2.GetConnection() +func (d *APIDao) GetAPIListByGroupList(projectID int, groupIDList string) (bool, []map[string]interface{}, error) { + db := d.db // 获取分组ID列表 - sql := `SELECT goku_gateway_api.apiID,goku_gateway_api.apiName,goku_gateway_api.requestURL,IFNULL(goku_gateway_api.updateTime,""),goku_gateway_api.lastUpdateUserID,goku_gateway_api.managerID FROM goku_gateway_api WHERE goku_gateway_api.projectID = ? AND goku_gateway_api.groupID IN (` + groupIDList + `) ORDER BY goku_gateway_api.updateTime DESC;` + sql := `SELECT A.apiID,A.apiName,A.requestURL,IFNULL(A.updateTime,""),A.lastUpdateUserID,A.managerID FROM goku_gateway_api A WHERE A.projectID = ? AND A.groupID IN (` + groupIDList + `) ORDER BY A.updateTime DESC;` rows, err := db.Query(sql, projectID) if err != nil { @@ -182,8 +200,8 @@ func getAPIRule(projectID int, keyword string, condition int, ids []int) []strin } // GetAPIIDList 获取接口ID列表 -func GetAPIIDList(projectID int, groupID int, keyword string, condition int, ids []int) (bool, []int, error) { - db := database2.GetConnection() +func (d *APIDao) GetAPIIDList(projectID int, groupID int, keyword string, condition int, ids []int) (bool, []int, error) { + db := d.db rule := getAPIRule(projectID, keyword, condition, ids) if groupID < 1 { @@ -213,7 +231,7 @@ func GetAPIIDList(projectID int, groupID int, keyword string, condition int, ids ruleStr += "WHERE " + strings.Join(rule, " AND ") } - sql := fmt.Sprintf(`SELECT A.apiID FROM goku_gateway_api A %s`, ruleStr) + sql := fmt.Sprintf(`SELECT A.apiID FROM goku_gateway_api A %s`, ruleStr) rows, err := db.Query(sql) if err != nil { return false, make([]int, 0), err @@ -234,8 +252,8 @@ func GetAPIIDList(projectID int, groupID int, keyword string, condition int, ids } // GetAPIList 获取所有接口列表 -func GetAPIList(projectID int, groupID int, keyword string, condition, page, pageSize int, ids []int) (bool, []map[string]interface{}, int, error) { - db := database2.GetConnection() +func (d *APIDao) GetAPIList(projectID int, groupID int, keyword string, condition, page, pageSize int, ids []int) (bool, []map[string]interface{}, int, error) { + db := d.db rule := getAPIRule(projectID, keyword, condition, ids) if groupID < 1 { @@ -265,9 +283,9 @@ func GetAPIList(projectID int, groupID int, keyword string, condition, page, pag ruleStr += "WHERE " + strings.Join(rule, " AND ") } - 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.balanceName,''),IFNULL(A.updateTime,""),CASE WHEN B.remark is null or B.remark = "" THEN B.loginCall ELSE B.remark END AS updaterName,CASE WHEN C.remark is null or C.remark = "" THEN C.loginCall ELSE C.remark END AS managerName,A.lastUpdateUserID,A.managerID,A.isFollow,IFNULL(A.protocol,"http"),A.targetMethod,A.groupID,IFNULL(D.groupPath,"0"),IFNULL(D.groupName,"未分组") FROM goku_gateway_api A INNER JOIN goku_admin B ON A.lastUpdateUserID = B.userID INNER JOIN goku_admin C ON A.managerID=C.userID LEFT JOIN goku_gateway_api_group D ON D.groupID = A.groupID %s`, ruleStr) - count := getCountSQL(sql) - rows, err := getPageSQL(sql, "A.updateTime", "DESC", page, pageSize) + 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.balanceName,''),IFNULL(A.updateTime,""),CASE WHEN B.remark is null or B.remark = "" THEN B.loginCall ELSE B.remark END AS updaterName,CASE WHEN C.remark is null or C.remark = "" THEN C.loginCall ELSE C.remark END AS managerName,A.lastUpdateUserID,A.managerID,A.isFollow,IFNULL(A.protocol,"http"),A.targetMethod,A.groupID,IFNULL(D.groupPath,"0"),IFNULL(D.groupName,"未分组") FROM goku_gateway_api A INNER JOIN goku_admin B ON A.lastUpdateUserID = B.userID INNER JOIN goku_admin C ON A.managerID=C.userID LEFT JOIN goku_gateway_api_group D ON D.groupID = A.groupID %s`, ruleStr) + count := getCountSQL(d.db, sql) + rows, err := getPageSQL(d.db, sql, "A.updateTime", "DESC", page, pageSize) if err != nil { return false, make([]map[string]interface{}, 0), 0, err } @@ -307,11 +325,11 @@ func GetAPIList(projectID int, groupID int, keyword string, condition, page, pag } //CheckURLIsExist 接口路径是否存在 -func CheckURLIsExist(requestURL, requestMethod string, projectID, apiID int) bool { - db := database2.GetConnection() +func (d *APIDao) CheckURLIsExist(requestURL, requestMethod string, projectID, apiID int) bool { + db := d.db var id int var m string - sql := "SELECT apiID,requestMethod FROM goku_gateway_api WHERE requestURL = ? AND projectID = ?;" + sql := "SELECT apiID,requestMethod FROM goku_gateway_api A WHERE requestURL = ? AND projectID = ?;" err := db.QueryRow(sql, requestURL, projectID).Scan(&id, &m) if err != nil { return false @@ -332,9 +350,9 @@ func CheckURLIsExist(requestURL, requestMethod string, projectID, apiID int) boo } //CheckAPIIsExist 检查接口是否存在 -func CheckAPIIsExist(apiID int) (bool, error) { - db := database2.GetConnection() - sql := "SELECT apiID FROM goku_gateway_api WHERE apiID = ?;" +func (d *APIDao) CheckAPIIsExist(apiID int) (bool, error) { + db := d.db + sql := "SELECT apiID FROM goku_gateway_api A WHERE apiID = ?;" var id int err := db.QueryRow(sql, apiID).Scan(&id) if err != nil { @@ -343,9 +361,29 @@ func CheckAPIIsExist(apiID int) (bool, error) { return true, err } +//CheckAliasIsExist 检查别名是否存在 +func (d *APIDao) CheckAliasIsExist(apiID int, alias string) bool { + if alias == "" { + return false + } + + db := d.db + sql := "SELECT apiID FROM goku_gateway_api A WHERE alias = ?;" + var id int + err := db.QueryRow(sql, apiID).Scan(&id) + if err != nil { + return false + } + if id != 0 && apiID == id { + return false + } + + return true +} + //BatchEditAPIBalance 批量修改接口负载 -func BatchEditAPIBalance(apiIDList []string, balance string) (string, error) { - db := database2.GetConnection() +func (d *APIDao) BatchEditAPIBalance(apiIDList []string, balance string) (string, error) { + db := d.db now := time.Now().Format("2006-01-02 15:04:05") sqlTpl := "UPDATE `goku_gateway_api` A LEFT JOIN `goku_gateway_project` P ON A.`projectID` = P.`projectID` SET A.`updateTime` = ?, P.`updateTime`=?, A.`balanceName`=? WHERE A.`apiID` IN (%s)" @@ -365,8 +403,8 @@ func BatchEditAPIBalance(apiIDList []string, balance string) (string, error) { } //BatchEditAPIGroup 批量修改接口分组 -func BatchEditAPIGroup(apiIDList []string, groupID int) (string, error) { - db := database2.GetConnection() +func (d *APIDao) BatchEditAPIGroup(apiIDList []string, groupID int) (string, error) { + db := d.db now := time.Now().Format("2006-01-02 15:04:05") sqlTpl := "UPDATE `goku_gateway_api` A LEFT JOIN `goku_gateway_project` P ON A.`projectID` = P.`projectID` SET A.`updateTime` = ?, P.`updateTime`=?, A.`groupID`=? WHERE A.`apiID` IN (%s)" @@ -386,11 +424,11 @@ func BatchEditAPIGroup(apiIDList []string, groupID int) (string, error) { } //BatchDeleteAPI 批量修改接口 -func BatchDeleteAPI(apiIDList string) (bool, string, error) { - db := database2.GetConnection() +func (d *APIDao) BatchDeleteAPI(apiIDList string) (bool, string, error) { + db := d.db now := time.Now().Format("2006-01-02 15:04:05") Tx, _ := db.Begin() - sql := "DELETE FROM goku_gateway_api WHERE apiID IN (" + apiIDList + ");" + sql := "DELETE FROM goku_gateway_api A WHERE apiID IN (" + apiIDList + ");" _, err := Tx.Exec(sql) if err != nil { Tx.Rollback() @@ -410,7 +448,7 @@ func BatchDeleteAPI(apiIDList string) (bool, string, error) { } // 查询接口的projectID - rows, err := db.Query("SELECT projectID FROM goku_gateway_api WHERE apiID IN (" + apiIDList + ");") + rows, err := db.Query("SELECT projectID FROM goku_gateway_api A WHERE apiID IN (" + apiIDList + ");") if err != nil { Tx.Rollback() return false, "[ERROR]Fail to excute SQL statement!", err diff --git a/server/dao/console-sqlite3/apiGroup.go b/server/dao/console-sqlite3/apiGroup.go index 023143ed..938b9b84 100644 --- a/server/dao/console-sqlite3/apiGroup.go +++ b/server/dao/console-sqlite3/apiGroup.go @@ -5,12 +5,38 @@ import ( "strconv" "time" - database2 "github.com/eolinker/goku-api-gateway/common/database" + "github.com/eolinker/goku-api-gateway/common/pdao" + "github.com/eolinker/goku-api-gateway/server/dao" ) +var ( + apiDao dao.APIDao +) + +func init() { + pdao.Need(&apiDao) +} + +//APIGroupDao APIGroupDao +type APIGroupDao struct { + db *SQL.DB +} + +//NewAPIGroupDao new APIGroupDao +func NewAPIGroupDao() *APIGroupDao { + return &APIGroupDao{} +} + +//Create create +func (d *APIGroupDao) Create(db *SQL.DB) (interface{}, error) { + d.db = db + var i dao.APIGroupDao = d + return &i, nil +} + //AddAPIGroup 新建接口分组 -func AddAPIGroup(groupName string, projectID, parentGroupID int) (bool, interface{}, error) { - db := database2.GetConnection() +func (d *APIGroupDao) AddAPIGroup(groupName string, projectID, parentGroupID int) (bool, interface{}, error) { + db := d.db now := time.Now().Format("2006-01-02 15:04:05") Tx, _ := db.Begin() groupPath := "" @@ -69,8 +95,8 @@ func AddAPIGroup(groupName string, projectID, parentGroupID int) (bool, interfac } //EditAPIGroup 修改接口分组 -func EditAPIGroup(groupName string, groupID, projectID int) (bool, string, error) { - db := database2.GetConnection() +func (d *APIGroupDao) EditAPIGroup(groupName string, groupID, projectID int) (bool, string, error) { + db := d.db now := time.Now().Format("2006-01-02 15:04:05") Tx, _ := db.Begin() sql := "UPDATE goku_gateway_api_group SET groupName = ? WHERE groupID = ? AND projectID = ?;" @@ -90,8 +116,8 @@ func EditAPIGroup(groupName string, groupID, projectID int) (bool, string, error } //DeleteAPIGroup 删除接口分组 -func DeleteAPIGroup(projectID, groupID int) (bool, string, error) { - db := database2.GetConnection() +func (d *APIGroupDao) DeleteAPIGroup(projectID, groupID int) (bool, string, error) { + db := d.db Tx, _ := db.Begin() var groupPath string // 获取分组信息 @@ -114,7 +140,7 @@ func DeleteAPIGroup(projectID, groupID int) (bool, string, error) { Tx.Rollback() return false, "[ERROR]Fail to delete data!", err } - flag, apiList, _ := GetAPIListByGroupList(projectID, concatGroupID) + flag, apiList, _ := apiDao.GetAPIListByGroupList(projectID, concatGroupID) if flag { listLen := len(apiList) if listLen > 0 { @@ -167,8 +193,8 @@ func DeleteAPIGroup(projectID, groupID int) (bool, string, error) { } //GetAPIGroupList 获取接口分组列表 -func GetAPIGroupList(projectID int) (bool, []map[string]interface{}, error) { - db := database2.GetConnection() +func (d *APIGroupDao) GetAPIGroupList(projectID int) (bool, []map[string]interface{}, error) { + db := d.db sql := "SELECT groupID,groupName,parentGroupID,groupDepth FROM goku_gateway_api_group WHERE projectID = ?;" rows, err := db.Query(sql, projectID) if err != nil { diff --git a/server/dao/console-sqlite3/apiPlugin.go b/server/dao/console-sqlite3/apiPlugin.go index ec4e4f81..f23e8360 100644 --- a/server/dao/console-sqlite3/apiPlugin.go +++ b/server/dao/console-sqlite3/apiPlugin.go @@ -6,18 +6,33 @@ import ( "fmt" "strings" - log "github.com/eolinker/goku-api-gateway/goku-log" + "github.com/eolinker/goku-api-gateway/server/dao" - database2 "github.com/eolinker/goku-api-gateway/common/database" + log "github.com/eolinker/goku-api-gateway/goku-log" "time" ) -var apiPlugins = []string{"goku-proxy_caching", "goku-circuit_breaker"} +//APIPluginDao APIPluginDao +type APIPluginDao struct { + db *SQL.DB +} + +//NewAPIPluginDao new APIPluginDao +func NewAPIPluginDao() *APIPluginDao { + return &APIPluginDao{} +} + +//Create create +func (d *APIPluginDao) Create(db *SQL.DB) (interface{}, error) { + d.db = db + var i dao.APIPluginDao = d + return &i, nil +} //AddPluginToAPI 新增接口插件 -func AddPluginToAPI(pluginName, config, strategyID string, apiID, userID int) (bool, interface{}, error) { - db := database2.GetConnection() +func (d *APIPluginDao) AddPluginToAPI(pluginName, config, strategyID string, apiID, userID int) (bool, interface{}, error) { + db := d.db // 查询接口是否添加该插件 sql := "SELECT apiID FROM goku_conn_plugin_api WHERE strategyID = ? AND pluginName = ? AND apiID = ?;" var id int @@ -44,8 +59,8 @@ func AddPluginToAPI(pluginName, config, strategyID string, apiID, userID int) (b } //EditAPIPluginConfig 修改接口插件配置 -func EditAPIPluginConfig(pluginName, config, strategyID string, apiID, userID int) (bool, interface{}, error) { - db := database2.GetConnection() +func (d *APIPluginDao) EditAPIPluginConfig(pluginName, config, strategyID string, apiID, userID int) (bool, interface{}, error) { + db := d.db // 查询接口是否添加该插件 t := time.Now() now := t.Format("2006-01-02 15:04:05") @@ -75,8 +90,8 @@ func EditAPIPluginConfig(pluginName, config, strategyID string, apiID, userID in } //GetAPIPluginList 获取接口插件列表 -func GetAPIPluginList(apiID int, strategyID string) (bool, []map[string]interface{}, error) { - db := database2.GetConnection() +func (d *APIPluginDao) GetAPIPluginList(apiID int, strategyID string) (bool, []map[string]interface{}, error) { + db := d.db sql := `SELECT goku_conn_plugin_api.connID,goku_conn_plugin_api.pluginName,IFNULL(goku_conn_plugin_api.createTime,""),IFNULL(goku_conn_plugin_api.updateTime,""),goku_conn_plugin_api.pluginConfig,goku_plugin.pluginPriority, IF(goku_plugin.pluginStatus=0,-1,goku_conn_plugin_api.pluginStatus) as pluginStatus,goku_gateway_api.requestURL FROM goku_conn_plugin_api INNER JOIN goku_plugin ON goku_plugin.pluginName = goku_conn_plugin_api.pluginName INNER goku_gateway_api.apiID = goku_conn_plugin_api.apiID WHERE goku_conn_plugin_api.apiID = ? AND goku_conn_plugin_api.strategyID = ? ORDER BY pluginStatus DESC,goku_conn_plugin_api.updateTime DESC;` rows, err := db.Query(sql, apiID, strategyID) if err != nil { @@ -110,8 +125,8 @@ func GetAPIPluginList(apiID int, strategyID string) (bool, []map[string]interfac } //GetPluginIndex 获取插件优先级 -func GetPluginIndex(pluginName string) (bool, int, error) { - db := database2.GetConnection() +func (d *APIPluginDao) GetPluginIndex(pluginName string) (bool, int, error) { + db := d.db var pluginPriority int sql := "SELECT pluginPriority FROM goku_plugin WHERE pluginName = ?;" err := db.QueryRow(sql, pluginName).Scan(pluginPriority) @@ -122,8 +137,8 @@ func GetPluginIndex(pluginName string) (bool, int, error) { } //GetAPIPluginConfig 通过APIID获取配置信息 -func GetAPIPluginConfig(apiID int, strategyID, pluginName string) (bool, map[string]string, error) { - db := database2.GetConnection() +func (d *APIPluginDao) GetAPIPluginConfig(apiID int, strategyID, pluginName string) (bool, map[string]string, error) { + db := d.db sql := "SELECT goku_gateway_api.apiName,goku_gateway_api.requestURL,goku_conn_plugin_api.pluginConfig FROM goku_conn_plugin_api INNER JOIN goku_gateway_api ON goku_gateway_api.apiID = goku_conn_plugin_api.apiID WHERE goku_conn_plugin_api.apiID = ? AND goku_conn_plugin_api.strategyID = ? AND goku_conn_plugin_api.pluginName = ?;" var p, apiName, requestURL string err := db.QueryRow(sql, apiID, strategyID, pluginName).Scan(&apiName, &requestURL, &p) @@ -142,8 +157,8 @@ func GetAPIPluginConfig(apiID int, strategyID, pluginName string) (bool, map[str } //CheckPluginIsExistInAPI 检查策略组是否绑定插件 -func CheckPluginIsExistInAPI(strategyID, pluginName string, apiID int) (bool, error) { - db := database2.GetConnection() +func (d *APIPluginDao) CheckPluginIsExistInAPI(strategyID, pluginName string, apiID int) (bool, error) { + db := d.db sql := "SELECT apiID FROM goku_conn_plugin_api WHERE strategyID = ? AND pluginName = ? AND apiID = ?;" var id int err := db.QueryRow(sql, strategyID, pluginName, apiID).Scan(&id) @@ -154,8 +169,8 @@ func CheckPluginIsExistInAPI(strategyID, pluginName string, apiID int) (bool, er } // GetAPIPluginInStrategyByAPIID 通过接口ID获取策略组中接口插件列表 -func GetAPIPluginInStrategyByAPIID(strategyID string, apiID int, keyword string, condition int) (bool, []map[string]interface{}, map[string]interface{}, error) { - db := database2.GetConnection() +func (d *APIPluginDao) GetAPIPluginInStrategyByAPIID(strategyID string, apiID int, keyword string, condition int) (bool, []map[string]interface{}, map[string]interface{}, error) { + db := d.db var ( apiName string requestURL string @@ -224,8 +239,8 @@ func GetAPIPluginInStrategyByAPIID(strategyID string, apiID int, keyword string, } //GetAllAPIPluginInStrategy 获取策略组中所有接口插件列表 -func GetAllAPIPluginInStrategy(strategyID string) (bool, []map[string]interface{}, error) { - db := database2.GetConnection() +func (d *APIPluginDao) GetAllAPIPluginInStrategy(strategyID string) (bool, []map[string]interface{}, error) { + db := d.db sql := `SELECT goku_conn_plugin_api.connID,goku_conn_plugin_api.apiID,goku_gateway_api.apiName,goku_gateway_api.requestURL,goku_conn_plugin_api.pluginName,IFNULL(goku_conn_plugin_api.createTime,""),IFNULL(goku_conn_plugin_api.updateTime,""),IF(goku_plugin.pluginStatus=0,-1,goku_conn_plugin_api.pluginStatus) as pluginStatus,IFNULL(goku_plugin.pluginDesc,"") FROM goku_conn_plugin_api INNER JOIN goku_gateway_api ON goku_gateway_api.apiID = goku_conn_plugin_api.apiID INNER JOIN goku_plugin ON goku_plugin.pluginName = goku_conn_plugin_api.pluginName WHERE goku_conn_plugin_api.strategyID = ? ORDER BY pluginStatus DESC,goku_conn_plugin_api.updateTime DESC;` rows, err := db.Query(sql, strategyID) if err != nil { @@ -259,8 +274,8 @@ func GetAllAPIPluginInStrategy(strategyID string) (bool, []map[string]interface{ } //BatchEditAPIPluginStatus 批量修改策略组插件状态 -func BatchEditAPIPluginStatus(connIDList, strategyID string, pluginStatus, userID int) (bool, string, error) { - db := database2.GetConnection() +func (d *APIPluginDao) BatchEditAPIPluginStatus(connIDList, strategyID string, pluginStatus, userID int) (bool, string, error) { + db := d.db t := time.Now() now := t.Format("2006-01-02 15:04:05") updateTag := t.Format("20060102150405") @@ -301,8 +316,8 @@ func BatchEditAPIPluginStatus(connIDList, strategyID string, pluginStatus, userI } //BatchDeleteAPIPlugin 批量删除策略组插件 -func BatchDeleteAPIPlugin(connIDList, strategyID string) (bool, string, error) { - db := database2.GetConnection() +func (d *APIPluginDao) BatchDeleteAPIPlugin(connIDList, strategyID string) (bool, string, error) { + db := d.db now := time.Now().Format("2006-01-02 15:04:05") Tx, _ := db.Begin() apiIDList := make([]int, 0) @@ -343,8 +358,8 @@ func BatchDeleteAPIPlugin(connIDList, strategyID string) (bool, string, error) { } //GetAPIPluginName 通过connID获取插件名称 -func GetAPIPluginName(connID int) (bool, string, error) { - db := database2.GetConnection() +func (d *APIPluginDao) GetAPIPluginName(connID int) (bool, string, error) { + db := d.db var pluginName string sql := "SELECT pluginName FROM goku_conn_plugin_api WHERE connID = ?" err := db.QueryRow(sql, connID).Scan(&pluginName) @@ -355,8 +370,8 @@ func GetAPIPluginName(connID int) (bool, string, error) { } //CheckAPIPluginIsExistByConnIDList 通过connIDList判断插件是否存在 -func CheckAPIPluginIsExistByConnIDList(connIDList, pluginName string) (bool, []int, error) { - db := database2.GetConnection() +func (d *APIPluginDao) CheckAPIPluginIsExistByConnIDList(connIDList, pluginName string) (bool, []int, error) { + db := d.db sql := "SELECT apiID FROM goku_conn_plugin_api WHERE connID IN (" + connIDList + ") AND pluginName = ?;" rows, err := db.Query(sql, pluginName) if err != nil { @@ -377,8 +392,8 @@ func CheckAPIPluginIsExistByConnIDList(connIDList, pluginName string) (bool, []i } //GetAPIPluginListWithNotAssignAPIList 获取没有绑定嵌套插件列表 -func GetAPIPluginListWithNotAssignAPIList(strategyID string) (bool, []map[string]interface{}, error) { - db := database2.GetConnection() +func (d *APIPluginDao) GetAPIPluginListWithNotAssignAPIList(strategyID string) (bool, []map[string]interface{}, error) { + db := d.db sql := "SELECT pluginID,pluginDesc,pluginName FROM goku_plugin WHERE pluginType = 2 AND pluginStatus = 1;" rows, err := db.Query(sql) if err != nil { diff --git a/server/dao/console-sqlite3/apiStrategy.go b/server/dao/console-sqlite3/apiStrategy.go index c85a74c5..7d88c63d 100644 --- a/server/dao/console-sqlite3/apiStrategy.go +++ b/server/dao/console-sqlite3/apiStrategy.go @@ -1,17 +1,35 @@ package console_sqlite3 import ( + "database/sql" "fmt" "strconv" "strings" "time" - database2 "github.com/eolinker/goku-api-gateway/common/database" + "github.com/eolinker/goku-api-gateway/server/dao" ) +//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 +} + //AddAPIToStrategy 将接口加入策略组 -func AddAPIToStrategy(apiList []string, strategyID string) (bool, string, error) { - db := database2.GetConnection() +func (d *APIStrategyDao) AddAPIToStrategy(apiList []string, strategyID string) (bool, string, error) { + db := d.db 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 = ?" @@ -60,8 +78,8 @@ func AddAPIToStrategy(apiList []string, strategyID string) (bool, string, error) } // SetAPITargetOfStrategy 重定向接口负载 -func SetAPITargetOfStrategy(apiID int, strategyID string, target string) (bool, string, error) { - db := database2.GetConnection() +func (d *APIStrategyDao) SetAPITargetOfStrategy(apiID int, strategyID string, target string) (bool, string, error) { + db := d.db sql := "UPDATE goku_conn_strategy_api SET `target` = ? where apiID = ? AND strategyID = ? " stmt, err := db.Prepare(sql) if err != nil { @@ -78,7 +96,7 @@ func SetAPITargetOfStrategy(apiID int, strategyID string, target string) (bool, } // BatchSetAPITargetOfStrategy 批量重定向接口负载 -func BatchSetAPITargetOfStrategy(apiIds []int, strategyID string, target string) (bool, string, error) { +func (d *APIStrategyDao) BatchSetAPITargetOfStrategy(apiIds []int, strategyID string, target string) (bool, string, error) { idLen := len(apiIds) s := make([]interface{}, 0, idLen+2) c := "" @@ -90,7 +108,7 @@ func BatchSetAPITargetOfStrategy(apiIds []int, strategyID string, target string) } s = append(s, id) } - db := database2.GetConnection() + db := d.db 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 { @@ -106,7 +124,7 @@ func BatchSetAPITargetOfStrategy(apiIds []int, strategyID string, target string) return true, "", nil } -func getAPIOfStrategyRule(condition int, balanceNames []string, ids []int) []string { +func (d *APIStrategyDao) getAPIOfStrategyRule(condition int, balanceNames []string, ids []int) []string { rule := make([]string, 0, 2) switch condition { case 1, 2: @@ -149,7 +167,7 @@ func getAPIOfStrategyRule(condition int, balanceNames []string, ids []int) []str } // GetAPIIDListFromStrategy 获取策略组接口列表 -func GetAPIIDListFromStrategy(strategyID, keyword string, condition int, ids []int, balanceNames []string) (bool, []int, error) { +func (d *APIStrategyDao) GetAPIIDListFromStrategy(strategyID, keyword string, condition int, ids []int, balanceNames []string) (bool, []int, error) { rule := make([]string, 0, 10) rule = append(rule, fmt.Sprintf("S.strategyID = '%s'", strategyID)) @@ -159,14 +177,14 @@ func GetAPIIDListFromStrategy(strategyID, keyword string, condition int, ids []i rule = append(rule, searchRule) } if condition > 0 { - rule = append(rule, getAPIOfStrategyRule(condition, balanceNames, ids)...) + rule = append(rule, d.getAPIOfStrategyRule(condition, balanceNames, ids)...) } 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) - rows, err := database2.GetConnection().Query(sql) + rows, err := d.db.Query(sql) if err != nil { return false, make([]int, 0), err } @@ -186,7 +204,7 @@ func GetAPIIDListFromStrategy(strategyID, keyword string, condition int, ids []i } // GetAPIListFromStrategy 获取策略组接口列表 -func GetAPIListFromStrategy(strategyID, keyword string, condition, page, pageSize int, ids []int, balanceNames []string) (bool, []map[string]interface{}, int, error) { +func (d *APIStrategyDao) GetAPIListFromStrategy(strategyID, keyword string, condition, page, pageSize int, ids []int, balanceNames []string) (bool, []map[string]interface{}, int, error) { rule := make([]string, 0, 2) rule = append(rule, fmt.Sprintf("S.strategyID = '%s'", strategyID)) @@ -196,7 +214,7 @@ func GetAPIListFromStrategy(strategyID, keyword string, condition, page, pageSiz rule = append(rule, searchRule) } if condition > 0 { - rule = append(rule, getAPIOfStrategyRule(condition, balanceNames, ids)...) + rule = append(rule, d.getAPIOfStrategyRule(condition, balanceNames, ids)...) } ruleStr := "" if len(rule) > 0 { @@ -204,8 +222,8 @@ func GetAPIListFromStrategy(strategyID, keyword string, condition, page, pageSiz } 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) - count := getCountSQL(sql) - rows, err := getPageSQL(sql, "S.`connID`", "DESC", page, pageSize) + count := getCountSQL(d.db, sql) + rows, err := getPageSQL(d.db, sql, "S.`connID`", "DESC", page, pageSize) if err != nil { return false, make([]map[string]interface{}, 0), 0, err } @@ -242,8 +260,8 @@ func GetAPIListFromStrategy(strategyID, keyword string, condition, page, pageSiz } // CheckIsExistAPIInStrategy 检查插件是否添加进策略组 -func CheckIsExistAPIInStrategy(apiID int, strategyID string) (bool, string, error) { - db := database2.GetConnection() +func (d *APIStrategyDao) CheckIsExistAPIInStrategy(apiID int, strategyID string) (bool, string, error) { + db := d.db var id int sql := "SELECT connID FROM goku_conn_strategy_api WHERE apiID = ? AND strategyID = ?" err := db.QueryRow(sql, apiID, strategyID).Scan(&id) @@ -254,8 +272,8 @@ func CheckIsExistAPIInStrategy(apiID int, strategyID string) (bool, string, erro } // 获取策略绑定的简易接口列表 -func getSimpleAPIListInStrategy(strategyID string, projectID int) map[string]string { - db := database2.GetConnection() +func (d *APIStrategyDao) getSimpleAPIListInStrategy(strategyID string, projectID int) map[string]string { + db := d.db 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 { @@ -275,8 +293,8 @@ func getSimpleAPIListInStrategy(strategyID string, projectID int) map[string]str } // GetAPIIDListNotInStrategy 获取未被该策略组绑定的接口ID列表(通过项目) -func GetAPIIDListNotInStrategy(strategyID string, projectID, groupID int, keyword string) (bool, []int, error) { - requestMap := getSimpleAPIListInStrategy(strategyID, projectID) +func (d *APIStrategyDao) GetAPIIDListNotInStrategy(strategyID string, projectID, groupID int, keyword string) (bool, []int, error) { + requestMap := d.getSimpleAPIListInStrategy(strategyID, projectID) rule := make([]string, 0, 3) rule = append(rule, fmt.Sprintf("A.projectID = %d", projectID)) @@ -286,7 +304,7 @@ func GetAPIIDListNotInStrategy(strategyID string, projectID, groupID int, keywor searchRule += " OR IFNULL(A.balanceName,'') LIKE '%" + keyword + "%' OR A.targetURL LIKE '%" + keyword + "%')" rule = append(rule, searchRule) } - groupRule, err := getAPIGroupRule(projectID, groupID) + groupRule, err := d.getAPIGroupRule(projectID, groupID) if err != nil { return false, make([]int, 0), err } @@ -299,7 +317,7 @@ func GetAPIIDListNotInStrategy(strategyID string, projectID, groupID int, keywor } sql := fmt.Sprintf("SELECT A.apiID,A.requestURL,A.requestMethod FROM goku_gateway_api A %s", ruleStr) - rows, err := database2.GetConnection().Query(sql) + rows, err := d.db.Query(sql) if err != nil { return false, make([]int, 0), err } @@ -323,8 +341,8 @@ func GetAPIIDListNotInStrategy(strategyID string, projectID, groupID int, keywor return true, apiIDList, nil } -func getAPIGroupRule(projectID, groupID int) (string, error) { - db := database2.GetConnection() +func (d *APIStrategyDao) getAPIGroupRule(projectID, groupID int) (string, error) { + db := d.db if groupID < 1 { if groupID == 0 { groupRule := fmt.Sprintf("A.groupID = %d", groupID) @@ -349,8 +367,8 @@ func getAPIGroupRule(projectID, groupID int) (string, error) { } // GetAPIListNotInStrategy 获取未被该策略组绑定的接口列表(通过项目) -func GetAPIListNotInStrategy(strategyID string, projectID, groupID, page, pageSize int, keyword string) (bool, []map[string]interface{}, int, error) { - requestMap := getSimpleAPIListInStrategy(strategyID, projectID) +func (d *APIStrategyDao) GetAPIListNotInStrategy(strategyID string, projectID, groupID, page, pageSize int, keyword string) (bool, []map[string]interface{}, int, error) { + requestMap := d.getSimpleAPIListInStrategy(strategyID, projectID) rule := make([]string, 0, 3) rule = append(rule, fmt.Sprintf("A.projectID = %d", projectID)) @@ -361,7 +379,7 @@ func GetAPIListNotInStrategy(strategyID string, projectID, groupID, page, pageSi rule = append(rule, searchRule) } - groupRule, err := getAPIGroupRule(projectID, groupID) + groupRule, err := d.getAPIGroupRule(projectID, groupID) if err != nil { return false, make([]map[string]interface{}, 0), 0, err } @@ -374,8 +392,8 @@ func GetAPIListNotInStrategy(strategyID string, projectID, groupID, page, pageSi ruleStr += "WHERE " + strings.Join(rule, " AND ") } 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) - count := getCountSQL(sql) - rows, err := getPageSQL(sql, "A.`updateTime`", "DESC", page, pageSize) + count := getCountSQL(d.db, sql) + rows, err := getPageSQL(d.db, sql, "A.`updateTime`", "DESC", page, pageSize) if err != nil { return false, make([]map[string]interface{}, 0), 0, err } @@ -415,8 +433,8 @@ func GetAPIListNotInStrategy(strategyID string, projectID, groupID, page, pageSi } //BatchDeleteAPIInStrategy 批量删除策略组接口 -func BatchDeleteAPIInStrategy(apiIDList, strategyID string) (bool, string, error) { - db := database2.GetConnection() +func (d *APIStrategyDao) BatchDeleteAPIInStrategy(apiIDList, strategyID string) (bool, string, error) { + db := d.db 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 + ")" diff --git a/server/dao/console-sqlite3/auth.go b/server/dao/console-sqlite3/auth.go index 0f42c389..2017a02c 100644 --- a/server/dao/console-sqlite3/auth.go +++ b/server/dao/console-sqlite3/auth.go @@ -1,12 +1,13 @@ package console_sqlite3 import ( + "database/sql" "encoding/json" "time" - log "github.com/eolinker/goku-api-gateway/goku-log" + "github.com/eolinker/goku-api-gateway/server/dao" - database2 "github.com/eolinker/goku-api-gateway/common/database" + log "github.com/eolinker/goku-api-gateway/goku-log" ) type basicAuthConf struct { @@ -66,9 +67,29 @@ type oauth2Credential struct { Remark string `json:"remark"` } +//AuthDao AuthDao +type AuthDao struct { + db *sql.DB +} + +//NewAuthDao new AuthDao +func NewAuthDao() *AuthDao { + return &AuthDao{} +} + +//Create create +func (d *AuthDao) Create(db *sql.DB) (interface{}, error) { + + d.db = db + + var i dao.AuthDao = d + + return &i, nil +} + //GetAuthStatus 获取认证状态 -func GetAuthStatus(strategyID string) (bool, map[string]interface{}, error) { - db := database2.GetConnection() +func (d *AuthDao) GetAuthStatus(strategyID string) (bool, map[string]interface{}, error) { + db := d.db var basicStatus, apikeyStatus int sql := `SELECT CASE WHEN goku_plugin.pluginStatus = 0 THEN 0 ELSE goku_conn_plugin_strategy.pluginStatus END AS pluginStatus FROM goku_conn_plugin_strategy INNER JOIN goku_plugin ON goku_plugin.pluginName = goku_conn_plugin_strategy.pluginName WHERE goku_conn_plugin_strategy.pluginName = ? AND goku_conn_plugin_strategy.strategyID = ?;` db.QueryRow(sql, "goku-basic_auth", strategyID).Scan(&basicStatus) @@ -85,8 +106,8 @@ func GetAuthStatus(strategyID string) (bool, map[string]interface{}, error) { } //GetAuthInfo 获取认证信息 -func GetAuthInfo(strategyID string) (bool, map[string]interface{}, error) { - db := database2.GetConnection() +func (d *AuthDao) GetAuthInfo(strategyID string) (bool, map[string]interface{}, error) { + db := d.db var strategyName, auth string sql := "SELECT IFNULL(auth,''),strategyName FROM goku_gateway_strategy WHERE strategyID = ?;" err := db.QueryRow(sql, strategyID).Scan(&auth, &strategyName) @@ -132,8 +153,8 @@ func GetAuthInfo(strategyID string) (bool, map[string]interface{}, error) { } //EditAuthInfo 编辑认证信息 -func EditAuthInfo(strategyID, strategyName, basicAuthList, apikeyList, jwtCredentialList, oauth2CredentialList string, delClientIDList []string) (bool, error) { - db := database2.GetConnection() +func (d *AuthDao) EditAuthInfo(strategyID, strategyName, basicAuthList, apikeyList, jwtCredentialList, oauth2CredentialList string, delClientIDList []string) (bool, error) { + db := d.db now := time.Now().Format("2006-01-02 15:04:05") sql := "UPDATE goku_gateway_strategy SET strategyName = ? WHERE strategyID = ?;" stmt, err := db.Prepare(sql) diff --git a/server/dao/console-sqlite3/cluster.go b/server/dao/console-sqlite3/cluster.go index cc5684e5..afd9f22f 100644 --- a/server/dao/console-sqlite3/cluster.go +++ b/server/dao/console-sqlite3/cluster.go @@ -1,13 +1,35 @@ package console_sqlite3 import ( - "github.com/eolinker/goku-api-gateway/common/database" + "database/sql" + + "github.com/eolinker/goku-api-gateway/server/dao" entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" ) +//ClusterDao ClusterDao +type ClusterDao struct { + db *sql.DB +} + +//NewClusterDao new ClusterDao +func NewClusterDao() *ClusterDao { + return &ClusterDao{} +} + +//Create create +func (d *ClusterDao) Create(db *sql.DB) (interface{}, error) { + + d.db = db + + var i dao.ClusterDao = d + + return &i, nil +} + //AddCluster 新增集群 -func AddCluster(name, title, note string) error { - db := database.GetConnection() +func (d *ClusterDao) AddCluster(name, title, note string) error { + db := d.db sql := "INSERT INTO goku_cluster (`name`,`title`,`note`) VALUES (?,?,?)" stmt, err := db.Prepare(sql) if err != nil { @@ -19,8 +41,8 @@ func AddCluster(name, title, note string) error { } //EditCluster 修改集群信息 -func EditCluster(name, title, note string) error { - db := database.GetConnection() +func (d *ClusterDao) EditCluster(name, title, note string) error { + db := d.db sql := "UPDATE goku_cluster SET `title` = ?,`note` = ? WHERE `name` = ?" stmt, err := db.Prepare(sql) if err != nil { @@ -32,8 +54,8 @@ func EditCluster(name, title, note string) error { } //DeleteCluster 删除集群 -func DeleteCluster(name string) error { - db := database.GetConnection() +func (d *ClusterDao) DeleteCluster(name string) error { + db := d.db sql := "DELETE FROM goku_cluster WHERE `name` = ?" stmt, err := db.Prepare(sql) if err != nil { @@ -45,8 +67,8 @@ func DeleteCluster(name string) error { } //GetClusterCount 获取集群数量 -func GetClusterCount() int { - db := database.GetConnection() +func (d *ClusterDao) GetClusterCount() int { + db := d.db var count int sql := "SELECT COUNT(*) FROM goku_cluster;" err := db.QueryRow(sql).Scan(&count) @@ -57,8 +79,8 @@ func GetClusterCount() int { } //GetClusterNodeCount 获取集群节点数量 -func GetClusterNodeCount(name string) int { - db := database.GetConnection() +func (d *ClusterDao) GetClusterNodeCount(name string) int { + db := d.db var count int sql := "SELECT COUNT(*) FROM goku_node_info INNER JOIN goku_cluster ON goku_node_info.clusterID = goku_clutser.id WHERE goku_clutser.`name` = ?;" err := db.QueryRow(sql, name).Scan(&count) @@ -69,8 +91,8 @@ func GetClusterNodeCount(name string) int { } //GetClusterIDByName 通过集群名称获取集群ID -func GetClusterIDByName(name string) int { - db := database.GetConnection() +func (d *ClusterDao) GetClusterIDByName(name string) int { + db := d.db var id int sql := "SELECT `id` FROM goku_cluster WHERE `name` = ?" err := db.QueryRow(sql, name).Scan(&id) @@ -80,9 +102,21 @@ func GetClusterIDByName(name string) int { return id } +//GetClusterByID 获取集群信息 +func (d *ClusterDao) GetClusterByID(id int) (*entity.Cluster, error) { + db := d.db + sql := "SELECT `id`,`name`,`title`,`note` FROM goku_cluster WHERE `id` = ?" + var cluster entity.Cluster + err := db.QueryRow(sql, id).Scan(&cluster.ID, &cluster.Name, &cluster.Title, &cluster.Note) + if err != nil { + return nil, err + } + return &cluster, nil +} + //GetClusters 获取集群列表 -func GetClusters() ([]*entity.Cluster, error) { - db := database.GetConnection() +func (d *ClusterDao) GetClusters() ([]*entity.Cluster, error) { + db := d.db sql := "SELECT `id`,`name`,`title`,`note`,count(I.`nodeID`) as num FROM `goku_cluster` C left join `goku_node_info` I on c.id = I.`clusterID` group by `id`,`name`,`title`,`note`;" rows, err := db.Query(sql) if err != nil { @@ -92,7 +126,7 @@ func GetClusters() ([]*entity.Cluster, error) { defer rows.Close() for rows.Next() { var cluster entity.Cluster - err = rows.Scan(&cluster.ID, &cluster.Name, &cluster.Title, &cluster.Note,&cluster.NodeCount) + err = rows.Scan(&cluster.ID, &cluster.Name, &cluster.Title, &cluster.Note, &cluster.NodeCount) if err != nil { return []*entity.Cluster{}, err } @@ -102,8 +136,8 @@ func GetClusters() ([]*entity.Cluster, error) { } //GetCluster 获取集群信息 -func GetCluster(name string) (*entity.Cluster, error) { - db := database.GetConnection() +func (d *ClusterDao) GetCluster(name string) (*entity.Cluster, error) { + db := d.db sql := "SELECT `id`,`name`,`title`,`note` FROM goku_cluster WHERE `name` = ?" var cluster entity.Cluster err := db.QueryRow(sql, name).Scan(&cluster.ID, &cluster.Name, &cluster.Title, &cluster.Note) @@ -114,8 +148,8 @@ func GetCluster(name string) (*entity.Cluster, error) { } //CheckClusterNameIsExist 判断集群名称是否存在 -func CheckClusterNameIsExist(name string) bool { - db := database.GetConnection() +func (d *ClusterDao) CheckClusterNameIsExist(name string) bool { + db := d.db sql := "SELECT `name` FROM goku_cluster WHERE `name` = ?" var clusterName string err := db.QueryRow(sql, name).Scan(&clusterName) diff --git a/server/dao/console-sqlite3/config-log/log.go b/server/dao/console-sqlite3/config-log/log.go index 805517a6..269dbc8d 100644 --- a/server/dao/console-sqlite3/config-log/log.go +++ b/server/dao/console-sqlite3/config-log/log.go @@ -1,16 +1,35 @@ package config_log import ( - "github.com/eolinker/goku-api-gateway/common/database" + "database/sql" + + "github.com/eolinker/goku-api-gateway/server/dao" entity "github.com/eolinker/goku-api-gateway/server/entity/config-log" ) const sqlSelect = "SELECT `name`,`enable`,`dir`,`file`,`level`,`period`,`expire`,`fields` FROM `goku_config_log` WHERE `name` = ? LIMIT 1;" const sqlInsert = "REPLACE INTO `goku_config_log`(`name`,`enable`,`dir`,`file`,`level`,`period`,`expire`,`fields`)VALUES(?,?,?,?,?,?,?,?);" +//ConfigLogDao ConfigLogDao +type ConfigLogDao struct { + db *sql.DB +} + +//NewConfigLogDao new ConfigLogDao +func NewConfigLogDao() *ConfigLogDao { + return &ConfigLogDao{} +} + +//Create create +func (d *ConfigLogDao) Create(db *sql.DB) (interface{}, error) { + d.db = db + var i dao.ConfigLogDao = d + return &i, nil +} + //Get get -func Get(name string) (*entity.LogConfig, error) { - stmt, e := database.GetConnection().Prepare(sqlSelect) +func (d *ConfigLogDao) Get(name string) (*entity.LogConfig, error) { + stmt, e := d.db.Prepare(sqlSelect) if e != nil { return nil, e } @@ -33,8 +52,8 @@ func Get(name string) (*entity.LogConfig, error) { } //Set set -func Set(ent *entity.LogConfig) error { - stmt, e := database.GetConnection().Prepare(sqlInsert) +func (d *ConfigLogDao) Set(ent *entity.LogConfig) error { + stmt, e := d.db.Prepare(sqlInsert) if e != nil { return e } diff --git a/server/dao/console-sqlite3/dao-balance-update/update.go b/server/dao/console-sqlite3/dao-balance-update/update.go index 8ff0b881..1ffd9576 100644 --- a/server/dao/console-sqlite3/dao-balance-update/update.go +++ b/server/dao/console-sqlite3/dao-balance-update/update.go @@ -1,15 +1,40 @@ package dao_balance_update import ( - "github.com/eolinker/goku-api-gateway/common/database" - dao_service2 "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3/dao-service" + "database/sql" + + "github.com/eolinker/goku-api-gateway/common/pdao" + "github.com/eolinker/goku-api-gateway/server/dao" entity "github.com/eolinker/goku-api-gateway/server/entity/balance-entity" ) +var serviceDao dao.ServiceDao + +func init() { + pdao.Need(&serviceDao) +} + +//BalanceUpdateDao BalanceUpdateDao +type BalanceUpdateDao struct { + db *sql.DB +} + +//NewBalanceUpdateDao new BalanceUpdateDao +func NewBalanceUpdateDao() *BalanceUpdateDao { + return &BalanceUpdateDao{} +} + +//Create create +func (d *BalanceUpdateDao) Create(db *sql.DB) (interface{}, error) { + d.db = db + i := dao.BalanceUpdateDao(d) + return &i, nil +} + //GetAllOldVerSion 获取所有旧负载配置 -func GetAllOldVerSion() ([]*entity.BalanceInfoEntity, error) { +func (d *BalanceUpdateDao) GetAllOldVerSion() ([]*entity.BalanceInfoEntity, error) { const sql = "SELECT `balanceName`,IFNULL(`balanceDesc`, ''),IFNULL(`balanceConfig`, ''),IFNULL(`defaultConfig`, ''),IFNULL(`clusterConfig`, ''),`updateTime`,`createTime` FROM `goku_balance` WHERE `serviceName` = '';" - db := database.GetConnection() + db := d.db rows, err := db.Query(sql) if err != nil { return nil, err @@ -30,14 +55,14 @@ func GetAllOldVerSion() ([]*entity.BalanceInfoEntity, error) { } //GetDefaultServiceStatic 获取默认静态负载 -func GetDefaultServiceStatic() string { +func (d *BalanceUpdateDao) GetDefaultServiceStatic() string { - tx := database.GetConnection() + tx := d.db name := "" err := tx.QueryRow("SELECT `name` FROM `goku_service_config` WHERE `driver`='static' ORDER BY `default` DESC LIMIT 1; ").Scan(&name) if err != nil { name = "static" - dao_service2.Add(name, "static", "默认静态服务", "", "", false, false, "", "", 5, 300) + serviceDao.Add(name, "static", "默认静态服务", "", "", false, false, "", "", 5, 300) } return name diff --git a/server/dao/console-sqlite3/dao-balance/add.go b/server/dao/console-sqlite3/dao-balance/add.go index 2c07e819..93c4ed12 100644 --- a/server/dao/console-sqlite3/dao-balance/add.go +++ b/server/dao/console-sqlite3/dao-balance/add.go @@ -1,33 +1,11 @@ package dao_balance -import ( - "github.com/eolinker/goku-api-gateway/common/database" -) - -//Add add -func Add(name, serviceName, desc, appName, static, staticCluster, now string) (string, error) { - - //const sql = "INSERT INTO goku_balance (`balanceName`,`serviceName`,`appName`,`balanceDesc`,`static`,`staticCluster`,`createTime`,`updateTime`) VALUES (?,?,?,?,?,?,?,?,);" - // - //db := database.GetConnection() - //stmt, err := db.Prepare(sql) - //if err != nil { - // return "[ERROR]Illegal SQL statement!", err - //} - //defer stmt.Close() - //_, err = stmt.Exec(name,serviceName,appName, desc, static, staticCluster, now, now) - //if err != nil { - // return "[ERROR]Failed to add data!", err - //} - return "", nil -} - //AddStatic 新增静态负载 -func AddStatic(name, serviceName, static, staticCluster, desc, now string) (string, error) { +func (b *BalanceDao) AddStatic(name, serviceName, static, staticCluster, desc, now string) (string, error) { const sql = "INSERT INTO goku_balance (`balanceName`,`serviceName`,`static`,`staticCluster`,`balanceDesc`,`createTime`,`updateTime`,`appName`,`defaultConfig`,`clusterConfig`,`balanceConfig`) VALUES (?,?,?,?,?,?,?,'','','','');" - db := database.GetConnection() + db := b.db stmt, err := db.Prepare(sql) if err != nil { return "[ERROR]Illegal SQL statement!", err @@ -41,11 +19,11 @@ func AddStatic(name, serviceName, static, staticCluster, desc, now string) (stri } //AddDiscovery 新增服务发现 -func AddDiscovery(name, serviceName, appName, desc, now string) (string, error) { +func (b *BalanceDao) AddDiscovery(name, serviceName, appName, desc, now string) (string, error) { const sql = "INSERT INTO goku_balance (`balanceName`,`serviceName`,`appName`,`balanceDesc`,`createTime`,`updateTime`,`static`,`staticCluster`,`defaultConfig`,`clusterConfig`,`balanceConfig`) VALUES (?,?,?,?,?,?,'','','','','');" - db := database.GetConnection() + db := b.db stmt, err := db.Prepare(sql) if err != nil { return "[ERROR]Illegal SQL statement!", err @@ -59,9 +37,9 @@ func AddDiscovery(name, serviceName, appName, desc, now string) (string, error) } //SaveStatic 保存静态负载信息 -func SaveStatic(name, serviceName, static, staticCluster, desc string, now string) (string, error) { +func (b *BalanceDao) SaveStatic(name, serviceName, static, staticCluster, desc string, now string) (string, error) { const sql = "UPDATE `goku_balance` SET `serviceName`=? ,`static` = ?,`staticCluster`=?,`balanceDesc` =?,`updateTime`=? WHERE `balanceName`=?;" - db := database.GetConnection() + db := b.db stmt, err := db.Prepare(sql) if err != nil { return "[ERROR]Illegal SQL statement!", err @@ -75,9 +53,9 @@ func SaveStatic(name, serviceName, static, staticCluster, desc string, now strin } //SaveDiscover 保存服务发现信息 -func SaveDiscover(name, serviceName, appName, desc string, now string) (string, error) { +func (b *BalanceDao) SaveDiscover(name, serviceName, appName, desc string, now string) (string, error) { const sql = "UPDATE `goku_balance` SET `serviceName`=? ,`appName` = ?,`balanceDesc` =?,`updateTime`=? WHERE `balanceName`=?;" - db := database.GetConnection() + db := b.db stmt, err := db.Prepare(sql) if err != nil { return "[ERROR]Illegal SQL statement!", err @@ -90,27 +68,10 @@ func SaveDiscover(name, serviceName, appName, desc string, now string) (string, return "", nil } -//Save save -func Save(name, desc, static, staticCluster, now string) (string, error) { - //const sql = "UPDATE `goku_balance` SET `balanceDesc` = ?,`static` =?,`staticCluster`=?,`updateTime`=? WHERE `balanceName` = ?;" - // - //db := database.GetConnection() - //stmt, err := db.Prepare(sql) - //if err != nil { - // return "[ERROR]Illegal SQL statement!", err - //} - //defer stmt.Close() - //_, err = stmt.Exec(desc, defaultConfig, clusterConfig, now, name) - //if err != nil { - // return "[ERROR]Failed to add data!", err - //} - return "", nil -} - //Delete 删除负载 -func Delete(name string) (string, error) { +func (b *BalanceDao) Delete(name string) (string, error) { const sql = "DELETE FROM `goku_balance` WHERE `balanceName`= ?;" - db := database.GetConnection() + db := b.db stmt, err := db.Prepare(sql) if err != nil { return "[ERROR]Illegal SQL statement!", err @@ -121,12 +82,11 @@ func Delete(name string) (string, error) { return "[ERROR]DELETE fail", err } return "", nil - } //BatchDelete 批量删除负载 -func BatchDelete(balanceNames []string) (string, error) { - db := database.GetConnection() +func (b *BalanceDao) BatchDelete(balanceNames []string) (string, error) { + db := b.db sql := "DELETE FROM `goku_balance` WHERE `balanceName` = ?;" sql2 := "UPDATE goku_conn_strategy_api SET target = '' WHERE target = ?" stmt, err := db.Prepare(sql) diff --git a/server/dao/console-sqlite3/dao-balance/balance.go b/server/dao/console-sqlite3/dao-balance/balance.go index 61f1f8e5..59c2d14c 100644 --- a/server/dao/console-sqlite3/dao-balance/balance.go +++ b/server/dao/console-sqlite3/dao-balance/balance.go @@ -1,33 +1,24 @@ package dao_balance import ( - "github.com/eolinker/goku-api-gateway/common/database" -) + "database/sql" -//GetBalanceNames 获取负载名称列表 -func GetBalanceNames() (bool, []string, error) { - db := database.GetConnection() - sql := "SELECT balanceName FROM goku_balance ;" + dao "github.com/eolinker/goku-api-gateway/server/dao" +) - rows, err := db.Query(sql) - if err != nil { - return false, nil, err - } - defer rows.Close() - //获取记录列 +//BalanceDao BalanceDao +type BalanceDao struct { + db *sql.DB +} - if _, err = rows.Columns(); err != nil { - return false, nil, err - } - balanceList := make([]string, 0) - for rows.Next() { - balanceName := "" - err = rows.Scan(&balanceName) - if err != nil { - return false, nil, err - } - balanceList = append(balanceList, balanceName) - } - return true, balanceList, nil +//NewBalanceDao new BalanceDao +func NewBalanceDao() *BalanceDao { + return &BalanceDao{} +} +//Create create +func (b *BalanceDao) Create(db *sql.DB) (interface{}, error) { + b.db = db + i := dao.BalanceDao(b) + return &i, nil } diff --git a/server/dao/console-sqlite3/dao-balance/get.go b/server/dao/console-sqlite3/dao-balance/get.go index c7d2dd54..006e8f53 100644 --- a/server/dao/console-sqlite3/dao-balance/get.go +++ b/server/dao/console-sqlite3/dao-balance/get.go @@ -1,17 +1,45 @@ package dao_balance import ( + sql2 "database/sql" "fmt" "strings" - "github.com/eolinker/goku-api-gateway/common/database" entity "github.com/eolinker/goku-api-gateway/server/entity/balance-entity-service" ) +//GetBalanceNames 获取负载名称列表 +func (b *BalanceDao) GetBalanceNames() (bool, []string, error) { + db := b.db + sql := "SELECT balanceName FROM goku_balance ;" + + rows, err := db.Query(sql) + if err != nil { + return false, nil, err + } + defer rows.Close() + //获取记录列 + + if _, err = rows.Columns(); err != nil { + return false, nil, err + } + balanceList := make([]string, 0) + for rows.Next() { + balanceName := "" + err = rows.Scan(&balanceName) + if err != nil { + return false, nil, err + } + balanceList = append(balanceList, balanceName) + } + return true, balanceList, nil + +} + //Get 根据负载名获取负载配置 -func Get(name string) (*entity.Balance, error) { +func (b *BalanceDao) Get(name string) (*entity.Balance, error) { const sql = "SELECT A.`balanceName`,A.`serviceName`,IFNULL(B.`driver`,''),A.`appName`,IFNULL(A.`static`,''),IFNULL(A.`staticCluster`,''),A.`balanceDesc`,A.`updateTime`,A.`createTime` FROM `goku_balance` A LEFT JOIN `goku_service_config` B ON A.`serviceName` = B.`NAME` WHERE A.`balanceName`= ?;" - db := database.GetConnection() + db := b.db v := new(entity.Balance) err := db.QueryRow(sql, name).Scan(&v.Name, &v.ServiceName, &v.ServiceDriver, &v.AppName, &v.Static, &v.StaticCluster, &v.Desc, &v.UpdateTime, &v.CreateTime) if err != nil { @@ -22,9 +50,9 @@ func Get(name string) (*entity.Balance, error) { } //GetAll 获取所有负载配置 -func GetAll() ([]*entity.Balance, error) { +func (b *BalanceDao) GetAll() ([]*entity.Balance, error) { const sql = "SELECT A.`balanceName`,A.`serviceName`,IFNULL(B.`driver`,''),A.`appName`,IFNULL(A.`static`,''),IFNULL(A.`staticCluster`,''),A.`balanceDesc`,A.`updateTime`,A.`createTime` FROM `goku_balance` A LEFT JOIN `goku_service_config` B ON A.`serviceName` = B.`name` ORDER BY A.`updateTime` DESC;" - db := database.GetConnection() + db := b.db rows, err := db.Query(sql) if err != nil { return nil, err @@ -44,7 +72,7 @@ func GetAll() ([]*entity.Balance, error) { } //Search 关键字获取负载列表 -func Search(keyword string) ([]*entity.Balance, error) { +func (b *BalanceDao) Search(keyword string) ([]*entity.Balance, error) { const sqlTpl = "SELECT A.`balanceName`,A.`serviceName`,IFNULL(B.`driver`,''),A.`appName`,IFNULL(A.`static`,''),IFNULL(A.`staticCluster`,''),A.`balanceDesc`,A.`updateTime`,A.`createTime` FROM `goku_balance` A LEFT JOIN `goku_service_config` B ON A.`serviceName` = B.`name` %s ORDER BY `updateTime` DESC;" where := "" @@ -56,7 +84,7 @@ func Search(keyword string) ([]*entity.Balance, error) { args = append(args, kp, kp, kp) } sql := fmt.Sprintf(sqlTpl, where) - db := database.GetConnection() + db := b.db rows, err := db.Query(sql, args...) if err != nil { return nil, err @@ -74,3 +102,31 @@ func Search(keyword string) ([]*entity.Balance, error) { } return r, nil } + +//GetUseBalanceNames 获取使用的负载名称列表 +func (b *BalanceDao) GetUseBalanceNames() (map[string]int, error) { + const sql = "SELECT `balanceName` as `name` FROM goku_gateway_api UNION SELECT `target` as `name` FROM goku_conn_strategy_api;" + db := b.db + rows, err := db.Query(sql) + if err != nil { + return nil, err + } + defer rows.Close() + + r := make(map[string]int) + for rows.Next() { + var balanceName sql2.NullString + err := rows.Scan(&balanceName) + if err != nil { + return nil, err + } + if balanceName.Valid == false || balanceName.String == "" { + continue + } + if _, ok := r[balanceName.String]; !ok { + r[balanceName.String] = 0 + } + r[balanceName.String] = r[balanceName.String] + 1 + } + return r, nil +} diff --git a/server/dao/console-sqlite3/dao-service/add.go b/server/dao/console-sqlite3/dao-service/add.go index c5d11710..2cfcfa30 100644 --- a/server/dao/console-sqlite3/dao-service/add.go +++ b/server/dao/console-sqlite3/dao-service/add.go @@ -2,22 +2,21 @@ package dao_service import ( "time" - - "github.com/eolinker/goku-api-gateway/common/database" ) const sqlAdd = "INSERT INTO `goku_service_config`(`name`,`driver`,`default`,`desc`,`config`,`clusterConfig`,`healthCheck`,`healthCheckPath`,`healthCheckPeriod`,`healthCheckCode`,`healthCheckTimeOut`,`createTime`,`updateTime`)VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?);" //Add 新增服务 -func Add(name, driver, desc, config, clusterConfig string, isDefault, healthCheck bool, healthCheckPath string, healthCheckCode string, healthCheckPeriod, healthCheckTimeOut int) error { +func (d *ServiceDao) Add(name, driver, desc, config, clusterConfig string, isDefault, healthCheck bool, healthCheckPath string, healthCheckCode string, healthCheckPeriod, healthCheckTimeOut int) error { now := time.Now().Format("2006-01-02 15:04:05") - stmt, e := database.GetConnection().Prepare(sqlAdd) + stmt, e := d.db.Prepare(sqlAdd) if e != nil { return e } defer stmt.Close() + _, err := stmt.Exec(name, driver, isDefault, desc, config, clusterConfig, healthCheck, healthCheckPath, healthCheckPeriod, healthCheckCode, healthCheckTimeOut, now, now) return err } diff --git a/server/dao/console-sqlite3/dao-service/dao.go b/server/dao/console-sqlite3/dao-service/dao.go new file mode 100644 index 00000000..e8e34e4e --- /dev/null +++ b/server/dao/console-sqlite3/dao-service/dao.go @@ -0,0 +1,24 @@ +package dao_service + +import ( + "database/sql" + + "github.com/eolinker/goku-api-gateway/server/dao" +) + +//ServiceDao ServiceDao +type ServiceDao struct { + db *sql.DB +} + +//NewServiceDao new ServiceDao +func NewServiceDao() *ServiceDao { + return &ServiceDao{} +} + +//Create create +func (d *ServiceDao) Create(db *sql.DB) (interface{}, error) { + d.db = db + i := dao.ServiceDao(d) + return &i, nil +} diff --git a/server/dao/console-sqlite3/dao-service/default.go b/server/dao/console-sqlite3/dao-service/default.go index edcf25a3..af67b009 100644 --- a/server/dao/console-sqlite3/dao-service/default.go +++ b/server/dao/console-sqlite3/dao-service/default.go @@ -2,14 +2,12 @@ package dao_service import ( "fmt" - - "github.com/eolinker/goku-api-gateway/common/database" ) //SetDefault 设置默认服务 -func SetDefault(name string) error { +func (d *ServiceDao) SetDefault(name string) error { count := 0 - err := database.GetConnection().QueryRow("SELECT count(1) FROM `goku_service_config` WHERE `name` = ?;", name).Scan(&count) + err := d.db.QueryRow("SELECT count(1) FROM `goku_service_config` WHERE `name` = ?;", name).Scan(&count) if err != nil { return err @@ -18,7 +16,7 @@ func SetDefault(name string) error { return fmt.Errorf("has no name=%s", name) } - tx, e := database.GetConnection().Begin() + tx, e := d.db.Begin() if e != nil { return e } diff --git a/server/dao/console-sqlite3/dao-service/delete.go b/server/dao/console-sqlite3/dao-service/delete.go index e17fef74..baf0e2f3 100644 --- a/server/dao/console-sqlite3/dao-service/delete.go +++ b/server/dao/console-sqlite3/dao-service/delete.go @@ -2,8 +2,6 @@ package dao_service import ( "fmt" - - "github.com/eolinker/goku-api-gateway/common/database" ) const sqlDelete = "DELETE FROM `goku_service_config` WHERE `name` = ? AND NOT EXISTS (SELECT * FROM `goku_balance` B WHERE B.`serviceName` = `goku_service_config`.`name` ) " @@ -16,16 +14,15 @@ func (e DeleteError) Error() string { } //Delete 删除服务发现 -func Delete(names []string) error { +func (d *ServiceDao) Delete(names []string) error { - tx, err := database.GetConnection().Begin() + tx, err := d.db.Begin() if err != nil { return err } stmt, e := tx.Prepare(sqlDelete) if e != nil { - return e } diff --git a/server/dao/console-sqlite3/dao-service/get.go b/server/dao/console-sqlite3/dao-service/get.go index ddff8f96..3f661df0 100644 --- a/server/dao/console-sqlite3/dao-service/get.go +++ b/server/dao/console-sqlite3/dao-service/get.go @@ -3,16 +3,15 @@ package dao_service import ( "fmt" - "github.com/eolinker/goku-api-gateway/common/database" entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" ) const sqlGet = "SELECT `name`,`driver`,`default`,`desc`,`config`,`clusterConfig`,`healthCheck`,`healthCheckPath`,`healthCheckPeriod`,`healthCheckCode`,`healthCheckTimeOut`,`createTime`,`updateTime` FROM `goku_service_config` WHERE `name`=?; " //Get 获取服务发现信息 -func Get(name string) (*entity.Service, error) { +func (d *ServiceDao) Get(name string) (*entity.Service, error) { - stmt, e := database.GetConnection().Prepare(sqlGet) + stmt, e := d.db.Prepare(sqlGet) if e != nil { return nil, e } diff --git a/server/dao/console-sqlite3/dao-service/list.go b/server/dao/console-sqlite3/dao-service/list.go index cc434ac5..d50a1e42 100644 --- a/server/dao/console-sqlite3/dao-service/list.go +++ b/server/dao/console-sqlite3/dao-service/list.go @@ -3,21 +3,20 @@ package dao_service import ( "fmt" - "github.com/eolinker/goku-api-gateway/common/database" entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" ) const sqlList = "SELECT `name`,`driver`,`default`,`desc`,`config`,`clusterConfig`,`healthCheck`,`healthCheckPath`,`healthCheckPeriod`,`healthCheckCode`,`healthCheckTimeOut`,`createTime`,`updateTime` FROM `goku_service_config` %s ORDER BY `updateTime` DESC;" //List 获取服务发现列表 -func List(keyword string) ([]*entity.Service, error) { +func (d *ServiceDao) List(keyword string) ([]*entity.Service, error) { where := "" if keyword != "" { where = fmt.Sprint("where `name` like '%", keyword, "%' OR `driver` like '%", keyword, "%'") } sql := fmt.Sprintf(sqlList, where) - stmt, e := database.GetConnection().Prepare(sql) + stmt, e := d.db.Prepare(sql) if e != nil { return nil, e } diff --git a/server/dao/console-sqlite3/dao-service/save.go b/server/dao/console-sqlite3/dao-service/save.go index ad54a282..28b7d873 100644 --- a/server/dao/console-sqlite3/dao-service/save.go +++ b/server/dao/console-sqlite3/dao-service/save.go @@ -2,21 +2,19 @@ package dao_service import ( "time" - - "github.com/eolinker/goku-api-gateway/common/database" ) const sqlSave = "UPDATE `goku_service_config` SET `desc`=?,`config`=?,`clusterConfig`=?,`healthCheck`=?,`healthCheckPath`=?,`healthCheckPeriod`=?,`healthCheckCode`=?,`healthCheckTimeOut`=?,`updateTime`=? WHERE `name`=?;" //Save 存储服务发现信息 -func Save(name, desc, config, clusterConfig string, healthCheck bool, healthCheckPath string, healthCheckCode string, healthCheckPeriod, healthCheckTimeOut int) error { +func (d *ServiceDao) Save(name, desc, config, clusterConfig string, healthCheck bool, healthCheckPath string, healthCheckCode string, healthCheckPeriod, healthCheckTimeOut int) error { now := time.Now().Format("2006-01-02 15:04:05") - stmt, e := database.GetConnection().Prepare(sqlSave) + stmt, e := d.db.Prepare(sqlSave) if e != nil { return e } - + defer stmt.Close() _, err := stmt.Exec(desc, config, clusterConfig, healthCheck, healthCheckPath, healthCheckPeriod, healthCheckCode, healthCheckTimeOut, now, name) return err } diff --git a/server/dao/console-sqlite3/dao-version-config/api.go b/server/dao/console-sqlite3/dao-version-config/api.go index 28e5629f..1177b3e2 100644 --- a/server/dao/console-sqlite3/dao-version-config/api.go +++ b/server/dao/console-sqlite3/dao-version-config/api.go @@ -4,13 +4,12 @@ import ( "encoding/json" "strings" - "github.com/eolinker/goku-api-gateway/common/database" "github.com/eolinker/goku-api-gateway/config" ) //GetAPIContent 获取接口信息 -func GetAPIContent() ([]*config.APIContent, error) { - db := database.GetConnection() +func (d *VersionConfigDao)GetAPIContent() ([]*config.APIContent, error) { + db := d.db sql := "SELECT apiID,apiName,IFNULL(protocol,'http'),IFNULL(balanceName,''),IFNULL(targetURL,''),CASE WHEN isFollow = 'true' THEN 'FOLLOW' ELSE targetMethod END targetMethod,responseDataType,requestURL,requestMethod,timeout,alertValve,retryCount,IFNULL(linkApis,''),IFNULL(staticResponse,'') FROM goku_gateway_api" rows, err := db.Query(sql) if err != nil { diff --git a/server/dao/console-sqlite3/dao-version-config/balance.go b/server/dao/console-sqlite3/dao-version-config/balance.go index 873e5a50..0ddf50a9 100644 --- a/server/dao/console-sqlite3/dao-version-config/balance.go +++ b/server/dao/console-sqlite3/dao-version-config/balance.go @@ -3,14 +3,13 @@ package dao_version_config import ( "encoding/json" - "github.com/eolinker/goku-api-gateway/common/database" "github.com/eolinker/goku-api-gateway/config" entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" ) //GetBalances 获取balance信息 -func GetBalances(clusters []*entity.Cluster) (map[string]map[string]*config.BalanceConfig, error) { - db := database.GetConnection() +func (d *VersionConfigDao)GetBalances(clusters []*entity.Cluster) (map[string]map[string]*config.BalanceConfig, error) { + db := d.db sql := "SELECT goku_balance.balanceName,goku_balance.static,goku_balance.staticCluster,goku_balance.serviceName,goku_balance.appName,goku_service_config.driver FROM goku_balance INNER JOIN goku_service_config ON goku_service_config.`name` = goku_balance.serviceName" rows, err := db.Query(sql) if err != nil { diff --git a/server/dao/console-sqlite3/dao-version-config/dao.go b/server/dao/console-sqlite3/dao-version-config/dao.go new file mode 100644 index 00000000..37c5c06f --- /dev/null +++ b/server/dao/console-sqlite3/dao-version-config/dao.go @@ -0,0 +1,25 @@ +package dao_version_config + +import ( + "database/sql" + + "github.com/eolinker/goku-api-gateway/server/dao" +) + +//VersionConfigDao VersionConfigDao +type VersionConfigDao struct { + db *sql.DB +} + +//NewVersionConfigDao new VersionConfigDao +func NewVersionConfigDao() *VersionConfigDao { + return &VersionConfigDao{} +} + +//Create create +func (d *VersionConfigDao) Create(db *sql.DB) (interface{}, error) { + d.db = db + + i := dao.VersionConfigDao(d) + return &i, nil +} diff --git a/server/dao/console-sqlite3/dao-version-config/discovery.go b/server/dao/console-sqlite3/dao-version-config/discovery.go index 6bd56849..14c2e95f 100644 --- a/server/dao/console-sqlite3/dao-version-config/discovery.go +++ b/server/dao/console-sqlite3/dao-version-config/discovery.go @@ -5,12 +5,12 @@ import ( entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" - "github.com/eolinker/goku-api-gateway/common/database" "github.com/eolinker/goku-api-gateway/config" ) -func GetDiscoverConfig(clusters []*entity.Cluster) (map[string]map[string]*config.DiscoverConfig, error) { - db := database.GetConnection() +//GetDiscoverConfig 获取服务发现信息 +func (d *VersionConfigDao)GetDiscoverConfig(clusters []*entity.Cluster) (map[string]map[string]*config.DiscoverConfig, error) { + db := d.db sql := "SELECT `name`,`driver`,`config`,`clusterConfig`,`healthCheck`,`healthCheckPath`,`healthCheckPeriod`,`healthCheckCode`,`healthCheckTimeOut` FROM goku_service_config" rows, err := db.Query(sql) if err != nil { diff --git a/server/dao/console-sqlite3/dao-version-config/gateway.go b/server/dao/console-sqlite3/dao-version-config/gateway.go new file mode 100644 index 00000000..4b442a4a --- /dev/null +++ b/server/dao/console-sqlite3/dao-version-config/gateway.go @@ -0,0 +1,19 @@ +package dao_version_config + +import ( + "github.com/eolinker/goku-api-gateway/config" +) + +//GetGatewayBasicConfig GetGatewayBasicConfig +func (d *VersionConfigDao) GetGatewayBasicConfig() (*config.Gateway, error) { + db := d.db + sql := "SELECT skipCertificate FROM goku_gateway;" + + var g config.Gateway + err := db.QueryRow(sql).Scan(&g.SkipCertificate) + if err != nil { + return nil, err + } + + return &g, nil +} diff --git a/server/dao/console-sqlite3/dao-version-config/log.go b/server/dao/console-sqlite3/dao-version-config/log.go index 460b65c0..8310e46c 100644 --- a/server/dao/console-sqlite3/dao-version-config/log.go +++ b/server/dao/console-sqlite3/dao-version-config/log.go @@ -3,12 +3,12 @@ package dao_version_config import ( "encoding/json" - "github.com/eolinker/goku-api-gateway/common/database" "github.com/eolinker/goku-api-gateway/config" ) -func GetLogInfo() (*config.LogConfig, *config.AccessLogConfig, error) { - db := database.GetConnection() +//GetLogInfo 获取日志信息 +func (d *VersionConfigDao)GetLogInfo() (*config.LogConfig, *config.AccessLogConfig, error) { + db := d.db sql := "SELECT `name`,`enable`,`dir`,`file`,`period`,IFNULL(`level`,''),IFNULL(`fields`,''),`expire` FROM goku_config_log;" rows, err := db.Query(sql) if err != nil { diff --git a/server/dao/console-sqlite3/dao-version-config/monitorModule.go b/server/dao/console-sqlite3/dao-version-config/monitorModule.go index 8543c729..2b3bfff2 100644 --- a/server/dao/console-sqlite3/dao-version-config/monitorModule.go +++ b/server/dao/console-sqlite3/dao-version-config/monitorModule.go @@ -2,12 +2,11 @@ package dao_version_config import ( "fmt" - - "github.com/eolinker/goku-api-gateway/common/database" ) -func GetMonitorModules(status int, isAll bool) (map[string]string, error) { - db := database.GetConnection() +//GetMonitorModules 获取监控模块信息 +func (d *VersionConfigDao)GetMonitorModules(status int, isAll bool) (map[string]string, error) { + db := d.db sql := "SELECT `name`,`config` FROM goku_monitor_module %s;" if isAll { sql = fmt.Sprintf(sql, "") diff --git a/server/dao/console-sqlite3/dao-version-config/plugin.go b/server/dao/console-sqlite3/dao-version-config/plugin.go index a1962695..871c1abd 100644 --- a/server/dao/console-sqlite3/dao-version-config/plugin.go +++ b/server/dao/console-sqlite3/dao-version-config/plugin.go @@ -3,13 +3,12 @@ package dao_version_config import ( "strconv" - "github.com/eolinker/goku-api-gateway/common/database" "github.com/eolinker/goku-api-gateway/config" ) //GetGlobalPlugin 获取全局插件 -func GetGlobalPlugin() (*config.GatewayPluginConfig, error) { - db := database.GetConnection() +func (d *VersionConfigDao) GetGlobalPlugin() (*config.GatewayPluginConfig, error) { + db := d.db sql := "SELECT pluginName,isStop,IFNULL(pluginConfig,''),pluginType FROM goku_plugin" rows, err := db.Query(sql) if err != nil { @@ -46,9 +45,9 @@ func GetGlobalPlugin() (*config.GatewayPluginConfig, error) { } //GetAPIPlugins 获取接口插件 -func GetAPIPlugins() (map[string][]*config.PluginConfig, error) { - db := database.GetConnection() - sql := "SELECT goku_conn_plugin_api.apiID,goku_conn_plugin_api.strategyID,goku_conn_plugin_api.pluginName,goku_conn_plugin_api.pluginConfig,goku_plugin.isStop,goku_conn_plugin_api.updateTag FROM goku_conn_plugin_api INNER JOIN goku_plugin ON goku_conn_plugin_api.pluginName = goku_plugin.pluginName" +func (d *VersionConfigDao) GetAPIPlugins() (map[string][]*config.PluginConfig, error) { + db := d.db + sql := "SELECT goku_conn_plugin_api.apiID,goku_conn_plugin_api.strategyID,goku_conn_plugin_api.pluginName,goku_conn_plugin_api.pluginConfig,goku_plugin.isStop FROM goku_conn_plugin_api INNER JOIN goku_plugin ON goku_conn_plugin_api.pluginName = goku_plugin.pluginName" rows, err := db.Query(sql) if err != nil { return nil, err @@ -58,8 +57,8 @@ func GetAPIPlugins() (map[string][]*config.PluginConfig, error) { for rows.Next() { var apiID int var isStop bool - var pluginName, pluginConfig, updateTag, strategyID string - err = rows.Scan(&apiID, &strategyID, &pluginName, &pluginConfig, &isStop, &updateTag) + var pluginName, pluginConfig, strategyID string + err = rows.Scan(&apiID, &strategyID, &pluginName, &pluginConfig, &isStop) if err != nil { return nil, err } @@ -68,10 +67,9 @@ func GetAPIPlugins() (map[string][]*config.PluginConfig, error) { pluginMaps[key] = make([]*config.PluginConfig, 0, 20) } pluginMaps[key] = append(pluginMaps[key], &config.PluginConfig{ - Name: pluginName, - IsStop: isStop, - Config: pluginConfig, - UpdateTag: updateTag, + Name: pluginName, + IsStop: isStop, + Config: pluginConfig, }) } return pluginMaps, nil @@ -79,9 +77,9 @@ func GetAPIPlugins() (map[string][]*config.PluginConfig, error) { } //GetStrategyPlugins 获取策略插件 -func GetStrategyPlugins() (map[string][]*config.PluginConfig, map[string]map[string]string, error) { - db := database.GetConnection() - sql := "SELECT goku_conn_plugin_strategy.strategyID,goku_conn_plugin_strategy.pluginName,goku_conn_plugin_strategy.pluginConfig,goku_plugin.isStop,goku_conn_plugin_strategy.updateTag FROM goku_conn_plugin_strategy INNER JOIN goku_plugin ON goku_conn_plugin_strategy.pluginName = goku_plugin.pluginName WHERE goku_plugin.pluginStatus = 1 AND goku_conn_plugin_strategy.pluginStatus = 1" +func (d *VersionConfigDao) GetStrategyPlugins() (map[string][]*config.PluginConfig, map[string]map[string]string, error) { + db := d.db + sql := "SELECT goku_conn_plugin_strategy.strategyID,goku_conn_plugin_strategy.pluginName,goku_conn_plugin_strategy.pluginConfig,goku_plugin.isStop FROM goku_conn_plugin_strategy INNER JOIN goku_plugin ON goku_conn_plugin_strategy.pluginName = goku_plugin.pluginName WHERE goku_plugin.pluginStatus = 1 AND goku_conn_plugin_strategy.pluginStatus = 1" rows, err := db.Query(sql) if err != nil { return nil, nil, err @@ -91,8 +89,8 @@ func GetStrategyPlugins() (map[string][]*config.PluginConfig, map[string]map[str authMaps := make(map[string]map[string]string) for rows.Next() { var isStop bool - var pluginName, pluginConfig, updateTag, strategyID string - err = rows.Scan(&strategyID, &pluginName, &pluginConfig, &isStop, &updateTag) + var pluginName, pluginConfig, strategyID string + err = rows.Scan(&strategyID, &pluginName, &pluginConfig, &isStop) if err != nil { return nil, nil, err } @@ -108,10 +106,9 @@ func GetStrategyPlugins() (map[string][]*config.PluginConfig, map[string]map[str } pluginMaps[key] = append(pluginMaps[key], &config.PluginConfig{ - Name: pluginName, - IsStop: isStop, - Config: pluginConfig, - UpdateTag: updateTag, + Name: pluginName, + IsStop: isStop, + Config: pluginConfig, }) } return pluginMaps, authMaps, nil diff --git a/server/dao/console-sqlite3/dao-version-config/router.go b/server/dao/console-sqlite3/dao-version-config/router.go new file mode 100644 index 00000000..98c15bd4 --- /dev/null +++ b/server/dao/console-sqlite3/dao-version-config/router.go @@ -0,0 +1,37 @@ +package dao_version_config + +import ( + "fmt" + "strings" + + "github.com/eolinker/goku-api-gateway/config" +) + +//GetRouterRules GetRouterRules +func (d *VersionConfigDao) GetRouterRules(enable int) ([]*config.Router, error) { + db := d.db + sql := "SELECT rules,target FROM goku_gateway_router %s ORDER BY priority DESC;" + rules := make([]string, 0, 1) + if enable != -1 { + rules = append(rules, fmt.Sprintf("enable = %d", enable)) + } + ruleStr := "" + if len(rules) > 0 { + ruleStr += "WHERE " + strings.Join(rules, " AND ") + } + rows, err := db.Query(fmt.Sprintf(sql, ruleStr)) + if err != nil { + return nil, err + } + defer rows.Close() + rs := make([]*config.Router, 0) + for rows.Next() { + var r config.Router + err = rows.Scan(&r.Rules, &r.Target) + if err != nil { + return nil, err + } + rs = append(rs, &r) + } + return rs, nil +} diff --git a/server/dao/console-sqlite3/dao-version-config/strategy.go b/server/dao/console-sqlite3/dao-version-config/strategy.go index b6508b43..9e06564d 100644 --- a/server/dao/console-sqlite3/dao-version-config/strategy.go +++ b/server/dao/console-sqlite3/dao-version-config/strategy.go @@ -3,7 +3,6 @@ package dao_version_config import ( "strconv" - "github.com/eolinker/goku-api-gateway/common/database" "github.com/eolinker/goku-api-gateway/config" ) @@ -15,15 +14,15 @@ var autoAuthNames = map[string]string{ } //GetAPIsOfStrategy 获取策略内接口数据 -func GetAPIsOfStrategy() (map[string][]*config.APIOfStrategy, error) { - db := database.GetConnection() +func (d *VersionConfigDao)GetAPIsOfStrategy() (map[string][]*config.APIOfStrategy, error) { + db := d.db sql := "SELECT goku_conn_strategy_api.apiID,IFNULL(goku_conn_strategy_api.target,''),goku_conn_strategy_api.strategyID FROM goku_conn_strategy_api;" rows, err := db.Query(sql) if err != nil { return nil, err } defer rows.Close() - apiPlugins, err := GetAPIPlugins() + apiPlugins, err := d.GetAPIPlugins() if err != nil { return nil, err } @@ -53,8 +52,8 @@ func GetAPIsOfStrategy() (map[string][]*config.APIOfStrategy, error) { } //GetStrategyConfig 获取策略配置 -func GetStrategyConfig() (string, []*config.StrategyConfig, error) { - db := database.GetConnection() +func (d *VersionConfigDao)GetStrategyConfig() (string, []*config.StrategyConfig, error) { + db := d.db sql := "SELECT strategyID,strategyName,enableStatus,strategyType FROM goku_gateway_strategy" rows, err := db.Query(sql) @@ -63,11 +62,11 @@ func GetStrategyConfig() (string, []*config.StrategyConfig, error) { } defer rows.Close() strategyConfigs := make([]*config.StrategyConfig, 0, 20) - strategyPlugins, authMaps, err := GetStrategyPlugins() + strategyPlugins, authMaps, err := d.GetStrategyPlugins() if err != nil { return "", nil, err } - apiOfStrategy, err := GetAPIsOfStrategy() + apiOfStrategy, err := d.GetAPIsOfStrategy() if err != nil { return "", nil, err } diff --git a/server/dao/console-sqlite3/gateway.go b/server/dao/console-sqlite3/gateway.go index 8c87ac96..1b8b9d6a 100644 --- a/server/dao/console-sqlite3/gateway.go +++ b/server/dao/console-sqlite3/gateway.go @@ -1,12 +1,35 @@ package console_sqlite3 import ( - database2 "github.com/eolinker/goku-api-gateway/common/database" + "database/sql" + + "github.com/eolinker/goku-api-gateway/server/dao" + entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" ) +//GatewayDao GatewayDao +type GatewayDao struct { + db *sql.DB +} + +//NewGatewayDao new GatewayDao +func NewGatewayDao() *GatewayDao { + return &GatewayDao{} +} + +//Create create +func (d *GatewayDao) Create(db *sql.DB) (interface{}, error) { + + d.db = db + + var i dao.GatewayDao = d + + return &i, nil +} + //GetGatewayConfig 获取网关配置 -func GetGatewayConfig() (map[string]interface{}, error) { - db := database2.GetConnection() +func (d *GatewayDao) GetGatewayConfig() (map[string]interface{}, error) { + db := d.db var successCode string var nodeUpdatePeriod, monitorUpdatePeriod, monitorTimeout int sql := `SELECT successCode,nodeUpdatePeriod,monitorUpdatePeriod,monitorTimeout FROM goku_gateway WHERE id = 1;` @@ -24,8 +47,8 @@ func GetGatewayConfig() (map[string]interface{}, error) { } //EditGatewayBaseConfig 编辑网关基本配置 -func EditGatewayBaseConfig(successCode string, nodeUpdatePeriod, monitorUpdatePeriod, monitorTimeout int) (bool, string, error) { - db := database2.GetConnection() +func (d *GatewayDao) EditGatewayBaseConfig(config entity.GatewayBasicConfig) (bool, string, error) { + db := d.db sql := "SELECT successCode FROM goku_gateway WHERE id = 1;" code := "" err := db.QueryRow(sql).Scan(&code) @@ -39,30 +62,7 @@ func EditGatewayBaseConfig(successCode string, nodeUpdatePeriod, monitorUpdatePe return false, "[ERROR]Illegal SQL Statement!", err } defer stmt.Close() - _, err = stmt.Exec(successCode, nodeUpdatePeriod, monitorUpdatePeriod, monitorTimeout) - if err != nil { - return false, "[ERROR]Fail to excute SQL Statement!", err - } - return true, "", nil -} - -//EditGatewayAlarmConfig 编辑网关告警配置 -func EditGatewayAlarmConfig(apiAlertInfo, sender, senderPassword, smtpAddress string, alertStatus, smtpPort, smtpProtocol int) (bool, string, error) { - db := database2.GetConnection() - sql := "SELECT successCode FROM goku_gateway WHERE id = 1;" - code := "" - err := db.QueryRow(sql).Scan(&code) - if err != nil { - sql = "INSERT INTO goku_gateway (id,apiAlertInfo,alertStatus,sender,senderPassword,smtpAddress,smtpPort,smtpProtocol) VALUES (1,?,?,?,?,?,?,?)" - } else { - sql = "UPDATE goku_gateway SET apiAlertInfo = ?,alertStatus = ?,sender = ?,senderPassword = ?,smtpAddress = ?,smtpPort = ?,smtpProtocol = ? WHERE id = 1;" - } - stmt, err := db.Prepare(sql) - if err != nil { - return false, "[ERROR]Illegal SQL Statement!", err - } - defer stmt.Close() - _, err = stmt.Exec(apiAlertInfo, alertStatus, sender, senderPassword, smtpAddress, smtpPort, smtpProtocol) + _, err = stmt.Exec(config.SuccessCode, config.NodeUpdatePeriod, config.MonitorUpdatePeriod, config.MonitorTimeout) if err != nil { return false, "[ERROR]Fail to excute SQL Statement!", err } @@ -70,8 +70,8 @@ func EditGatewayAlarmConfig(apiAlertInfo, sender, senderPassword, smtpAddress st } //GetGatewayInfo 获取网关信息 -func GetGatewayInfo() (nodeStartCount, nodeStopCount, projectCount, apiCount, strategyCount int, err error) { - db := database2.GetConnection() +func (d *GatewayDao) GetGatewayInfo() (nodeStartCount, nodeStopCount, projectCount, apiCount, strategyCount int, err error) { + db := d.db // 获取节点启动数量 err = db.QueryRow("SELECT COUNT(0) FROM goku_node_info WHERE nodeStatus = 1;").Scan(&nodeStartCount) diff --git a/server/dao/console-sqlite3/guest.go b/server/dao/console-sqlite3/guest.go index 55547a38..d70053d4 100644 --- a/server/dao/console-sqlite3/guest.go +++ b/server/dao/console-sqlite3/guest.go @@ -3,13 +3,31 @@ package console_sqlite3 import ( SQL "database/sql" - "github.com/eolinker/goku-api-gateway/common/database" + "github.com/eolinker/goku-api-gateway/server/dao" + "github.com/eolinker/goku-api-gateway/utils" ) +//GuestDao GuestDao +type GuestDao struct { + db *SQL.DB +} + +//NewGuestDao new GuestDao +func NewGuestDao() *GuestDao { + return &GuestDao{} +} + +//Create create +func (d *GuestDao) Create(db *SQL.DB) (interface{}, error) { + d.db = db + var i dao.GuestDao = d + return &i, nil +} + //Login 登录 -func Login(loginCall, loginPassword string) (bool, int) { - db := database.GetConnection() +func (d *GuestDao) Login(loginCall, loginPassword string) (bool, int) { + db := d.db var userID int err := db.QueryRow("SELECT userID FROM goku_admin WHERE loginCall = ? AND loginPassword = ?;", loginCall, loginPassword).Scan(&userID) if err != nil { @@ -19,8 +37,8 @@ func Login(loginCall, loginPassword string) (bool, int) { } //CheckLogin 检查用户是否登录 -func CheckLogin(userToken string, userID int) bool { - db := database.GetConnection() +func (d *GuestDao) CheckLogin(userToken string, userID int) bool { + db := d.db var loginPassword, loginCall string err := db.QueryRow("SELECT loginCall,loginPassword FROM goku_admin WHERE userID = ?;", userID).Scan(&loginCall, &loginPassword) if err != nil { @@ -33,8 +51,8 @@ func CheckLogin(userToken string, userID int) bool { } //Register 用户注册 -func Register(loginCall, loginPassword string) bool { - db := database.GetConnection() +func (d *GuestDao) Register(loginCall, loginPassword string) bool { + db := d.db sql := "SELECT userID,loginPassword FROM goku_admin WHERE loginCall = ?;" password := "" userID := 0 diff --git a/server/dao/console-sqlite3/import.go b/server/dao/console-sqlite3/import.go index 5bf1f9f5..a635dd5f 100644 --- a/server/dao/console-sqlite3/import.go +++ b/server/dao/console-sqlite3/import.go @@ -7,16 +7,34 @@ import ( "strings" "time" + "github.com/eolinker/goku-api-gateway/server/dao" + log "github.com/eolinker/goku-api-gateway/goku-log" - database2 "github.com/eolinker/goku-api-gateway/common/database" entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" ) var method = []string{"POST", "GET", "PUT", "DELETE", "HEAD", "OPTIONS", "PATCH"} +//ImportDao ImportDao +type ImportDao struct { + db *SQL.DB +} + +//NewImportDao ImportDao +func NewImportDao() *ImportDao { + return &ImportDao{} +} + +//Create create +func (d *ImportDao) Create(db *SQL.DB) (interface{}, error) { + d.db = db + var i dao.ImportDao = d + return &i, nil +} + // 导入接口信息 -func importAPIInfo(Tx *SQL.Tx, api entity.AmsAPIInfo, projectID, groupID, userID int, now string) bool { +func (d *ImportDao) importAPIInfo(Tx *SQL.Tx, api entity.AmsAPIInfo, projectID, groupID, userID int, now string) bool { // 新增API requestURL := "" host := "" @@ -44,7 +62,7 @@ func importAPIInfo(Tx *SQL.Tx, api entity.AmsAPIInfo, projectID, groupID, userID return true } -func recursiveImportAPIGroupFromAms(Tx *SQL.Tx, projectID, userID int, groupInfo entity.AmsGroupInfo, groupDepth, parentGroupID int, groupPath, now string) (bool, string, error) { +func (d *ImportDao) recursiveImportAPIGroupFromAms(Tx *SQL.Tx, projectID, userID int, groupInfo entity.AmsGroupInfo, groupDepth, parentGroupID int, groupPath, now string) (bool, string, error) { // 插入分组信息 result, err := Tx.Exec("INSERT INTO goku_gateway_api_group (projectID,groupName,groupDepth,parentGroupID) VALUES (?,?,?,?);", projectID, groupInfo.GroupName, groupDepth, parentGroupID) if err != nil { @@ -72,19 +90,19 @@ func recursiveImportAPIGroupFromAms(Tx *SQL.Tx, projectID, userID int, groupInfo return false, err.Error(), err } for _, childGroup := range groupInfo.APIGroupChildList { - _, _, err := recursiveImportAPIGroupFromAms(Tx, projectID, userID, childGroup, groupDepth+1, int(groupID), groupPath, now) + _, _, err := d.recursiveImportAPIGroupFromAms(Tx, projectID, userID, childGroup, groupDepth+1, int(groupID), groupPath, now) if err != nil { continue } } for _, childGroup := range groupInfo.ChildGroupList { - _, _, err := recursiveImportAPIGroupFromAms(Tx, projectID, userID, childGroup, groupDepth+1, int(groupID), groupPath, now) + _, _, err := d.recursiveImportAPIGroupFromAms(Tx, projectID, userID, childGroup, groupDepth+1, int(groupID), groupPath, now) if err != nil { continue } } for _, api := range groupInfo.APIList { - flag := importAPIInfo(Tx, api, projectID, int(groupID), userID, now) + flag := d.importAPIInfo(Tx, api, projectID, int(groupID), userID, now) if !flag { continue } @@ -93,11 +111,11 @@ func recursiveImportAPIGroupFromAms(Tx *SQL.Tx, projectID, userID int, groupInfo } //ImportAPIGroupFromAms 导入分组 -func ImportAPIGroupFromAms(projectID, userID int, groupInfo entity.AmsGroupInfo) (bool, string, error) { - db := database2.GetConnection() +func (d *ImportDao) ImportAPIGroupFromAms(projectID, userID int, groupInfo entity.AmsGroupInfo) (bool, string, error) { + db := d.db Tx, _ := db.Begin() now := time.Now().Format("2006-01-02 15:04:05") - _, errInfo, err := recursiveImportAPIGroupFromAms(Tx, projectID, userID, groupInfo, 1, 0, "", now) + _, errInfo, err := d.recursiveImportAPIGroupFromAms(Tx, projectID, userID, groupInfo, 1, 0, "", now) if err != nil { Tx.Rollback() return false, errInfo, err @@ -113,8 +131,8 @@ func ImportAPIGroupFromAms(projectID, userID int, groupInfo entity.AmsGroupInfo) } //ImportProjectFromAms 导入项目 -func ImportProjectFromAms(userID int, projectInfo entity.AmsProject) (bool, string, error) { - db := database2.GetConnection() +func (d *ImportDao) ImportProjectFromAms(userID int, projectInfo entity.AmsProject) (bool, string, error) { + db := d.db Tx, _ := db.Begin() now := time.Now().Format("2006-01-02 15:04:05") // 插入项目信息 @@ -132,7 +150,7 @@ func ImportProjectFromAms(userID int, projectInfo entity.AmsProject) (bool, stri } id := int(projectID) for _, groupInfo := range projectInfo.APIGroupList { - _, _, err := recursiveImportAPIGroupFromAms(Tx, id, userID, groupInfo, 1, 0, "", now) + _, _, err := d.recursiveImportAPIGroupFromAms(Tx, id, userID, groupInfo, 1, 0, "", now) if err != nil { continue } @@ -142,12 +160,12 @@ func ImportProjectFromAms(userID int, projectInfo entity.AmsProject) (bool, stri } //ImportAPIFromAms 从ams中导入接口 -func ImportAPIFromAms(projectID, groupID, userID int, apiList []entity.AmsAPIInfo) (bool, string, error) { - db := database2.GetConnection() +func (d *ImportDao) ImportAPIFromAms(projectID, groupID, userID int, apiList []entity.AmsAPIInfo) (bool, string, error) { + db := d.db Tx, _ := db.Begin() now := time.Now().Format("2006-01-02 15:04:05") for _, a := range apiList { - flag := importAPIInfo(Tx, a, projectID, groupID, userID, now) + flag := d.importAPIInfo(Tx, a, projectID, groupID, userID, now) if !flag { continue } diff --git a/server/dao/console-sqlite3/internal/goku311/gokuMonitorModule.go b/server/dao/console-sqlite3/internal/goku311/gokuMonitorModule.go new file mode 100644 index 00000000..dfef9608 --- /dev/null +++ b/server/dao/console-sqlite3/internal/goku311/gokuMonitorModule.go @@ -0,0 +1,24 @@ +package goku311 + +import SQL "database/sql" + +const gokuMonitorModuleSQL = `DROP TABLE IF EXISTS goku_monitor_module; +CREATE TABLE "goku_monitor_module" ( + "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + "name" TEXT NOT NULL, + "config" TEXT NOT NULL, + "moduleStatus" integer NOT NULL DEFAULT 0 +); + +CREATE UNIQUE INDEX "moduleName" +ON "goku_monitor_module" ( + "name" ASC +);` + +func createGokuMonitorModule(db *SQL.DB) error { + _, err := db.Exec(gokuMonitorModuleSQL) + if err != nil { + return err + } + return nil +} diff --git a/server/dao/console-sqlite3/internal/goku311/gokuNodeInfo.go b/server/dao/console-sqlite3/internal/goku311/gokuNodeInfo.go new file mode 100644 index 00000000..f7835be4 --- /dev/null +++ b/server/dao/console-sqlite3/internal/goku311/gokuNodeInfo.go @@ -0,0 +1,58 @@ +package goku311 + +import ( + SQL "database/sql" +) + +const gokuNodeInfoSQL = `DROP TABLE IF EXISTS goku_node_info_new; +CREATE TABLE "goku_node_info_new" ( + "nodeID" integer NOT NULL PRIMARY KEY AUTOINCREMENT, + "createTime" text, + "updateTime" text, + "groupID" integer(11) NOT NULL DEFAULT 0, + "nodeName" text(255) NOT NULL, + "nodeStatus" integer(11) NOT NULL, + "version" text(255), + "sshAddress" text(255) DEFAULT 22, + "sshUserName" text(255), + "sshPassword" text(255), + "gatewayPath" text(255), + "sshKey" text, + "authMethod" integer(4) NOT NULL DEFAULT 0, + "clusterID" integer(11) NOT NULL DEFAULT 0, + "listenAddress" text(22) NOT NULL DEFAULT '', + "adminAddress" text(22) NOT NULL DEFAULT '', + "nodeKey" TEXT(32) NOT NULL DEFAULT '' +); + +CREATE UNIQUE INDEX "nodeKey_new" +ON "goku_node_info_new" ( + "nodeKey" ASC +);` + +func createGokuNodeInfo(db *SQL.DB) error { + _, err := db.Exec(gokuNodeInfoSQL) + if err != nil { + return err + } + + sql := "INSERT INTO goku_node_info_new (`nodeID`,`createTime`,`updateTime`,`groupID`,`nodeName`,`nodeStatus`,`version`,`sshAddress`,`sshUserName`,`sshPassword`,`gatewayPath`,`sshKey`,`authMethod`,`clusterID`,`listenAddress`,`adminAddress`,`nodeKey`) SELECT `nodeID`,`createTime`,`updateTime`,`groupID`,`nodeName`,`nodeStatus`,`version`,`sshPort`,`userName`,`password`,`gatewayPath`,`key`,`authMethod`,`clusterID`,`nodeIP` || ':' || `nodePort`,`nodeIP` || ':' || `nodePort`,`nodeID` || `nodeIP` || ':' || `nodePort` FROM goku_node_info;" + _, err = db.Exec(sql) + if err != nil { + return err + } + _, err = db.Exec("DROP TABLE IF EXISTS goku_node_info") + if err != nil { + return err + } + _, err = db.Exec("ALTER TABLE goku_node_info_new RENAME TO goku_node_info") + if err != nil { + return err + } + _, err = db.Exec("DROP TABLE IF EXISTS goku_node_info_new") + if err != nil { + return err + } + + return nil +} diff --git a/server/dao/console-sqlite3/internal/goku311/gokuTableVersion.go b/server/dao/console-sqlite3/internal/goku311/gokuTableVersion.go new file mode 100644 index 00000000..26f85dd5 --- /dev/null +++ b/server/dao/console-sqlite3/internal/goku311/gokuTableVersion.go @@ -0,0 +1,23 @@ +package goku311 + +import SQL "database/sql" + +const gokuTableVersionSQL = `CREATE TABLE "goku_table_version" ( + "tableID" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + "tableName" TEXT NOT NULL, + "version" TEXT NOT NULL +); + +CREATE UNIQUE INDEX "tableName" +ON "goku_table_version" ( + "tableName" +);` + +func createGokuTableVersion(db *SQL.DB) error { + _, err := db.Exec(gokuTableVersionSQL) + if err != nil { + return err + } + + return nil +} diff --git a/server/dao/console-sqlite3/internal/goku311/update.go b/server/dao/console-sqlite3/internal/goku311/update.go new file mode 100644 index 00000000..7a1b988a --- /dev/null +++ b/server/dao/console-sqlite3/internal/goku311/update.go @@ -0,0 +1,60 @@ +package goku311 + +import ( + "database/sql" + + "github.com/eolinker/goku-api-gateway/common/pdao" + "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3/updater" +) + +//Version 版本号 +const Version = "3.1.1" + +//DBDriver dbDriver +const DBDriver = "sqlite3" + +//RegisterUpdate RegisterUpdate +func RegisterUpdate() { + pdao.RegisterDBBuilder(DBDriver, new(factory)) +} + +type factory struct { +} + +func (f *factory) Build(db *sql.DB) error { + return Exec(db) +} + +//Exec 执行goku_node_info +func Exec(db *sql.DB) error { + + updaterDao := updater.NewUpdaterDaoWidthDB(db) + + existed := updaterDao.IsTableExist("goku_table_version") + if !existed { + err := createGokuTableVersion(db) + if err != nil { + + return err + } + } + if version := updaterDao.GetTableVersion("goku_node_info"); version != Version { + err := createGokuNodeInfo(db) + if err != nil { + + return err + } + updaterDao.UpdateTableVersion("goku_node_info", Version) + } + if version := updaterDao.GetTableVersion("goku_monitor_module"); version != Version { + err := createGokuMonitorModule(db) + if err != nil { + return err + } + updaterDao.UpdateTableVersion("goku_monitor_module", Version) + } + + updaterDao.SetGokuVersion(Version) + + return nil +} diff --git a/server/dao/console-sqlite3/monitorModule.go b/server/dao/console-sqlite3/monitorModule.go index 3899e1ac..cf832f6f 100644 --- a/server/dao/console-sqlite3/monitorModule.go +++ b/server/dao/console-sqlite3/monitorModule.go @@ -1,13 +1,32 @@ package console_sqlite3 import ( - "github.com/eolinker/goku-api-gateway/common/database" + SQL "database/sql" + + "github.com/eolinker/goku-api-gateway/server/dao" entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" ) +//MonitorModulesDao MonitorModulesDao +type MonitorModulesDao struct { + db *SQL.DB +} + +//NewMonitorModulesDao MonitorModulesDao +func NewMonitorModulesDao() *MonitorModulesDao { + return &MonitorModulesDao{} +} + +//Create create +func (d *MonitorModulesDao) Create(db *SQL.DB) (interface{}, error) { + d.db = db + var i dao.MonitorModulesDao = d + return &i, nil +} + //GetMonitorModules 获取监控模块列表 -func GetMonitorModules() (map[string]*entity.MonitorModule, error) { - db := database.GetConnection() +func (d *MonitorModulesDao) GetMonitorModules() (map[string]*entity.MonitorModule, error) { + db := d.db sql := "SELECT `name`,IFNULL(`config`,'{}'),`moduleStatus` FROM goku_monitor_module;" rows, err := db.Query(sql) if err != nil { @@ -28,8 +47,8 @@ func GetMonitorModules() (map[string]*entity.MonitorModule, error) { } //SetMonitorModule 设置监控模块 -func SetMonitorModule(moduleName string, config string, moduleStatus int) error { - db := database.GetConnection() +func (d *MonitorModulesDao) SetMonitorModule(moduleName string, config string, moduleStatus int) error { + db := d.db sql := "REPLACE INTO goku_monitor_module (`name`,`config`,`moduleStatus`) VALUES (?,?,?)" _, err := db.Exec(sql, moduleName, config, moduleStatus) if err != nil { @@ -37,3 +56,15 @@ func SetMonitorModule(moduleName string, config string, moduleStatus int) error } return nil } + +//CheckModuleStatus 检查模块状态 +func (d *MonitorModulesDao) CheckModuleStatus(moduleName string) int { + db := d.db + status := 0 + sql := "SELECT moduleStatus FROM goku_monitor_module WHERE moduleName = ?" + err := db.QueryRow(sql, moduleName).Scan(&status) + if err != nil { + return status + } + return status +} diff --git a/server/dao/console-sqlite3/node.go b/server/dao/console-sqlite3/node.go index 11ebf8e6..fa1a3f0f 100644 --- a/server/dao/console-sqlite3/node.go +++ b/server/dao/console-sqlite3/node.go @@ -1,73 +1,91 @@ package console_sqlite3 import ( + SQL "database/sql" "fmt" "strconv" "strings" "time" - "github.com/eolinker/goku-api-gateway/common/database" v "github.com/eolinker/goku-api-gateway/common/version" + "github.com/eolinker/goku-api-gateway/server/dao" entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" ) +//NodeDao NodeDao +type NodeDao struct { + db *SQL.DB +} + +//NewNodeDao new NodeDao +func NewNodeDao() *NodeDao { + return &NodeDao{} +} + +//Create create +func (d *NodeDao) Create(db *SQL.DB) (interface{}, error) { + d.db = db + var i dao.NodeDao = d + return &i, nil +} + //AddNode 新增节点信息 -func AddNode(clusterID int, nodeName, nodeKey, listenAddress, adminAddress, gatewayPath string, groupID int) (bool, map[string]interface{}, error) { - db := database.GetConnection() +func (d *NodeDao) AddNode(clusterID int, nodeName, nodeKey, listenAddress, adminAddress, gatewayPath string, groupID int) (int64, string, string, error) { + db := d.db now := time.Now().Format("2006-01-02 15:04:05") sql := "INSERT INTO goku_node_info (`clusterID`,`nodeName`,`groupID`,`nodeKey`,`listenAddress`,`adminAddress`,`updateTime`,`createTime`,`version`, `gatewayPath`,`nodeStatus`) VALUES (?,?,?,?,?,?,?,?,?,?,0);" stmt, err := db.Prepare(sql) if err != nil { - return false, map[string]interface{}{"error": "[ERROR]Illegal SQL statement!"}, err + return 0, "", "[ERROR]Illegal SQL statement!", err } defer stmt.Close() res, err := stmt.Exec(clusterID, nodeName, groupID, nodeKey, listenAddress, adminAddress, now, now, v.Version, gatewayPath) if err != nil { - return false, map[string]interface{}{"error": "[ERROR]Failed to insert data!"}, err + return 0, "", "[ERROR]Failed to insert data!", err } nodeID, err := res.LastInsertId() if err != nil { - return false, map[string]interface{}{"error": "[ERROR]Failed to insert data!"}, err + return 0, "", "[ERROR]Failed to insert data!", err } - return true, map[string]interface{}{"nodeID": nodeID, "version": v.Version}, nil + return nodeID, v.Version, "", nil } //EditNode 修改节点信息 -func EditNode(nodeName, listenAddress, adminAddress, gatewayPath string, nodeID, groupID int) (bool, string, error) { - db := database.GetConnection() +func (d *NodeDao) EditNode(nodeName, listenAddress, adminAddress, gatewayPath string, nodeID, groupID int) (string, error) { + db := d.db now := time.Now().Format("2006-01-02 15:04:05") sql := "UPDATE goku_node_info SET nodeName = ?,listenAddress = ?,adminAddress = ?,updateTime = ?,groupID = ?,gatewayPath = ? WHERE nodeID = ?;" stmt, err := db.Prepare(sql) if err != nil { - return false, "[ERROR]Illegal SQL statement!", err + return "[ERROR]Illegal SQL statement!", err } defer stmt.Close() _, err = stmt.Exec(nodeName, listenAddress, adminAddress, now, groupID, gatewayPath, nodeID) if err != nil { - return false, "[ERROR]Failed to update data!", err + return "[ERROR]Failed to update data!", err } - return true, "", nil + return "", nil } //DeleteNode 删除节点信息 -func DeleteNode(nodeID int) (bool, string, error) { - db := database.GetConnection() +func (d *NodeDao) DeleteNode(nodeID int) (string, error) { + db := d.db sql := "DELETE FROM goku_node_info WHERE nodeID = ?;" stmt, err := db.Prepare(sql) if err != nil { - return false, "[ERROR]Illegal SQL statement!", err + return "[ERROR]Illegal SQL statement!", err } defer stmt.Close() _, err = stmt.Exec(nodeID) if err != nil { - return false, "[ERROR]Failed to delete data!", err + return "[ERROR]Failed to delete data!", err } - return true, "", nil + return "", nil } // GetNodeList 获取节点列表 -func GetNodeList(clusterID, groupID int, keyword string) (bool, []*entity.Node, error) { - db := database.GetConnection() +func (d *NodeDao) GetNodeList(clusterID, groupID int, keyword string) ([]*entity.Node, error) { + rule := make([]string, 0, 2) rule = append(rule, fmt.Sprintf("A.clusterID = %d", clusterID)) @@ -81,77 +99,113 @@ func GetNodeList(clusterID, groupID int, keyword string) (bool, []*entity.Node, } ruleStr := "" if len(rule) > 0 { - ruleStr += "WHERE " + strings.Join(rule, " AND ") + ruleStr += " WHERE " + strings.Join(rule, " AND ") } - sql := fmt.Sprintf("SELECT A.nodeID,A.nodeName,A.nodeKey,A.listenAddress,A.adminAddress,A.updateTime,A.createTime,A.version,A.gatewayPath,A.groupID,IFNULL(G.groupName,'未分类') FROM goku_node_info A LEFT JOIN goku_node_group G ON A.groupID = G.groupID %s ORDER BY updateTime DESC;", ruleStr) - rows, err := db.Query(sql) - if err != nil { - return false, nil, err + sql := fmt.Sprint(nodeSQLAll, ruleStr, " ORDER BY updateTime DESC;") + + return d.getNodeInfo(sql) + + //rows, err := db.Query(sql) + //if err != nil { + // return nil, err + //} + ////延时关闭Rows + //defer rows.Close() + ////获取记录列 + //nodeList := make([]*entity.Node, 0) + //for rows.Next() { + // node := entity.Node{} + // err = rows.Scan(&node.NodeID, &node.NodeName, &node.NodeKey, &node.ListenAddress, &node.AdminAddress, &node.UpdateTime, &node.CreateTime, &node.Version, &node.GatewayPath, &node.GroupID, &node.GroupName) + // if err != nil { + // return nil, err + // } + // if node.Version == v.Version { + // // 判断节点版本号是否是最新 + // node.IsUpdate = true + // } + // nodeList = append(nodeList, &node) + //} + //return nodeList, nil +} + +const nodeSQLAll = "SELECT A.`nodeID` , A.`nodeName` , A.`listenAddress` , A.`adminAddress` , A.`nodeKey` , A.`updateTime` , A.`createTime` , A.`version` , A.`gatewayPath` , A.`groupID` , IFNULL(G.`groupName` , '未分类') , C.`name`As cluster , C.`title` As cluster_title FROM goku_node_info A LEFT JOIN goku_node_group G ON A.`groupID` = G.`groupID` LEFT JOIN `goku_cluster` C ON A.`clusterID`=C.`id`" +const nodeSQLID = nodeSQLAll + " WHERE A.`nodeID` = ? ;" +const nodeSQLInstance = nodeSQLAll + " WHERE A.`nodeKey` = ? ;" + +func (d *NodeDao) getNodeInfo(sql string, args ...interface{}) ([]*entity.Node, error) { + + db := d.db + + rows, e := db.Query(sql, args...) + if e != nil { + return nil, e } - //延时关闭Rows - defer rows.Close() - //获取记录列 - nodeList := make([]*entity.Node, 0) + nodes := make([]*entity.Node, 0, 10) for rows.Next() { - node := entity.Node{} - err = rows.Scan(&node.NodeID, &node.NodeName, &node.NodeKey, &node.ListenAddress, &node.AdminAddress, &node.UpdateTime, &node.CreateTime, &node.Version, &node.GatewayPath, &node.GroupID, &node.GroupName) + node := &entity.Node{} + err := rows.Scan(&node.NodeID, + &node.NodeName, + &node.ListenAddress, + &node.AdminAddress, + &node.NodeKey, + &node.UpdateTime, + &node.CreateTime, + &node.Version, + &node.GatewayPath, + &node.GroupID, + &node.GroupName, + &node.Cluster, + &node.ClusterTitle) if err != nil { - return false, nil, err - } - if node.Version == v.Version { - // 判断节点版本号是否是最新 - node.IsUpdate = true + return nil, err } - nodeList = append(nodeList, &node) + nodes = append(nodes, node) } - return true, nodeList, nil + return nodes, nil } -const nodeSQLID = "SELECT A.`nodeID`, A.`nodeName`,A.`listenAddress`,A.`adminAddress`, A.`nodeKey`, A.`updateTime`, A.`createTime`, A.`version`, A.`gatewayPath`, A.`groupID`, IFNULL(G.`groupName`,''), C.`name` As cluster, C.`title` As cluster_title FROM goku_node_info A LEFT JOIN goku_node_group G ON A.`groupID` = G.`groupID` LEFT JOIN `goku_cluster` C ON A.`clusterID` = C.`id` WHERE A.`nodeID` = ? ;" -const nodeSQLInstance = "SELECT A.`nodeID`, A.`nodeName`,A.`listenAddress`,A.`adminAddress`, A.`nodeKey`, A.`updateTime`, A.`createTime`, A.`version`, A.`gatewayPath`, A.`groupID`, IFNULL(G.`groupName`,'') , C.`name` As cluster, C.`title` As cluster_title FROM goku_node_info A LEFT JOIN goku_node_group G ON A.`groupID` = G.`groupID` LEFT JOIN `goku_cluster` C ON A.`clusterID` = C.`id` WHERE A.`nodeKey` = ? ;" - -func getNodeInfo(sql string, args ...interface{}) (*entity.Node, error) { +//GetNodeInfoAll get all node +func (d *NodeDao) GetNodeInfoAll() ([]*entity.Node, error) { + nodes, e := d.getNodeInfo(nodeSQLAll) + if e != nil { + return nil, e + } - db := database.GetConnection() + return nodes, nil - node := &entity.Node{} - err := db.QueryRow(sql, args...).Scan(&node.NodeID, - &node.NodeName, - &node.ListenAddress, - &node.AdminAddress, - &node.NodeKey, - &node.UpdateTime, - &node.CreateTime, - &node.Version, - &node.GatewayPath, - &node.GroupID, - &node.GroupName, - &node.Cluster, - &node.ClusterTitle) - if err != nil { - return nil, err - } - return node, err } //GetNodeInfo 获取节点信息 -func GetNodeInfo(nodeID int) (*entity.Node, error) { - - return getNodeInfo(nodeSQLID, nodeID) +func (d *NodeDao) GetNodeInfo(nodeID int) (*entity.Node, error) { + nodes, e := d.getNodeInfo(nodeSQLID, nodeID) + if e != nil { + return nil, e + } + if len(nodes) > 0 { + return nodes[0], nil + } + return nil, fmt.Errorf("not exit node width noddID:%d", nodeID) } //GetNodeByKey 通过Key查询节点信息 -func GetNodeByKey(nodeKey string) (*entity.Node, error) { - return getNodeInfo(nodeSQLInstance, nodeKey) +func (d *NodeDao) GetNodeByKey(nodeKey string) (*entity.Node, error) { + nodes, e := d.getNodeInfo(nodeSQLInstance, nodeKey) + if e != nil { + return nil, e + } + if len(nodes) > 0 { + return nodes[0], nil + } + return nil, fmt.Errorf("not exit node width nodeKey:%s", nodeKey) } //GetAvaliableNodeListFromNodeList 从待操作节点中获取关闭节点列表 -func GetAvaliableNodeListFromNodeList(nodeIDList string, nodeStatus int) (bool, string, error) { - db := database.GetConnection() +func (d *NodeDao) GetAvaliableNodeListFromNodeList(nodeIDList string, nodeStatus int) (string, error) { + db := d.db sql := "SELECT nodeID FROM goku_node_info WHERE nodeID IN (" + nodeIDList + ") AND nodeStatus = ?" rows, err := db.Query(sql, nodeStatus) if err != nil { - return false, "[ERROR]Fail to excute SQL statement!", err + return "[ERROR]Fail to excute SQL statement!", err } defer rows.Close() idList := make([]string, 0) @@ -159,45 +213,45 @@ func GetAvaliableNodeListFromNodeList(nodeIDList string, nodeStatus int) (bool, var nodeID int err = rows.Scan(&nodeID) if err != nil { - return false, err.Error(), err + return err.Error(), err } idList = append(idList, strconv.Itoa(nodeID)) } - return true, strings.Join(idList, ","), nil + return strings.Join(idList, ","), nil } //BatchEditNodeGroup 批量修改节点分组 -func BatchEditNodeGroup(nodeIDList string, groupID int) (bool, string, error) { - db := database.GetConnection() +func (d *NodeDao) BatchEditNodeGroup(nodeIDList string, groupID int) (string, error) { + db := d.db now := time.Now().Format("2006-01-02 15:04:05") Tx, _ := db.Begin() sql := "UPDATE goku_node_info SET groupID = ?,updateTime = ? WHERE nodeID IN (" + nodeIDList + ");" _, err := Tx.Exec(sql, groupID, now) if err != nil { Tx.Rollback() - return false, "[ERROR]Fail to excute SQL statement!", err + return "[ERROR]Fail to excute SQL statement!", err } Tx.Commit() - return true, "", nil + return "", nil } //BatchDeleteNode 批量修改接口分组 -func BatchDeleteNode(nodeIDList string) (bool, string, error) { - db := database.GetConnection() +func (d *NodeDao) BatchDeleteNode(nodeIDList string) (string, error) { + db := d.db Tx, _ := db.Begin() sql := "DELETE FROM goku_node_info WHERE nodeID IN (" + nodeIDList + ");" _, err := Tx.Exec(sql) if err != nil { Tx.Rollback() - return false, "[ERROR]Fail to excute SQL statement!", err + return "[ERROR]Fail to excute SQL statement!", err } Tx.Commit() - return true, "", nil + return "", nil } //UpdateAllNodeClusterID 更新节点集群ID -func UpdateAllNodeClusterID(clusterID int) { - db := database.GetConnection() +func (d *NodeDao) UpdateAllNodeClusterID(clusterID int) { + db := d.db Tx, _ := db.Begin() sql := "UPDATE goku_node_info SET clusterID = ?;" _, err := Tx.Exec(sql, clusterID) @@ -213,3 +267,33 @@ func UpdateAllNodeClusterID(clusterID int) { } Tx.Commit() } + +//GetHeartBeatTime 获取节点心跳时间 +func (d *NodeDao) GetHeartBeatTime(nodeKey string) (time.Time, error) { + db := d.db + heartBeat := "" + + sql := "SELECT heartBeatTime FROM goku_node_info WHERE nodeKey = ?" + err := db.QueryRow(sql, nodeKey).Scan(&heartBeat) + if err != nil { + return time.Time{}, err + } + heartBeatTime, err := time.ParseInLocation("2006-01-02 15:04:05", heartBeat, time.Local) + if err != nil { + return time.Time{}, err + } + return heartBeatTime, nil +} + +//SetHeartBeatTime 设置节点心跳时间 +func (d *NodeDao) SetHeartBeatTime(nodeKey string, heartBeatTime time.Time) error { + db := d.db + heartBeat := heartBeatTime.Format("2006-01-02 15:04:05") + + sql := "UPDATE goku_node_info SET heartBeatTime = ? WHERE nodeKey = ?" + _, err := db.Exec(sql, heartBeat, nodeKey) + if err != nil { + return err + } + return nil +} diff --git a/server/dao/console-sqlite3/nodeGroup.go b/server/dao/console-sqlite3/nodeGroup.go index bb79d220..f2536266 100644 --- a/server/dao/console-sqlite3/nodeGroup.go +++ b/server/dao/console-sqlite3/nodeGroup.go @@ -1,12 +1,31 @@ package console_sqlite3 import ( - database2 "github.com/eolinker/goku-api-gateway/common/database" + SQL "database/sql" + + "github.com/eolinker/goku-api-gateway/server/dao" ) +//NodeGroupDao NodeGroupDao +type NodeGroupDao struct { + db *SQL.DB +} + +//NewNodeGroupDao new NodeGroupDao +func NewNodeGroupDao() *NodeGroupDao { + return &NodeGroupDao{} +} + +//Create create +func (d *NodeGroupDao) Create(db *SQL.DB) (interface{}, error) { + d.db = db + var i dao.NodeGroupDao = d + return &i, nil +} + //AddNodeGroup 新建节点分组 -func AddNodeGroup(groupName string, clusterID int) (bool, interface{}, error) { - db := database2.GetConnection() +func (d *NodeGroupDao) AddNodeGroup(groupName string, clusterID int) (bool, interface{}, error) { + db := d.db sql := "INSERT INTO goku_node_group (`groupName`,`clusterID`) VALUES (?,?);" stmt, err := db.Prepare(sql) if err != nil { @@ -22,8 +41,8 @@ func AddNodeGroup(groupName string, clusterID int) (bool, interface{}, error) { } //EditNodeGroup 修改节点分组信息 -func EditNodeGroup(groupName string, groupID int) (bool, string, error) { - db := database2.GetConnection() +func (d *NodeGroupDao) EditNodeGroup(groupName string, groupID int) (bool, string, error) { + db := d.db sql := "UPDATE goku_node_group SET groupName = ? WHERE groupID = ?;" stmt, err := db.Prepare(sql) if err != nil { @@ -38,8 +57,8 @@ func EditNodeGroup(groupName string, groupID int) (bool, string, error) { } //DeleteNodeGroup 删除节点分组 -func DeleteNodeGroup(groupID int) (bool, string, error) { - db := database2.GetConnection() +func (d *NodeGroupDao) DeleteNodeGroup(groupID int) (bool, string, error) { + db := d.db Tx, _ := db.Begin() sql := "DELETE FROM goku_node_group WHERE groupID = ?;" _, err := Tx.Exec(sql, groupID) @@ -58,8 +77,8 @@ func DeleteNodeGroup(groupID int) (bool, string, error) { } //GetNodeGroupInfo 获取节点分组信息 -func GetNodeGroupInfo(groupID int) (bool, map[string]interface{}, error) { - db := database2.GetConnection() +func (d *NodeGroupDao) GetNodeGroupInfo(groupID int) (bool, map[string]interface{}, error) { + db := d.db sql := "SELECT G.`groupName`,C.`name` FROM goku_node_group G left join `goku_cluster` C ON C.`id` = G.`clusterID` WHERE G.`groupID` = ?;" var groupName string @@ -77,8 +96,8 @@ func GetNodeGroupInfo(groupID int) (bool, map[string]interface{}, error) { } //GetNodeGroupList 获取节点分组列表 -func GetNodeGroupList(clusterID int) (bool, []map[string]interface{}, error) { - db := database2.GetConnection() +func (d *NodeGroupDao) GetNodeGroupList(clusterID int) (bool, []map[string]interface{}, error) { + db := d.db sql := "SELECT G.`groupID`, G.groupName,C.`name` as cluster FROM goku_node_group G left join `goku_cluster` C ON C.`id` = G.`clusterID` where G.`clusterID`=?;" rows, err := db.Query(sql, clusterID) if err != nil { @@ -108,8 +127,8 @@ func GetNodeGroupList(clusterID int) (bool, []map[string]interface{}, error) { } //CheckNodeGroupIsExist 检查节点分组是否存在 -func CheckNodeGroupIsExist(groupID int) (bool, error) { - db := database2.GetConnection() +func (d *NodeGroupDao) CheckNodeGroupIsExist(groupID int) (bool, error) { + db := d.db var id int sql := "SELECT groupID FROM goku_node_group WHERE groupID = ?;" err := db.QueryRow(sql, groupID).Scan(&id) @@ -120,8 +139,8 @@ func CheckNodeGroupIsExist(groupID int) (bool, error) { } //GetRunningNodeCount 获取分组内启动节点数量 -func GetRunningNodeCount(groupID int) (bool, interface{}, error) { - db := database2.GetConnection() +func (d *NodeGroupDao) GetRunningNodeCount(groupID int) (bool, interface{}, error) { + db := d.db var count int sql := "SELECT COUNT(0) FROM goku_node_info WHERE groupID = ? AND nodeStatus = 1" err := db.QueryRow(sql, groupID).Scan(&count) diff --git a/server/dao/console-sqlite3/plugin.go b/server/dao/console-sqlite3/plugin.go index 43df4dc7..f66beac0 100644 --- a/server/dao/console-sqlite3/plugin.go +++ b/server/dao/console-sqlite3/plugin.go @@ -6,15 +6,33 @@ import ( "fmt" "strings" + "github.com/eolinker/goku-api-gateway/server/dao" + log "github.com/eolinker/goku-api-gateway/goku-log" - database2 "github.com/eolinker/goku-api-gateway/common/database" entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" ) +//PluginDao PluginDao +type PluginDao struct { + db *SQL.DB +} + +//NewPluginDao new PluginDao +func NewPluginDao() *PluginDao { + return &PluginDao{} +} + +//Create create +func (d *PluginDao) Create(db *SQL.DB) (interface{}, error) { + d.db = db + var i dao.PluginDao = d + return &i, nil +} + //GetPluginInfo 获取插件配置信息 -func GetPluginInfo(pluginName string) (bool, *entity.Plugin, error) { - db := database2.GetConnection() +func (d *PluginDao) GetPluginInfo(pluginName string) (bool, *entity.Plugin, error) { + db := d.db sql := `SELECT pluginID,pluginName,pluginStatus,IFNULL(pluginConfig,""),pluginPriority,isStop,IFNULL(pluginDesc,""),IFNULL(version,""),pluginType FROM goku_plugin WHERE pluginName = ?;` plugin := &entity.Plugin{} err := db.QueryRow(sql, pluginName).Scan(&plugin.PluginID, &plugin.PluginName, &plugin.PluginStatus, &plugin.PluginConfig, &plugin.PluginIndex, &plugin.IsStop, &plugin.PluginDesc, &plugin.Version, &plugin.PluginType) @@ -25,8 +43,8 @@ func GetPluginInfo(pluginName string) (bool, *entity.Plugin, error) { } // GetPluginList 获取插件列表 -func GetPluginList(keyword string, condition int) (bool, []*entity.Plugin, error) { - db := database2.GetConnection() +func (d *PluginDao) GetPluginList(keyword string, condition int) (bool, []*entity.Plugin, error) { + db := d.db rule := make([]string, 0, 2) if keyword != "" { @@ -64,10 +82,10 @@ func GetPluginList(keyword string, condition int) (bool, []*entity.Plugin, error } // GetPluginCount 获取插件数量 -func GetPluginCount() int { +func (d *PluginDao) GetPluginCount() int { var count int sql := "SELECT COUNT(*) FROM goku_plugin;" - err := database2.GetConnection().QueryRow(sql).Scan(&count) + err := d.db.QueryRow(sql).Scan(&count) if err != nil { return 0 } @@ -75,8 +93,8 @@ func GetPluginCount() int { } // AddPlugin 新增插件信息 -func AddPlugin(pluginName, pluginConfig, pluginDesc, version string, pluginPriority, isStop, pluginType int) (bool, string, error) { - db := database2.GetConnection() +func (d *PluginDao) AddPlugin(pluginName, pluginConfig, pluginDesc, version string, pluginPriority, isStop, pluginType int) (bool, string, error) { + db := d.db stmt, err := db.Prepare(`INSERT INTO goku_plugin (pluginName,pluginConfig,pluginDesc,version,pluginStatus,pluginPriority,isStop,official,pluginType,isCheck) VALUES (?,?,?,?,?,?,?,?,?,0);`) if err != nil { return false, "[ERROR]Illegal SQL statement!", err @@ -90,8 +108,8 @@ func AddPlugin(pluginName, pluginConfig, pluginDesc, version string, pluginPrior } // EditPlugin 修改插件信息 -func EditPlugin(pluginName, pluginConfig, pluginDesc, version string, pluginPriority, isStop, pluginType int) (bool, string, error) { - db := database2.GetConnection() +func (d *PluginDao) EditPlugin(pluginName, pluginConfig, pluginDesc, version string, pluginPriority, isStop, pluginType int) (bool, string, error) { + db := d.db // 查询插件是否是官方插件 var sql string sql = "SELECT pluginType,official FROM goku_plugin WHERE pluginName = ?;" @@ -115,19 +133,14 @@ func EditPlugin(pluginName, pluginConfig, pluginDesc, version string, pluginPrio Tx.Rollback() return false, "[ERROR]Failed to update data!", err } - flag, err := EditPluginCache(pluginName, oldPluginType, pluginType, Tx) - if !flag { - Tx.Rollback() - return false, "[ERROR]Failed to update plugin cache!", err - } Tx.Commit() return true, "", nil } // DeletePlugin 删除插件信息 -func DeletePlugin(pluginName string) (bool, string, error) { - db := database2.GetConnection() +func (d *PluginDao) DeletePlugin(pluginName string) (bool, string, error) { + db := d.db var sql string sql = "SELECT pluginType,official FROM goku_plugin WHERE pluginName = ?;" var official string @@ -145,19 +158,14 @@ func DeletePlugin(pluginName string) (bool, string, error) { Tx.Rollback() return false, "[ERROR]Failed to delete data!", err } - flag, err := EditPluginCache(pluginName, pluginType, 5, Tx) - if !flag { - Tx.Rollback() - return false, "[ERROR]Failed to update plugin cache!", err - } Tx.Commit() return true, "", nil } //CheckIndexIsExist 判断插件ID是否存在 -func CheckIndexIsExist(pluginName string, pluginPriority int) (bool, error) { - db := database2.GetConnection() +func (d *PluginDao) CheckIndexIsExist(pluginName string, pluginPriority int) (bool, error) { + db := d.db sql := "SELECT pluginName FROM goku_plugin WHERE pluginPriority = ?;" var p string err := db.QueryRow(sql, pluginPriority).Scan(&p) @@ -171,8 +179,8 @@ func CheckIndexIsExist(pluginName string, pluginPriority int) (bool, error) { } //GetPluginConfig 获取插件配置及插件信息 -func GetPluginConfig(pluginName string) (bool, string, error) { - db := database2.GetConnection() +func (d *PluginDao) GetPluginConfig(pluginName string) (bool, string, error) { + db := d.db sql := `SELECT IFNULL(pluginConfig,"") FROM goku_plugin WHERE pluginName = ?` var pluginConfig string err := db.QueryRow(sql, pluginName).Scan(&pluginConfig) @@ -183,8 +191,8 @@ func GetPluginConfig(pluginName string) (bool, string, error) { } //CheckNameIsExist 检查插件名称是否存在 -func CheckNameIsExist(pluginName string) (bool, error) { - db := database2.GetConnection() +func (d *PluginDao) CheckNameIsExist(pluginName string) (bool, error) { + db := d.db sql := "SELECT pluginName FROM goku_plugin WHERE pluginName = ?;" var p string err := db.QueryRow(sql, pluginName).Scan(&p) @@ -195,8 +203,8 @@ func CheckNameIsExist(pluginName string) (bool, error) { } //EditPluginStatus 修改插件开启状态 -func EditPluginStatus(pluginName string, pluginStatus int) (bool, error) { - db := database2.GetConnection() +func (d *PluginDao) EditPluginStatus(pluginName string, pluginStatus int) (bool, error) { + db := d.db Tx, _ := db.Begin() isCheck := 1 @@ -218,8 +226,8 @@ func EditPluginStatus(pluginName string, pluginStatus int) (bool, error) { } //GetPluginListByPluginType 获取不同类型的插件列表 -func GetPluginListByPluginType(pluginType int) (bool, []map[string]interface{}, error) { - db := database2.GetConnection() +func (d *PluginDao) GetPluginListByPluginType(pluginType int) (bool, []map[string]interface{}, error) { + db := d.db sql := `SELECT pluginID,pluginName,pluginDesc FROM goku_plugin WHERE pluginType = ? AND pluginStatus = 1;` rows, err := db.Query(sql, pluginType) if err != nil { @@ -250,8 +258,8 @@ func GetPluginListByPluginType(pluginType int) (bool, []map[string]interface{}, } //BatchStopPlugin 批量关闭插件 -func BatchStopPlugin(pluginNameList string) (bool, string, error) { - db := database2.GetConnection() +func (d *PluginDao) BatchStopPlugin(pluginNameList string) (bool, string, error) { + db := d.db Tx, _ := db.Begin() plugin := strings.Split(pluginNameList, ",") code := "" @@ -274,8 +282,8 @@ func BatchStopPlugin(pluginNameList string) (bool, string, error) { } //BatchStartPlugin 批量关闭插件 -func BatchStartPlugin(pluginNameList string) (bool, string, error) { - db := database2.GetConnection() +func (d *PluginDao) BatchStartPlugin(pluginNameList string) (bool, string, error) { + db := d.db Tx, _ := db.Begin() plugin := strings.Split(pluginNameList, ",") code := "" @@ -297,79 +305,9 @@ func BatchStartPlugin(pluginNameList string) (bool, string, error) { return true, "", nil } -//EditPluginCache 将插件配置写进缓存表中 -func EditPluginCache(pluginName string, oldPluginType, pluginType int, Tx *SQL.Tx) (bool, error) { - if oldPluginType == 1 { - // 获取策略ID列表 - sql := "SELECT strategyID FROM goku_conn_plugin_strategy WHERE pluginName = ?;" - strategyIDList := make([]string, 0) - rows, err := Tx.Query(sql, pluginName) - if err != nil { - return false, err - } - //延时关闭Rows - defer rows.Close() - //获取记录列 - - for rows.Next() { - var strategyID string - err = rows.Scan(&strategyID) - if err != nil { - return false, err - } - strategyIDList = append(strategyIDList, strategyID) - } - if len(strategyIDList) > 0 { - if oldPluginType != pluginType { - // 删除策略组插件 - _, err = Tx.Exec("DELETE FROM goku_conn_plugin_strategy WHERE strategyID AND pluginName = ?;", pluginName) - if err != nil { - return false, err - } - } - } - return true, nil - } else if oldPluginType == 2 { - // 获取策略ID列表 - sql := "SELECT strategyID,apiID FROM goku_conn_plugin_api WHERE pluginName = ?;" - connList := make([]map[string]interface{}, 0) - rows, err := Tx.Query(sql, pluginName) - if err != nil { - return false, err - } - //延时关闭Rows - defer rows.Close() - //获取记录列 - - for rows.Next() { - var strategyID string - var apiID int - err = rows.Scan(&strategyID, &apiID) - if err != nil { - return false, err - } - connList = append(connList, map[string]interface{}{ - "strategyID": strategyID, - "apiID": apiID, - }) - } - if len(connList) > 0 { - if oldPluginType != pluginType { - // 删除接口插件 - _, err = Tx.Exec("DELETE FROM goku_conn_plugin_api WHERE pluginName = ?;", pluginName) - if err != nil { - return false, err - } - } - } - return true, nil - } - return true, nil -} - //EditPluginCheckStatus 更新插件检测状态 -func EditPluginCheckStatus(pluginName string, isCheck int) (bool, string, error) { - db := database2.GetConnection() +func (d *PluginDao) EditPluginCheckStatus(pluginName string, isCheck int) (bool, string, error) { + db := d.db sql := "UPDATE goku_plugin SET isCheck = ? WHERE pluginName = ?;" _, err := db.Exec(sql, isCheck, pluginName) if err != nil { diff --git a/server/dao/console-sqlite3/project.go b/server/dao/console-sqlite3/project.go index 622e3822..aee9551a 100644 --- a/server/dao/console-sqlite3/project.go +++ b/server/dao/console-sqlite3/project.go @@ -1,20 +1,39 @@ package console_sqlite3 import ( + SQL "database/sql" "fmt" + "strconv" "strings" "time" - database2 "github.com/eolinker/goku-api-gateway/common/database" log "github.com/eolinker/goku-api-gateway/goku-log" + "github.com/eolinker/goku-api-gateway/server/dao" entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" ) +//ProjectDao ProjectDao +type ProjectDao struct { + db *SQL.DB +} + +//NewProjectDao new ProjectDao +func NewProjectDao() *ProjectDao { + return &ProjectDao{} +} + +//Create create +func (d *ProjectDao) Create(db *SQL.DB) (interface{}, error) { + d.db = db + var i dao.ProjectDao = d + return &i, nil +} + //AddProject 新建项目 -func AddProject(projectName string) (bool, interface{}, error) { +func (d *ProjectDao) AddProject(projectName string) (bool, interface{}, error) { now := time.Now().Format("2006-01-02 15:04:05") - db := database2.GetConnection() + db := d.db sql := "INSERT INTO goku_gateway_project (projectName,createTime,updateTime) VALUES (?,?,?);" stmt, err := db.Prepare(sql) if err != nil { @@ -30,9 +49,9 @@ func AddProject(projectName string) (bool, interface{}, error) { } //EditProject 修改项目信息 -func EditProject(projectName string, projectID int) (bool, string, error) { +func (d *ProjectDao) EditProject(projectName string, projectID int) (bool, string, error) { now := time.Now().Format("2006-01-02 15:04:05") - db := database2.GetConnection() + db := d.db sql := "UPDATE goku_gateway_project SET projectName = ?,updateTime = ? WHERE projectID = ?;" stmt, err := db.Prepare(sql) if err != nil { @@ -47,8 +66,8 @@ func EditProject(projectName string, projectID int) (bool, string, error) { } //DeleteProject 修改项目信息 -func DeleteProject(projectID int) (bool, string, error) { - db := database2.GetConnection() +func (d *ProjectDao) DeleteProject(projectID int) (bool, string, error) { + db := d.db Tx, _ := db.Begin() // 获取项目分组列表 sql := "SELECT groupID FROM goku_gateway_api_group WHERE projectID = ?;" @@ -68,6 +87,7 @@ func DeleteProject(projectID int) (bool, string, error) { if err != nil { Tx.Rollback() log.Info(err.Error()) + return false, "", err } groupIDList += strconv.Itoa(groupID) + "," } @@ -144,8 +164,8 @@ func DeleteProject(projectID int) (bool, string, error) { } //BatchDeleteProject 批量删除项目 -func BatchDeleteProject(projectIDList string) (bool, string, error) { - db := database2.GetConnection() +func (d *ProjectDao) BatchDeleteProject(projectIDList string) (bool, string, error) { + db := d.db Tx, _ := db.Begin() // 获取项目分组列表 sql := "SELECT groupID FROM goku_gateway_api_group WHERE projectID IN (" + projectIDList + ");" @@ -167,6 +187,7 @@ func BatchDeleteProject(projectIDList string) (bool, string, error) { err = rows.Scan(&groupID) if err != nil { Tx.Rollback() + return false, "", err } groupIDList += strconv.Itoa(groupID) + "," } @@ -237,8 +258,8 @@ func BatchDeleteProject(projectIDList string) (bool, string, error) { } //GetProjectInfo 获取项目信息 -func GetProjectInfo(projectID int) (bool, entity.Project, error) { - db := database2.GetConnection() +func (d *ProjectDao) GetProjectInfo(projectID int) (bool, entity.Project, error) { + db := d.db var project entity.Project sql := "SELECT projectID,projectName,createTime,updateTime FROM goku_gateway_project WHERE projectID = ?;" err := db.QueryRow(sql, projectID).Scan(&project.ProjectID, &project.ProjectName, &project.CreateTime, &project.UpdateTime) @@ -249,7 +270,7 @@ func GetProjectInfo(projectID int) (bool, entity.Project, error) { } //GetProjectList 获取项目列表 -func GetProjectList(keyword string) (bool, []*entity.Project, error) { +func (d *ProjectDao) GetProjectList(keyword string) (bool, []*entity.Project, error) { sql := "SELECT `projectID`,`projectName`,`updateTime` FROM `goku_gateway_project` %s ORDER BY `updateTime` DESC;" keywordValue := strings.Trim(keyword, "%") @@ -264,7 +285,7 @@ func GetProjectList(keyword string) (bool, []*entity.Project, error) { } } sql = fmt.Sprintf(sql, where) - db := database2.GetConnection() + db := d.db rows, err := db.Query(sql, arg...) if err != nil { return false, nil, err @@ -286,8 +307,8 @@ func GetProjectList(keyword string) (bool, []*entity.Project, error) { } //CheckProjectIsExist 检查项目是否存在 -func CheckProjectIsExist(projectID int) (bool, error) { - db := database2.GetConnection() +func (d *ProjectDao) CheckProjectIsExist(projectID int) (bool, error) { + db := d.db sql := "SELECT projectID FROM goku_gateway_project WHERE projectID = ?;" var id int err := db.QueryRow(sql, projectID).Scan(&id) @@ -298,8 +319,8 @@ func CheckProjectIsExist(projectID int) (bool, error) { } //GetAPIListFromProjectNotInStrategy 获取项目列表中没有被策略组绑定的接口 -func GetAPIListFromProjectNotInStrategy() (bool, []map[string]interface{}, error) { - db := database2.GetConnection() +func (d *ProjectDao) GetAPIListFromProjectNotInStrategy() (bool, []map[string]interface{}, error) { + db := d.db sql := "SELECT projectID,projectName FROM goku_gateway_project;" projectRows, err := db.Query(sql) if err != nil { diff --git a/server/dao/console-sqlite3/register.go b/server/dao/console-sqlite3/register.go new file mode 100644 index 00000000..21ee9451 --- /dev/null +++ b/server/dao/console-sqlite3/register.go @@ -0,0 +1,77 @@ +package console_sqlite3 + +import ( + "database/sql" + "io/ioutil" + "log" + "strings" + + "github.com/eolinker/goku-api-gateway/common/pdao" + config_log "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3/config-log" + dao_balance "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3/dao-balance" + dao_balance_update "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3/dao-balance-update" + dao_service "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3/dao-service" + dao_version_config "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3/dao-version-config" + "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3/internal/goku311" + "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3/updater" +) + +//DBDriver db驱动类型 +const DBDriver = "sqlite3" + +//DoRegister 注册数据库 +func DoRegister() { + + pdao.RegisterDBBuilder(DBDriver, new(TableBuilder)) + goku311.RegisterUpdate() + + pdao.RegisterDao(DBDriver, NewAPIDao(), NewAPIGroupDao(), NewAPIPluginDao(), NewAPIStrategyDao()) + pdao.RegisterDao(DBDriver, NewAuthDao()) + pdao.RegisterDao(DBDriver, NewClusterDao()) + pdao.RegisterDao(DBDriver, NewGatewayDao()) + pdao.RegisterDao(DBDriver, NewGuestDao()) + pdao.RegisterDao(DBDriver, NewImportDao()) + pdao.RegisterDao(DBDriver, NewMonitorModulesDao()) + pdao.RegisterDao(DBDriver, NewNodeDao(), NewNodeGroupDao()) + pdao.RegisterDao(DBDriver, NewPluginDao()) + pdao.RegisterDao(DBDriver, NewProjectDao()) + pdao.RegisterDao(DBDriver, NewStrategyDao(), NewStrategyGroupDao(), NewStrategyPluginDao()) + pdao.RegisterDao(DBDriver, NewUserDao()) + pdao.RegisterDao(DBDriver, NewVersionDao()) + + pdao.RegisterDao(DBDriver, config_log.NewConfigLogDao()) + pdao.RegisterDao(DBDriver, dao_balance.NewBalanceDao()) + pdao.RegisterDao(DBDriver, dao_balance_update.NewBalanceUpdateDao()) + pdao.RegisterDao(DBDriver, dao_service.NewServiceDao()) + pdao.RegisterDao(DBDriver, dao_version_config.NewVersionConfigDao()) + pdao.RegisterDao(DBDriver, updater.NewUpdaterDao()) +} + +//TableBuilder tableBuilder +type TableBuilder struct { +} + +//Build build +func (t *TableBuilder) Build(db *sql.DB) error { + + userDao := NewUserDao() + userDao.db = db + + _, err := userDao.CheckSuperAdminCount() + if err != nil { + content, err := ioutil.ReadFile("sql/goku_ce.sql") + sqls := strings.Split(string(content), ";") + Tx, _ := db.Begin() + for _, sql := range sqls { + _, err = Tx.Exec(sql) + if err != nil { + Tx.Rollback() + log.Panic("InitTable error:", err, "\t sql:", sql) + return err + } + } + Tx.Commit() + } + + return nil +} diff --git a/server/dao/console-sqlite3/strategy.go b/server/dao/console-sqlite3/strategy.go index e16b0fff..8855cb0b 100644 --- a/server/dao/console-sqlite3/strategy.go +++ b/server/dao/console-sqlite3/strategy.go @@ -1,18 +1,38 @@ package console_sqlite3 import ( + "database/sql" "fmt" "strings" "time" - database2 "github.com/eolinker/goku-api-gateway/common/database" + "github.com/eolinker/goku-api-gateway/server/dao" + entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" "github.com/eolinker/goku-api-gateway/utils" ) -//AddStrategy 新增策略组 -func AddStrategy(strategyName string, groupID int) (bool, string, error) { - db := database2.GetConnection() +//StrategyDao StrategyDao +type StrategyDao struct { + db *sql.DB +} + +//NewStrategyDao new StrategyDao +func NewStrategyDao() *StrategyDao { + return &StrategyDao{} +} + +//Create create +func (d *StrategyDao) Create(db *sql.DB) (interface{}, error) { + d.db = db + var i dao.StrategyDao = d + + return &i, nil +} + +//AddStrategy 新增策略组 +func (d *StrategyDao) AddStrategy(strategyName string, groupID, userID int) (bool, string, error) { + db := d.db now := time.Now().Format("2006-01-02 15:04:05") // 随机生成字符串 sqlCode := "SELECT strategyID FROM goku_gateway_strategy WHERE strategyID = ?" @@ -29,8 +49,8 @@ func AddStrategy(strategyName string, groupID int) (bool, string, error) { if strategyID == "" { return false, "[ERROR]Empty strategy id !", nil } - stmt, err := db.Prepare(`INSERT INTO goku_gateway_strategy (strategyID,strategyName,updateTime,createTime,groupID) VALUES (?,?,?,?,?);`) - defer stmt.Close() + stmt, err := db.Prepare(`INSERT INTO goku_gateway_strategy (strategyID,strategyName,updateTime,createTime,groupID) VALUES (?,?,?,?,?)`) + if err != nil { return false, "[ERROR]Illegal SQL statement!", err } @@ -43,10 +63,10 @@ func AddStrategy(strategyName string, groupID int) (bool, string, error) { } //EditStrategy 修改策略组信息 -func EditStrategy(strategyID, strategyName string, groupID int) (bool, string, error) { - db := database2.GetConnection() +func (d *StrategyDao) EditStrategy(strategyID, strategyName string, groupID, userID int) (bool, string, error) { + db := d.db now := time.Now().Format("2006-01-02 15:04:05") - stmt, err := db.Prepare(`UPDATE goku_gateway_strategy SET strategyName = ?,groupID = ?,updateTime = ? WHERE strategyID = ?;`) + stmt, err := db.Prepare(`UPDATE goku_gateway_strategy SET strategyName = ?,groupID = ?,updateTime = ? WHERE strategyID = ?`) if err != nil { return false, "[ERROR]Illegal SQL statement!", err } @@ -59,8 +79,8 @@ func EditStrategy(strategyID, strategyName string, groupID int) (bool, string, e } //DeleteStrategy 删除策略组 -func DeleteStrategy(strategyID string) (bool, string, error) { - db := database2.GetConnection() +func (d *StrategyDao) DeleteStrategy(strategyID string) (bool, string, error) { + db := d.db Tx, _ := db.Begin() _, err := Tx.Exec(`DELETE FROM goku_gateway_strategy WHERE strategyID = ?;`, strategyID) if err != nil { @@ -96,9 +116,7 @@ func DeleteStrategy(strategyID string) (bool, string, error) { } // GetStrategyList 获取策略组列表 -func GetStrategyList(groupID int, keyword string, condition int) (bool, []*entity.Strategy, error) { - db := database2.GetConnection() - +func (d *StrategyDao) GetStrategyList(groupID int, keyword string, condition, page, pageSize int) (bool, []*entity.Strategy, int, error) { rule := make([]string, 0, 2) rule = append(rule, "A.strategyType != 1") @@ -118,10 +136,11 @@ func GetStrategyList(groupID int, keyword string, condition int) (bool, []*entit if len(rule) > 0 { ruleStr += "WHERE " + strings.Join(rule, " AND ") } - sql := fmt.Sprintf("SELECT A.strategyID,A.strategyName,IFNULL(A.updateTime,''),IFNULL(A.createTime,''),A.enableStatus,A.groupID,IFNULL(B.groupName,'未分组') FROM goku_gateway_strategy A LEFT JOIN goku_gateway_strategy_group B ON A.groupID = B.groupID %s ORDER BY A.updateTime DESC;", ruleStr) - rows, err := db.Query(sql) + sql := fmt.Sprintf("SELECT A.strategyID,A.strategyName,IFNULL(A.updateTime,''),IFNULL(A.createTime,''),A.enableStatus,A.groupID,IFNULL(B.groupName,'未分组') FROM goku_gateway_strategy A LEFT JOIN goku_gateway_strategy_group B ON A.groupID = B.groupID %s", ruleStr) + count := getCountSQL(d.db, sql) + rows, err := getPageSQL(d.db, sql, "A.updateTime", "DESC", page, pageSize) if err != nil { - return false, nil, err + return false, make([]*entity.Strategy, 0), 0, err } //延时关闭Rows defer rows.Close() @@ -131,17 +150,17 @@ func GetStrategyList(groupID int, keyword string, condition int) (bool, []*entit var strategy entity.Strategy err = rows.Scan(&strategy.StrategyID, &strategy.StrategyName, &strategy.UpdateTime, &strategy.CreateTime, &strategy.EnableStatus, &strategy.GroupID, &strategy.GroupName) if err != nil { - return false, nil, err + return false, make([]*entity.Strategy, 0), 0, err } strategyList = append(strategyList, &strategy) } - return true, strategyList, nil + return true, strategyList, count, nil } // GetOpenStrategy 获取策略组列表 -func GetOpenStrategy() (bool, *entity.Strategy, error) { +func (d *StrategyDao) GetOpenStrategy() (bool, *entity.Strategy, error) { var openStrategy entity.Strategy - db := database2.GetConnection() + db := d.db sql := `SELECT strategyID,strategyName,IFNULL(updateTime,""),IFNULL(createTime,""),enableStatus,strategyType FROM goku_gateway_strategy WHERE strategyType = 1 ORDER BY updateTime DESC;` err := db.QueryRow(sql).Scan(&openStrategy.StrategyID, &openStrategy.StrategyName, &openStrategy.UpdateTime, &openStrategy.CreateTime, &openStrategy.EnableStatus, &openStrategy.StrategyType) if err != nil { @@ -152,8 +171,8 @@ func GetOpenStrategy() (bool, *entity.Strategy, error) { } //GetStrategyInfo 获取策略组信息 -func GetStrategyInfo(strategyID string) (bool, *entity.Strategy, error) { - db := database2.GetConnection() +func (d *StrategyDao) GetStrategyInfo(strategyID string) (bool, *entity.Strategy, error) { + db := d.db sql := `SELECT strategyID,strategyName,IFNULL(updateTime,''),strategyType,enableStatus FROM goku_gateway_strategy WHERE strategyID = ?;` strategy := new(entity.Strategy) err := db.QueryRow(sql, strategyID).Scan(&strategy.StrategyID, &strategy.StrategyName, &strategy.UpdateTime, &strategy.StrategyType, &strategy.EnableStatus) @@ -164,8 +183,8 @@ func GetStrategyInfo(strategyID string) (bool, *entity.Strategy, error) { } //CheckStrategyIsExist 检查策略组ID是否存在 -func CheckStrategyIsExist(strategyID string) (bool, error) { - db := database2.GetConnection() +func (d *StrategyDao) CheckStrategyIsExist(strategyID string) (bool, error) { + db := d.db sql := "SELECT strategyID FROM goku_gateway_strategy WHERE strategyID = ?;" var id string err := db.QueryRow(sql, strategyID).Scan(&id) @@ -176,8 +195,8 @@ func CheckStrategyIsExist(strategyID string) (bool, error) { } //BatchEditStrategyGroup 批量修改策略组分组 -func BatchEditStrategyGroup(strategyIDList string, groupID int) (bool, string, error) { - db := database2.GetConnection() +func (d *StrategyDao) BatchEditStrategyGroup(strategyIDList string, groupID int) (bool, string, error) { + db := d.db now := time.Now().Format("2006-01-02 15:04:05") Tx, _ := db.Begin() strategy := strings.Split(strategyIDList, ",") @@ -199,8 +218,8 @@ func BatchEditStrategyGroup(strategyIDList string, groupID int) (bool, string, e } //BatchDeleteStrategy 批量修改策略组 -func BatchDeleteStrategy(strategyIDList string) (bool, string, error) { - db := database2.GetConnection() +func (d *StrategyDao) BatchDeleteStrategy(strategyIDList string) (bool, string, error) { + db := d.db Tx, _ := db.Begin() strategy := strings.Split(strategyIDList, ",") code := "" @@ -247,8 +266,8 @@ func BatchDeleteStrategy(strategyIDList string) (bool, string, error) { } //CheckIsOpenStrategy 判断是否是开放策略 -func CheckIsOpenStrategy(strategyID string) bool { - db := database2.GetConnection() +func (d *StrategyDao) CheckIsOpenStrategy(strategyID string) bool { + db := d.db var strategyType int sql := "SELECT strategyType FROM goku_gateway_strategy WHERE strategyID = ?;" err := db.QueryRow(sql, strategyID).Scan(&strategyType) @@ -262,8 +281,8 @@ func CheckIsOpenStrategy(strategyID string) bool { } //BatchUpdateStrategyEnableStatus 更新策略启动状态 -func BatchUpdateStrategyEnableStatus(strategyIDList string, enableStatus int) (bool, string, error) { - db := database2.GetConnection() +func (d *StrategyDao) BatchUpdateStrategyEnableStatus(strategyIDList string, enableStatus int) (bool, string, error) { + db := d.db now := time.Now().Format("2006-01-02 15:04:05") strategy := strings.Split(strategyIDList, ",") code := "" @@ -290,8 +309,8 @@ func BatchUpdateStrategyEnableStatus(strategyIDList string, enableStatus int) (b } // GetBalanceListInStrategy 获取在策略中的负载列表 -func GetBalanceListInStrategy(strategyID string, balanceType int) (bool, []string, error) { - db := database2.GetConnection() +func (d *StrategyDao) GetBalanceListInStrategy(strategyID string, balanceType int) (bool, []string, error) { + db := d.db sql := "SELECT DISTINCT(IFNULL(A.balanceName,'')) FROM goku_gateway_api A INNER JOIN goku_conn_strategy_api B ON A.apiID = B.apiID WHERE B.strategyID = ?;" if balanceType == 1 { @@ -320,8 +339,8 @@ func GetBalanceListInStrategy(strategyID string, balanceType int) (bool, []strin } // CopyStrategy 复制策略 -func CopyStrategy(strategyID string, newStrategyID string, userID int) (string, error) { - db := database2.GetConnection() +func (d *StrategyDao) CopyStrategy(strategyID string, newStrategyID string, userID int) (string, error) { + db := d.db now := time.Now().Format("2006-01-02 15:04:05") sql := "INSERT INTO goku_conn_strategy_api (strategyID,apiID,apiMonitorStatus,strategyMonitorStatus,target,updateTime) SELECT ?,apiID,apiMonitorStatus,strategyMonitorStatus,target,? FROM goku_conn_strategy_api WHERE strategyID = ?" _, err := db.Exec(sql, newStrategyID, now, strategyID) @@ -342,21 +361,9 @@ func CopyStrategy(strategyID string, newStrategyID string, userID int) (string, return newStrategyID, nil } -//GetOpenStrategyCount 获取开放策略数量 -func GetOpenStrategyCount() int { - db := database2.GetConnection() - var count int - sql := "SELECT COUNT(*) FROM goku_gateway_strategy WHERE strategyType = 1" - err := db.QueryRow(sql).Scan(&count) - if err != nil { - return 0 - } - return count -} - //GetStrategyIDList 获取策略ID列表 -func GetStrategyIDList(groupID int, keyword string, condition int) (bool, []string, error) { - db := database2.GetConnection() +func (d *StrategyDao) GetStrategyIDList(groupID int, keyword string, condition int) (bool, []string, error) { + db := d.db rule := make([]string, 0, 2) rule = append(rule, fmt.Sprintf("A.strategyType != 1")) diff --git a/server/dao/console-sqlite3/strategyGroup.go b/server/dao/console-sqlite3/strategyGroup.go index 3964b49e..d693bfdf 100644 --- a/server/dao/console-sqlite3/strategyGroup.go +++ b/server/dao/console-sqlite3/strategyGroup.go @@ -1,12 +1,32 @@ package console_sqlite3 import ( - database2 "github.com/eolinker/goku-api-gateway/common/database" + "database/sql" + + "github.com/eolinker/goku-api-gateway/server/dao" ) +//StrategyGroupDao StrategyGroupDao +type StrategyGroupDao struct { + db *sql.DB +} + +//NewStrategyGroupDao new StrategyGroupDao +func NewStrategyGroupDao() *StrategyGroupDao { + return &StrategyGroupDao{} +} + +//Create create +func (d *StrategyGroupDao) Create(db *sql.DB) (interface{}, error) { + d.db = db + var i dao.StrategyGroupDao = d + + return &i, nil +} + //AddStrategyGroup 新建策略组分组 -func AddStrategyGroup(groupName string) (bool, interface{}, error) { - db := database2.GetConnection() +func (d *StrategyGroupDao) AddStrategyGroup(groupName string) (bool, interface{}, error) { + db := d.db sql := "INSERT INTO goku_gateway_strategy_group (groupName) VALUES (?);" stmt, err := db.Prepare(sql) if err != nil { @@ -25,8 +45,8 @@ func AddStrategyGroup(groupName string) (bool, interface{}, error) { } //EditStrategyGroup 修改策略组分组 -func EditStrategyGroup(groupName string, groupID int) (bool, string, error) { - db := database2.GetConnection() +func (d *StrategyGroupDao) EditStrategyGroup(groupName string, groupID int) (bool, string, error) { + db := d.db sql := "UPDATE goku_gateway_strategy_group SET groupName = ? WHERE groupID = ?;" stmt, err := db.Prepare(sql) if err != nil { @@ -41,8 +61,8 @@ func EditStrategyGroup(groupName string, groupID int) (bool, string, error) { } //DeleteStrategyGroup 删除策略组分组 -func DeleteStrategyGroup(groupID int) (bool, string, error) { - db := database2.GetConnection() +func (d *StrategyGroupDao) DeleteStrategyGroup(groupID int) (bool, string, error) { + db := d.db // 查询该分组下所有策略组ID sql := "SELECT strategyID FROM goku_gateway_strategy WHERE groupID = ?;" rows, err := db.Query(sql, groupID) @@ -108,8 +128,8 @@ func DeleteStrategyGroup(groupID int) (bool, string, error) { } //GetStrategyGroupList 获取策略组分组列表 -func GetStrategyGroupList() (bool, []map[string]interface{}, error) { - db := database2.GetConnection() +func (d *StrategyGroupDao) GetStrategyGroupList() (bool, []map[string]interface{}, error) { + db := d.db sql := "SELECT groupID,groupName,groupType FROM goku_gateway_strategy_group WHERE groupType = 0;" rows, err := db.Query(sql) if err != nil { @@ -137,8 +157,8 @@ func GetStrategyGroupList() (bool, []map[string]interface{}, error) { } //CheckIsOpenGroup 判断是否是开放分组 -func CheckIsOpenGroup(groupID int) bool { - db := database2.GetConnection() +func (d *StrategyGroupDao) CheckIsOpenGroup(groupID int) bool { + db := d.db var groupType int sql := "SELECT groupType FROM goku_gateway_strategy_group WHERE groupID = ?;" err := db.QueryRow(sql, groupID).Scan(&groupType) diff --git a/server/dao/console-sqlite3/strategyPlugin.go b/server/dao/console-sqlite3/strategyPlugin.go index 1cae721a..6605d221 100644 --- a/server/dao/console-sqlite3/strategyPlugin.go +++ b/server/dao/console-sqlite3/strategyPlugin.go @@ -7,14 +7,30 @@ import ( "strings" "time" - database2 "github.com/eolinker/goku-api-gateway/common/database" + "github.com/eolinker/goku-api-gateway/server/dao" ) -var strategyPlugins = []string{"goku-oauth2_auth", "goku-rate_limiting", "goku-replay_attack_defender"} +//StrategyPluginDao StrategyPluginDao +type StrategyPluginDao struct { + db *SQL.DB +} + +//NewStrategyPluginDao new StrategyPluginDao +func NewStrategyPluginDao() *StrategyPluginDao { + return &StrategyPluginDao{} +} + +//Create create +func (d *StrategyPluginDao) Create(db *SQL.DB) (interface{}, error) { + d.db = db + var i dao.StrategyPluginDao = d + + return &i, nil +} //AddPluginToStrategy 新增策略组插件 -func AddPluginToStrategy(pluginName, config, strategyID string) (bool, interface{}, error) { - db := database2.GetConnection() +func (d *StrategyPluginDao) AddPluginToStrategy(pluginName, config, strategyID string) (bool, interface{}, error) { + db := d.db // 查询接口是否添加该插件 sql := "SELECT strategyID FROM goku_conn_plugin_strategy WHERE strategyID = ? AND pluginName = ?;" var id string @@ -47,8 +63,8 @@ func AddPluginToStrategy(pluginName, config, strategyID string) (bool, interface } //EditStrategyPluginConfig 新增策略组插件配置 -func EditStrategyPluginConfig(pluginName, config, strategyID string) (bool, string, error) { - db := database2.GetConnection() +func (d *StrategyPluginDao) EditStrategyPluginConfig(pluginName, config, strategyID string) (bool, string, error) { + db := d.db // 查询策略组是否添加该插件 t := time.Now() now := t.Format("2006-01-02 15:04:05") @@ -77,8 +93,8 @@ func EditStrategyPluginConfig(pluginName, config, strategyID string) (bool, stri } // GetStrategyPluginList 获取策略插件列表 -func GetStrategyPluginList(strategyID, keyword string, condition int) (bool, []map[string]interface{}, error) { - db := database2.GetConnection() +func (d *StrategyPluginDao) GetStrategyPluginList(strategyID, keyword string, condition int) (bool, []map[string]interface{}, error) { + db := d.db rule := make([]string, 0, 3) @@ -125,8 +141,8 @@ func GetStrategyPluginList(strategyID, keyword string, condition int) (bool, []m } //GetStrategyPluginConfig 通过策略组ID获取配置信息 -func GetStrategyPluginConfig(strategyID, pluginName string) (bool, string, error) { - db := database2.GetConnection() +func (d *StrategyPluginDao) GetStrategyPluginConfig(strategyID, pluginName string) (bool, string, error) { + db := d.db sql := "SELECT pluginConfig FROM goku_conn_plugin_strategy WHERE strategyID = ? AND pluginName = ?;" var p string err := db.QueryRow(sql, strategyID, pluginName).Scan(&p) @@ -141,8 +157,8 @@ func GetStrategyPluginConfig(strategyID, pluginName string) (bool, string, error } //CheckPluginIsExistInStrategy 检查策略组是否绑定插件 -func CheckPluginIsExistInStrategy(strategyID, pluginName string) (bool, error) { - db := database2.GetConnection() +func (d *StrategyPluginDao) CheckPluginIsExistInStrategy(strategyID, pluginName string) (bool, error) { + db := d.db sql := "SELECT strategyID FROM goku_conn_plugin_strategy WHERE strategyID = ? AND pluginName = ?;" var id string err := db.QueryRow(sql, strategyID, pluginName).Scan(&id) @@ -153,8 +169,8 @@ func CheckPluginIsExistInStrategy(strategyID, pluginName string) (bool, error) { } //GetStrategyPluginStatus 检查策略组插件是否开启 -func GetStrategyPluginStatus(strategyID, pluginName string) (bool, error) { - db := database2.GetConnection() +func (d *StrategyPluginDao) GetStrategyPluginStatus(strategyID, pluginName string) (bool, error) { + db := d.db sql := "SELECT pluginStatus FROM goku_conn_plugin_strategy WHERE strategyID = ? AND pluginName = ?;" var pluginStatus int err := db.QueryRow(sql, strategyID, pluginName).Scan(&pluginStatus) @@ -168,8 +184,8 @@ func GetStrategyPluginStatus(strategyID, pluginName string) (bool, error) { } //GetConnIDFromStrategyPlugin 获取Connid -func GetConnIDFromStrategyPlugin(pluginName, strategyID string) (bool, int, error) { - db := database2.GetConnection() +func (d *StrategyPluginDao) GetConnIDFromStrategyPlugin(pluginName, strategyID string) (bool, int, error) { + db := d.db sql := "SELECT connID FROM goku_conn_plugin_strategy WHERE strategyID = ? AND pluginName = ?;" var connID int err := db.QueryRow(sql, strategyID, pluginName).Scan(&connID) @@ -180,8 +196,8 @@ func GetConnIDFromStrategyPlugin(pluginName, strategyID string) (bool, int, erro } //BatchEditStrategyPluginStatus 批量修改策略组插件状态 -func BatchEditStrategyPluginStatus(connIDList, strategyID string, pluginStatus int) (bool, string, error) { - db := database2.GetConnection() +func (d *StrategyPluginDao) BatchEditStrategyPluginStatus(connIDList, strategyID string, pluginStatus int) (bool, string, error) { + db := d.db t := time.Now() now := t.Format("2006-01-02 15:04:05") updateTag := t.Format("20060102150405") @@ -204,8 +220,8 @@ func BatchEditStrategyPluginStatus(connIDList, strategyID string, pluginStatus i } //BatchDeleteStrategyPlugin 批量删除策略组插件 -func BatchDeleteStrategyPlugin(connIDList, strategyID string) (bool, string, error) { - db := database2.GetConnection() +func (d *StrategyPluginDao) BatchDeleteStrategyPlugin(connIDList, strategyID string) (bool, string, error) { + db := d.db now := time.Now().Format("2006-01-02 15:04:05") Tx, _ := db.Begin() sql := "DELETE FROM goku_conn_plugin_strategy WHERE connID IN (" + connIDList + ");" @@ -226,8 +242,8 @@ func BatchDeleteStrategyPlugin(connIDList, strategyID string) (bool, string, err } //CheckStrategyPluginIsExistByConnIDList 通过connIDList判断插件是否存在 -func CheckStrategyPluginIsExistByConnIDList(connIDList, pluginName string) (bool, error) { - db := database2.GetConnection() +func (d *StrategyPluginDao) CheckStrategyPluginIsExistByConnIDList(connIDList, pluginName string) (bool, error) { + db := d.db sql := "SELECT pluginStatus FROM goku_conn_plugin_strategy WHERE connID IN (" + connIDList + ") AND pluginName = ?;" var pluginStatus int err := db.QueryRow(sql, pluginName).Scan(&pluginStatus) diff --git a/server/dao/console-sqlite3/updater/check.go b/server/dao/console-sqlite3/updater/check.go index e1b20ceb..f09997f6 100644 --- a/server/dao/console-sqlite3/updater/check.go +++ b/server/dao/console-sqlite3/updater/check.go @@ -3,13 +3,11 @@ package updater import ( SQL "database/sql" "fmt" - - "github.com/eolinker/goku-api-gateway/common/database" ) //IsTableExist 检查table是否存在 -func IsTableExist(name string) bool { - db := database.GetConnection() +func (d *Dao)IsTableExist(name string) bool { + db := d.db selectType := "" sql := "SELECT type FROM sqlite_master WHERE `type` = 'table' AND `name` = ?" err := db.QueryRow(sql, name).Scan(&selectType) @@ -20,8 +18,8 @@ func IsTableExist(name string) bool { } //IsColumnExist 检查列是否存在 -func IsColumnExist(name string, column string) bool { - db := database.GetConnection() +func (d *Dao)IsColumnExist(name string, column string) bool { + db := d.db sql := fmt.Sprintf("PRAGMA table_info(%s)", name) rows, err := db.Query(sql) if err != nil { diff --git a/server/dao/console-sqlite3/updater/dao.go b/server/dao/console-sqlite3/updater/dao.go new file mode 100644 index 00000000..d3e96ce2 --- /dev/null +++ b/server/dao/console-sqlite3/updater/dao.go @@ -0,0 +1,30 @@ +package updater + +import ( + "database/sql" + + "github.com/eolinker/goku-api-gateway/server/dao" +) + +//Dao Dao +type Dao struct { + db *sql.DB +} + +//NewUpdaterDaoWidthDB NewUpdaterDaoWidthDB +func NewUpdaterDaoWidthDB(db *sql.DB) *Dao { + return &Dao{db: db} +} + +//NewUpdaterDao NewUpdaterDao +func NewUpdaterDao() *Dao { + return &Dao{} +} + +//Create create +func (d *Dao) Create(db *sql.DB) (interface{}, error) { + d.db = db + + i := dao.UpdaterDao(d) + return &i, nil +} diff --git a/server/dao/console-sqlite3/updater/get.go b/server/dao/console-sqlite3/updater/get.go index 5e3a060e..a0dd6c1b 100644 --- a/server/dao/console-sqlite3/updater/get.go +++ b/server/dao/console-sqlite3/updater/get.go @@ -1,10 +1,8 @@ package updater -import "github.com/eolinker/goku-api-gateway/common/database" - //GetTableVersion 获取当前表版本号 -func GetTableVersion(name string) string { - db := database.GetConnection() +func (d *Dao)GetTableVersion(name string) string { + db := d.db version := "" sql := "SELECT version FROM goku_table_version WHERE tableName = ?" err := db.QueryRow(sql, name).Scan(&version) @@ -15,8 +13,8 @@ func GetTableVersion(name string) string { } //UpdateTableVersion 更新表版本号 -func UpdateTableVersion(name, version string) error { - db := database.GetConnection() +func (d *Dao)UpdateTableVersion(name, version string) error { + db := d.db sql := "REPLACE INTO goku_table_version (tableName,version) VALUES (?,?);" _, err := db.Exec(sql, name, version) if err != nil { @@ -26,8 +24,8 @@ func UpdateTableVersion(name, version string) error { } //GetGokuVersion 获取goku当前版本号 -func GetGokuVersion() string { - db := database.GetConnection() +func (d *Dao)GetGokuVersion() string { + db := d.db version := "" sql := "SELECT version FROM goku_version;" err := db.QueryRow(sql).Scan(&version) @@ -38,8 +36,8 @@ func GetGokuVersion() string { } //SetGokuVersion 设置goku版本号 -func SetGokuVersion(version string) error { - db := database.GetConnection() +func (d *Dao)SetGokuVersion(version string) error { + db := d.db sql := "REPLACE INTO goku_version (sol,version) VALUES (?,?);" _, err := db.Exec(sql, 1, version) if err != nil { diff --git a/server/dao/console-sqlite3/user.go b/server/dao/console-sqlite3/user.go index 463e064b..c3cd057d 100644 --- a/server/dao/console-sqlite3/user.go +++ b/server/dao/console-sqlite3/user.go @@ -1,18 +1,38 @@ package console_sqlite3 import ( + "database/sql" "encoding/json" "errors" - database2 "github.com/eolinker/goku-api-gateway/common/database" + "github.com/eolinker/goku-api-gateway/server/dao" + "github.com/eolinker/goku-api-gateway/utils" ) -type permissionsJSON map[string]bool +type permissionsJSON = map[string]bool + +//UserDao UserDao +type UserDao struct { + db *sql.DB +} + +//NewUserDao new UserDao +func NewUserDao() *UserDao { + return &UserDao{} +} + +//Create create +func (d *UserDao) Create(db *sql.DB) (interface{}, error) { + d.db = db + var i dao.UserDao = d + + return &i, nil +} //EditPassword 修改账户信息 -func EditPassword(oldPassword, newPassword string, userID int) (bool, string, error) { - db := database2.GetConnection() +func (d *UserDao) EditPassword(oldPassword, newPassword string, userID int) (bool, string, error) { + db := d.db // 查询旧密码是否存在 var loginCall, password string oldPassword = utils.Md5(oldPassword) @@ -41,8 +61,8 @@ func EditPassword(oldPassword, newPassword string, userID int) (bool, string, er } //GetUserInfo 获取账户信息 -func GetUserInfo(userID int) (bool, interface{}, error) { - db := database2.GetConnection() +func (d *UserDao) GetUserInfo(userID int) (bool, interface{}, error) { + db := d.db sql := `SELECT loginCall,IFNULL(remark,""),IFNULL(permissions,""),userType FROM goku_admin WHERE userID = ?;` var loginCall, remark, permissions string var userType int @@ -69,8 +89,8 @@ func GetUserInfo(userID int) (bool, interface{}, error) { } //GetUserType 获取用户类型 -func GetUserType(userID int) (bool, interface{}, error) { - db := database2.GetConnection() +func (d *UserDao) GetUserType(userID int) (bool, interface{}, error) { + db := d.db sql := "SELECT userType FROM goku_admin WHERE userID = ?;" var userType int err := db.QueryRow(sql, userID).Scan(&userType) @@ -81,8 +101,8 @@ func GetUserType(userID int) (bool, interface{}, error) { } //CheckUserIsAdmin 判断是否是管理员 -func CheckUserIsAdmin(userID int) (bool, string, error) { - db := database2.GetConnection() +func (d *UserDao) CheckUserIsAdmin(userID int) (bool, string, error) { + db := d.db sql := "SELECT userType FROM goku_admin WHERE userID = ? AND (userType = 0 OR userType = 1);" var userType int err := db.QueryRow(sql, userID).Scan(&userType) @@ -93,8 +113,8 @@ func CheckUserIsAdmin(userID int) (bool, string, error) { } //CheckUserIsSuperAdmin 判断是否是超级管理员 -func CheckUserIsSuperAdmin(userID int) (bool, string, error) { - db := database2.GetConnection() +func (d *UserDao) CheckUserIsSuperAdmin(userID int) (bool, string, error) { + db := d.db sql := "SELECT userType FROM goku_admin WHERE userID = ? AND userType = 0;" var userType int err := db.QueryRow(sql, userID).Scan(&userType) @@ -105,8 +125,8 @@ func CheckUserIsSuperAdmin(userID int) (bool, string, error) { } //CheckSuperAdminCount 获取超级管理员数量 -func CheckSuperAdminCount() (int, error) { - db := database2.GetConnection() +func (d *UserDao) CheckSuperAdminCount() (int, error) { + db := d.db sql := "SELECT count(*) FROM goku_admin WHERE userType = 0;" count := 0 err := db.QueryRow(sql).Scan(&count) @@ -117,44 +137,9 @@ func CheckSuperAdminCount() (int, error) { return count, nil } -//CheckUserPermission 检查用户权限 -func CheckUserPermission(operationType, operation string, userID int) (bool, string, error) { - db := database2.GetConnection() - var permissions string - var userType int - sql := `SELECT userType,IFNULL(permissions,"") FROM goku_admin WHERE userID = ?;` - err := db.QueryRow(sql, userID).Scan(&userType, &permissions) - if err != nil { - return false, "[ERROR]This user does not exist!", err - } - if userType == 0 || userType == 1 { - return true, "", nil - } - if permissions == "" { - return false, "[ERROR]This user does not assigned permission", nil - } - permissionsMap := make(map[string]permissionsJSON) - err = json.Unmarshal([]byte(permissions), &permissionsMap) - if err != nil { - return false, "[ERROR]Fail to parse json!!", err - } - value, ok := permissionsMap[operationType] - if !ok { - return false, "[ERROR]Operation type does not exist!", nil - } - v, temp := value[operation] - if !temp { - return false, "[ERROR]Operation does not exist!!", nil - } - if !v { - return false, "[ERROR]No permissions!", nil - } - return true, "", nil -} - //GetUserListWithPermission 获取具有编辑权限的用户列表 -func GetUserListWithPermission(operationType, operation string) (bool, []map[string]interface{}, error) { - db := database2.GetConnection() +func (d *UserDao) GetUserListWithPermission(operationType, operation string) (bool, []map[string]interface{}, error) { + db := d.db sql := `SELECT userID,IF(remark IS NULL OR remark = "",loginCall,remark) as userName,userType,IFNULL(permissions,"") FROM goku_admin ORDER BY userType ASC;` rows, err := db.Query(sql) if err != nil { diff --git a/server/dao/console-sqlite3/utils.go b/server/dao/console-sqlite3/utils.go index 36e29ec6..fcf61d63 100644 --- a/server/dao/console-sqlite3/utils.go +++ b/server/dao/console-sqlite3/utils.go @@ -3,22 +3,20 @@ package console_sqlite3 import ( SQL "database/sql" "fmt" - - "github.com/eolinker/goku-api-gateway/common/database" ) -func getCountSQL(sql string, args ...interface{}) int { +func getCountSQL(db *SQL.DB,sql string, args ...interface{}) int { var count int countSQL := fmt.Sprintf("SELECT COUNT(*) FROM (%s) A", sql) - err := database.GetConnection().QueryRow(countSQL, args...).Scan(&count) + err := db.QueryRow(countSQL, args...).Scan(&count) if err != nil { return 0 } return count } -func getPageSQL(sql string, orderBy, orderType string, page, pageSize int, args ...interface{}) (*SQL.Rows, error) { +func getPageSQL(db *SQL.DB,sql string, orderBy, orderType string, page, pageSize int, args ...interface{}) (*SQL.Rows, error) { pageSQL := fmt.Sprintf("%s ORDER BY %s %s LIMIT ?,?", sql, orderBy, orderType) args = append(args, (page-1)*pageSize, pageSize) - return database.GetConnection().Query(pageSQL, args...) + return db.Query(pageSQL, args...) } diff --git a/server/dao/console-sqlite3/version.go b/server/dao/console-sqlite3/version.go index ce1b4eba..558a16a3 100644 --- a/server/dao/console-sqlite3/version.go +++ b/server/dao/console-sqlite3/version.go @@ -1,19 +1,38 @@ package console_sqlite3 import ( + SQL "database/sql" "encoding/json" "fmt" "strconv" "strings" - "github.com/eolinker/goku-api-gateway/common/database" + "github.com/eolinker/goku-api-gateway/server/dao" "github.com/eolinker/goku-api-gateway/config" ) +//VersionDao VersionDao +type VersionDao struct { + db *SQL.DB +} + +//NewVersionDao new VersionDao +func NewVersionDao() *VersionDao { + return &VersionDao{} +} + +//Create create +func (d *VersionDao) Create(db *SQL.DB) (interface{}, error) { + d.db = db + var i dao.VersionDao = d + + return &i, nil +} + //GetVersionList 获取版本列表 -func GetVersionList(keyword string) ([]config.VersionConfig, error) { - db := database.GetConnection() +func (d *VersionDao) GetVersionList(keyword string) ([]config.VersionConfig, error) { + db := d.db rule := make([]string, 0, 2) if keyword != "" { rule = append(rule, "V.name LIKE '%"+keyword+"%' OR V.version LIKE '%"+keyword+"%' OR V.remark LIKE '%"+keyword+"%'") @@ -36,16 +55,17 @@ func GetVersionList(keyword string) ([]config.VersionConfig, error) { if err != nil { return configList, err } + configList = append(configList, config) } return configList, nil } //AddVersionConfig 新增版本配置 -func AddVersionConfig(name, version, remark, config, balanceConfig, discoverConfig, now string) (int, error) { - db := database.GetConnection() - sql := "INSERT INTO goku_gateway_version_config (`name`,`version`,`remark`,`createTime`,`publishTime`,`config`,`balanceConfig`,`discoverConfig`) VALUES (?,?,?,?,?,?,?,?)" - result, err := db.Exec(sql, name, version, remark, now, now, config, balanceConfig, discoverConfig) +func (d *VersionDao) AddVersionConfig(name, version, remark, config, balanceConfig, discoverConfig, now string, userID int) (int, error) { + db := d.db + sql := "INSERT INTO goku_gateway_version_config (`name`,`version`,`remark`,`createTime`,`updateTime`,`publishTime`,`config`,`balanceConfig`,`discoverConfig`) VALUES (?,?,?,?,?,?,?,?,?)" + result, err := db.Exec(sql, name, version, remark, now, now, now, config, balanceConfig, discoverConfig) if err != nil { return 0, err } @@ -56,9 +76,21 @@ func AddVersionConfig(name, version, remark, config, balanceConfig, discoverConf return int(lastID), nil } +//EditVersionBasicConfig 修改版本基本配置 +func (d *VersionDao) EditVersionBasicConfig(name, version, remark string, userID, versionID int) error { + db := d.db + sql := "UPDATE goku_gateway_version_config SET `name` = ?,`version` = ?,`remark` = ?,`updaterID` = ? WHERE versionID = ?" + _, err := db.Exec(sql, name, version, remark, userID, versionID) + if err != nil { + return err + } + + return nil +} + //BatchDeleteVersionConfig 批量删除版本配置 -func BatchDeleteVersionConfig(ids []int, publishID int) error { - db := database.GetConnection() +func (d *VersionDao) BatchDeleteVersionConfig(ids []int, publishID int) error { + db := d.db s := "" idCount := len(ids) for i, id := range ids { @@ -79,8 +111,8 @@ func BatchDeleteVersionConfig(ids []int, publishID int) error { } //PublishVersion 发布版本 -func PublishVersion(id int, now string) error { - db := database.GetConnection() +func (d *VersionDao) PublishVersion(id, userID int, now string) error { + db := d.db sql := "UPDATE goku_gateway SET versionID = ?" _, err := db.Exec(sql, id) if err != nil { @@ -95,8 +127,8 @@ func PublishVersion(id int, now string) error { } //GetVersionConfigCount 获取版本配置数量 -func GetVersionConfigCount() int { - db := database.GetConnection() +func (d *VersionDao) GetVersionConfigCount() int { + db := d.db sql := "SELECT COUNT(*) FROM goku_gateway_version_config" var count int err := db.QueryRow(sql).Scan(&count) @@ -107,8 +139,8 @@ func GetVersionConfigCount() int { } //GetPublishVersionID 获取发布版本ID -func GetPublishVersionID() int { - db := database.GetConnection() +func (d *VersionDao) GetPublishVersionID() int { + db := d.db sql := "SELECT versionID FROM goku_gateway" var id int err := db.QueryRow(sql).Scan(&id) @@ -119,8 +151,8 @@ func GetPublishVersionID() int { } //GetVersionConfig 获取当前版本配置 -func GetVersionConfig() (*config.GokuConfig, map[string]map[string]*config.BalanceConfig, map[string]map[string]*config.DiscoverConfig, error) { - db := database.GetConnection() +func (d *VersionDao) GetVersionConfig() (*config.GokuConfig, map[string]map[string]*config.BalanceConfig, map[string]map[string]*config.DiscoverConfig, error) { + db := d.db sql := "SELECT IFNULL(goku_gateway_version_config.config,'{}'),IFNULL(goku_gateway_version_config.balanceConfig,'{}'),IFNULL(goku_gateway_version_config.discoverConfig,'{}') FROM goku_gateway_version_config INNER JOIN goku_gateway ON goku_gateway.versionID = goku_gateway_version_config.versionID" var cf, bf, df string @@ -129,8 +161,8 @@ func GetVersionConfig() (*config.GokuConfig, map[string]map[string]*config.Balan return nil, nil, nil, err } var c config.GokuConfig - b := make(map[string]map[string]*config.BalanceConfig) - d := make(map[string]map[string]*config.DiscoverConfig) + bc := make(map[string]map[string]*config.BalanceConfig) + dc := make(map[string]map[string]*config.DiscoverConfig) err = json.Unmarshal([]byte(cf), &c) if cf != "" { if err != nil { @@ -138,18 +170,18 @@ func GetVersionConfig() (*config.GokuConfig, map[string]map[string]*config.Balan } } if bf != "" { - err = json.Unmarshal([]byte(bf), &b) + err = json.Unmarshal([]byte(bf), &bc) if err != nil { return nil, nil, nil, err } } if df != "" { - err = json.Unmarshal([]byte(df), &d) + err = json.Unmarshal([]byte(df), &dc) if err != nil { return nil, nil, nil, err } } - return &c, b, d, nil + return &c, bc, dc, nil } diff --git a/server/dao/dao-balance.go b/server/dao/dao-balance.go new file mode 100644 index 00000000..a8fafe45 --- /dev/null +++ b/server/dao/dao-balance.go @@ -0,0 +1,41 @@ +package dao + +import ( + entity "github.com/eolinker/goku-api-gateway/server/entity/balance-entity-service" +) + +//BalanceDao balanceDao +type BalanceDao interface { + //RegisterDao add + //Add(name, serviceName, desc, appName, static, staticCluster, now string) (string, error) + + //AddStatic 新增静态负载 + AddStatic(name, serviceName, static, staticCluster, desc, now string) (string, error) + //SaveStatic 保存静态负载信息 + SaveStatic(name, serviceName, static, staticCluster, desc string, now string) (string, error) + + //SaveDiscover 保存服务发现信息 + SaveDiscover(name, serviceName, appName, desc string, now string) (string, error) + //AddDiscovery 新增服务发现 + AddDiscovery(name, serviceName, appName, desc, now string) (string, error) + //Save save + //Save(name, desc, static, staticCluster, now string) (string, error) + + //Delete 删除负载 + Delete(name string) (string, error) + + //BatchDelete 批量删除负载 + BatchDelete(balanceNames []string) (string, error) + //GetBalanceNames 获取负载名称列表 + GetBalanceNames() (bool, []string, error) + //Get 根据负载名获取负载配置 + Get(name string) (*entity.Balance, error) + + //GetAll 获取所有负载配置 + GetAll() ([]*entity.Balance, error) + + //Search 关键字获取负载列表 + Search(keyword string) ([]*entity.Balance, error) + + GetUseBalanceNames() (map[string]int, error) +} diff --git a/server/dao/daos.go b/server/dao/daos.go new file mode 100644 index 00000000..c9cd53bb --- /dev/null +++ b/server/dao/daos.go @@ -0,0 +1,458 @@ +package dao + +import ( + "time" + + "github.com/eolinker/goku-api-gateway/config" + balanceentity "github.com/eolinker/goku-api-gateway/server/entity/balance-entity" + configLogEntry "github.com/eolinker/goku-api-gateway/server/entity/config-log" + entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" +) + +//APIDao apiDao +type APIDao interface { + // AddAPI 新增接口 + AddAPI(apiName, alias, requestURL, targetURL, requestMethod, targetMethod, isFollow, linkAPIs, staticResponse, responseDataType, balanceName, protocol string, projectID, groupID, timeout, retryCount, alertValve, managerID, userID, apiType int) (bool, int, error) + // EditAPI 修改接口 + EditAPI(apiName, alias, requestURL, targetURL, requestMethod, targetMethod, isFollow, linkAPIs, staticResponse, responseDataType, balanceName, protocol string, projectID, groupID, timeout, retryCount, alertValve, apiID, managerID, userID int) (bool, error) + // GetAPIInfo 获取接口信息 + GetAPIInfo(apiID int) (bool, *entity.API, error) + //GetAPIListByGroupList 通过分组列表获取接口列表 + GetAPIListByGroupList(projectID int, groupIDList string) (bool, []map[string]interface{}, error) + + // GetAPIIDList 获取接口ID列表 + GetAPIIDList(projectID int, groupID int, keyword string, condition int, ids []int) (bool, []int, error) + // GetAPIList 获取所有接口列表 + GetAPIList(projectID int, groupID int, keyword string, condition, page, pageSize int, ids []int) (bool, []map[string]interface{}, int, error) + //CheckURLIsExist 接口路径是否存在 + CheckURLIsExist(requestURL, requestMethod string, projectID, apiID int) bool + //CheckAPIIsExist 检查接口是否存在 + CheckAPIIsExist(apiID int) (bool, error) + //CheckAliasIsExist 检查别名是否存在 + CheckAliasIsExist(apiID int, alias string) bool + //BatchEditAPIBalance 批量修改接口负载 + BatchEditAPIBalance(apiIDList []string, balance string) (string, error) + //BatchEditAPIGroup 批量修改接口分组 + BatchEditAPIGroup(apiIDList []string, groupID int) (string, error) + //BatchDeleteAPI 批量修改接口 + BatchDeleteAPI(apiIDList string) (bool, string, error) +} + +//APIGroupDao apiGroupDao +type APIGroupDao interface { + //AddAPIGroup 新建接口分组 + AddAPIGroup(groupName string, projectID, parentGroupID int) (bool, interface{}, error) + //EditAPIGroup 修改接口分组 + EditAPIGroup(groupName string, groupID, projectID int) (bool, string, error) + //DeleteAPIGroup 删除接口分组 + DeleteAPIGroup(projectID, groupID int) (bool, string, error) + //GetAPIGroupList 获取接口分组列表 + GetAPIGroupList(projectID int) (bool, []map[string]interface{}, error) +} + +//APIPluginDao apiPlugin.go +type APIPluginDao interface { + //AddPluginToAPI 新增接口插件 + AddPluginToAPI(pluginName, config, strategyID string, apiID, userID int) (bool, interface{}, error) + //EditAPIPluginConfig 修改接口插件配置 + EditAPIPluginConfig(pluginName, config, strategyID string, apiID, userID int) (bool, interface{}, error) + //GetAPIPluginList 获取接口插件列表 + GetAPIPluginList(apiID int, strategyID string) (bool, []map[string]interface{}, error) + //GetPluginIndex 获取插件优先级 + GetPluginIndex(pluginName string) (bool, int, error) + //GetAPIPluginConfig 通过APIID获取配置信息 + GetAPIPluginConfig(apiID int, strategyID, pluginName string) (bool, map[string]string, error) + //CheckPluginIsExistInAPI 检查策略组是否绑定插件 + CheckPluginIsExistInAPI(strategyID, pluginName string, apiID int) (bool, error) + // GetAPIPluginInStrategyByAPIID 通过接口ID获取策略组中接口插件列表 + GetAPIPluginInStrategyByAPIID(strategyID string, apiID int, keyword string, condition int) (bool, []map[string]interface{}, map[string]interface{}, error) + //GetAllAPIPluginInStrategy 获取策略组中所有接口插件列表 + GetAllAPIPluginInStrategy(strategyID string) (bool, []map[string]interface{}, error) + //BatchEditAPIPluginStatus 批量修改策略组插件状态 + BatchEditAPIPluginStatus(connIDList, strategyID string, pluginStatus, userID int) (bool, string, error) + //BatchDeleteAPIPlugin 批量删除策略组插件 + BatchDeleteAPIPlugin(connIDList, strategyID string) (bool, string, error) + //GetAPIPluginName 通过connID获取插件名称 + GetAPIPluginName(connID int) (bool, string, error) + //CheckAPIPluginIsExistByConnIDList 通过connIDList判断插件是否存在 + CheckAPIPluginIsExistByConnIDList(connIDList, pluginName string) (bool, []int, error) + //GetAPIPluginListWithNotAssignAPIList 获取没有绑定嵌套插件列表 + GetAPIPluginListWithNotAssignAPIList(strategyID string) (bool, []map[string]interface{}, error) +} + +//APIStrategyDao apiStrategy.go +type APIStrategyDao interface { + //AddAPIToStrategy 将接口加入策略组 + AddAPIToStrategy(apiList []string, strategyID string) (bool, string, error) + // SetAPITargetOfStrategy 重定向接口负载 + SetAPITargetOfStrategy(apiID int, strategyID string, target string) (bool, string, error) + // BatchSetAPITargetOfStrategy 批量重定向接口负载 + BatchSetAPITargetOfStrategy(apiIds []int, strategyID string, target string) (bool, string, error) + // GetAPIIDListFromStrategy 获取策略组接口列表 + GetAPIIDListFromStrategy(strategyID, keyword string, condition int, ids []int, balanceNames []string) (bool, []int, error) + // GetAPIListFromStrategy 获取策略组接口列表 + GetAPIListFromStrategy(strategyID, keyword string, condition, page, pageSize int, ids []int, balanceNames []string) (bool, []map[string]interface{}, int, error) + // CheckIsExistAPIInStrategy 检查插件是否添加进策略组 + CheckIsExistAPIInStrategy(apiID int, strategyID string) (bool, string, error) + + // GetAPIIDListNotInStrategy 获取未被该策略组绑定的接口ID列表(通过项目) + GetAPIIDListNotInStrategy(strategyID string, projectID, groupID int, keyword string) (bool, []int, error) + // GetAPIListNotInStrategy 获取未被该策略组绑定的接口列表(通过项目) + GetAPIListNotInStrategy(strategyID string, projectID, groupID, page, pageSize int, keyword string) (bool, []map[string]interface{}, int, error) + //BatchDeleteAPIInStrategy 批量删除策略组接口 + BatchDeleteAPIInStrategy(apiIDList, strategyID string) (bool, string, error) +} + +//AuthDao auth.go +type AuthDao interface { + //GetAuthStatus 获取认证状态 + GetAuthStatus(strategyID string) (bool, map[string]interface{}, error) + //GetAuthInfo 获取认证信息 + GetAuthInfo(strategyID string) (bool, map[string]interface{}, error) + //EditAuthInfo 编辑认证信息 + EditAuthInfo(strategyID, strategyName, basicAuthList, apikeyList, jwtCredentialList, oauth2CredentialList string, delClientIDList []string) (bool, error) +} + +//ClusterDao cluster.go +type ClusterDao interface { + //AddCluster 新增集群 + AddCluster(name, title, note string) error + //EditCluster 修改集群信息 + EditCluster(name, title, note string) error + //DeleteCluster 删除集群 + DeleteCluster(name string) error + //GetClusterCount 获取集群数量 + GetClusterCount() int + //GetClusterNodeCount 获取集群节点数量 + GetClusterNodeCount(name string) int + //GetClusterIDByName 通过集群名称获取集群ID + GetClusterIDByName(name string) int + //GetClusters 获取集群列表 + GetClusters() ([]*entity.Cluster, error) + //GetCluster 获取集群信息 + GetCluster(name string) (*entity.Cluster, error) + GetClusterByID(id int) (*entity.Cluster, error) + //CheckClusterNameIsExist 判断集群名称是否存在 + CheckClusterNameIsExist(name string) bool +} + +//ConfigLogDao config-log +type ConfigLogDao interface { + //Get get + Get(name string) (*configLogEntry.LogConfig, error) + //Set set + Set(ent *configLogEntry.LogConfig) error +} + +//BalanceUpdateDao dao-balance-update +type BalanceUpdateDao interface { + //GetAllOldVerSion 获取所有旧负载配置 + GetAllOldVerSion() ([]*balanceentity.BalanceInfoEntity, error) + //GetDefaultServiceStatic 获取默认静态负载 + GetDefaultServiceStatic() string +} + +//ServiceDao dao-service +type ServiceDao interface { + //RegisterDao 新增服务 + Add(name, driver, desc, config, clusterConfig string, isDefault, healthCheck bool, healthCheckPath string, healthCheckCode string, healthCheckPeriod, healthCheckTimeOut int) error + //SetDefault 设置默认服务 + SetDefault(name string) error + //Delete 删除服务发现 + Delete(names []string) error + //Get 获取服务发现信息 + Get(name string) (*entity.Service, error) + //List 获取服务发现列表 + List(keyword string) ([]*entity.Service, error) + //Save 存储服务发现信息 + Save(name, desc, config, clusterConfig string, healthCheck bool, healthCheckPath string, healthCheckCode string, healthCheckPeriod, healthCheckTimeOut int) error +} + +//VersionConfigDao dao-version-config +type VersionConfigDao interface { + //GetAPIContent 获取接口信息 + GetAPIContent() ([]*config.APIContent, error) + //GetBalances 获取balance信息 + GetDiscoverConfig(clusters []*entity.Cluster) (map[string]map[string]*config.DiscoverConfig, error) + //GetDiscoverConfig 获取服务发现信息 + GetBalances(clusters []*entity.Cluster) (map[string]map[string]*config.BalanceConfig, error) + //GetGlobalPlugin 获取全局插件 + GetGlobalPlugin() (*config.GatewayPluginConfig, error) + //GetAPIPlugins 获取接口插件 + GetAPIPlugins() (map[string][]*config.PluginConfig, error) + //GetStrategyPlugins 获取策略插件 + GetStrategyPlugins() (map[string][]*config.PluginConfig, map[string]map[string]string, error) + //GetAPIsOfStrategy 获取策略内接口数据 + GetAPIsOfStrategy() (map[string][]*config.APIOfStrategy, error) + //GetStrategyConfig 获取策略配置 + GetStrategyConfig() (string, []*config.StrategyConfig, error) + //GetLogInfo 获取日志信息 + GetLogInfo() (*config.LogConfig, *config.AccessLogConfig, error) + //GetMonitorModules 获取监控模块信息 + GetMonitorModules(status int, isAll bool) (map[string]string, error) + + GetRouterRules(enable int) ([]*config.Router, error) + + GetGatewayBasicConfig() (*config.Gateway, error) +} + +//GatewayDao gateway.go +type GatewayDao interface { + //GetGatewayConfig 获取网关配置 + GetGatewayConfig() (map[string]interface{}, error) + //EditGatewayBaseConfig 编辑网关基本配置 + EditGatewayBaseConfig(config entity.GatewayBasicConfig) (bool, string, error) + //GetGatewayInfo 获取网关信息 + GetGatewayInfo() (nodeStartCount, nodeStopCount, projectCount, apiCount, strategyCount int, err error) +} + +//GuestDao guest.go +type GuestDao interface { + //Login 登录 + Login(loginCall, loginPassword string) (bool, int) + //CheckLogin 检查用户是否登录 + CheckLogin(userToken string, userID int) bool + //Register 用户注册 + Register(loginCall, loginPassword string) bool +} + +//ImportDao import.go +type ImportDao interface { + //ImportAPIGroupFromAms 导入分组 + ImportAPIGroupFromAms(projectID, userID int, groupInfo entity.AmsGroupInfo) (bool, string, error) + //ImportProjectFromAms 导入项目 + ImportProjectFromAms(userID int, projectInfo entity.AmsProject) (bool, string, error) + //ImportAPIFromAms 从ams中导入接口 + ImportAPIFromAms(projectID, groupID, userID int, apiList []entity.AmsAPIInfo) (bool, string, error) +} + +//MonitorModulesDao monitorModule.go +type MonitorModulesDao interface { + //GetMonitorModules 获取监控模块列表 + GetMonitorModules() (map[string]*entity.MonitorModule, error) + //SetMonitorModule 设置监控模块 + SetMonitorModule(moduleName string, config string, moduleStatus int) error + + CheckModuleStatus(moduleName string) int +} + +//NodeDao node.go +type NodeDao interface { + //AddNode 新增节点信息 + AddNode(clusterID int, nodeName, nodeKey, listenAddress, adminAddress, gatewayPath string, groupID int) (int64, string, string, error) + //EditNode 修改节点信息 + EditNode(nodeName, listenAddress, adminAddress, gatewayPath string, nodeID, groupID int) (string, error) + //DeleteNode 删除节点信息 + DeleteNode(nodeID int) (string, error) + // GetNodeList 获取节点列表 + GetNodeList(clusterID, groupID int, keyword string) ([]*entity.Node, error) + //GetNodeInfo 获取节点信息 + GetNodeInfo(nodeID int) (*entity.Node, error) + //GetNodeByKey 通过Key查询节点信息 + GetNodeByKey(nodeKey string) (*entity.Node, error) + //GetAvaliableNodeListFromNodeList 从待操作节点中获取关闭节点列表 + GetAvaliableNodeListFromNodeList(nodeIDList string, nodeStatus int) (string, error) + //BatchEditNodeGroup 批量修改节点分组 + BatchEditNodeGroup(nodeIDList string, groupID int) (string, error) + //BatchDeleteNode 批量修改接口分组 + BatchDeleteNode(nodeIDList string) (string, error) + //UpdateAllNodeClusterID 更新节点集群ID + UpdateAllNodeClusterID(clusterID int) + //GetNodeInfoAll get all node + GetNodeInfoAll() ([]*entity.Node, error) + + GetHeartBeatTime(nodeKey string) (time.Time, error) + + SetHeartBeatTime(nodeKey string, heartBeatTime time.Time) error +} + +//NodeGroupDao nodeGroup.go +type NodeGroupDao interface { + //AddNodeGroup 新建节点分组 + AddNodeGroup(groupName string, clusterID int) (bool, interface{}, error) + //EditNodeGroup 修改节点分组信息 + EditNodeGroup(groupName string, groupID int) (bool, string, error) + //DeleteNodeGroup 删除节点分组 + DeleteNodeGroup(groupID int) (bool, string, error) + //GetNodeGroupInfo 获取节点分组信息 + GetNodeGroupInfo(groupID int) (bool, map[string]interface{}, error) + //GetNodeGroupList 获取节点分组列表 + GetNodeGroupList(clusterID int) (bool, []map[string]interface{}, error) + //CheckNodeGroupIsExist 检查节点分组是否存在 + CheckNodeGroupIsExist(groupID int) (bool, error) + //GetRunningNodeCount 获取分组内启动节点数量 + GetRunningNodeCount(groupID int) (bool, interface{}, error) +} + +//PluginDao plugin.go +type PluginDao interface { + //GetPluginInfo 获取插件配置信息 + GetPluginInfo(pluginName string) (bool, *entity.Plugin, error) + // GetPluginList 获取插件列表 + GetPluginList(keyword string, condition int) (bool, []*entity.Plugin, error) + // GetPluginCount 获取插件数量 + GetPluginCount() int + // AddPlugin 新增插件信息 + AddPlugin(pluginName, pluginConfig, pluginDesc, version string, pluginPriority, isStop, pluginType int) (bool, string, error) + // EditPlugin 修改插件信息 + EditPlugin(pluginName, pluginConfig, pluginDesc, version string, pluginPriority, isStop, pluginType int) (bool, string, error) + // DeletePlugin 删除插件信息 + DeletePlugin(pluginName string) (bool, string, error) + //CheckIndexIsExist 判断插件ID是否存在 + CheckIndexIsExist(pluginName string, pluginPriority int) (bool, error) + //GetPluginConfig 获取插件配置及插件信息 + GetPluginConfig(pluginName string) (bool, string, error) + //CheckNameIsExist 检查插件名称是否存在 + CheckNameIsExist(pluginName string) (bool, error) + //EditPluginStatus 修改插件开启状态 + EditPluginStatus(pluginName string, pluginStatus int) (bool, error) + //GetPluginListByPluginType 获取不同类型的插件列表 + GetPluginListByPluginType(pluginType int) (bool, []map[string]interface{}, error) + //BatchStopPlugin 批量关闭插件 + BatchStopPlugin(pluginNameList string) (bool, string, error) + //BatchStartPlugin 批量关闭插件 + BatchStartPlugin(pluginNameList string) (bool, string, error) + //EditPluginCheckStatus 更新插件检测状态 + EditPluginCheckStatus(pluginName string, isCheck int) (bool, string, error) +} + +//ProjectDao project.go +type ProjectDao interface { + //AddProject 新建项目 + AddProject(projectName string) (bool, interface{}, error) + //EditProject 修改项目信息 + EditProject(projectName string, projectID int) (bool, string, error) + //DeleteProject 修改项目信息 + DeleteProject(projectID int) (bool, string, error) + //BatchDeleteProject 批量删除项目 + BatchDeleteProject(projectIDList string) (bool, string, error) + //GetProjectInfo 获取项目信息 + GetProjectInfo(projectID int) (bool, entity.Project, error) + //GetProjectList 获取项目列表 + GetProjectList(keyword string) (bool, []*entity.Project, error) + //CheckProjectIsExist 检查项目是否存在 + CheckProjectIsExist(projectID int) (bool, error) + //GetAPIListFromProjectNotInStrategy 获取项目列表中没有被策略组绑定的接口 + GetAPIListFromProjectNotInStrategy() (bool, []map[string]interface{}, error) +} + +//StrategyDao strategy.go +type StrategyDao interface { + //AddStrategy 新增策略组 + AddStrategy(strategyName string, groupID, userID int) (bool, string, error) + //EditStrategy 修改策略组信息 + EditStrategy(strategyID, strategyName string, groupID, userID int) (bool, string, error) + //DeleteStrategy 删除策略组 + DeleteStrategy(strategyID string) (bool, string, error) + // GetStrategyList 获取策略组列表 + GetStrategyList(groupID int, keyword string, condition, page, pageSize int) (bool, []*entity.Strategy, int, error) + // GetOpenStrategy 获取策略组列表 + GetOpenStrategy() (bool, *entity.Strategy, error) + //GetStrategyInfo 获取策略组信息 + GetStrategyInfo(strategyID string) (bool, *entity.Strategy, error) + //CheckStrategyIsExist 检查策略组ID是否存在 + CheckStrategyIsExist(strategyID string) (bool, error) + //BatchEditStrategyGroup 批量修改策略组分组 + BatchEditStrategyGroup(strategyIDList string, groupID int) (bool, string, error) + //BatchDeleteStrategy 批量修改策略组 + BatchDeleteStrategy(strategyIDList string) (bool, string, error) + //CheckIsOpenStrategy 判断是否是开放策略 + CheckIsOpenStrategy(strategyID string) bool + //BatchUpdateStrategyEnableStatus 更新策略启动状态 + BatchUpdateStrategyEnableStatus(strategyIDList string, enableStatus int) (bool, string, error) + // GetBalanceListInStrategy 获取在策略中的负载列表 + GetBalanceListInStrategy(strategyID string, balanceType int) (bool, []string, error) + // CopyStrategy 复制策略 + CopyStrategy(strategyID string, newStrategyID string, userID int) (string, error) + //GetStrategyIDList 获取策略ID列表 + GetStrategyIDList(groupID int, keyword string, condition int) (bool, []string, error) +} + +//StrategyGroupDao strategyGroup.go +type StrategyGroupDao interface { + //AddStrategyGroup 新建策略组分组 + AddStrategyGroup(groupName string) (bool, interface{}, error) + //EditStrategyGroup 修改策略组分组 + EditStrategyGroup(groupName string, groupID int) (bool, string, error) + //DeleteStrategyGroup 删除策略组分组 + DeleteStrategyGroup(groupID int) (bool, string, error) + //GetStrategyGroupList 获取策略组分组列表 + GetStrategyGroupList() (bool, []map[string]interface{}, error) + //CheckIsOpenGroup 判断是否是开放分组 + CheckIsOpenGroup(groupID int) bool +} + +//StrategyPluginDao strategyPlugin.go +type StrategyPluginDao interface { + //AddPluginToStrategy 新增策略组插件 + AddPluginToStrategy(pluginName, config, strategyID string) (bool, interface{}, error) + //EditStrategyPluginConfig 新增策略组插件配置 + EditStrategyPluginConfig(pluginName, config, strategyID string) (bool, string, error) + // GetStrategyPluginList 获取策略插件列表 + GetStrategyPluginList(strategyID, keyword string, condition int) (bool, []map[string]interface{}, error) + //GetStrategyPluginConfig 通过策略组ID获取配置信息 + GetStrategyPluginConfig(strategyID, pluginName string) (bool, string, error) + //CheckPluginIsExistInStrategy 检查策略组是否绑定插件 + CheckPluginIsExistInStrategy(strategyID, pluginName string) (bool, error) + //GetStrategyPluginStatus 检查策略组插件是否开启 + GetStrategyPluginStatus(strategyID, pluginName string) (bool, error) + //GetConnIDFromStrategyPlugin 获取Connid + GetConnIDFromStrategyPlugin(pluginName, strategyID string) (bool, int, error) + //BatchEditStrategyPluginStatus 批量修改策略组插件状态 + BatchEditStrategyPluginStatus(connIDList, strategyID string, pluginStatus int) (bool, string, error) + //BatchDeleteStrategyPlugin 批量删除策略组插件 + BatchDeleteStrategyPlugin(connIDList, strategyID string) (bool, string, error) + //CheckStrategyPluginIsExistByConnIDList 通过connIDList判断插件是否存在 + CheckStrategyPluginIsExistByConnIDList(connIDList, pluginName string) (bool, error) +} + +//UpdaterDao updater +type UpdaterDao interface { + //IsTableExist 检查table是否存在 + IsTableExist(name string) bool + //IsColumnExist 检查列是否存在 + IsColumnExist(name string, column string) bool + //GetTableVersion 获取当前表版本号 + GetTableVersion(name string) string + //UpdateTableVersion 更新表版本号 + UpdateTableVersion(name, version string) error + //GetGokuVersion 获取goku当前版本号 + GetGokuVersion() string + //SetGokuVersion 设置goku版本号 + SetGokuVersion(version string) error +} + +//UserDao user.go +type UserDao interface { + //EditPassword 修改账户信息 + EditPassword(oldPassword, newPassword string, userID int) (bool, string, error) + //GetUserInfo 获取账户信息 + GetUserInfo(userID int) (bool, interface{}, error) + //GetUserType 获取用户类型 + GetUserType(userID int) (bool, interface{}, error) + //CheckUserIsAdmin 判断是否是管理员 + CheckUserIsAdmin(userID int) (bool, string, error) + //CheckUserIsSuperAdmin 判断是否是超级管理员 + CheckUserIsSuperAdmin(userID int) (bool, string, error) + //CheckSuperAdminCount 获取超级管理员数量 + CheckSuperAdminCount() (int, error) +} + +//VersionDao version.go +type VersionDao interface { + //GetVersionList 获取版本列表 + GetVersionList(keyword string) ([]config.VersionConfig, error) + //AddVersionConfig 新增版本配置 + AddVersionConfig(name, version, remark, config, balanceConfig, discoverConfig, now string, userID int) (int, error) + EditVersionBasicConfig(name, version, remark string, userID, versionID int) error + //BatchDeleteVersionConfig 批量删除版本配置 + BatchDeleteVersionConfig(ids []int, publishID int) error + //PublishVersion 发布版本 + PublishVersion(id, userID int, now string) error + //GetVersionConfigCount 获取版本配置数量 + GetVersionConfigCount() int + //GetPublishVersionID 获取发布版本ID + GetPublishVersionID() int + //GetVersionConfig 获取当前版本配置 + GetVersionConfig() (*config.GokuConfig, map[string]map[string]*config.BalanceConfig, map[string]map[string]*config.DiscoverConfig, error) +} diff --git a/server/entity/balance-entity-service/balance.go b/server/entity/balance-entity-service/balance.go index 21953fe5..70bc1c71 100644 --- a/server/entity/balance-entity-service/balance.go +++ b/server/entity/balance-entity-service/balance.go @@ -14,6 +14,7 @@ type Balance struct { Desc string CreateTime string UpdateTime string + CanDelete int } //Type 获取负载类型 diff --git a/server/entity/balance-entity/balance.go b/server/entity/balance-entity/balance.go index c6f621e8..c4facb68 100644 --- a/server/entity/balance-entity/balance.go +++ b/server/entity/balance-entity/balance.go @@ -53,7 +53,7 @@ type _OldVersionBalanceInfo struct { } // -//func (info *BalanceInfo) Encode() *BalanceInfoEntity { +//func (info *BalanceInfo) Write() *BalanceInfoEntity { // // ent := new(BalanceInfoEntity) // ent.Name = info.Name diff --git a/server/entity/cluster.go b/server/entity/cluster.go index e79d25d1..a25f2b5b 100644 --- a/server/entity/cluster.go +++ b/server/entity/cluster.go @@ -1,23 +1,8 @@ package entity -import "fmt" - -//Cluster 集群配置 -type Cluster struct { - ID int `json:"-" yaml:"-"` - Name string `json:"name" yaml:"name"` - Title string `json:"title" yaml:"title"` -} - -//ClusterInfo 集群信息 -type ClusterInfo struct { - ID int `json:"-" yaml:"-"` - Name string `json:"name" yaml:"name"` - Title string `json:"title" yaml:"title"` - Note string `json:"note" yaml:"note"` - DB ClusterDB `json:"db" yaml:"db"` - Redis CLusterRedis `json:"redis" yaml:"redis"` -} +import ( + "fmt" +) //ClusterDB 集群DB配置 type ClusterDB struct { @@ -30,15 +15,6 @@ type ClusterDB struct { Path string `json:"path" yaml:"path"` } -//CLusterRedis 集群redis配置 -type CLusterRedis struct { - Mode string `json:"mode" yaml:"mode"` - Addrs string `json:"addrs" yaml:"addrs"` - DbIndex int `json:"dbIndex" yaml:"dbIndex"` - Masters string `json:"masters" yaml:"masters"` - Password string `json:"password" yaml:"password"` -} - //GetDriver 获取驱动名称 func (c *ClusterDB) GetDriver() string { return c.Driver @@ -48,13 +24,3 @@ func (c *ClusterDB) GetDriver() string { func (c *ClusterDB) GetSource() string { return fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8", c.UserName, c.Password, c.Host, c.Port, c.Database) } - -//Cluster 获取集群 -func (c *ClusterInfo) Cluster() *Cluster { - return &Cluster{ - ID: c.ID, - Name: c.Name, - Title: c.Title, - } - -} diff --git a/server/entity/console-entity/ams_import.go b/server/entity/console-entity/ams_import.go index f4c98122..9a9986e2 100644 --- a/server/entity/console-entity/ams_import.go +++ b/server/entity/console-entity/ams_import.go @@ -29,4 +29,5 @@ type AmsAPI struct { APIName string `json:"apiName"` APIURI string `json:"apiURI"` APIRequestType int `json:"apiRequestType"` + APIProtocol int `json:"apiProtocol"` } diff --git a/server/entity/console-entity/api.go b/server/entity/console-entity/api.go index 1f341cde..8dd1e98b 100644 --- a/server/entity/console-entity/api.go +++ b/server/entity/console-entity/api.go @@ -6,6 +6,7 @@ import "github.com/eolinker/goku-api-gateway/config" type API struct { APIID int `json:"apiID"` APIName string `json:"apiName"` + Alias string `json:"alias"` GroupID int `json:"groupID,omitempty"` ProjectID int `json:"projectID,omitempty"` RequestURL string `json:"requestURL"` diff --git a/server/entity/console-entity/cluster.go b/server/entity/console-entity/cluster.go index 7dd4f54d..5aca2fe6 100644 --- a/server/entity/console-entity/cluster.go +++ b/server/entity/console-entity/cluster.go @@ -1,10 +1,47 @@ package entity +import "strings" + //Cluster 集群配置 type Cluster struct { - ID int `json:"id"` - Name string `json:"name"` - Title string `json:"title"` - Note string `json:"note"` - NodeCount int `json:"nodeCount"` + ID int `json:"id"` + Name string `json:"name"` + Title string `json:"title"` + Note string `json:"note"` + NodeCount int `json:"nodeCount"` + Redis *ClusterRedis `json:"redis"` +} + +//ClusterRedis 集群redis配置 +type ClusterRedis struct { + Mode string `json:"mode" yaml:"mode"` + Addrs string `json:"addrs" yaml:"addrs"` + DbIndex int `json:"dbIndex" yaml:"dbIndex"` + Masters string `json:"masters" yaml:"masters"` + Password string `json:"password" yaml:"password"` +} + +//GetMode 获取redis模式 +func (c ClusterRedis) GetMode() string { + return c.Mode +} + +//GetAddrs 获取地址 +func (c ClusterRedis) GetAddrs() []string { + return strings.Split(c.Addrs, ",") +} + +//GetMasters 或者masters +func (c ClusterRedis) GetMasters() []string { + return strings.Split(c.Masters, ",") +} + +//GetDbIndex 获取所有 +func (c ClusterRedis) GetDbIndex() int { + return c.DbIndex +} + +//GetPassword 获取密码 +func (c ClusterRedis) GetPassword() string { + return c.Password } diff --git a/server/entity/console-entity/gateway.go b/server/entity/console-entity/gateway.go new file mode 100644 index 00000000..e0b4308a --- /dev/null +++ b/server/entity/console-entity/gateway.go @@ -0,0 +1,10 @@ +package entity + +//GatewayBasicConfig 网关基础配置 +type GatewayBasicConfig struct { + SuccessCode string `json:"successCode"` + NodeUpdatePeriod int `json:"nodeUpdatePeriod"` + MonitorUpdatePeriod int `json:"monitorUpdatePeriod"` + MonitorTimeout int `json:"monitorTimeout"` + SkipCertificate int `json:"skipCertificate"` +} diff --git a/server/entity/console-entity/node.go b/server/entity/console-entity/node.go index af1493c9..d3c1ed16 100644 --- a/server/entity/console-entity/node.go +++ b/server/entity/console-entity/node.go @@ -18,14 +18,15 @@ type Node struct { CreateTime string `json:"createTime"` UpdateTime string `json:"updateTime"` UpdatePeriod int `json:"updatePeriod,omitempty"` - //*SSHInfo + *SSHInfo } -//type SSHInfo struct { -// SSHPort string `json:"sshPort"` -// UserName string `json:"userName"` -// Password string `json:"password"` -// -// Key string `json:"key"` -// AuthMethod int `json:"authMethod"` -//} +//SSHInfo sshInfo +type SSHInfo struct { + SSHAddress string `json:"sshAddress"` + UserName string `json:"sshUserName"` + Password string `json:"sshPassword"` + Key string `json:"sshKey"` + AuthMethod int `json:"authMethod"` + IsSave int `json:"isSave"` +} diff --git a/server/entity/console-entity/redis.go b/server/entity/console-entity/redis.go index dfc7959f..be3767f0 100644 --- a/server/entity/console-entity/redis.go +++ b/server/entity/console-entity/redis.go @@ -2,6 +2,7 @@ package entity //RedisNode redis节点 type RedisNode struct { + ID int Server string Password string ClusterID int diff --git a/server/entity/console-entity/strategy.go b/server/entity/console-entity/strategy.go index 7e2ee8ed..3aef1bf2 100644 --- a/server/entity/console-entity/strategy.go +++ b/server/entity/console-entity/strategy.go @@ -11,4 +11,6 @@ type Strategy struct { GroupName string `json:"groupName,omitempty"` EnableStatus int `json:"enableStatus"` StrategyType int `json:"strategyType"` + Updater string `json:"updater"` + Creater string `json:"creater"` } diff --git a/server/entity/redis_config.go b/server/entity/redis_config.go index cf8388be..9356433d 100644 --- a/server/entity/redis_config.go +++ b/server/entity/redis_config.go @@ -1,30 +1 @@ package entity - -import ( - "strings" -) - -//GetMode 获取redis使用模式 -func (c CLusterRedis) GetMode() string { - return c.Mode -} - -//GetAddrs 获取地址 -func (c CLusterRedis) GetAddrs() []string { - return strings.Split(c.Addrs, ",") -} - -//GetMasters 获取master -func (c CLusterRedis) GetMasters() []string { - return strings.Split(c.Masters, ",") -} - -//GetDbIndex 获取数据库序号 -func (c CLusterRedis) GetDbIndex() int { - return c.DbIndex -} - -//GetPassword 获取密码 -func (c CLusterRedis) GetPassword() string { - return c.Password -} diff --git a/server/entity/smtp.go b/server/entity/smtp.go new file mode 100644 index 00000000..ce6e27d2 --- /dev/null +++ b/server/entity/smtp.go @@ -0,0 +1,11 @@ +package entity + +//SMTPInfo SMTP信息 +type SMTPInfo struct { + Address string `json:"address"` + Port int `json:"port"` + Protocol int `json:"protocol"` + Sender string `json:"sender"` + Account string `json:"account"` + Password string `json:"password"` +} diff --git a/utils/function.go b/utils/function.go index 37b6d4a9..3e429a0b 100644 --- a/utils/function.go +++ b/utils/function.go @@ -14,6 +14,35 @@ import ( "time" ) +//ConvertIntArrayToString 转换整型数组 +func ConvertIntArrayToString(ids []int) string { + idLen := len(ids) + if idLen < 1 { + return "" + } + idStr := "" + for i, id := range ids { + idStr += strconv.Itoa(id) + if i < idLen-1 { + idStr += "," + } + } + return idStr +} + +//ConvertArray 将[]string转为[]int +func ConvertArray(arr []string) (bool, []int) { + result := make([]int, 0) + for _, i := range arr { + res, err := strconv.Atoi(i) + if err != nil { + return false, result + } + result = append(result, res) + } + return true, result +} + //ValidateRemoteAddr 判断ip端口是否合法 func ValidateRemoteAddr(ip string) bool { match, err := regexp.MatchString(`^(?:(?:1[0-9][0-9]\.)|(?:2[0-4][0-9]\.)|(?:25[0-5]\.)|(?:[1-9][0-9]\.)|(?:[0-9]\.)){3}(?:(?:1[0-9][0-9])|(?:2[0-4][0-9])|(?:25[0-5])|(?:[1-9][0-9])|(?:[0-9]))\:(([0-9])|([1-9][0-9]{1,3})|([1-6][0-9]{0,4}))$`, ip) @@ -23,16 +52,28 @@ func ValidateRemoteAddr(ip string) bool { return match } -//InterceptIP 获取IP -func InterceptIP(str, substr string) string { +//ValidateURL 判断ip端口是否合法 +func ValidateURL(url string) bool { + match, err := regexp.MatchString(`^/(([a-zA-Z][0-9a-zA-Z+\-\.]*:)?/{0,2}[0-9a-zA-Z;/?:@&=+$\.\-_!~*'()%]+)?(#[0-9a-zA-Z;/?:@&=+$\.\-_!~*'()%]+)?$`, url) + if err != nil { + return false + } + return match +} + +//Intercept 获取IP +func Intercept(str, substr string) (string, string) { result := strings.Index(str, substr) var rs string + var bs string if result != -1 { rs = str[:result] + bs = str[result+1:] } else { rs = str + bs = str } - return rs + return rs, bs } //Md5 md5加密 diff --git a/utils/json.go b/utils/json.go new file mode 100644 index 00000000..3ae10fd1 --- /dev/null +++ b/utils/json.go @@ -0,0 +1,20 @@ +package utils + +import ( + "fmt" + + "github.com/robertkrimen/otto" +) + +//JSObjectToJSON 将js对象转为json +func JSObjectToJSON(s string) ([]byte, error) { + vm := otto.New() + v, err := vm.Run(fmt.Sprintf(` + cs = %s + JSON.stringify(cs) +`, s)) + if err != nil { + return nil, err + } + return []byte(v.String()), nil +} diff --git a/utils/mail.go b/utils/mail.go index 05ae12f5..6adda598 100644 --- a/utils/mail.go +++ b/utils/mail.go @@ -2,118 +2,134 @@ package utils import ( "crypto/tls" - "net" - "net/smtp" - "strings" + "fmt" - log "github.com/eolinker/goku-api-gateway/goku-log" + "github.com/eolinker/goku-api-gateway/server/entity" + + "gopkg.in/gomail.v2" ) -//SendToMail 发送邮件 -func SendToMail(user, password, host, to, subject, body, mailtype, smtpProtocol string) error { - hp := strings.Split(host, ":") - auth := smtp.PlainAuth("", user, password, hp[0]) - sendTO := strings.Split(to, ",") - if len(sendTO) < 2 { - if sendTO[0] == "" { - return nil - } - } - log.Debug(user, password, auth) - var contentType string - if mailtype == "html" { - contentType = "Content-Type: text/" + mailtype + "; charset=UTF-8" - } else { - contentType = "Content-Type: text/plain" + "; charset=UTF-8" - } - var err error - msg := []byte("To: " + to + "\r\nFrom: " + user + ">\r\nSubject: " + subject + "\r\n" + contentType + "\r\n\r\n" + body) - log.Debug("SendToMail", msg) - if smtpProtocol != "0" { - err = SendMailUsingTLS( - host, - auth, - user, - sendTO, - msg, - ) - if err != nil { +//SendMails 发送邮件 +func SendMails(smtpInfo entity.SMTPInfo, mailTo []string, subject string, body string) error { - err = SendMailUsingTLS( - host, - nil, - user, - sendTO, - msg, - ) + m := gomail.NewMessage() + m.SetHeader("From", fmt.Sprintf("%s<%s>", smtpInfo.Sender, smtpInfo.Account)) + m.SetHeader("To", mailTo...) + m.SetHeader("Subject", subject) + m.SetBody("text/html", body) - } - } else { - err = smtp.SendMail(host, auth, user, sendTO, msg) - if err != nil { - err = smtp.SendMail(host, nil, user, sendTO, msg) - } - } + d := gomail.NewDialer(smtpInfo.Address, smtpInfo.Port, smtpInfo.Account, smtpInfo.Password) + d.TLSConfig = &tls.Config{InsecureSkipVerify: true} + var err error + err = d.DialAndSend(m) return err } -//Dial return a smtp client -func Dial(addr string) (*smtp.Client, error) { - conn, err := tls.Dial("tcp", addr, nil) - if err != nil { - return nil, err - } - //分解主机端口字符串 - host, _, _ := net.SplitHostPort(addr) - return smtp.NewClient(conn, host) -} - -//SendMailUsingTLS 参考net/smtp的func SendMail() -//使用net.Dial连接tls(ssl)端口时,smtp.NewClient()会卡住且不提示err -//len(to)>1时,to[1]开始提示是密送 -func SendMailUsingTLS(addr string, auth smtp.Auth, from string, - to []string, msg []byte) (err error) { - - //create smtp client - c, err := Dial(addr) - if err != nil { - log.Error("Create smpt client error:", err) - return err - } - defer c.Close() - - if auth != nil { - if ok, _ := c.Extension("AUTH"); ok { - if err = c.Auth(auth); err != nil { - log.Error("Error during AUTH", err) - return err - } - } - } - - if err = c.Mail(from); err != nil { - return err - } - - for _, addr := range to { - if err = c.Rcpt(addr); err != nil { - return err - } - } - - w, err := c.Data() - if err != nil { - return err - } - - _, err = w.Write(msg) - if err != nil { - return err - } - - err = w.Close() - if err != nil { - return err - } - return c.Quit() -} +////SendToMail 发送邮件 +//func SendToMail(user, password, host, to, subject, body, mailtype, smtpProtocol string) error { +// hp := strings.Split(host, ":") +// auth := smtp.PlainAuth("", user, password, hp[0]) +// sendTO := strings.Split(to, ",") +// if len(sendTO) < 2 { +// if sendTO[0] == "" { +// return nil +// } +// } +// log.Debug(user, password, auth) +// var contentType string +// if mailtype == "html" { +// contentType = "Content-Type: text/" + mailtype + "; charset=UTF-8" +// } else { +// contentType = "Content-Type: text/plain" + "; charset=UTF-8" +// } +// var err error +// msg := []byte("To: " + to + "\r\nFrom: " + user + ">\r\nSubject: " + subject + "\r\n" + contentType + "\r\n\r\n" + body) +// log.Debug("SendToMail", msg) +// if smtpProtocol != "0" { +// err = SendMailUsingTLS( +// host, +// auth, +// user, +// sendTO, +// msg, +// ) +// if err != nil { +// +// err = SendMailUsingTLS( +// host, +// nil, +// user, +// sendTO, +// msg, +// ) +// +// } +// } else { +// err = smtp.SendMail(host, auth, user, sendTO, msg) +// if err != nil { +// err = smtp.SendMail(host, nil, user, sendTO, msg) +// } +// } +// return err +//} +// +////Dial return a smtp client +//func Dial(addr string) (*smtp.Client, error) { +// conn, err := tls.Dial("tcp", addr, nil) +// if err != nil { +// return nil, err +// } +// //分解主机端口字符串 +// host, _, _ := net.SplitHostPort(addr) +// return smtp.NewClient(conn, host) +//} +// +////SendMailUsingTLS 参考net/smtp的func SendMail() +////使用net.Dial连接tls(ssl)端口时,smtp.NewClient()会卡住且不提示err +////len(to)>1时,to[1]开始提示是密送 +//func SendMailUsingTLS(addr string, auth smtp.Auth, from string, +// to []string, msg []byte) (err error) { +// +// //create smtp client +// c, err := Dial(addr) +// if err != nil { +// log.Error("Create smpt client error:", err) +// return err +// } +// defer c.Close() +// +// if auth != nil { +// if ok, _ := c.Extension("AUTH"); ok { +// if err = c.Auth(auth); err != nil { +// log.Error("Error during AUTH", err) +// return err +// } +// } +// } +// +// if err = c.Mail(from); err != nil { +// return err +// } +// +// for _, addr := range to { +// if err = c.Rcpt(addr); err != nil { +// return err +// } +// } +// +// w, err := c.Data() +// if err != nil { +// return err +// } +// +// _, err = w.Write(msg) +// if err != nil { +// return err +// } +// +// err = w.Close() +// if err != nil { +// return err +// } +// return c.Quit() +//} diff --git a/utils/sftp.go b/utils/sftp.go new file mode 100644 index 00000000..801de4fe --- /dev/null +++ b/utils/sftp.go @@ -0,0 +1,128 @@ +package utils + +import ( + "fmt" + "os" + "path" + + "github.com/pkg/sftp" + + "golang.org/x/crypto/ssh" +) + +//SftpClient sftp客户端 +type SftpClient struct { + client *sftp.Client + passSize int64 + totalSize int64 + finish chan error +} + +//NewSftpClient new sftp客户端 +func NewSftpClient(client *ssh.Client) (*SftpClient, error) { + sc, err := SftpConnect(client) + if err != nil { + return nil, err + } + return &SftpClient{ + client: sc, + passSize: 0, + totalSize: 0, + finish: make(chan error), + }, nil +} + +//ScpCopy scp复制 +func (s *SftpClient) ScpCopy(localFilePath, remoteDir string) error { + var ( + err error + ) + + srcFile, err := os.Open(localFilePath) + if err != nil { + s.finish <- err + return err + } + defer srcFile.Close() + fInfo, err := srcFile.Stat() + if err != nil { + s.finish <- err + return err + } + s.totalSize = fInfo.Size() + + var remoteFileName = path.Base(localFilePath) + tmpFile := path.Join(remoteDir, fmt.Sprintf("%s%s", remoteFileName, ".tmp")) + + dstFile, err := s.client.Create(tmpFile) + if err != nil { + s.finish <- err + return err + } + defer dstFile.Close() + fmt.Println(dstFile.ReadFrom(srcFile)) + + _, err = dstFile.ReadFrom(srcFile) + if err != nil { + s.finish <- err + return err + } + s.client.Rename(tmpFile, path.Join(remoteDir, remoteFileName)) + s.finish <- nil + + return nil +} + +//GetProcess GetProcess +func (s *SftpClient) GetProcess() string { + if s.totalSize == 0 { + return "0.00" + } + return fmt.Sprintf("%.2f", float64(s.passSize)*100/float64(s.totalSize)) +} + +//CheckPathIsExisted CheckPathIsExisted +func (s *SftpClient) CheckPathIsExisted(path string) error { + _, err := s.client.Stat(path) + return err +} + +//Finish Finish +func (s *SftpClient) Finish() error { + //period := time.Duration(5) * time.Second + //t := time.NewTicker(period) + //for { + // select { + // case <-t.C: + // { + // fmt.Println(s.GetProcess()) + // } + // case err := <-s.finish: + // { + // fmt.Println("100.00") + // return err + // } + // } + //} + return <-s.finish +} + +//Close Close +func (s *SftpClient) Close() error { + close(s.finish) + return s.client.Close() +} + +//SftpConnect SftpConnect +func SftpConnect(client *ssh.Client) (*sftp.Client, error) { + var ( + sftpClient *sftp.Client + err error + ) + // create sftp client + if sftpClient, err = sftp.NewClient(client); err != nil { + return nil, err + } + + return sftpClient, nil +} diff --git a/utils/ssh.go b/utils/ssh.go index 09a463ba..28a85772 100644 --- a/utils/ssh.go +++ b/utils/ssh.go @@ -9,15 +9,14 @@ import ( // "io/ioutil" ) -//Connect SSH连接 -func Connect(user, password, host, key string, port int, cipherList []string) (*ssh.Session, error) { +//SSHClient SSHClient +func SSHClient(user, password, host, key string, port int, cipherList []string) (*ssh.Client, error) { var ( auth []ssh.AuthMethod addr string clientConfig *ssh.ClientConfig client *ssh.Client config ssh.Config - session *ssh.Session err error ) // get auth method @@ -65,7 +64,15 @@ func Connect(user, password, host, key string, port int, cipherList []string) (* if client, err = ssh.Dial("tcp", addr, clientConfig); err != nil { return nil, err } + return client, nil +} +//SessionConnect SessionConnect +func SessionConnect(client *ssh.Client) (*ssh.Session, error) { + var ( + session *ssh.Session + err error + ) // create session if session, err = client.NewSession(); err != nil { return nil, err -- GitLab