├── .editorconfig ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.yml │ ├── config.yml │ ├── docs_issue.yml │ ├── feature_request.yml │ └── request_help.yml ├── PULL_REQUEST_TEMPLATE.md └── workflows │ └── actions.yaml ├── .gitignore ├── .goreleaser.yaml ├── CODE_OF_CONDUCT.md ├── CODE_OF_CONDUCT_EN.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── README_EN.md ├── ai-convert ├── convert.go ├── key.go ├── label.go ├── manager.go ├── mapping.go ├── message.go ├── node.go ├── openai.go ├── provider.go └── status.go ├── app ├── .gitignore └── apinto │ ├── .gitignore │ ├── admin.go │ ├── driver.go │ ├── helper.go │ ├── log.go │ ├── main.go │ ├── master.go │ ├── plugin.go │ ├── profession.go │ ├── work │ └── logs │ │ └── read_log_test.go │ └── worker.go ├── application ├── app.go ├── auth │ ├── aksk │ │ ├── aksk.go │ │ ├── config.go │ │ ├── factory.go │ │ ├── sign.go │ │ └── sign_test.go │ ├── apikey │ │ ├── apikey.go │ │ ├── config.go │ │ └── factory.go │ ├── basic │ │ ├── basic.go │ │ ├── config.go │ │ └── factory.go │ ├── factory.go │ ├── jwt │ │ ├── config.go │ │ ├── factory.go │ │ ├── jwt.go │ │ └── verify.go │ ├── oauth2 │ │ ├── config.go │ │ ├── factory.go │ │ ├── hash.go │ │ ├── hash_test.go │ │ ├── manager.go │ │ └── oauth2.go │ ├── openid-connect-jwt │ │ ├── config.go │ │ ├── discovery.go │ │ ├── factory.go │ │ ├── handler.go │ │ ├── jwt.go │ │ ├── manager.go │ │ ├── token.go │ │ └── verify.go │ ├── para-hmac │ │ ├── config.go │ │ ├── executor.go │ │ ├── factory.go │ │ ├── sign.go │ │ └── sign_test.go │ └── register.go ├── token.go └── user.go ├── build ├── .gitignore ├── cmd │ ├── .gitignore │ ├── Dockerfile │ ├── build.sh │ ├── common.sh │ ├── docker_build.sh │ ├── docker_publish.sh │ ├── package.sh │ └── qiniu_publish.sh └── resources │ ├── Dockerfile │ ├── apinto.yml.tpl │ ├── auto-join.sh │ ├── auto-start.sh │ ├── check_remove.sh │ ├── config.yml.k8s.tpl │ ├── config.yml.tpl │ ├── install.sh │ ├── join.sh │ ├── join.sh.bak │ ├── leave.sh │ └── start.sh ├── certs └── cert.go ├── checker ├── checkType.go ├── checker-all.go ├── checker-equal.go ├── checker-exist.go ├── checker-none.go ├── checker-notequal.go ├── checker-prefix.go ├── checker-regex.go ├── checker-regex_test.go ├── checker-sub.go ├── checker-suffix.go ├── checker.go ├── checker_test.go ├── checker_usage.md └── multiple.go ├── discovery ├── app.go ├── check.go ├── discovery.go ├── node.go └── nodes.go ├── drivers ├── .gitignore ├── ai-key │ ├── config.go │ ├── executor.go │ ├── factory.go │ └── key.go ├── ai-model │ ├── config.go │ ├── executor.go │ └── factory.go ├── ai-provider │ ├── authropic │ │ └── authropic.go │ ├── baichuan │ │ └── baichuan.go │ ├── bailianyun │ │ └── bailianyun.go │ ├── bedrock │ │ ├── bedrock.go │ │ ├── message.go │ │ └── sign_test.go │ ├── chatglm │ │ └── chatglm.go │ ├── cohere │ │ └── cohere.go │ ├── config.go │ ├── customize-openai │ │ └── customize-openai.go │ ├── deepseek │ │ └── deepseek.go │ ├── executor.go │ ├── factory.go │ ├── fakegpt │ │ └── fakegpt.go │ ├── fireworks │ │ └── fireworks.go │ ├── google │ │ └── gemini.go │ ├── groq │ │ └── groq.go │ ├── hugging-face │ │ └── hugging_face.go │ ├── hunyuan │ │ └── hunyuan.go │ ├── init.go │ ├── lm-studio │ │ └── lm-studio.go │ ├── local-model │ │ └── local.go │ ├── mapping.go │ ├── minimax │ │ ├── message.go │ │ └── minimax.go │ ├── mistralai │ │ └── mistralai.go │ ├── moonshot │ │ └── moonshot.go │ ├── novita │ │ └── novita.go │ ├── nvidia │ │ └── nvidia.go │ ├── ollama │ │ └── ollama.go │ ├── openAI │ │ ├── openai.go │ │ └── openai_test.go │ ├── openrouter │ │ └── openrouter.go │ ├── perfxcloud │ │ └── perfxcloud.go │ ├── siliconflow │ │ └── siliconflow.go │ ├── spark │ │ └── spark.go │ ├── stepfun │ │ └── stepfun.go │ ├── tongyi │ │ └── tongyi.go │ ├── upstage │ │ └── upstage.go │ ├── vertex_ai │ │ └── vertex_ai.go │ ├── volcengine_maas │ │ └── openai.go │ ├── wenxin │ │ └── wenxin.go │ ├── xinference │ │ └── xinference.go │ ├── yi │ │ └── yi.go │ ├── zhinao │ │ └── zhinao.go │ └── zhipuai │ │ └── zhipu.go ├── app │ ├── app.go │ ├── config.go │ ├── driver.go │ ├── executor.go │ ├── extend-param.go │ ├── factory.go │ └── manager │ │ ├── app.go │ │ └── manager.go ├── certs │ ├── config.go │ ├── controller.go │ ├── driver.go │ ├── factory.go │ └── worker.go ├── discovery │ ├── consul │ │ ├── clients.go │ │ ├── config.go │ │ ├── consul.go │ │ ├── consul_test.go │ │ ├── driver.go │ │ └── factory.go │ ├── eureka │ │ ├── client.go │ │ ├── config.go │ │ ├── driver.go │ │ ├── eureka.go │ │ ├── eureka_request.go │ │ ├── eureka_test.go │ │ └── factory.go │ ├── nacos │ │ ├── client.go │ │ ├── config.go │ │ ├── driver.go │ │ ├── factory.go │ │ ├── nacos.go │ │ └── nacos_test.go │ ├── polaris │ │ ├── clients.go │ │ ├── config.go │ │ ├── driver.go │ │ ├── factory.go │ │ ├── polaris.go │ │ └── polaris_test.go │ └── static │ │ ├── config.go │ │ ├── driver.go │ │ ├── factory.go │ │ ├── heath.go │ │ └── static.go ├── generics.go ├── output │ ├── fileoutput │ │ ├── config.go │ │ ├── driver.go │ │ ├── error.go │ │ ├── factory.go │ │ ├── output.go │ │ └── write.go │ ├── httpoutput │ │ ├── config.go │ │ ├── driver.go │ │ ├── error.go │ │ ├── factory.go │ │ ├── http.go │ │ └── output.go │ ├── kafka │ │ ├── config.go │ │ ├── driver.go │ │ ├── factory.go │ │ ├── kafka_test.go │ │ ├── output.go │ │ ├── producer.go │ │ └── sarama_client.go │ ├── loki │ │ ├── config.go │ │ ├── factory.go │ │ ├── output.go │ │ └── output_test.go │ ├── nsq │ │ ├── config.go │ │ ├── driver.go │ │ ├── error.go │ │ ├── factory.go │ │ ├── output.go │ │ ├── pool.go │ │ └── write.go │ ├── prometheus │ │ ├── check.go │ │ ├── config.go │ │ ├── driver.go │ │ ├── error.go │ │ ├── factory.go │ │ ├── metrics.go │ │ └── output.go │ └── syslog │ │ ├── config.go │ │ ├── driver.go │ │ ├── factory.go │ │ ├── linux.go │ │ ├── output.go │ │ └── output_test.go ├── plugin-manager │ ├── config.go │ ├── factory.go │ ├── manager.go │ ├── obj.go │ └── plugin.go ├── plugins │ ├── access-log │ │ ├── config.go │ │ ├── driver.go │ │ ├── factory.go │ │ └── log.go │ ├── access-relational │ │ ├── config.go │ │ ├── driver.go │ │ ├── factory.go │ │ ├── filter.go │ │ ├── handler.go │ │ └── worker.go │ ├── acl │ │ ├── config.go │ │ ├── executor.go │ │ └── factory.go │ ├── aes │ │ ├── aes.go │ │ ├── aes_test.go │ │ ├── config.go │ │ ├── executor.go │ │ └── factory.go │ ├── ai-formatter │ │ ├── config.go │ │ ├── driver.go │ │ ├── executor.go │ │ └── factory.go │ ├── ai-prompt │ │ ├── config.go │ │ ├── driver.go │ │ ├── executor.go │ │ └── factory.go │ ├── app │ │ ├── app.go │ │ ├── config.go │ │ ├── driver.go │ │ └── factory.go │ ├── auth-interceptor │ │ ├── auth.go │ │ ├── config.go │ │ ├── factory.go │ │ └── redis-cli.go │ ├── auto-redirect │ │ ├── config.go │ │ ├── driver.go │ │ ├── factory.go │ │ ├── handler.go │ │ └── url_test.go │ ├── body-check │ │ ├── body-check.go │ │ ├── config.go │ │ └── factory.go │ ├── body-record-truncation │ │ ├── config.go │ │ ├── executor.go │ │ └── factory.go │ ├── circuit-breaker │ │ ├── breaker-info.go │ │ ├── circuit-breaker.go │ │ ├── circuit-count.go │ │ ├── config.go │ │ ├── driver.go │ │ ├── factory.go │ │ └── utils.go │ ├── cors │ │ ├── config.go │ │ ├── cors.go │ │ ├── driver.go │ │ ├── factory.go │ │ └── header.go │ ├── counter │ │ ├── callback.lua │ │ ├── config.go │ │ ├── counter.go │ │ ├── decr.lua │ │ ├── executor.go │ │ ├── factory.go │ │ ├── key.go │ │ ├── key_test.go │ │ ├── matcher │ │ │ ├── json.go │ │ │ ├── match.go │ │ │ └── statuscode.go │ │ ├── redis.go │ │ ├── script.go │ │ └── separator │ │ │ ├── count.go │ │ │ ├── empty.go │ │ │ ├── file.go │ │ │ ├── formdata.go │ │ │ └── json.go │ ├── data-transform │ │ ├── config.go │ │ ├── executor.go │ │ ├── factory.go │ │ └── utils.go │ ├── dubbo2-proxy-rewrite │ │ ├── config.go │ │ ├── driver.go │ │ ├── factory.go │ │ └── proxy-rewrite.go │ ├── dubbo2-to-http │ │ ├── complete.go │ │ ├── config.go │ │ ├── driver.go │ │ ├── factory.go │ │ ├── http.go │ │ └── to-http.go │ ├── extra-params │ │ ├── config.go │ │ ├── driver.go │ │ ├── extra-params.go │ │ ├── factory.go │ │ └── util.go │ ├── extra-params_v2 │ │ ├── config.go │ │ ├── driver.go │ │ ├── dynamic-params │ │ │ ├── concat │ │ │ │ ├── concat.go │ │ │ │ └── factory.go │ │ │ ├── datetime │ │ │ │ ├── datetime.go │ │ │ │ └── factory.go │ │ │ ├── dynamic.go │ │ │ ├── factory.go │ │ │ ├── hmac-sha256 │ │ │ │ ├── executor.go │ │ │ │ ├── executor_test.go │ │ │ │ └── factory.go │ │ │ ├── md5 │ │ │ │ ├── factory.go │ │ │ │ └── md5.go │ │ │ ├── param.go │ │ │ ├── timestamp │ │ │ │ ├── factory.go │ │ │ │ └── timestamp.go │ │ │ └── uuid │ │ │ │ ├── factory.go │ │ │ │ └── uuid.go │ │ ├── executor.go │ │ ├── factory.go │ │ └── util.go │ ├── gRPC-to-http │ │ ├── complete.go │ │ ├── config.go │ │ ├── driver.go │ │ ├── factory.go │ │ └── tohttp.go │ ├── grpc-proxy-rewrite │ │ ├── config.go │ │ ├── driver.go │ │ ├── factory.go │ │ └── proxy-rewrite.go │ ├── gzip │ │ ├── config.go │ │ ├── driver.go │ │ ├── factory.go │ │ ├── gzip.go │ │ └── gzip_test.go │ ├── http-to-dubbo2 │ │ ├── complete.go │ │ ├── config.go │ │ ├── dial.go │ │ ├── driver.go │ │ ├── factory.go │ │ └── to-dubbo2.go │ ├── http-to-gRPC │ │ ├── complete.go │ │ ├── config.go │ │ ├── descriptor.go │ │ ├── driver.go │ │ ├── factory.go │ │ ├── response.go │ │ └── toGRPC.go │ ├── http_mocking │ │ ├── complete.go │ │ ├── config.go │ │ ├── driver.go │ │ ├── factory.go │ │ └── mocking.go │ ├── ip-restriction │ │ ├── config.go │ │ ├── driver.go │ │ ├── factory.go │ │ ├── restriction.go │ │ └── restriction_test.go │ ├── js-inject │ │ ├── config.go │ │ ├── executor.go │ │ ├── factory.go │ │ └── tool.go │ ├── monitor │ │ ├── config.go │ │ ├── driver.go │ │ ├── factory.go │ │ └── monitor.go │ ├── oauth2-introspection │ │ ├── config.go │ │ ├── executor.go │ │ ├── factory.go │ │ └── introspect.go │ ├── oauth2 │ │ ├── authorize.go │ │ ├── config.go │ │ ├── executor.go │ │ ├── factory.go │ │ └── token.go │ ├── params-check-v2 │ │ ├── check.go │ │ ├── check_test.go │ │ ├── config.go │ │ ├── executor.go │ │ └── factory.go │ ├── params-check │ │ ├── check.go │ │ ├── check_test.go │ │ ├── config.go │ │ ├── executor.go │ │ └── factory.go │ ├── params-transformer │ │ ├── config.go │ │ ├── driver.go │ │ ├── factory.go │ │ ├── params-transformer.go │ │ └── util.go │ ├── prometheus │ │ ├── config.go │ │ ├── driver.go │ │ ├── error.go │ │ ├── factory.go │ │ └── prometheus.go │ ├── proxy-mirror │ │ ├── config.go │ │ ├── driver.go │ │ ├── error.go │ │ ├── factory.go │ │ ├── handler.go │ │ ├── mirror-service.go │ │ └── proxy-mirror.go │ ├── proxy-rewrite │ │ ├── config.go │ │ ├── driver.go │ │ ├── factory.go │ │ ├── host.go │ │ ├── proxy-rewrite.go │ │ └── util.go │ ├── proxy_rewrite_v2 │ │ ├── config.go │ │ ├── driver.go │ │ ├── factory.go │ │ ├── host.go │ │ └── proxy-rewrite2.go │ ├── rate-limiting │ │ ├── config.go │ │ ├── driver.go │ │ ├── factory.go │ │ ├── rate-limiting.go │ │ └── timer.go │ ├── request-file-parse │ │ ├── config.go │ │ ├── executor.go │ │ └── factory.go │ ├── request-interception │ │ ├── config.go │ │ ├── executor.go │ │ └── factory.go │ ├── response-file-parse │ │ ├── config.go │ │ ├── executor.go │ │ └── factory.go │ ├── response-filter │ │ ├── config.go │ │ ├── executor.go │ │ └── factory.go │ ├── response-rewrite │ │ ├── config.go │ │ ├── driver.go │ │ ├── factory.go │ │ └── response-rewrite.go │ ├── response-rewrite_v2 │ │ ├── config.go │ │ ├── executor.go │ │ ├── factory.go │ │ ├── match.go │ │ ├── rewrite.go │ │ └── rewrite_test.go │ ├── rsa-filter │ │ ├── config.go │ │ ├── executor.go │ │ ├── factory.go │ │ └── tool.go │ ├── script-handler │ │ ├── config.go │ │ ├── factory.go │ │ ├── github_com-eolinker-eosc-eocontext-http-context.go │ │ ├── github_com-eolinker-eosc-eocontext.go │ │ ├── github_com-eolinker-eosc.go │ │ ├── handler.go │ │ └── script_test.go │ └── strategy │ │ ├── cache │ │ ├── driver.go │ │ ├── factory.go │ │ └── strategy.go │ │ ├── data-mask │ │ ├── driver.go │ │ ├── factory.go │ │ └── strategy.go │ │ ├── fuse │ │ ├── driver.go │ │ ├── factory.go │ │ └── strategy.go │ │ ├── grey │ │ ├── driver.go │ │ ├── factory.go │ │ └── strategy.go │ │ ├── limiting │ │ ├── driver.go │ │ ├── factory.go │ │ └── strategy.go │ │ └── visit │ │ ├── driver.go │ │ ├── factory.go │ │ └── strategy.go ├── resources │ ├── datasource │ │ └── influxdbv2 │ │ │ ├── client.go │ │ │ ├── config.go │ │ │ ├── driver.go │ │ │ ├── error.go │ │ │ ├── factory.go │ │ │ └── output.go │ └── redis │ │ ├── cmdable.go │ │ ├── config.go │ │ ├── driver.go │ │ ├── factory.go │ │ ├── redis.go │ │ ├── vector.go │ │ └── worker.go ├── router │ ├── dubbo2-router │ │ ├── config.go │ │ ├── driver.go │ │ ├── factory.go │ │ ├── finish.go │ │ ├── handler.go │ │ ├── manager │ │ │ ├── append.go │ │ │ ├── complete.go │ │ │ ├── data.go │ │ │ ├── endpoint.go │ │ │ ├── error.go │ │ │ ├── init.go │ │ │ └── manager.go │ │ └── router.go │ ├── grpc-router │ │ ├── config.go │ │ ├── driver.go │ │ ├── factory.go │ │ ├── finish.go │ │ ├── handler.go │ │ ├── manager │ │ │ ├── append.go │ │ │ ├── complete.go │ │ │ ├── data.go │ │ │ ├── endpoint.go │ │ │ ├── init.go │ │ │ └── manager.go │ │ └── router.go │ ├── http-router │ │ ├── config.go │ │ ├── driver.go │ │ ├── finish.go │ │ ├── http-complete │ │ │ └── complete.go │ │ ├── http-handler.go │ │ ├── manager │ │ │ ├── append.go │ │ │ ├── data.go │ │ │ ├── endpoint.go │ │ │ ├── export.go │ │ │ ├── init.go │ │ │ ├── manager.go │ │ │ └── pre.go │ │ ├── register.go │ │ ├── router.go │ │ ├── stream │ │ │ └── complete.go │ │ └── websocket │ │ │ ├── complate.go │ │ │ └── dial.go │ └── listener.go ├── service │ ├── config.go │ ├── driver.go │ ├── factory.go │ ├── send_test.go │ ├── service.go │ └── worker.go ├── strategy │ ├── cache-strategy │ │ ├── actuator.go │ │ ├── cache │ │ │ └── cache.go │ │ ├── cache_valid_time.go │ │ ├── config.go │ │ ├── controller.go │ │ ├── driver.go │ │ ├── factory.go │ │ └── handler.go │ ├── data-mask-strategy │ │ ├── actuator.go │ │ ├── config.go │ │ ├── controller.go │ │ ├── driver.go │ │ ├── exector.go │ │ ├── factory.go │ │ ├── handler.go │ │ └── mask │ │ │ ├── entity.go │ │ │ ├── inner │ │ │ ├── bank-card.go │ │ │ ├── id-card.go │ │ │ ├── inner.go │ │ │ ├── inner_test.go │ │ │ ├── name.go │ │ │ └── phone.go │ │ │ ├── json-path │ │ │ ├── json-path.go │ │ │ └── json-path_test.go │ │ │ ├── keyword │ │ │ ├── keyword.go │ │ │ └── keyword_test.go │ │ │ ├── manager.go │ │ │ ├── mask.go │ │ │ ├── mask_test.go │ │ │ ├── match.go │ │ │ └── regex │ │ │ └── regex.go │ ├── fuse-strategy │ │ ├── actuator.go │ │ ├── config.go │ │ ├── controller.go │ │ ├── driver.go │ │ ├── factory.go │ │ ├── fuse.go │ │ └── handler.go │ ├── grey-strategy │ │ ├── actuator.go │ │ ├── config.go │ │ ├── controller.go │ │ ├── driver.go │ │ ├── factory.go │ │ ├── grey.go │ │ ├── handler.go │ │ ├── match-robin.go │ │ ├── match-rule.go │ │ ├── match-session.go │ │ └── round-robin.go │ ├── limiting-strategy │ │ ├── actuator-handle.go │ │ ├── actuator.go │ │ ├── config.go │ │ ├── controller.go │ │ ├── driver.go │ │ ├── factory.go │ │ ├── handler.go │ │ ├── http-handler.go │ │ ├── limiting.go │ │ └── limiting_test.go │ └── visit-strategy │ │ ├── actuator.go │ │ ├── config.go │ │ ├── controller.go │ │ ├── driver.go │ │ ├── factory.go │ │ ├── handler.go │ │ └── visit.go ├── template │ ├── config.go │ ├── driver.go │ ├── factory.go │ ├── proxy.go │ └── template.go └── transcode │ └── protobuf │ ├── config.go │ ├── driver.go │ ├── factory.go │ ├── file_test.go │ └── worker.go ├── dubbo-getty ├── client.go ├── connection.go ├── const.go ├── getty.go ├── options.go ├── server.go ├── server │ ├── config.go │ ├── getty_server.go │ ├── listener.go │ └── readwriter.go ├── session.go └── tls.go ├── encoder ├── br.go ├── encoder.go └── gzip.go ├── entries ├── ctx_key │ └── ctx_key.go ├── http-entry │ ├── entry.go │ ├── proxy-reader.go │ ├── reader-index.go │ └── reader.go ├── metric-entry │ ├── metric_entry.go │ ├── proxy-reader.go │ └── request-reader.go ├── monitor-entry │ ├── client.go │ ├── label.go │ ├── output.go │ ├── point.go │ ├── proxy-reader.go │ └── request-reader.go └── router │ └── router.go ├── example ├── dubbo2 │ ├── README.md │ ├── client │ │ ├── flag.go │ │ └── main.go │ ├── go.mod │ ├── go.sum │ ├── model │ │ └── server.go │ └── server │ │ ├── dubbogo.yaml │ │ ├── main.go │ │ └── server.go └── grpc │ ├── README.md │ ├── client │ ├── .gitignore │ ├── client.go │ ├── flag.go │ ├── main.go │ └── options.go │ ├── demo_service │ ├── msg.pb.go │ ├── service.pb.go │ ├── service.pb.gw.go │ └── service_grpc.pb.go │ ├── go.mod │ ├── go.sum │ ├── grpc.sh │ ├── msg.proto │ ├── server │ ├── .gitignore │ ├── flag.go │ ├── main.go │ └── server.go │ └── service.proto ├── go.mod ├── grpc-descriptor └── transcode.go ├── health-check-http ├── agent.go ├── config.go ├── health_check_http.png ├── health_check_http_usage.md └── http-check.go ├── monitor-manager ├── concurrent.go └── manager.go ├── node ├── .gitignore ├── dubbo2-context │ ├── context.go │ ├── proxy.go │ ├── request-reader.go │ ├── response.go │ ├── service_reader.go │ └── service_write.go ├── fasthttp-client │ ├── client.go │ ├── client_test.go │ └── dial.go ├── grpc-context │ ├── addr.go │ ├── client.go │ ├── context.go │ ├── pool.go │ ├── request.go │ ├── response.go │ └── stream.go └── http-context │ ├── body.go │ ├── clone.go │ ├── context.go │ ├── error.go │ ├── header.go │ ├── pool.go │ ├── proxy-agent.go │ ├── proxy.go │ ├── request-reader.go │ ├── response.go │ ├── uri.go │ └── websocket-context.go ├── output ├── .gitignore ├── http-transport │ ├── config.go │ ├── transporter.go │ └── writer.go ├── metrics.go └── output.go ├── plugin ├── plugin.go ├── plugin_test.go └── plugins.go ├── resources ├── cache-local.go ├── cache-local_test.go ├── cache.go ├── cache_test.go ├── metrics.go ├── vector-local.go └── vector.go ├── router ├── dubbo2-router │ ├── append.go │ ├── matcher.go │ └── rule.go ├── grpc-router │ ├── append.go │ ├── matcher.go │ └── rule.go ├── http-router │ ├── append.go │ ├── append_test.go │ ├── matcher.go │ ├── rule.go │ └── rule_test.go ├── match.go └── rule.go ├── scope-manager ├── auto.go ├── manager.go └── proxy.go ├── service └── service.go ├── strategy ├── checker.go ├── filter.go ├── manager.go └── strategy.go ├── template └── template.go ├── upstream ├── balance │ └── balance.go ├── ip-hash │ └── ip_hash.go ├── round-robin │ ├── round_robin.go │ └── round_robin_test.go └── session-keep │ └── balance.go └── utils ├── aes.go ├── aes_test.go ├── clone ├── block.go ├── conn.go ├── conn_test.go └── reader.go ├── encode.go ├── float.go ├── function.go ├── function_test.go ├── globalID ├── uuid.go └── uuid_test.go ├── header.go ├── hmac.go ├── int.go ├── json.go ├── json_test.go ├── map.go ├── must.go ├── queue └── queue.go ├── regex.go ├── response └── response.go ├── scan.go ├── sftp.go ├── ssh.go ├── string.go ├── version.go └── version └── version.go /.editorconfig: -------------------------------------------------------------------------------- 1 | [*] 2 | indent_style = tab 3 | indent_size = 2 4 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: APINTO Discussion Forum 4 | url: https://github.com/eolinker/apinto/discussions 5 | about: Please ask and answer questions here. -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.yml: -------------------------------------------------------------------------------- 1 | name: "Feature Request" 2 | description: Suggest an enhancement to APINTO. 3 | title: "feat: As a user, I want to ..., so that ..." 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: | 8 | _The more information you share, the faster we can help you._ 9 | 10 | Prior to opening the issue, please make sure that you: 11 | 12 | - Use English to communicate. 13 | - Search the [open issues](https://github.com/eolinker/apinto/issues) and [discussion forum](https://github.com/eolinker/apinto/discussions) to avoid duplicating the issue. 14 | 15 | - type: textarea 16 | id: description 17 | attributes: 18 | label: Description 19 | description: Describe the feature you would like to see. 20 | placeholder: | 21 | As a user, I want to ..., so that... 22 | validations: 23 | required: true -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | 8 | # Test binary, built with `go test -c` 9 | *.test 10 | 11 | # Output of the go coverage tool, specifically when used with LiteIDE 12 | *.out 13 | /out/ 14 | # Dependency directories (remove the comment below to include it) 15 | # vendor/ 16 | /.idea/ 17 | .vscode 18 | /vendor/ 19 | /go.sum 20 | *.DS_Store 21 | /dist/ 22 | .gitlab-ci.yml 23 | /outer/ 24 | .env 25 | -------------------------------------------------------------------------------- /ai-convert/convert.go: -------------------------------------------------------------------------------- 1 | package ai_convert 2 | 3 | import "github.com/eolinker/eosc/eocontext" 4 | 5 | type IConverterFactory interface { 6 | Create(cfg string) (IConverter, error) 7 | } 8 | 9 | type IConverterCreateFunc func(cfg string) (IConverter, error) 10 | 11 | type IConverter interface { 12 | RequestConvert(ctx eocontext.EoContext, extender map[string]interface{}) error 13 | ResponseConvert(ctx eocontext.EoContext) error 14 | } 15 | 16 | type IChildConverter interface { 17 | IConverter 18 | Endpoint() string 19 | } 20 | type FGenerateConfig func(cfg string) (map[string]interface{}, error) 21 | 22 | func CheckKeySourceSkill(skill string) bool { 23 | return skill == "github.com/eolinker/apinto/convert.key.IKeyResource" 24 | } 25 | 26 | func CheckProviderSkill(skill string) bool { 27 | return skill == "github.com/eolinker/apinto/convert.provider.IProvider" 28 | } 29 | -------------------------------------------------------------------------------- /ai-convert/key.go: -------------------------------------------------------------------------------- 1 | package ai_convert 2 | 3 | type IKeyResource interface { 4 | ID() string 5 | Health() bool 6 | Priority() int 7 | // Up 上线 8 | Up() 9 | // Down 下线 10 | Down() 11 | 12 | IsBreaker() bool 13 | // Breaker 熔断 14 | Breaker() 15 | 16 | IConverter 17 | } 18 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /debug/ 2 | /demo/ 3 | -------------------------------------------------------------------------------- /app/apinto/.gitignore: -------------------------------------------------------------------------------- 1 | /eosc-*/ 2 | apinto* 3 | *.log 4 | /export/ 5 | /runtime_config/ 6 | /apinto 7 | /tmp/ 8 | /tmp_bak/ 9 | /logs/ 10 | /.scannerwork/ 11 | /config.yml 12 | /tmp_apinto/ 13 | /tmp_apipark/ 14 | -------------------------------------------------------------------------------- /app/apinto/admin.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/eolinker/eosc/log" 5 | process_admin "github.com/eolinker/eosc/process-admin" 6 | ) 7 | 8 | func ProcessAdmin() { 9 | log.Debug("start admin") 10 | registerInnerExtenders() 11 | process_admin.Process() 12 | } 13 | -------------------------------------------------------------------------------- /app/apinto/helper.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | helper "github.com/eolinker/eosc/process-helper" 5 | ) 6 | 7 | func ProcessHelper() { 8 | registerInnerExtenders() 9 | helper.Process() 10 | } 11 | -------------------------------------------------------------------------------- /app/apinto/log.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "os" 5 | 6 | "github.com/eolinker/eosc/env" 7 | "github.com/eolinker/eosc/log" 8 | ) 9 | 10 | func InitCLILog() { 11 | formatter := &log.LineFormatter{ 12 | TimestampFormat: "2006-01-02 15:04:05", 13 | CallerPrettyfier: nil, 14 | } 15 | level, err := log.ParseLevel(env.ErrorLevel()) 16 | if err != nil { 17 | level = log.InfoLevel 18 | } 19 | 20 | transport := log.NewTransport(os.Stdout, level) 21 | transport.SetFormatter(formatter) 22 | log.Reset(transport) 23 | } 24 | -------------------------------------------------------------------------------- /app/apinto/master.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | process_master "github.com/eolinker/eosc/process-master" 5 | ) 6 | 7 | func ProcessMaster() { 8 | handler := &process_master.MasterHandler{ 9 | InitProfession: ApintoProfession, 10 | } 11 | process_master.ProcessDo(handler) 12 | } 13 | -------------------------------------------------------------------------------- /app/apinto/worker.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/eolinker/eosc" 5 | "github.com/eolinker/eosc/extends" 6 | process_worker "github.com/eolinker/eosc/process-worker" 7 | ) 8 | 9 | func ProcessWorker() { 10 | registerInnerExtenders() 11 | process_worker.Process() 12 | } 13 | func registerInnerExtenders() { 14 | extends.AddInnerExtendProject("eolinker.com", "apinto", Register) 15 | } 16 | 17 | func Register(extenderRegister eosc.IExtenderDriverRegister) { 18 | driverRegister(extenderRegister) 19 | pluginRegister(extenderRegister) 20 | } 21 | -------------------------------------------------------------------------------- /application/auth/aksk/config.go: -------------------------------------------------------------------------------- 1 | package aksk 2 | 3 | import "github.com/eolinker/apinto/application" 4 | 5 | type Config struct { 6 | application.Auth 7 | Users []*User `json:"users" label:"用户列表"` 8 | } 9 | 10 | type User struct { 11 | Pattern Pattern `json:"pattern" label:"用户信息"` 12 | application.User 13 | } 14 | 15 | type Pattern struct { 16 | AK string `json:"ak" label:"AK"` 17 | SK string `json:"sk" label:"SK"` 18 | } 19 | 20 | func (u *User) Username() string { 21 | return u.Pattern.AK 22 | } 23 | -------------------------------------------------------------------------------- /application/auth/apikey/config.go: -------------------------------------------------------------------------------- 1 | package apikey 2 | 3 | import "github.com/eolinker/apinto/application" 4 | 5 | type Config struct { 6 | application.Auth 7 | Users []*User `json:"users" label:"用户列表"` 8 | } 9 | 10 | type User struct { 11 | Pattern Pattern `json:"pattern" label:"用户信息"` 12 | application.User 13 | } 14 | 15 | type Pattern struct { 16 | Apikey string `json:"apikey" label:"Apikey"` 17 | } 18 | 19 | func (u *User) Username() string { 20 | return u.Pattern.Apikey 21 | } 22 | -------------------------------------------------------------------------------- /application/auth/basic/config.go: -------------------------------------------------------------------------------- 1 | package basic 2 | 3 | import "github.com/eolinker/apinto/application" 4 | 5 | type Config struct { 6 | application.Auth 7 | Users []*User `json:"users" label:"用户列表"` 8 | } 9 | 10 | type User struct { 11 | Pattern Pattern `json:"pattern" label:"用户信息"` 12 | application.User 13 | } 14 | 15 | type Pattern struct { 16 | Username string `json:"username" label:"用户名"` 17 | Password string `json:"password" label:"密码"` 18 | } 19 | 20 | func (u *User) Username() string { 21 | return u.Pattern.Username 22 | } 23 | -------------------------------------------------------------------------------- /application/auth/oauth2/config.go: -------------------------------------------------------------------------------- 1 | package oauth2 2 | 3 | import "github.com/eolinker/apinto/application" 4 | 5 | type Config struct { 6 | application.Auth 7 | Users []*User `json:"users" label:"用户列表"` 8 | } 9 | 10 | type User struct { 11 | Pattern Pattern `json:"pattern" label:"用户信息"` 12 | application.User 13 | } 14 | 15 | type Pattern struct { 16 | ClientId string `json:"client_id" label:"客户端ID"` 17 | ClientSecret string `json:"client_secret" label:"客户端密钥"` 18 | ClientType string `json:"client_type" label:"客户端类型" enum:"public,confidential"` 19 | HashSecret bool `json:"hash_secret" label:"是否Hash加密"` 20 | RedirectUrls []string `json:"redirect_urls" label:"重定向URL列表"` 21 | } 22 | 23 | func (u *User) Username() string { 24 | return u.Pattern.ClientId 25 | } 26 | -------------------------------------------------------------------------------- /application/auth/oauth2/hash_test.go: -------------------------------------------------------------------------------- 1 | package oauth2 2 | 3 | import "testing" 4 | 5 | func TestHash(t *testing.T) { 6 | data := "$pbkdf2-sha512$i=10000,l=32$7BGLyS03BLF+F+M01p7MBg$OTAR1PTJpXzCVBfRq3VcGXYlSeRD2IUEzk/RsRQwfwI" 7 | 8 | _, err := extractHashRule(data) 9 | if err != nil { 10 | t.Fatal(err) 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /application/auth/openid-connect-jwt/config.go: -------------------------------------------------------------------------------- 1 | package openid_connect_jwt 2 | 3 | import ( 4 | "encoding/base64" 5 | 6 | "github.com/eolinker/apinto/application" 7 | ) 8 | 9 | type Config struct { 10 | application.Auth 11 | Users []*User `json:"users" label:"用户列表"` 12 | } 13 | 14 | type User struct { 15 | Pattern Pattern `json:"pattern" label:"用户信息"` 16 | application.User 17 | } 18 | 19 | type Pattern struct { 20 | Issuer string `json:"issuer"` 21 | AuthenticatedGroupsClaim []string `json:"authenticated_groups_claim"` 22 | } 23 | 24 | func (u *User) Username() string { 25 | return base64.RawStdEncoding.EncodeToString([]byte(u.Pattern.Issuer)) 26 | } 27 | -------------------------------------------------------------------------------- /application/auth/openid-connect-jwt/token.go: -------------------------------------------------------------------------------- 1 | package openid_connect_jwt 2 | 3 | import ( 4 | "encoding/base64" 5 | "encoding/json" 6 | "errors" 7 | "strings" 8 | ) 9 | 10 | var ( 11 | ErrInvalidToken = errors.New("invalid token") 12 | ) 13 | 14 | type tokenHeader struct { 15 | Alg string `json:"alg"` 16 | Kid string `json:"kid"` 17 | Typ string `json:"typ"` 18 | } 19 | 20 | func extractTokenHeader(token string) (*tokenHeader, error) { 21 | ts := strings.Split(token, ".") 22 | if len(ts) != 3 { 23 | return nil, ErrInvalidToken 24 | } 25 | headerData, err := base64.RawStdEncoding.DecodeString(ts[0]) 26 | if err != nil { 27 | return nil, err 28 | } 29 | var th tokenHeader 30 | err = json.Unmarshal(headerData, &th) 31 | if err != nil { 32 | return nil, err 33 | } 34 | return &th, nil 35 | } 36 | -------------------------------------------------------------------------------- /application/auth/para-hmac/config.go: -------------------------------------------------------------------------------- 1 | package para_hmac 2 | 3 | import "github.com/eolinker/apinto/application" 4 | 5 | type Config struct { 6 | application.Auth 7 | Users []*User `json:"users" label:"用户列表"` 8 | } 9 | 10 | type User struct { 11 | Pattern Pattern `json:"pattern" label:"用户信息"` 12 | application.User 13 | } 14 | 15 | type Pattern struct { 16 | AppID string `json:"app_id"` 17 | AppKey string `json:"app_key"` 18 | } 19 | 20 | func (u *User) Username() string { 21 | return u.Pattern.AppID 22 | } 23 | -------------------------------------------------------------------------------- /application/auth/para-hmac/sign.go: -------------------------------------------------------------------------------- 1 | package para_hmac 2 | 3 | import ( 4 | "crypto/sha256" 5 | "encoding/base64" 6 | "fmt" 7 | "strings" 8 | ) 9 | 10 | var signSort = []string{ 11 | "Body", 12 | "X-App-Id", 13 | "X-Sequence-No", 14 | "X-Timestamp", 15 | } 16 | 17 | func sign(appId string, appKey string, timestamp string, sequenceNo string, body string) string { 18 | headerMap := make(map[string]string) 19 | headerMap["X-App-Id"] = appId 20 | headerMap["X-Sequence-No"] = sequenceNo 21 | headerMap["X-Timestamp"] = timestamp 22 | headerMap["Body"] = base64.StdEncoding.EncodeToString([]byte(body)) 23 | builder := strings.Builder{} 24 | for _, key := range signSort { 25 | v, ok := headerMap[key] 26 | if !ok || v == "" { 27 | continue 28 | } 29 | builder.WriteString(fmt.Sprintf("%s=%s&", key, v)) 30 | } 31 | builder.WriteString(appKey) 32 | h := sha256.New() 33 | h.Write([]byte(builder.String())) 34 | return base64.StdEncoding.EncodeToString(h.Sum(nil)) 35 | } 36 | -------------------------------------------------------------------------------- /application/auth/para-hmac/sign_test.go: -------------------------------------------------------------------------------- 1 | package para_hmac 2 | 3 | import ( 4 | "net/url" 5 | "testing" 6 | ) 7 | 8 | func TestSign(t *testing.T) { 9 | appId := "ed3DtlYh" 10 | appKey := "3YnxRNwULya0W56A" 11 | sequenceNo := "2024103117392905280623" 12 | timestamp := "20241031173929052" 13 | 14 | body := "{\"agentId\":\"nx\"}" 15 | t.Log(url.PathUnescape("qqY%2BkJ2LUany%2FSZf3a3Rd73scYsEXDGRoeF5FPuZJ2g%3D")) 16 | t.Log(sign(appId, appKey, timestamp, sequenceNo, body)) 17 | } 18 | -------------------------------------------------------------------------------- /application/auth/register.go: -------------------------------------------------------------------------------- 1 | package auth 2 | 3 | import ( 4 | "github.com/eolinker/eosc" 5 | "github.com/eolinker/eosc/setting" 6 | ) 7 | 8 | func Register(register eosc.IExtenderDriverRegister) { 9 | setting.RegisterSetting("auth", defaultAuthFactoryRegister) 10 | } 11 | -------------------------------------------------------------------------------- /build/.gitignore: -------------------------------------------------------------------------------- 1 | *.DS_Store 2 | -------------------------------------------------------------------------------- /build/cmd/.gitignore: -------------------------------------------------------------------------------- 1 | /docker-build.sh 2 | -------------------------------------------------------------------------------- /build/cmd/Dockerfile: -------------------------------------------------------------------------------- 1 | # 名称:apinto镜像,携带了部署k8s集群所需要的脚本 2 | # 创建时间:2024-11-19 3 | FROM alpine:latest 4 | 5 | RUN sed -i 's|https://dl-cdn.alpinelinux.org/alpine|https://mirrors.aliyun.com/alpine|g' /etc/apk/repositories \ 6 | && apk update \ 7 | && apk add --no-cache bash tzdata 8 | 9 | RUN apk add --no-cache netcat-openbsd curl 10 | 11 | ENV TZ=Asia/Shanghai 12 | 13 | RUN cp /usr/share/zoneinfo/${TZ} /etc/localtime && echo ${TZ} > /etc/timezone 14 | 15 | #设置环境变量 16 | ARG AppName=apinto 17 | 18 | #定义数据卷 19 | VOLUME /var/lib/${AppName} 20 | 21 | #解压网关程序压缩包 22 | COPY ./apinto.linux.x64.tar.gz / 23 | RUN tar -zxvf apinto.linux.x64.tar.gz && ls /${AppName} / && rm -rf ../apinto.linux.x64.tar.gz 24 | 25 | #复制程序默认配置文件以及修改脚本权限 26 | RUN mkdir /etc/${AppName} 27 | RUN cp /${AppName}/${AppName}.yml.tpl /etc/${AppName}/${AppName}.yml && cp /${AppName}/config.yml.tpl /etc/${AppName}/config.yml 28 | 29 | RUN chmod 777 /${AppName}/*.sh 30 | 31 | WORKDIR /apinto 32 | 33 | CMD ["bash","/apinto/auto-start.sh"] -------------------------------------------------------------------------------- /build/cmd/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echo $0 4 | 5 | . $(dirname $0)/common.sh 6 | 7 | #echo ${BasePath} 8 | #echo ${CMD} 9 | #echo ${Hour} 10 | 11 | VERSION=$(genVersion $1) 12 | ARCH=$2 13 | OUTPATH="${BasePath}/out/apinto-${VERSION}" 14 | buildApp apinto $VERSION ${ARCH} 15 | 16 | cp -a ${BasePath}/build/resources/* ${OUTPATH}/ 17 | 18 | cd ${ORGPATH} 19 | -------------------------------------------------------------------------------- /build/cmd/docker_build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echo $0 4 | . $(dirname $0)/common.sh 5 | 6 | #VERSION=`git describe --abbrev=0 --tags` 7 | VERSION=$(genVersion $1) 8 | 9 | Username="eolinker" 10 | if [[ "$2" != "" ]] 11 | then 12 | Username=$2 13 | fi 14 | 15 | ARCH=$3 16 | PLATFORM="" 17 | if [[ "$ARCH" == "" ]] 18 | then 19 | ARCH="amd64" 20 | fi 21 | if [[ "$ARCH" == "amd64" ]] 22 | then 23 | PLATFORM="--platform=linux/amd64" 24 | fi 25 | ./build/cmd/package.sh ${VERSION} ${ARCH} 26 | PackageName=apinto_${VERSION}_linux_${ARCH}.tar.gz 27 | cp out/${PackageName} ./build/resources/apinto.linux.x64.tar.gz 28 | 29 | docker build $PLATFORM -t ${Username}/apinto-gateway:${VERSION}-${ARCH} -f ./build/cmd/Dockerfile ./build/resources 30 | 31 | rm -rf ./build/resources/apinto.linux.x64.tar.gz 32 | 33 | cd ${ORGPATH} 34 | -------------------------------------------------------------------------------- /build/cmd/package.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | . $(dirname $0)/common.sh 4 | 5 | cd ${BasePath}/ 6 | 7 | 8 | VERSION=$(genVersion $1) 9 | folder="${BasePath}/out/apinto-${VERSION}" 10 | ARCH=$2 11 | if [[ ! -d "$folder" ]] 12 | then 13 | # mkdir -p "$folder" 14 | ${CMD}/build.sh $1 ${ARCH} 15 | if [[ "$?" != "0" ]] 16 | then 17 | exit 1 18 | fi 19 | fi 20 | packageApp apinto $VERSION ${ARCH} 21 | 22 | cd ${ORGPATH} 23 | -------------------------------------------------------------------------------- /build/cmd/qiniu_publish.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | . $(dirname $0)/common.sh 6 | 7 | 8 | Version=$(genVersion) 9 | 10 | ImageName="docker.eolinker.com/apinto/apinto-gateway" 11 | APP="apinto-gateway" 12 | 13 | ARCH=$1 14 | if [[ $ARCH == "" ]];then 15 | ARCH="amd64" 16 | fi 17 | 18 | Tar="${APP}.${Version}.${ARCH}.tar.gz" 19 | 20 | docker tag ${ImageName}:${Version}-${ARCH} ${ImageName}:${Version} 21 | 22 | echo "docker save -o ${Tar} ${ImageName}:${Version}" 23 | docker save -o ${Tar} ${ImageName}:${Version} 24 | 25 | echo "qshell rput eolinker-main \"apinto/images/${Tar}\" ${Tar}" 26 | qshell rput eolinker-main "apinto/images/${Tar}" ${Tar} 27 | 28 | rm -f ${Tar} 29 | docker rmi -f ${ImageName}:${Version} -------------------------------------------------------------------------------- /build/resources/Dockerfile: -------------------------------------------------------------------------------- 1 | # 名称:apinto镜像,携带了部署k8s集群所需要的脚本 2 | # 创建时间:2024-11-19 3 | FROM alpine:latest 4 | 5 | RUN sed -i 's|https://dl-cdn.alpinelinux.org/alpine|https://mirrors.aliyun.com/alpine|g' /etc/apk/repositories \ 6 | && apk update \ 7 | && apk add --no-cache bash tzdata 8 | 9 | RUN apk add --no-cache netcat-openbsd curl 10 | 11 | ENV TZ=Asia/Shanghai 12 | 13 | RUN cp /usr/share/zoneinfo/${TZ} /etc/localtime && echo ${TZ} > /etc/timezone 14 | 15 | #设置环境变量 16 | ARG AppName=apinto 17 | 18 | #定义数据卷 19 | VOLUME /var/lib/${AppName} 20 | 21 | #解压网关程序压缩包 22 | COPY ./apinto.linux.x64.tar.gz / 23 | RUN tar -zxvf apinto.linux.x64.tar.gz && ls /${AppName} / && rm -rf ../apinto.linux.x64.tar.gz 24 | 25 | #复制程序默认配置文件以及修改脚本权限 26 | RUN mkdir /etc/${AppName} 27 | RUN cp /${AppName}/${AppName}.yml.tpl /etc/${AppName}/${AppName}.yml && cp /${AppName}/config.yml.tpl /etc/${AppName}/config.yml 28 | 29 | RUN chmod 777 /${AppName}/*.sh 30 | 31 | WORKDIR /apinto 32 | 33 | CMD ["bash","/apinto/auto-start.sh"] -------------------------------------------------------------------------------- /build/resources/apinto.yml.tpl: -------------------------------------------------------------------------------- 1 | # 数据文件放置目录 2 | data_dir: /var/lib/apinto 3 | 4 | # pid文件放置地址 5 | pid_dir: /var/run/apinto/ 6 | 7 | # 日志放置目录 8 | log_dir: /var/log/apinto 9 | 10 | # socket放置目录 11 | socket_dir: /tmp/apinto 12 | 13 | # apinto运行配置地址 14 | config: /etc/apinto/config.yml 15 | 16 | # 扩展仓库目录 17 | extends_dir: /var/lib/apinto/extenders/ 18 | 19 | # 错误日志文件名 20 | error_log_name: error.log 21 | 22 | # 错误日志等级 23 | error_log_level: error 24 | 25 | # 错误日志过期时间,默认单位为天,d|天,h|小时 26 | error_log_expire: 7d 27 | 28 | # 错误日志切割周期,仅支持day、hour 29 | error_log_period: day -------------------------------------------------------------------------------- /build/resources/check_remove.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | apinto_info=$(./apinto info) 3 | 4 | nodes_count=$(echo $apinto_info | grep -o 'Node' | wc -l) 5 | cluster_node=$(( $nodes_count + 1 )) 6 | 7 | for ((i=0;i<$cluster_node;i++)) 8 | do 9 | count_addr=$(( $i*8+6 )) 10 | count_node=$(( $i*8+4 )) 11 | info_addr=$(echo $apinto_info | awk '{print $'"$count_addr"'}') 12 | info_node=$(echo $apinto_info | awk '{print $'"$count_node"'}') 13 | { 14 | curl --max-time 5 --silent --fail $info_addr 15 | } || { 16 | ./apinto remove $info_node 17 | } 18 | echo "" 19 | 20 | done 21 | -------------------------------------------------------------------------------- /build/resources/config.yml.k8s.tpl: -------------------------------------------------------------------------------- 1 | version: 2 2 | #certificate: # 证书存放根目录 3 | # dir: /etc/apinto/cert 4 | client: 5 | #advertise_urls: # open api 服务的广播地址 6 | #- http://127.0.0.1:9400 7 | listen_urls: # open api 服务的监听地址 8 | - http://0.0.0.0:9400 9 | #certificate: # 证书配置,允许使用ip的自签证书 10 | # - cert: server.pem 11 | # key: server.key 12 | gateway: 13 | #advertise_urls: # 转发服务的广播地址 14 | #- http://127.0.0.1:9400 15 | listen_urls: # 转发服务的监听地址 16 | - https://0.0.0.0:8099 17 | - http://0.0.0.0:8099 18 | peer: # 集群间节点通信配置信息 19 | listen_urls: # 节点监听地址 20 | - http://0.0.0.0:9401 21 | advertise_urls: # 节点通信广播地址 22 | - http://{IP}:9401 23 | #certificate: # 证书配置,允许使用ip的自签证书 24 | # - cert: server.pem 25 | # key: server.key 26 | 27 | -------------------------------------------------------------------------------- /build/resources/config.yml.tpl: -------------------------------------------------------------------------------- 1 | version: 2 2 | #certificate: # 证书存放根目录 3 | # dir: /etc/apinto/cert 4 | client: 5 | #advertise_urls: # open api 服务的广播地址 6 | #- http://127.0.0.1:9400 7 | listen_urls: # open api 服务的监听地址 8 | - http://0.0.0.0:9400 9 | #certificate: # 证书配置,允许使用ip的自签证书 10 | # - cert: server.pem 11 | # key: server.key 12 | gateway: 13 | #advertise_urls: # 转发服务的广播地址 14 | #- http://127.0.0.1:9400 15 | listen_urls: # 转发服务的监听地址 16 | - https://0.0.0.0:8099 17 | - http://0.0.0.0:8099 18 | peer: # 集群间节点通信配置信息 19 | listen_urls: # 节点监听地址 20 | - http://0.0.0.0:9401 21 | #advertise_urls: # 节点通信广播地址 22 | # - http://127.0.0.1:9401 23 | #certificate: # 证书配置,允许使用ip的自签证书 24 | # - cert: server.pem 25 | # key: server.key 26 | 27 | -------------------------------------------------------------------------------- /build/resources/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | CURRENT_PATH="$(pwd)" 5 | 6 | install() { 7 | mkdir -p /etc/apinto 8 | 9 | #将模板配置文件复制到/etc/apinto目录, 若已存在则不覆盖 10 | cp -in ./apinto.yml.tpl /etc/apinto/apinto.yml 11 | cp -in ./config.yml.tpl /etc/apinto/config.yml 12 | 13 | #将程序链接至/usr/sbin 14 | ln -snf $CURRENT_PATH/apinto /usr/sbin/apinto 15 | } 16 | 17 | upgrade() { 18 | apinto stop 19 | install 20 | sleep 10s 21 | apinto start 22 | } 23 | 24 | case "$1" in 25 | install) 26 | install 27 | exit 0 28 | ;; 29 | upgrade) 30 | upgrade 31 | exit 0 32 | ;; 33 | **) 34 | echo "Usage: $0 {install|upgrade} " 1>&2 35 | exit 1 36 | ;; 37 | esac -------------------------------------------------------------------------------- /build/resources/leave.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | #This script is used to leave the K8S cluster 4 | ./apinto leave -------------------------------------------------------------------------------- /checker/checkType.go: -------------------------------------------------------------------------------- 1 | package checker 2 | 3 | // CheckType Checker类型 4 | type CheckType int 5 | 6 | const ( 7 | //CheckTypeEqual 全等匹配Checker类型 8 | CheckTypeEqual CheckType = iota 9 | //CheckTypePrefix 前缀匹配Checker类型 10 | CheckTypePrefix 11 | //CheckTypeSuffix 后缀匹配Checker类型 12 | CheckTypeSuffix 13 | //CheckTypeSub 子串匹配Checker类型 14 | CheckTypeSub 15 | //CheckTypeNotEqual 非等匹配Checker类型 16 | CheckTypeNotEqual 17 | //CheckTypeNone 空值匹配Checker类型 18 | CheckTypeNone 19 | //CheckTypeExist 存在匹配Checker类型 20 | CheckTypeExist 21 | //CheckTypeNotExist 不存在匹配Checker类型 22 | CheckTypeNotExist 23 | //CheckTypeRegular 区分大小写的正则匹配Checker类型 24 | CheckTypeRegular 25 | //CheckTypeRegularG 不区分大小写的正则匹配Checker类型 26 | CheckTypeRegularG 27 | //CheckTypeAll 任意匹配Checker类型 28 | CheckTypeAll 29 | // CheckMultiple 复合匹配 30 | CheckMultiple 31 | CheckTypeIP 32 | ) 33 | -------------------------------------------------------------------------------- /checker/checker-all.go: -------------------------------------------------------------------------------- 1 | package checker 2 | 3 | var globalCheckerAll = &checkerAll{} 4 | 5 | //checkerAll 实现了Checker接口,能进行任意匹配 6 | type checkerAll struct { 7 | } 8 | 9 | //Key 返回路由指标检查器带有完整规则符号的检测值 10 | func (t *checkerAll) Key() string { 11 | return "*" 12 | } 13 | 14 | //Value 返回路由指标检查器的检测值 15 | func (t *checkerAll) Value() string { 16 | return "*" 17 | } 18 | 19 | //Check 判断待检测的路由指标值是否满足检查器的匹配规则 20 | func (t *checkerAll) Check(v string, has bool) bool { 21 | //任意匹配能通过任何类型的路由指标值 22 | return true 23 | } 24 | 25 | //CheckType 返回检查器的类型值 26 | func (t *checkerAll) CheckType() CheckType { 27 | return CheckTypeAll 28 | } 29 | 30 | //newCheckerAll 创建一个任意匹配类型的检查器 31 | func newCheckerAll() *checkerAll { 32 | return globalCheckerAll 33 | } 34 | -------------------------------------------------------------------------------- /checker/checker-equal.go: -------------------------------------------------------------------------------- 1 | package checker 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | //checkerAll 实现了Checker接口,能进行全等匹配 8 | type checkerEqual struct { 9 | value string 10 | } 11 | 12 | //Key 返回路由指标检查器带有完整规则符号的检测值 13 | func (e *checkerEqual) Key() string { 14 | return fmt.Sprintf("=%s", e.value) 15 | } 16 | 17 | //Value 返回路由指标检查器的检测值 18 | func (e *checkerEqual) Value() string { 19 | return e.value 20 | } 21 | 22 | //newCheckerAll 创建一个全等匹配类型的检查器 23 | func newCheckerEqual(value string) *checkerEqual { 24 | return &checkerEqual{value: value} 25 | } 26 | 27 | //Check 判断待检测的路由指标值是否满足检查器的匹配规则 28 | func (e *checkerEqual) Check(v string, has bool) bool { 29 | //当待检测路由指标值存在 且值与检查器的检测值相等时匹配成功 30 | if !has { 31 | return false 32 | } 33 | return v == e.value 34 | } 35 | 36 | //CheckType 返回检查器的类型值 37 | func (e *checkerEqual) CheckType() CheckType { 38 | return CheckTypeEqual 39 | } 40 | -------------------------------------------------------------------------------- /checker/checker-none.go: -------------------------------------------------------------------------------- 1 | package checker 2 | 3 | import ( 4 | "strings" 5 | ) 6 | 7 | var ( 8 | globalCheckerNone = &checkerNone{} 9 | ) 10 | 11 | //checkerAll 实现了Checker接口,能进行空值匹配 12 | type checkerNone struct { 13 | } 14 | 15 | //Key 返回路由指标检查器带有完整规则符号的检测值 16 | func (t *checkerNone) Key() string { 17 | return "$" 18 | } 19 | 20 | //Value 返回路由指标检查器的检测值 21 | func (t *checkerNone) Value() string { 22 | return "$" 23 | } 24 | 25 | //Check 判断待检测的路由指标值是否满足检查器的匹配规则 26 | func (t *checkerNone) Check(v string, has bool) bool { 27 | //当待检测的路由指标值存在且值为空时匹配成功 28 | if !has { 29 | return false 30 | } 31 | return strings.TrimSpace(v) == "" 32 | } 33 | 34 | //CheckType 返回检查器的类型值 35 | func (t *checkerNone) CheckType() CheckType { 36 | return CheckTypeNone 37 | } 38 | 39 | //newCheckerAll 创建一个空值匹配类型的检查器 40 | func newCheckerNone() *checkerNone { 41 | return globalCheckerNone 42 | } 43 | -------------------------------------------------------------------------------- /checker/checker-notequal.go: -------------------------------------------------------------------------------- 1 | package checker 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | //checkerAll 实现了Checker接口,能进行非等匹配 8 | type checkerNotEqual struct { 9 | value string 10 | } 11 | 12 | //Key 返回路由指标检查器带有完整规则符号的检测值 13 | func (e *checkerNotEqual) Key() string { 14 | return fmt.Sprintf("!=%s", e.value) 15 | } 16 | 17 | //Value 返回路由指标检查器的检测值 18 | func (e *checkerNotEqual) Value() string { 19 | return e.value 20 | } 21 | 22 | //Check 判断待检测的路由指标值是否满足检查器的匹配规则 23 | func (e *checkerNotEqual) Check(v string, has bool) bool { 24 | //当待检测路由指标值存在且与检查器的检测值不相等时匹配成功 25 | if !has { 26 | return false 27 | } 28 | return v != e.value 29 | } 30 | 31 | //CheckType 返回检查器的类型值 32 | func (e *checkerNotEqual) CheckType() CheckType { 33 | return CheckTypeNotEqual 34 | } 35 | 36 | //newCheckerAll 创建一个非等匹配类型的检查器 37 | func newCheckerNotEqual(value string) *checkerNotEqual { 38 | return &checkerNotEqual{value: value} 39 | } 40 | -------------------------------------------------------------------------------- /checker/checker-prefix.go: -------------------------------------------------------------------------------- 1 | package checker 2 | 3 | import ( 4 | "fmt" 5 | "github.com/eolinker/eosc/log" 6 | "strings" 7 | ) 8 | 9 | //PrefixChecker 实现了Checker接口,能进行前缀匹配 10 | type PrefixChecker struct { 11 | prefix string 12 | } 13 | 14 | //Key 返回路由指标检查器带有完整规则符号的检测值 15 | func (p *PrefixChecker) Key() string { 16 | return fmt.Sprintf("%s*", p.prefix) 17 | } 18 | 19 | //Value 返回路由指标检查器的检测值 20 | func (p *PrefixChecker) Value() string { 21 | return p.prefix 22 | } 23 | 24 | //Check 判断待检测的路由指标值是否满足检查器的匹配规则 25 | func (p *PrefixChecker) Check(v string, has bool) bool { 26 | log.Debug("PrefixChecker:check", v, has, " on ", p.prefix) 27 | //当待检测的路由指标值存在 且 检查器的检测值为其前缀时匹配成功 28 | if !has { 29 | return false 30 | } 31 | 32 | return strings.HasPrefix(v, p.prefix) 33 | } 34 | 35 | //CheckType 返回检查器的类型值 36 | func (p *PrefixChecker) CheckType() CheckType { 37 | return CheckTypePrefix 38 | } 39 | 40 | //newCheckerAll 创建一个前缀匹配类型的检查器 41 | func newCheckerPrefix(prefix string) *PrefixChecker { 42 | return &PrefixChecker{prefix: prefix} 43 | } 44 | -------------------------------------------------------------------------------- /checker/checker-sub.go: -------------------------------------------------------------------------------- 1 | package checker 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | ) 7 | 8 | //SubChecker 实现了Checker接口,能进行子串匹配 9 | type SubChecker struct { 10 | sub string 11 | } 12 | 13 | //Key 返回路由指标检查器带有完整规则符号的检测值 14 | func (p *SubChecker) Key() string { 15 | return fmt.Sprintf("=*%s*", p.sub) 16 | } 17 | 18 | //Value 返回路由指标检查器的检测值 19 | func (p *SubChecker) Value() string { 20 | return p.sub 21 | } 22 | 23 | //Check 判断待检测的路由指标值是否满足检查器的匹配规则 24 | func (p *SubChecker) Check(v string, has bool) bool { 25 | //当待检测的路由指标值存在 且 检查器的检测值为其子串时匹配成功 26 | if !has { 27 | return false 28 | } 29 | return strings.Contains(v, p.sub) 30 | } 31 | 32 | //CheckType 返回检查器的类型值 33 | func (p *SubChecker) CheckType() CheckType { 34 | return CheckTypeSub 35 | } 36 | 37 | //newCheckerAll 创建一个子串匹配类型的检查器 38 | func newCheckerSub(sub string) *SubChecker { 39 | return &SubChecker{sub: sub} 40 | } 41 | -------------------------------------------------------------------------------- /checker/checker-suffix.go: -------------------------------------------------------------------------------- 1 | package checker 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | ) 7 | 8 | //SuffixChecker 实现了Checker接口,能进行后缀匹配 9 | type SuffixChecker struct { 10 | suffix string 11 | } 12 | 13 | //Key 返回路由指标检查器带有完整规则符号的检测值 14 | func (p *SuffixChecker) Key() string { 15 | return fmt.Sprintf("=*%s", p.suffix) 16 | } 17 | 18 | //Value 返回路由指标检查器的检测值 19 | func (p *SuffixChecker) Value() string { 20 | return p.suffix 21 | } 22 | 23 | //Check 判断待检测的路由指标值是否满足检查器的匹配规则 24 | func (p *SuffixChecker) Check(v string, has bool) bool { 25 | //当待检测的路由指标值存在 且 检查器的检测值为其后缀时匹配成功 26 | if !has { 27 | return false 28 | } 29 | return strings.HasSuffix(v, p.suffix) 30 | } 31 | 32 | //CheckType 返回检查器的类型值 33 | func (p *SuffixChecker) CheckType() CheckType { 34 | return CheckTypeSuffix 35 | } 36 | 37 | //newCheckerAll 创建一个后缀匹配类型的检查器 38 | func newCheckerSuffix(suffix string) *SuffixChecker { 39 | return &SuffixChecker{suffix: suffix} 40 | } 41 | -------------------------------------------------------------------------------- /checker/checker_usage.md: -------------------------------------------------------------------------------- 1 | # Checker 2 | 3 | ##### 规则: 4 | 5 | ``` 6 |

=str 7 | ``` 8 | 9 | ##### 可能值: 10 | 11 | p:^ ! ~ ~* 12 | 13 | pr: * ** ! $ 14 | 15 | su: * 16 | 17 | #### 匹配优先级(由上往下优先级递减) 18 | 19 | ``` 20 | 1.全等匹配:=str(=可省略) 21 | 2.前缀匹配:^=str、 =str*(=可省略) 22 | 3.后缀匹配:^=*str、 =*str(=可省略) 23 | 4.子串匹配:=*str*(=可省略) 24 | 5.非等匹配:!=str 25 | 6.空值匹配:=$(=可省略) 26 | 7.存在匹配:=**(=可省略) 27 | 8.不存在匹配:=!(=可省略) 28 | 9.区分大小写的正则匹配:~=str 29 | 10.不区分大小写的正则匹配:~*=str 30 | 11.任意匹配:=(=可省略)、 =*(=可省略) 31 | ``` 32 | 33 | -------------------------------------------------------------------------------- /discovery/check.go: -------------------------------------------------------------------------------- 1 | package discovery 2 | 3 | // IHealthChecker 健康检查接口 4 | type IHealthChecker interface { 5 | Check(nodes INodes) 6 | Reset(conf interface{}) error 7 | Stop() 8 | } 9 | -------------------------------------------------------------------------------- /discovery/nodes.go: -------------------------------------------------------------------------------- 1 | package discovery 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | var ( 8 | _ INodes = (*appContainer)(nil) 9 | ) 10 | 11 | type INodes interface { 12 | Get(ip string, port int) INode 13 | All() []INode 14 | SetHealthCheck(isHealthCheck bool) 15 | } 16 | 17 | func (ac *appContainer) Get(ip string, port int) INode { 18 | id := fmt.Sprintf("%s:%d", ip, port) 19 | 20 | node, has := ac.nodes.Get(id) 21 | 22 | if has { 23 | return node 24 | } 25 | ac.lock.Lock() 26 | defer ac.lock.Unlock() 27 | node, has = ac.nodes.Get(id) 28 | if has { 29 | return node 30 | } 31 | 32 | ac.nodes.Set(id, newBaseNode(id, ip, port, ac)) 33 | node, _ = ac.nodes.Get(id) 34 | return node 35 | } 36 | 37 | func (ac *appContainer) All() []INode { 38 | 39 | return ac.nodes.List() 40 | } 41 | -------------------------------------------------------------------------------- /drivers/.gitignore: -------------------------------------------------------------------------------- 1 | *.DS_Store 2 | ../.env -------------------------------------------------------------------------------- /drivers/ai-key/config.go: -------------------------------------------------------------------------------- 1 | package ai_key 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/eolinker/apinto/drivers" 7 | "github.com/eolinker/eosc" 8 | ) 9 | 10 | type Config struct { 11 | Expired int64 `json:"expired"` 12 | Config string `json:"config"` 13 | Provider string `json:"provider"` 14 | Priority int `json:"priority"` 15 | Disabled bool `json:"disabled"` 16 | } 17 | 18 | func checkConfig(v interface{}) (*Config, error) { 19 | conf, ok := v.(*Config) 20 | if !ok { 21 | return nil, eosc.ErrorConfigType 22 | } 23 | 24 | if conf.Provider == "" { 25 | return nil, fmt.Errorf("provider is required") 26 | } 27 | 28 | return conf, nil 29 | 30 | } 31 | func Create(id, name string, v *Config, workers map[eosc.RequireId]eosc.IWorker) (eosc.IWorker, error) { 32 | cfg, err := checkConfig(v) 33 | if err != nil { 34 | return nil, err 35 | } 36 | w := &executor{ 37 | WorkerBase: drivers.Worker(id, name), 38 | } 39 | err = w.reset(cfg) 40 | return w, err 41 | } 42 | -------------------------------------------------------------------------------- /drivers/ai-key/factory.go: -------------------------------------------------------------------------------- 1 | package ai_key 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | const name = "ai-key" 9 | 10 | // Register AI Key Factory 11 | func Register(register eosc.IExtenderDriverRegister) { 12 | register.RegisterExtenderDriver(name, NewFactory()) 13 | } 14 | 15 | // NewFactory creates AI Key Factory 16 | func NewFactory() eosc.IExtenderDriverFactory { 17 | 18 | return drivers.NewFactory[Config](Create) 19 | } 20 | -------------------------------------------------------------------------------- /drivers/ai-model/config.go: -------------------------------------------------------------------------------- 1 | package ai_model 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/eolinker/apinto/drivers" 7 | 8 | "github.com/eolinker/eosc" 9 | ) 10 | 11 | type Config struct { 12 | Provider string `json:"provider"` 13 | Model string `json:"model"` 14 | AccessConfig string `json:"access_config"` 15 | } 16 | 17 | // Create 创建驱动实例 18 | func Create(id, name string, v *Config, workers map[eosc.RequireId]eosc.IWorker) (eosc.IWorker, error) { 19 | 20 | cfg, err := checkConfig(v) 21 | if err != nil { 22 | return nil, err 23 | } 24 | w := &executor{ 25 | WorkerBase: drivers.Worker(id, name), 26 | } 27 | err = w.reset(cfg) 28 | return w, err 29 | } 30 | 31 | func checkConfig(v interface{}) (*Config, error) { 32 | conf, ok := v.(*Config) 33 | if !ok { 34 | return nil, eosc.ErrorConfigType 35 | } 36 | 37 | if conf.Provider == "" { 38 | return nil, fmt.Errorf("provider is required") 39 | } 40 | 41 | if conf.Model == "" { 42 | return nil, fmt.Errorf("model is required") 43 | } 44 | 45 | return conf, nil 46 | } 47 | -------------------------------------------------------------------------------- /drivers/ai-model/factory.go: -------------------------------------------------------------------------------- 1 | package ai_model 2 | 3 | import ( 4 | "sync" 5 | 6 | ai_convert "github.com/eolinker/apinto/ai-convert" 7 | "github.com/eolinker/apinto/drivers" 8 | "github.com/eolinker/eosc" 9 | "github.com/eolinker/eosc/common/bean" 10 | ) 11 | 12 | var name = "ai-model" 13 | 14 | var ( 15 | once sync.Once 16 | accessConfigManager ai_convert.IModelAccessConfigManager 17 | ) 18 | 19 | type Factory struct { 20 | } 21 | 22 | // Register AI供应商Factory 23 | func Register(register eosc.IExtenderDriverRegister) { 24 | register.RegisterExtenderDriver(name, NewFactory()) 25 | } 26 | 27 | // NewFactory 创建service_http驱动工厂 28 | func NewFactory() eosc.IExtenderDriverFactory { 29 | once.Do(func() { 30 | bean.Autowired(&accessConfigManager) 31 | }) 32 | return drivers.NewFactory[Config](Create) 33 | } 34 | -------------------------------------------------------------------------------- /drivers/ai-provider/factory.go: -------------------------------------------------------------------------------- 1 | package ai_provider 2 | 3 | import ( 4 | "sync" 5 | 6 | ai_convert "github.com/eolinker/apinto/ai-convert" 7 | 8 | "github.com/eolinker/eosc/common/bean" 9 | 10 | "github.com/eolinker/apinto/drivers" 11 | "github.com/eolinker/eosc" 12 | ) 13 | 14 | var name = "ai-provider" 15 | 16 | type Factory struct { 17 | } 18 | 19 | var ( 20 | providerManager ai_convert.IManager 21 | ones sync.Once 22 | ) 23 | 24 | // Register AI供应商Factory 25 | func Register(register eosc.IExtenderDriverRegister) { 26 | register.RegisterExtenderDriver(name, NewFactory()) 27 | } 28 | 29 | // NewFactory 创建service_http驱动工厂 30 | func NewFactory() eosc.IExtenderDriverFactory { 31 | ones.Do(func() { 32 | bean.Autowired(&providerManager) 33 | }) 34 | return drivers.NewFactory[Config](Create) 35 | } 36 | -------------------------------------------------------------------------------- /drivers/app/executor.go: -------------------------------------------------------------------------------- 1 | package app 2 | 3 | import ( 4 | "github.com/eolinker/apinto/application" 5 | http_service "github.com/eolinker/eosc/eocontext/http-context" 6 | ) 7 | 8 | const ( 9 | conflictConvert = "convert" 10 | conflictError = "error" 11 | conflictOrigin = "origin" 12 | ) 13 | 14 | var ( 15 | errorExist = "%s: %s is already exists" 16 | ) 17 | 18 | type executor struct { 19 | executors []application.IAppExecutor 20 | } 21 | 22 | func newExecutor() *executor { 23 | return &executor{executors: make([]application.IAppExecutor, 0, 3)} 24 | } 25 | 26 | func (e *executor) Execute(ctx http_service.IHttpContext) error { 27 | for _, f := range e.executors { 28 | err := f.Execute(ctx) 29 | if err != nil { 30 | return err 31 | } 32 | } 33 | return nil 34 | } 35 | 36 | func (e *executor) append(f ...application.IAppExecutor) { 37 | e.executors = append(e.executors, f...) 38 | } 39 | -------------------------------------------------------------------------------- /drivers/certs/config.go: -------------------------------------------------------------------------------- 1 | package certs 2 | 3 | type Config struct { 4 | Name string `json:"name" label:"证书名称" description:"证书名称"` 5 | Key string `json:"key" label:"密钥内容" format:"file" description:"密钥文件的后缀名一般为.key"` 6 | Pem string `json:"pem" label:"证书内容" format:"file" description:"证书文件的后缀名一般为.crt 或 .pem"` 7 | } 8 | -------------------------------------------------------------------------------- /drivers/certs/driver.go: -------------------------------------------------------------------------------- 1 | package certs 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | // Create 创建驱动实例 9 | func Create(id, name string, v *Config, workers map[eosc.RequireId]eosc.IWorker) (eosc.IWorker, error) { 10 | 11 | worker := &Worker{ 12 | WorkerBase: drivers.Worker(id, name), 13 | } 14 | 15 | err := worker.Reset(v, workers) 16 | if err != nil { 17 | return nil, err 18 | } 19 | 20 | controller.Store(id) 21 | 22 | return worker, nil 23 | } 24 | -------------------------------------------------------------------------------- /drivers/certs/factory.go: -------------------------------------------------------------------------------- 1 | package certs 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | func Register(register eosc.IExtenderDriverRegister) { 9 | _ = register.RegisterExtenderDriver("ssl-server", newFactory()) 10 | //setting.RegisterSetting("ssl-server", controller) 11 | } 12 | 13 | func newFactory() eosc.IExtenderDriverFactory { 14 | return &factory{IExtenderDriverFactory: drivers.NewFactory[Config](Create)} 15 | } 16 | 17 | type factory struct { 18 | eosc.IExtenderDriverFactory 19 | } 20 | 21 | func (f *factory) Create(profession string, name string, label string, desc string, params map[string]interface{}) (eosc.IExtenderDriver, error) { 22 | controller.driver = name 23 | controller.profession = profession 24 | return f.IExtenderDriverFactory.Create(profession, name, label, desc, params) 25 | } 26 | -------------------------------------------------------------------------------- /drivers/discovery/consul/config.go: -------------------------------------------------------------------------------- 1 | package consul 2 | 3 | import ( 4 | "github.com/hashicorp/consul/api" 5 | ) 6 | 7 | const defaultScheme = "http" 8 | 9 | //Config consul驱动配置 10 | type Config struct { 11 | Config AccessConfig `json:"config" label:"配置信息"` 12 | } 13 | 14 | //AccessConfig 接入地址配置 15 | type AccessConfig struct { 16 | Address []string `json:"address" label:"consul地址"` 17 | Params map[string]string `json:"params" label:"参数"` 18 | } 19 | 20 | type consulClients struct { 21 | clients []*api.Client 22 | } 23 | -------------------------------------------------------------------------------- /drivers/discovery/consul/consul_test.go: -------------------------------------------------------------------------------- 1 | package consul 2 | 3 | import ( 4 | "sync" 5 | "testing" 6 | 7 | "github.com/eolinker/apinto/discovery" 8 | ) 9 | 10 | func TestConsulGetNodes(t *testing.T) { 11 | //创建consul 12 | accessConfig := &AccessConfig{ 13 | Address: []string{"http://172.18.166.219:8500"}, 14 | //Params: map[string]string{"token": "a92316d8-5c99-4fa0-b4cd-30b9e66718aa"}, //token在10.1.94.48下的/opt/consul/server_config/node_3/conf/acl.hcl文件里 15 | } 16 | clients := newClients(accessConfig.Address, accessConfig.Params) 17 | 18 | newConsul := &consul{ 19 | clients: clients, 20 | 21 | services: discovery.NewAppContainer(), 22 | locker: sync.RWMutex{}, 23 | context: nil, 24 | cancelFunc: nil, 25 | } 26 | 27 | newConsul.Start() 28 | 29 | APP, _ := newConsul.GetApp("apinto-test") 30 | 31 | t.Log(APP) 32 | 33 | _, _ = newConsul.GetApp("redis") 34 | 35 | select {} 36 | } 37 | -------------------------------------------------------------------------------- /drivers/discovery/consul/driver.go: -------------------------------------------------------------------------------- 1 | package consul 2 | 3 | import ( 4 | "github.com/eolinker/apinto/discovery" 5 | "github.com/eolinker/apinto/drivers" 6 | "github.com/eolinker/eosc" 7 | "sync" 8 | ) 9 | 10 | const ( 11 | driverName = "consul" 12 | ) 13 | 14 | // Create 创建consul驱动实例 15 | func Create(id, name string, workerConfig *Config, workers map[eosc.RequireId]eosc.IWorker) (eosc.IWorker, error) { 16 | 17 | clients := newClients(workerConfig.Config.Address, workerConfig.Config.Params) 18 | 19 | c := &consul{ 20 | WorkerBase: drivers.Worker(id, name), 21 | clients: clients, 22 | services: discovery.NewAppContainer(), 23 | locker: sync.RWMutex{}, 24 | } 25 | return c, nil 26 | } 27 | -------------------------------------------------------------------------------- /drivers/discovery/consul/factory.go: -------------------------------------------------------------------------------- 1 | package consul 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | var name = "discovery_consul" 9 | 10 | //Register 注册consul驱动工厂 11 | func Register(register eosc.IExtenderDriverRegister) { 12 | register.RegisterExtenderDriver(name, NewFactory()) 13 | } 14 | 15 | func NewFactory() eosc.IExtenderDriverFactory { 16 | return drivers.NewFactory[Config](Create) 17 | } 18 | -------------------------------------------------------------------------------- /drivers/discovery/eureka/config.go: -------------------------------------------------------------------------------- 1 | package eureka 2 | 3 | import ( 4 | "fmt" 5 | "net/url" 6 | "strings" 7 | ) 8 | 9 | const defaultScheme = "http" 10 | 11 | //Config eureka驱动配置 12 | type Config struct { 13 | Config AccessConfig `json:"config" label:"配置信息"` 14 | } 15 | 16 | //AccessConfig 接入地址配置 17 | type AccessConfig struct { 18 | Address []string `json:"address" label:"eureka地址"` 19 | Params map[string]string `json:"params" label:"参数"` 20 | } 21 | 22 | func (c *Config) getAddress() []string { 23 | adds := make([]string, 0, len(c.Config.Address)) 24 | for _, a := range c.Config.Address { 25 | if !strings.HasPrefix(a, "http://") && !strings.HasPrefix(a, "https://") { 26 | a = fmt.Sprintf("%s://%s", defaultScheme, a) 27 | } 28 | adds = append(adds, a) 29 | } 30 | return adds 31 | } 32 | func (c *Config) getParams() url.Values { 33 | p := url.Values{} 34 | for k, v := range c.Config.Params { 35 | p.Set(k, v) 36 | } 37 | return p 38 | } 39 | -------------------------------------------------------------------------------- /drivers/discovery/eureka/driver.go: -------------------------------------------------------------------------------- 1 | package eureka 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "sync" 6 | 7 | "github.com/eolinker/apinto/discovery" 8 | "github.com/eolinker/eosc" 9 | ) 10 | 11 | const ( 12 | driverName = "eureka" 13 | ) 14 | 15 | // Create 创建eureka驱动实例 16 | func Create(id, name string, conf *Config, workers map[eosc.RequireId]eosc.IWorker) (eosc.IWorker, error) { 17 | 18 | return &eureka{ 19 | WorkerBase: drivers.Worker(id, name), 20 | client: newClient(conf.getAddress(), conf.getParams()), 21 | services: discovery.NewAppContainer(), 22 | locker: sync.RWMutex{}, 23 | }, nil 24 | } 25 | -------------------------------------------------------------------------------- /drivers/discovery/eureka/eureka_test.go: -------------------------------------------------------------------------------- 1 | package eureka 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "sync" 6 | "testing" 7 | 8 | "github.com/eolinker/apinto/discovery" 9 | ) 10 | 11 | func TestGetApp(t *testing.T) { 12 | serviceName := "DEMO" 13 | cfg := Config{ 14 | Config: AccessConfig{ 15 | Address: []string{ 16 | "10.1.94.48:8761/eureka", 17 | }, 18 | Params: map[string]string{ 19 | "username": "test", 20 | "password": "test", 21 | }, 22 | }, 23 | } 24 | e := &eureka{ 25 | WorkerBase: drivers.Worker("1", name), 26 | 27 | client: newClient(cfg.getAddress(), cfg.getParams()), 28 | services: discovery.NewAppContainer(), 29 | locker: sync.RWMutex{}, 30 | } 31 | app, err := e.GetApp(serviceName) 32 | if err != nil { 33 | t.Fatal(err) 34 | } 35 | for _, node := range app.Nodes() { 36 | t.Log(node.ID()) 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /drivers/discovery/eureka/factory.go: -------------------------------------------------------------------------------- 1 | package eureka 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | var name = "discovery_eureka" 9 | 10 | //Register 注册eureka驱动工厂 11 | func Register(register eosc.IExtenderDriverRegister) { 12 | register.RegisterExtenderDriver(name, NewFactory()) 13 | } 14 | func NewFactory() eosc.IExtenderDriverFactory { 15 | return drivers.NewFactory[Config](Create) 16 | } 17 | -------------------------------------------------------------------------------- /drivers/discovery/nacos/config.go: -------------------------------------------------------------------------------- 1 | package nacos 2 | 3 | const defaultScheme = "http" 4 | 5 | // Config nacos驱动配置 6 | type Config struct { 7 | Config AccessConfig `json:"config" label:"配置信息"` 8 | } 9 | 10 | // AccessConfig 接入地址配置 11 | type AccessConfig struct { 12 | Address []string `json:"address" label:"nacos地址"` 13 | Params map[string]string `json:"params" label:"参数"` 14 | } 15 | -------------------------------------------------------------------------------- /drivers/discovery/nacos/driver.go: -------------------------------------------------------------------------------- 1 | package nacos 2 | 3 | import ( 4 | "fmt" 5 | "sync" 6 | 7 | "github.com/eolinker/apinto/drivers" 8 | 9 | "github.com/eolinker/apinto/discovery" 10 | "github.com/eolinker/eosc" 11 | ) 12 | 13 | const ( 14 | driverName = "nacos" 15 | ) 16 | 17 | // Create 创建nacos驱动实例 18 | func Create(id, name string, cfg *Config, workers map[eosc.RequireId]eosc.IWorker) (eosc.IWorker, error) { 19 | c, err := newClient(name, cfg.Config.Address, cfg.Config.Params) 20 | if err != nil { 21 | return nil, fmt.Errorf("create nacos client fail. err: %w", err) 22 | } 23 | return &executor{ 24 | WorkerBase: drivers.Worker(id, name), 25 | client: c, 26 | services: discovery.NewAppContainer(), 27 | locker: sync.RWMutex{}, 28 | }, nil 29 | 30 | } 31 | -------------------------------------------------------------------------------- /drivers/discovery/nacos/factory.go: -------------------------------------------------------------------------------- 1 | package nacos 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | var name = "discovery_nacos" 9 | 10 | //Register 注册nacos驱动工厂 11 | func Register(register eosc.IExtenderDriverRegister) { 12 | register.RegisterExtenderDriver(name, NewFactory()) 13 | } 14 | func NewFactory() eosc.IExtenderDriverFactory { 15 | return drivers.NewFactory[Config](Create) 16 | } 17 | -------------------------------------------------------------------------------- /drivers/discovery/nacos/nacos_test.go: -------------------------------------------------------------------------------- 1 | package nacos 2 | 3 | import ( 4 | "sync" 5 | "testing" 6 | 7 | "github.com/eolinker/apinto/discovery" 8 | ) 9 | 10 | func TestGetApp(t *testing.T) { 11 | serviceName := "demo" 12 | cfg := Config{ 13 | Config: AccessConfig{ 14 | Address: []string{ 15 | "172.18.166.219:8848", 16 | }, 17 | Params: map[string]string{ 18 | "namespaceId": "82eab342-52a5-400d-a601-3dd7b7d4029c", 19 | }, 20 | }, 21 | } 22 | c, _ := newClient("asd", cfg.Config.Address, cfg.Config.Params) 23 | n := &executor{ 24 | client: c, 25 | services: discovery.NewAppContainer(), 26 | locker: sync.RWMutex{}, 27 | } 28 | app, err := n.GetApp(serviceName) 29 | if err != nil { 30 | t.Fatal(err) 31 | } 32 | for _, node := range app.Nodes() { 33 | t.Log(node.ID()) 34 | } 35 | ns, err := n.GetApp(serviceName) 36 | if err == nil { 37 | t.Log(len(ns.Nodes())) 38 | } else { 39 | t.Error("nodes error") 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /drivers/discovery/polaris/config.go: -------------------------------------------------------------------------------- 1 | package polaris 2 | 3 | import ( 4 | "github.com/polarismesh/polaris-go" 5 | ) 6 | 7 | // Config 北极星驱动配置 8 | type Config struct { 9 | Config AccessConfig `json:"config" label:"配置信息"` 10 | } 11 | 12 | // AccessConfig 接入地址配置 13 | type AccessConfig struct { 14 | Address []string `json:"address" label:"北极星地址"` 15 | Namespace string `json:"namespace" label:"命名空间"` 16 | Params map[string]string `json:"params" label:"参数"` 17 | } 18 | 19 | // polarisClient 北极星主调端 20 | type polarisClients struct { 21 | consumerAPI polaris.ConsumerAPI 22 | namespace string 23 | } 24 | -------------------------------------------------------------------------------- /drivers/discovery/polaris/driver.go: -------------------------------------------------------------------------------- 1 | package polaris 2 | 3 | import ( 4 | "sync" 5 | 6 | "github.com/eolinker/apinto/discovery" 7 | "github.com/eolinker/apinto/drivers" 8 | "github.com/eolinker/eosc" 9 | ) 10 | 11 | const ( 12 | driverName = "polaris" 13 | ) 14 | 15 | // Create 创建北极星驱动实例 16 | func Create(id, name string, workerConfig *Config, workers map[eosc.RequireId]eosc.IWorker) (eosc.IWorker, error) { 17 | clients := newClients(workerConfig.Config.Address, workerConfig.Config.Namespace, workerConfig.Config.Params) 18 | c := &polarisDiscovery{ 19 | WorkerBase: drivers.Worker(id, name), 20 | clients: clients, 21 | services: discovery.NewAppContainer(), 22 | locker: sync.RWMutex{}, 23 | } 24 | return c, nil 25 | } 26 | -------------------------------------------------------------------------------- /drivers/discovery/polaris/factory.go: -------------------------------------------------------------------------------- 1 | package polaris 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | var name = "discovery_polaris" 9 | 10 | // Register 注册北极星驱动工厂 11 | func Register(register eosc.IExtenderDriverRegister) { 12 | _ = register.RegisterExtenderDriver(name, NewFactory()) 13 | } 14 | 15 | func NewFactory() eosc.IExtenderDriverFactory { 16 | return drivers.NewFactory[Config](Create) 17 | } 18 | -------------------------------------------------------------------------------- /drivers/discovery/polaris/polaris_test.go: -------------------------------------------------------------------------------- 1 | package polaris 2 | 3 | import ( 4 | "sync" 5 | "testing" 6 | 7 | "github.com/eolinker/apinto/discovery" 8 | ) 9 | 10 | func TestPolarisGetNodes(t *testing.T) { 11 | accessConfig := &AccessConfig{ 12 | Address: []string{"127.0.0.1:8091"}, 13 | Namespace: "default", 14 | Params: map[string]string{}, 15 | } 16 | clients := newClients(accessConfig.Address, accessConfig.Namespace, accessConfig.Params) 17 | 18 | newConsul := &polarisDiscovery{ 19 | clients: clients, 20 | services: discovery.NewAppContainer(), 21 | locker: sync.RWMutex{}, 22 | context: nil, 23 | cancelFunc: nil, 24 | } 25 | 26 | _ = newConsul.Start() 27 | 28 | APP, _ := newConsul.GetApp("polaris_service") 29 | 30 | t.Log(len(APP.Nodes())) 31 | 32 | select {} 33 | } 34 | -------------------------------------------------------------------------------- /drivers/discovery/static/config.go: -------------------------------------------------------------------------------- 1 | package static 2 | 3 | // Config 静态服务发现配置 4 | type Config struct { 5 | HealthOn bool `json:"health_on" label:"是否开启健康检查"` 6 | Health *HealthConfig `json:"health" label:"健康检查配置" switch:"health_on===true"` 7 | } 8 | 9 | // HealthConfig 健康检查配置 10 | type HealthConfig struct { 11 | Scheme string `json:"scheme" enum:"HTTP,HTTPS" label:"请求协议"` 12 | Method string `json:"method" enum:"GET,POST,PUT" label:"请求方式"` 13 | URL string `json:"url" label:"请求URL"` 14 | SuccessCode int `json:"success_code" label:"成功状态码" minimum:"100" description:"最小值:100"` 15 | Period int `json:"period" label:"检查频率" minimum:"1" default:"30" description:"单位:s,最小值:1"` 16 | Timeout int `json:"timeout" label:"超时时间" description:"单位:ms"` 17 | } 18 | -------------------------------------------------------------------------------- /drivers/discovery/static/driver.go: -------------------------------------------------------------------------------- 1 | package static 2 | 3 | import ( 4 | "github.com/eolinker/apinto/discovery" 5 | "github.com/eolinker/apinto/drivers" 6 | 7 | "github.com/eolinker/eosc" 8 | ) 9 | 10 | // Create 创建静态服务发现驱动的实例 11 | func Create(id, name string, cfg *Config, workers map[eosc.RequireId]eosc.IWorker) (eosc.IWorker, error) { 12 | 13 | s := &static{ 14 | WorkerBase: drivers.Worker(id, name), 15 | services: discovery.NewAppContainer(), 16 | cfg: cfg, 17 | } 18 | return s, nil 19 | } 20 | 21 | func CreateAnonymous(conf *Config) discovery.IDiscovery { 22 | s := &static{ 23 | cfg: conf, 24 | services: discovery.NewAppContainer(), 25 | } 26 | _ = s.Start() 27 | return s 28 | } 29 | -------------------------------------------------------------------------------- /drivers/discovery/static/factory.go: -------------------------------------------------------------------------------- 1 | package static 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | var name = "discovery_static" 9 | 10 | // Register 注册静态服务发现的驱动工厂 11 | func Register(register eosc.IExtenderDriverRegister) { 12 | _ = register.RegisterExtenderDriver(name, NewFactory()) 13 | } 14 | func NewFactory() eosc.IExtenderDriverFactory { 15 | return drivers.NewFactory[Config](Create) 16 | } 17 | -------------------------------------------------------------------------------- /drivers/output/fileoutput/config.go: -------------------------------------------------------------------------------- 1 | package fileoutput 2 | 3 | import ( 4 | "github.com/eolinker/eosc" 5 | ) 6 | 7 | type Config struct { 8 | Scopes []string `json:"scopes" label:"作用域"` 9 | File string `json:"file" yaml:"file" label:"文件名称"` 10 | Dir string `json:"dir" yaml:"dir" label:"文件存放目录"` 11 | Period string `json:"period" yaml:"period" enum:"hour,day" label:"日志分割周期"` 12 | Expire int `json:"expire" yaml:"expire" label:"日志保存时间" description:"单位:天" default:"7" minimum:"1"` 13 | Type string `json:"type" yaml:"type" enum:"json,line" label:"输出格式"` 14 | ContentResize []ContentResize `json:"content_resize" yaml:"content_resize" label:"内容截断配置" switch:"type===json"` 15 | Formatter eosc.FormatterConfig `json:"formatter" yaml:"formatter" label:"格式化配置"` 16 | } 17 | 18 | type ContentResize struct { 19 | Size int `json:"size" label:"内容截断大小" description:"单位:M" default:"10" minimum:"0"` 20 | Suffix string `json:"suffix" label:"匹配标签后缀"` 21 | } 22 | -------------------------------------------------------------------------------- /drivers/output/fileoutput/error.go: -------------------------------------------------------------------------------- 1 | package fileoutput 2 | 3 | import "errors" 4 | 5 | var ( 6 | errorConfigType = errors.New("error config type") 7 | errorFormatterType = errors.New("error formatter type") 8 | errorNilConfig = errors.New("error nil config") 9 | errorConfDir = errors.New("error dir is illegal") 10 | errorConfFile = errors.New("error file is illegal") 11 | errorConfPeriod = errors.New("error period is illegal") 12 | errFormatterConf = errors.New("formatter config can not be null. ") 13 | ) 14 | -------------------------------------------------------------------------------- /drivers/output/fileoutput/factory.go: -------------------------------------------------------------------------------- 1 | package fileoutput 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | const name = "file_output" 9 | 10 | // Register 注册file_output驱动工厂 11 | func Register(register eosc.IExtenderDriverRegister) { 12 | register.RegisterExtenderDriver(name, NewFactory()) 13 | } 14 | 15 | func NewFactory() eosc.IExtenderDriverFactory { 16 | 17 | return drivers.NewFactory[Config](Create, Check) 18 | } 19 | -------------------------------------------------------------------------------- /drivers/output/httpoutput/error.go: -------------------------------------------------------------------------------- 1 | package httpoutput 2 | 3 | import "errors" 4 | 5 | var ( 6 | errConfigType = errors.New("config type does not match. ") 7 | errMethod = errors.New("method is illegal. ") 8 | errUrlNull = errors.New("url can not be null. ") 9 | errFormatterType = errors.New("type is illegal. ") 10 | errFormatterConf = errors.New("formatter config can not be null. ") 11 | ) 12 | -------------------------------------------------------------------------------- /drivers/output/httpoutput/factory.go: -------------------------------------------------------------------------------- 1 | package httpoutput 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | const name = "http_output" 9 | 10 | // Register 注册file_output驱动工厂 11 | func Register(register eosc.IExtenderDriverRegister) { 12 | register.RegisterExtenderDriver(name, NewFactory()) 13 | } 14 | func NewFactory() eosc.IExtenderDriverFactory { 15 | 16 | return drivers.NewFactory[Config](Create) 17 | } 18 | -------------------------------------------------------------------------------- /drivers/output/kafka/driver.go: -------------------------------------------------------------------------------- 1 | package kafka 2 | 3 | import ( 4 | "reflect" 5 | 6 | "github.com/eolinker/apinto/drivers" 7 | "github.com/eolinker/eosc" 8 | ) 9 | 10 | type Driver struct { 11 | configType reflect.Type 12 | } 13 | 14 | func Check(v *Config, workers map[eosc.RequireId]eosc.IWorker) error { 15 | _, err := v.doCheck() 16 | 17 | return err 18 | } 19 | 20 | func check(v interface{}) (*ProducerConfig, error) { 21 | conf, err := drivers.Assert[Config](v) 22 | if err != nil { 23 | return nil, err 24 | } 25 | 26 | pConf, err := conf.doCheck() 27 | if err != nil { 28 | return nil, err 29 | } 30 | return pConf, nil 31 | 32 | } 33 | 34 | func Create(id, name string, conf *Config, workers map[eosc.RequireId]eosc.IWorker) (eosc.IWorker, error) { 35 | cfg, err := conf.doCheck() 36 | if err != nil { 37 | return nil, err 38 | } 39 | 40 | worker := &Output{ 41 | WorkerBase: drivers.Worker(id, name), 42 | producer: nil, 43 | config: cfg, 44 | } 45 | 46 | return worker, err 47 | } 48 | -------------------------------------------------------------------------------- /drivers/output/kafka/factory.go: -------------------------------------------------------------------------------- 1 | package kafka 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | const name = "kafka_output" 9 | 10 | // Register 注册kafka_output驱动工厂 11 | func Register(register eosc.IExtenderDriverRegister) { 12 | register.RegisterExtenderDriver(name, NewFactory()) 13 | } 14 | 15 | func NewFactory() eosc.IExtenderDriverFactory { 16 | return drivers.NewFactory[Config](Create, Check) 17 | } 18 | -------------------------------------------------------------------------------- /drivers/output/kafka/sarama_client.go: -------------------------------------------------------------------------------- 1 | package kafka 2 | 3 | import ( 4 | "crypto/sha256" 5 | "crypto/sha512" 6 | 7 | "github.com/xdg-go/scram" 8 | ) 9 | 10 | var ( 11 | SHA256 scram.HashGeneratorFcn = sha256.New 12 | SHA512 scram.HashGeneratorFcn = sha512.New 13 | ) 14 | 15 | type XDGSCRAMClient struct { 16 | *scram.Client 17 | *scram.ClientConversation 18 | scram.HashGeneratorFcn 19 | } 20 | 21 | func (x *XDGSCRAMClient) Begin(userName, password, authzID string) (err error) { 22 | x.Client, err = x.HashGeneratorFcn.NewClient(userName, password, authzID) 23 | if err != nil { 24 | return err 25 | } 26 | x.ClientConversation = x.Client.NewConversation() 27 | return nil 28 | } 29 | 30 | func (x *XDGSCRAMClient) Step(challenge string) (response string, err error) { 31 | response, err = x.ClientConversation.Step(challenge) 32 | return 33 | } 34 | 35 | func (x *XDGSCRAMClient) Done() bool { 36 | return x.ClientConversation.Done() 37 | } 38 | -------------------------------------------------------------------------------- /drivers/output/loki/factory.go: -------------------------------------------------------------------------------- 1 | package loki 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/eolinker/apinto/drivers" 7 | "github.com/eolinker/eosc" 8 | ) 9 | 10 | const name = "loki_output" 11 | 12 | // Register 注册nsqd驱动工厂 13 | func Register(register eosc.IExtenderDriverRegister) { 14 | register.RegisterExtenderDriver(name, NewFactory()) 15 | } 16 | func NewFactory() eosc.IExtenderDriverFactory { 17 | 18 | return drivers.NewFactory[Config](Create) 19 | } 20 | 21 | func Create(id, name string, conf *Config, workers map[eosc.RequireId]eosc.IWorker) (eosc.IWorker, error) { 22 | cfg, err := check(conf) 23 | if err != nil { 24 | return nil, err 25 | } 26 | ctx, cancel := context.WithCancel(context.Background()) 27 | w := &Output{ 28 | WorkerBase: drivers.Worker(id, name), 29 | outputChan: make(chan *Request, 100), 30 | ctx: ctx, 31 | cancel: cancel, 32 | } 33 | err = w.reset(cfg) 34 | if err != nil { 35 | return nil, err 36 | } 37 | go w.doLoop() 38 | return w, nil 39 | } 40 | -------------------------------------------------------------------------------- /drivers/output/nsq/config.go: -------------------------------------------------------------------------------- 1 | package nsq 2 | 3 | import "github.com/eolinker/eosc" 4 | 5 | type Config struct { 6 | Scopes []string `json:"scopes" label:"作用域"` 7 | Topic string `json:"topic" yaml:"topic" label:"topic"` 8 | Address []string `json:"address" yaml:"address" label:"请求地址"` 9 | AuthSecret string `json:"auth_secret" yaml:"auth_secret" label:"鉴权secret"` 10 | ClientConf map[string]interface{} `json:"nsq_conf" yaml:"nsq_conf" skip:""` 11 | Type string `json:"type" yaml:"type" enum:"json,line" label:"输出格式"` 12 | ContentResize []ContentResize `json:"content_resize" yaml:"content_resize" label:"内容截断配置" switch:"type===json"` 13 | Formatter eosc.FormatterConfig `json:"formatter" yaml:"formatter" label:"格式化配置"` 14 | } 15 | 16 | type ContentResize struct { 17 | Size int `json:"size" label:"内容截断大小" description:"单位:M" default:"10" minimum:"0"` 18 | Suffix string `json:"suffix" label:"匹配标签后缀"` 19 | } 20 | -------------------------------------------------------------------------------- /drivers/output/nsq/error.go: -------------------------------------------------------------------------------- 1 | package nsq 2 | 3 | import "errors" 4 | 5 | var ( 6 | errConfigType = errors.New("config type does not match. ") 7 | errNsqConfNull = errors.New("config is null. ") 8 | errTopicNull = errors.New("topic can not be null. ") 9 | errAddressNull = errors.New("Address can not be null. ") 10 | errFormatterType = errors.New("type is illegal. ") 11 | errFormatterConf = errors.New("formatter config can not be null. ") 12 | errNoValidProducer = errors.New("no valid producer. ") 13 | errProducerInvalid = errors.New("the producer is invalid. ") 14 | ) 15 | -------------------------------------------------------------------------------- /drivers/output/nsq/factory.go: -------------------------------------------------------------------------------- 1 | package nsq 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | const name = "nsqd" 9 | 10 | // Register 注册nsqd驱动工厂 11 | func Register(register eosc.IExtenderDriverRegister) { 12 | register.RegisterExtenderDriver(name, NewFactory()) 13 | } 14 | func NewFactory() eosc.IExtenderDriverFactory { 15 | 16 | return drivers.NewFactory[Config](Create) 17 | } 18 | -------------------------------------------------------------------------------- /drivers/output/prometheus/error.go: -------------------------------------------------------------------------------- 1 | package prometheus 2 | 3 | import "errors" 4 | 5 | var ( 6 | errorConfigType = errors.New("error config type") 7 | errorNullMetrics = errors.New("error metrics can't be null. ") 8 | errorNullMetric = errors.New("error metric can't be null. ") 9 | errorNullScopeMetric = errors.New("error scope can't be null string. ") 10 | 11 | errorNullLabelsFormat = "error metric %s labels can't be null. " 12 | errorPathFormat = `error path %s is illegal. ` 13 | errorCollectorFormat = `error collector %s is illegal. ` 14 | errorMetricTypeFormat = `error metric_type %s is illegal. ` 15 | errorMetricReduplicatedFormat = `error metric %s is reduplicated. ` 16 | errorLabelFormat = `error label %s is illegal. ` 17 | errorLabelReduplicatedFormat = `error metric %s's label name %s is reduplicated. ` 18 | errorNullLabelFormat = `error metric %s's label can't be null string'. ` 19 | errorObjectivesFormat = `error metric %s's objectives %s is illegal. ` 20 | ) 21 | -------------------------------------------------------------------------------- /drivers/output/prometheus/factory.go: -------------------------------------------------------------------------------- 1 | package prometheus 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | const name = "prometheus_output" 9 | 10 | // Register 注册prometheus_output驱动工厂 11 | func Register(register eosc.IExtenderDriverRegister) { 12 | register.RegisterExtenderDriver(name, NewFactory()) 13 | } 14 | 15 | func NewFactory() eosc.IExtenderDriverFactory { 16 | 17 | return drivers.NewFactory[Config](Create, Check) 18 | } 19 | -------------------------------------------------------------------------------- /drivers/output/syslog/driver.go: -------------------------------------------------------------------------------- 1 | package syslog 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | func check(v interface{}) (*Config, error) { 9 | conf, ok := v.(*Config) 10 | if !ok { 11 | return nil, eosc.ErrorConfigFieldUnknown 12 | } 13 | err := conf.doCheck() 14 | if err != nil { 15 | return nil, err 16 | } 17 | return conf, nil 18 | 19 | } 20 | 21 | func Create(id, name string, cfg *Config, workers map[eosc.RequireId]eosc.IWorker) (eosc.IWorker, error) { 22 | err := cfg.doCheck() 23 | 24 | if err != nil { 25 | return nil, err 26 | } 27 | 28 | return &Output{ 29 | WorkerBase: drivers.Worker(id, name), 30 | config: cfg, 31 | writer: nil, 32 | }, nil 33 | 34 | } 35 | -------------------------------------------------------------------------------- /drivers/output/syslog/factory.go: -------------------------------------------------------------------------------- 1 | package syslog 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | const name = "syslog_output" 9 | 10 | // Register 注册file_output驱动工厂 11 | func Register(register eosc.IExtenderDriverRegister) { 12 | register.RegisterExtenderDriver(name, NewFactory()) 13 | } 14 | func NewFactory() eosc.IExtenderDriverFactory { 15 | 16 | return drivers.NewFactory[Config](Create) 17 | } 18 | -------------------------------------------------------------------------------- /drivers/output/syslog/output_test.go: -------------------------------------------------------------------------------- 1 | //go:build !windows && !plan9 2 | // +build !windows,!plan9 3 | 4 | package syslog 5 | 6 | import ( 7 | "testing" 8 | ) 9 | 10 | func TestPing(t *testing.T) { 11 | conf := &Config{ 12 | Network: "tcp", 13 | Address: "127.0.0.1:514", 14 | Level: "info", 15 | } 16 | w, err := newSysWriter(conf, "test") 17 | if err != nil { 18 | t.Fatal(err) 19 | return 20 | } 21 | n, err := w.Write([]byte("test")) 22 | if err != nil { 23 | t.Fatal(err) 24 | return 25 | } 26 | t.Logf("send %d;write %d", len([]byte("test")), n) 27 | } 28 | -------------------------------------------------------------------------------- /drivers/plugin-manager/factory.go: -------------------------------------------------------------------------------- 1 | package plugin_manager 2 | 3 | import ( 4 | "github.com/eolinker/apinto/plugin" 5 | "github.com/eolinker/eosc" 6 | "github.com/eolinker/eosc/common/bean" 7 | "github.com/eolinker/eosc/setting" 8 | ) 9 | 10 | var ( 11 | singleton *PluginManager 12 | _ eosc.ISetting = singleton 13 | ) 14 | 15 | func init() { 16 | singleton = NewPluginManager() 17 | var i plugin.IPluginManager = singleton 18 | bean.Injection(&i) 19 | } 20 | 21 | func Register(register eosc.IExtenderDriverRegister) { 22 | setting.RegisterSetting("plugin", singleton) 23 | } 24 | -------------------------------------------------------------------------------- /drivers/plugin-manager/obj.go: -------------------------------------------------------------------------------- 1 | package plugin_manager 2 | 3 | import ( 4 | "github.com/eolinker/apinto/plugin" 5 | eoscContext "github.com/eolinker/eosc/eocontext" 6 | ) 7 | 8 | type PluginObj struct { 9 | fs eoscContext.Filters 10 | id string 11 | conf map[string]*plugin.Config 12 | } 13 | 14 | func NewPluginObj(filters eoscContext.Filters, id string, conf map[string]*plugin.Config) *PluginObj { 15 | obj := &PluginObj{fs: filters, id: id, conf: conf} 16 | 17 | return obj 18 | } 19 | 20 | func (p *PluginObj) Chain(ctx eoscContext.EoContext, append ...eoscContext.IFilter) error { 21 | return eoscContext.DoChain(ctx, p.fs, append...) 22 | } 23 | func (p *PluginObj) Destroy() { 24 | 25 | handler := p.fs 26 | if handler != nil { 27 | handler.Destroy() 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /drivers/plugins/access-log/config.go: -------------------------------------------------------------------------------- 1 | package access_log 2 | 3 | import "github.com/eolinker/eosc" 4 | 5 | type Config struct { 6 | Output []eosc.RequireId `json:"output" skill:"github.com/eolinker/apinto/http-entry.http-entry.IOutput" label:"输出器列表"` 7 | } 8 | -------------------------------------------------------------------------------- /drivers/plugins/access-log/factory.go: -------------------------------------------------------------------------------- 1 | package access_log 2 | 3 | import ( 4 | "sync" 5 | 6 | "github.com/eolinker/apinto/drivers" 7 | "github.com/eolinker/eosc" 8 | "github.com/eolinker/eosc/common/bean" 9 | ) 10 | 11 | const ( 12 | Name = "access_log" 13 | ) 14 | 15 | var ( 16 | workers eosc.IWorkers 17 | once sync.Once 18 | ) 19 | 20 | func Register(register eosc.IExtenderDriverRegister) { 21 | register.RegisterExtenderDriver(Name, NewFactory()) 22 | } 23 | 24 | type Factory struct { 25 | eosc.IExtenderDriverFactory 26 | } 27 | 28 | func NewFactory() *Factory { 29 | return &Factory{ 30 | IExtenderDriverFactory: drivers.NewFactory[Config](Create), 31 | } 32 | } 33 | 34 | func (f *Factory) Create(profession string, name string, label string, desc string, params map[string]interface{}) (eosc.IExtenderDriver, error) { 35 | once.Do(func() { 36 | bean.Autowired(&workers) 37 | }) 38 | 39 | return f.IExtenderDriverFactory.Create(profession, name, label, desc, params) 40 | } 41 | -------------------------------------------------------------------------------- /drivers/plugins/access-relational/config.go: -------------------------------------------------------------------------------- 1 | package access_relational 2 | 3 | import "github.com/eolinker/apinto/utils/response" 4 | 5 | type Rule struct { 6 | A string `yaml:"a" json:"a,omitempty" label:"Key A" description:"A key 规则,支持#{}的metrics语法" require:"true"` // ser: #{label service} => service: uuid 7 | B string `yaml:"b" json:"b,omitempty" label:"key B" description:"B Key 规则,支持#{}的metrics语法" require:"true"` // {appid} 8 | } 9 | type Config struct { 10 | Rules []*Rule `yaml:"rules" json:"rules" label:"规则" description:"规则列表, 规则为空时,不执行拦截, 多个规则时,有任意规则通过则均放行, "` 11 | Response *response.Response `yaml:"response" json:"response" label:"响应内容" description:"请求被拦截时响应的内容"` 12 | } 13 | -------------------------------------------------------------------------------- /drivers/plugins/access-relational/driver.go: -------------------------------------------------------------------------------- 1 | package access_relational 2 | -------------------------------------------------------------------------------- /drivers/plugins/access-relational/filter.go: -------------------------------------------------------------------------------- 1 | package access_relational 2 | 3 | import ( 4 | http_entry "github.com/eolinker/apinto/entries/http-entry" 5 | "github.com/eolinker/eosc/eocontext" 6 | http_context "github.com/eolinker/eosc/eocontext/http-context" 7 | ) 8 | 9 | func (w *AccessRelational) DoHttpFilter(ctx http_context.IHttpContext, next eocontext.IChain) (err error) { 10 | 11 | if len(w.rules) == 0 { 12 | return next.DoChain(ctx) 13 | } 14 | entry := http_entry.NewEntry(ctx) 15 | for _, rule := range w.rules { 16 | if rule.Check(entry) { 17 | return next.DoChain(ctx) 18 | } 19 | } 20 | 21 | httpContext, err := http_context.Assert(ctx) 22 | if err != nil { 23 | return err 24 | } 25 | w.response.Response(httpContext) 26 | return nil 27 | } 28 | 29 | func (w *AccessRelational) DoFilter(ctx eocontext.EoContext, next eocontext.IChain) (err error) { 30 | return http_context.DoHttpFilter(w, ctx, next) 31 | } 32 | -------------------------------------------------------------------------------- /drivers/plugins/acl/config.go: -------------------------------------------------------------------------------- 1 | package acl 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | type Config struct { 9 | Allow []string `json:"allow"` 10 | Deny []string `json:"deny"` 11 | HideGroupsHeader bool `json:"hide_groups_header"` 12 | } 13 | 14 | func Create(id, name string, conf *Config, workers map[eosc.RequireId]eosc.IWorker) (eosc.IWorker, error) { 15 | allow := make(map[string]struct{}) 16 | deny := make(map[string]struct{}) 17 | for _, a := range conf.Allow { 18 | allow[a] = struct{}{} 19 | } 20 | for _, d := range conf.Deny { 21 | deny[d] = struct{}{} 22 | } 23 | return &executor{ 24 | WorkerBase: drivers.Worker(id, name), 25 | cfg: conf, 26 | allow: allow, 27 | deny: deny, 28 | }, nil 29 | } 30 | -------------------------------------------------------------------------------- /drivers/plugins/acl/factory.go: -------------------------------------------------------------------------------- 1 | package acl 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | const ( 9 | Name = "acl" 10 | ) 11 | 12 | func Register(register eosc.IExtenderDriverRegister) { 13 | register.RegisterExtenderDriver(Name, NewFactory()) 14 | } 15 | 16 | func NewFactory() eosc.IExtenderDriverFactory { 17 | return drivers.NewFactory[Config](Create) 18 | } 19 | -------------------------------------------------------------------------------- /drivers/plugins/aes/aes_test.go: -------------------------------------------------------------------------------- 1 | package aes 2 | 3 | import "testing" 4 | 5 | func TestAes(t *testing.T) { 6 | 7 | } 8 | -------------------------------------------------------------------------------- /drivers/plugins/aes/factory.go: -------------------------------------------------------------------------------- 1 | package aes 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | const ( 9 | Name = "aes" 10 | ) 11 | 12 | func Register(register eosc.IExtenderDriverRegister) { 13 | register.RegisterExtenderDriver(Name, NewFactory()) 14 | } 15 | 16 | func NewFactory() eosc.IExtenderDriverFactory { 17 | return drivers.NewFactory[Config](Create) 18 | } 19 | -------------------------------------------------------------------------------- /drivers/plugins/ai-formatter/config.go: -------------------------------------------------------------------------------- 1 | package ai_formatter 2 | 3 | import ( 4 | "github.com/eolinker/eosc" 5 | ) 6 | 7 | type Config struct { 8 | Provider string `json:"provider"` 9 | Model string `json:"model"` 10 | Config string `json:"config"` 11 | } 12 | 13 | func checkConfig(v interface{}) (*Config, error) { 14 | conf, ok := v.(*Config) 15 | if !ok { 16 | return nil, eosc.ErrorConfigType 17 | } 18 | return conf, nil 19 | } 20 | -------------------------------------------------------------------------------- /drivers/plugins/ai-formatter/driver.go: -------------------------------------------------------------------------------- 1 | package ai_formatter 2 | 3 | import ( 4 | "strings" 5 | 6 | "github.com/eolinker/apinto/drivers" 7 | "github.com/eolinker/eosc" 8 | ) 9 | 10 | func Create(id, name string, v *Config, workers map[eosc.RequireId]eosc.IWorker) (eosc.IWorker, error) { 11 | _, err := checkConfig(v) 12 | if err != nil { 13 | return nil, err 14 | } 15 | provider := strings.Split(v.Provider, "@") 16 | 17 | w := &executor{ 18 | WorkerBase: drivers.Worker(id, name), 19 | model: v.Model, 20 | modelCfg: v.Config, 21 | provider: provider[0], 22 | } 23 | if err != nil { 24 | return nil, err 25 | } 26 | return w, err 27 | } 28 | -------------------------------------------------------------------------------- /drivers/plugins/ai-formatter/factory.go: -------------------------------------------------------------------------------- 1 | package ai_formatter 2 | 3 | import ( 4 | "sync" 5 | 6 | "github.com/eolinker/eosc/common/bean" 7 | 8 | "github.com/eolinker/apinto/drivers" 9 | "github.com/eolinker/eosc" 10 | ) 11 | 12 | const ( 13 | Name = "ai_formatter" 14 | ) 15 | 16 | var ( 17 | workerResources eosc.IWorkers 18 | once sync.Once 19 | ) 20 | 21 | func Register(register eosc.IExtenderDriverRegister) { 22 | register.RegisterExtenderDriver(Name, NewFactory()) 23 | } 24 | 25 | type Factory struct { 26 | eosc.IExtenderDriverFactory 27 | } 28 | 29 | func NewFactory() *Factory { 30 | return &Factory{ 31 | IExtenderDriverFactory: drivers.NewFactory[Config](Create), 32 | } 33 | } 34 | 35 | func (f *Factory) Create(profession string, name string, label string, desc string, params map[string]interface{}) (eosc.IExtenderDriver, error) { 36 | once.Do(func() { 37 | bean.Autowired(&workerResources) 38 | }) 39 | return f.IExtenderDriverFactory.Create(profession, name, label, desc, params) 40 | } 41 | -------------------------------------------------------------------------------- /drivers/plugins/ai-prompt/config.go: -------------------------------------------------------------------------------- 1 | package ai_prompt 2 | 3 | type Config struct { 4 | Prompt string `json:"prompt"` 5 | Variables []Variable `json:"variables"` 6 | } 7 | 8 | type Variable struct { 9 | Key string `json:"key"` 10 | Require bool `json:"require"` 11 | } 12 | -------------------------------------------------------------------------------- /drivers/plugins/ai-prompt/driver.go: -------------------------------------------------------------------------------- 1 | package ai_prompt 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | func Create(id, name string, v *Config, workers map[eosc.RequireId]eosc.IWorker) (eosc.IWorker, error) { 9 | w := &executor{ 10 | WorkerBase: drivers.Worker(id, name), 11 | } 12 | err := w.reset(v, workers) 13 | return w, err 14 | } 15 | -------------------------------------------------------------------------------- /drivers/plugins/ai-prompt/factory.go: -------------------------------------------------------------------------------- 1 | package ai_prompt 2 | 3 | import ( 4 | "sync" 5 | 6 | "github.com/eolinker/apinto/drivers" 7 | "github.com/eolinker/eosc" 8 | "github.com/eolinker/eosc/common/bean" 9 | ) 10 | 11 | const ( 12 | Name = "ai_prompt" 13 | ) 14 | 15 | var ( 16 | customerVar eosc.ICustomerVar 17 | once sync.Once 18 | ) 19 | 20 | func init() { 21 | once.Do(func() { 22 | bean.Autowired(&customerVar) 23 | }) 24 | } 25 | 26 | func Register(register eosc.IExtenderDriverRegister) { 27 | register.RegisterExtenderDriver(Name, NewFactory()) 28 | } 29 | 30 | type Factory struct { 31 | eosc.IExtenderDriverFactory 32 | } 33 | 34 | func NewFactory() *Factory { 35 | return &Factory{ 36 | IExtenderDriverFactory: drivers.NewFactory[Config](Create), 37 | } 38 | } 39 | 40 | func (f *Factory) Create(profession string, name string, label string, desc string, params map[string]interface{}) (eosc.IExtenderDriver, error) { 41 | return f.IExtenderDriverFactory.Create(profession, name, label, desc, params) 42 | } 43 | -------------------------------------------------------------------------------- /drivers/plugins/app/config.go: -------------------------------------------------------------------------------- 1 | package app 2 | 3 | type Config struct { 4 | ForceAuth bool `json:"force_auth" label:"是否强制认证"` 5 | } 6 | -------------------------------------------------------------------------------- /drivers/plugins/app/driver.go: -------------------------------------------------------------------------------- 1 | package app 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | func Create(id, name string, v *Config, workers map[eosc.RequireId]eosc.IWorker) (eosc.IWorker, error) { 9 | return &App{ 10 | WorkerBase: drivers.Worker(id, name), 11 | }, nil 12 | } 13 | -------------------------------------------------------------------------------- /drivers/plugins/app/factory.go: -------------------------------------------------------------------------------- 1 | package app 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/apinto/drivers/app/manager" 6 | "github.com/eolinker/eosc" 7 | "github.com/eolinker/eosc/common/bean" 8 | "sync" 9 | ) 10 | 11 | const ( 12 | Name = "plugin_app" 13 | ) 14 | 15 | var ( 16 | ones sync.Once 17 | appManager manager.IManager 18 | ) 19 | 20 | func Register(register eosc.IExtenderDriverRegister) { 21 | register.RegisterExtenderDriver(Name, NewFactory()) 22 | } 23 | 24 | type Factory struct { 25 | eosc.IExtenderDriverFactory 26 | } 27 | 28 | func NewFactory() *Factory { 29 | return &Factory{ 30 | IExtenderDriverFactory: drivers.NewFactory[Config](Create), 31 | } 32 | } 33 | 34 | func (f *Factory) Create(profession string, name string, label string, desc string, params map[string]interface{}) (eosc.IExtenderDriver, error) { 35 | ones.Do(func() { 36 | bean.Autowired(&appManager) 37 | }) 38 | 39 | return f.IExtenderDriverFactory.Create(profession, name, label, desc, params) 40 | } 41 | -------------------------------------------------------------------------------- /drivers/plugins/auth-interceptor/factory.go: -------------------------------------------------------------------------------- 1 | package auth_interceptor 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | const ( 9 | Name = "auth_interceptor_redis" 10 | ) 11 | 12 | func Register(register eosc.IExtenderDriverRegister) { 13 | register.RegisterExtenderDriver(Name, NewFactory()) 14 | } 15 | 16 | func NewFactory() eosc.IExtenderDriverFactory { 17 | return drivers.NewFactory(Create) 18 | } 19 | -------------------------------------------------------------------------------- /drivers/plugins/auto-redirect/config.go: -------------------------------------------------------------------------------- 1 | package auto_redirect 2 | 3 | type Config struct { 4 | MaxRedirectCount int `json:"max_redirect_count" label:"最大重定向次数" description:"最大重定向次数"` 5 | PathPrefix string `json:"path_prefix" label:"重定向前缀" description:"重定向前缀"` 6 | AutoRedirect bool `json:"auto_redirect" label:"是否自动重定向" description:"是否自动重定向"` 7 | } 8 | 9 | var () 10 | 11 | func (c *Config) doCheck() error { 12 | return nil 13 | } 14 | -------------------------------------------------------------------------------- /drivers/plugins/auto-redirect/factory.go: -------------------------------------------------------------------------------- 1 | package auto_redirect 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | const ( 9 | Name = "auto_redirect" 10 | ) 11 | 12 | func Register(register eosc.IExtenderDriverRegister) { 13 | register.RegisterExtenderDriver(Name, NewFactory()) 14 | } 15 | 16 | func NewFactory() eosc.IExtenderDriverFactory { 17 | return drivers.NewFactory[Config](Create, Check) 18 | } 19 | -------------------------------------------------------------------------------- /drivers/plugins/auto-redirect/url_test.go: -------------------------------------------------------------------------------- 1 | package auto_redirect 2 | 3 | import "testing" 4 | 5 | func TestParseUrl(t *testing.T) { 6 | t.Log(insertPrefix("http://test:8982/aaa/aaa", "")) 7 | } 8 | -------------------------------------------------------------------------------- /drivers/plugins/body-check/config.go: -------------------------------------------------------------------------------- 1 | package body_check 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | type Config struct { 9 | IsEmpty bool `json:"is_empty" label:"是否允许为空"` 10 | AllowedPayloadSize int `json:"allowed_payload_size" label:"允许的最大请求体大小"` 11 | } 12 | 13 | func Create(id, name string, conf *Config, workers map[eosc.RequireId]eosc.IWorker) (eosc.IWorker, error) { 14 | 15 | bc := &BodyCheck{ 16 | WorkerBase: drivers.Worker(id, name), 17 | isEmpty: conf.IsEmpty, 18 | allowedPayloadSize: conf.AllowedPayloadSize * 1024, 19 | } 20 | 21 | return bc, nil 22 | } 23 | -------------------------------------------------------------------------------- /drivers/plugins/body-check/factory.go: -------------------------------------------------------------------------------- 1 | package body_check 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | const ( 9 | Name = "body_check" 10 | ) 11 | 12 | func Register(register eosc.IExtenderDriverRegister) { 13 | register.RegisterExtenderDriver(Name, NewFactory()) 14 | } 15 | 16 | func NewFactory() eosc.IExtenderDriverFactory { 17 | return drivers.NewFactory[Config](Create) 18 | } 19 | -------------------------------------------------------------------------------- /drivers/plugins/body-record-truncation/config.go: -------------------------------------------------------------------------------- 1 | package body_record_truncation 2 | 3 | type Config struct { 4 | BodySize int64 `json:"body_size" label:"截断大小"` 5 | } 6 | -------------------------------------------------------------------------------- /drivers/plugins/body-record-truncation/factory.go: -------------------------------------------------------------------------------- 1 | package body_record_truncation 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | const ( 9 | Name = "body-record-truncation" 10 | ) 11 | 12 | func Register(register eosc.IExtenderDriverRegister) { 13 | register.RegisterExtenderDriver(Name, NewFactory()) 14 | } 15 | 16 | func NewFactory() eosc.IExtenderDriverFactory { 17 | return drivers.NewFactory[Config](Create) 18 | } 19 | 20 | func Create(id, name string, conf *Config, workers map[eosc.RequireId]eosc.IWorker) (eosc.IWorker, error) { 21 | 22 | return &executor{ 23 | WorkerBase: drivers.Worker(id, name), 24 | bodySize: conf.BodySize << 20, 25 | }, nil 26 | } 27 | -------------------------------------------------------------------------------- /drivers/plugins/circuit-breaker/circuit-count.go: -------------------------------------------------------------------------------- 1 | package circuit_breaker 2 | 3 | import ( 4 | "sync" 5 | ) 6 | 7 | type circuitCount struct { 8 | locker sync.RWMutex 9 | //UpdateTag map[string]string 10 | CircuitBreakerInfo *CircuitBreakerInfo 11 | } 12 | 13 | func newCircuitCount() *circuitCount { 14 | return &circuitCount{ 15 | locker: sync.RWMutex{}, 16 | CircuitBreakerInfo: nil, 17 | } 18 | } 19 | 20 | func (dr *circuitCount) getCircuitBreakerInfo() *CircuitBreakerInfo { 21 | 22 | dr.locker.RLock() 23 | value := dr.CircuitBreakerInfo 24 | dr.locker.RUnlock() 25 | 26 | if value == nil { 27 | dr.locker.Lock() 28 | value = dr.CircuitBreakerInfo 29 | 30 | if value == nil { 31 | value = initCircuitBreakerInfo() 32 | dr.CircuitBreakerInfo = value 33 | } 34 | dr.locker.Unlock() 35 | 36 | } 37 | 38 | return value 39 | } 40 | 41 | func (dr *circuitCount) writeCircuitBreakerInfo(info *CircuitBreakerInfo) { 42 | 43 | dr.locker.Lock() 44 | dr.CircuitBreakerInfo = info 45 | dr.locker.Unlock() 46 | return 47 | } 48 | -------------------------------------------------------------------------------- /drivers/plugins/circuit-breaker/driver.go: -------------------------------------------------------------------------------- 1 | package circuit_breaker 2 | 3 | import ( 4 | "github.com/eolinker/eosc" 5 | ) 6 | 7 | func Check(conf *Config, workers map[eosc.RequireId]eosc.IWorker) error { 8 | 9 | return conf.doCheck() 10 | 11 | } 12 | 13 | func check(v interface{}) (*Config, error) { 14 | conf, ok := v.(*Config) 15 | if !ok { 16 | return nil, eosc.ErrorConfigFieldUnknown 17 | } 18 | err := conf.doCheck() 19 | if err != nil { 20 | return nil, err 21 | } 22 | return conf, nil 23 | } 24 | 25 | func Create(id, name string, conf *Config, workers map[eosc.RequireId]eosc.IWorker) (eosc.IWorker, error) { 26 | err := Check(conf, workers) 27 | if err != nil { 28 | return nil, err 29 | } 30 | 31 | cb := &CircuitBreaker{ 32 | 33 | counter: newCircuitCount(), 34 | conf: conf, 35 | } 36 | 37 | return cb, nil 38 | } 39 | -------------------------------------------------------------------------------- /drivers/plugins/circuit-breaker/factory.go: -------------------------------------------------------------------------------- 1 | package circuit_breaker 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | const ( 9 | Name = "circuit_breaker" 10 | ) 11 | 12 | func Register(register eosc.IExtenderDriverRegister) { 13 | register.RegisterExtenderDriver(Name, NewFactory()) 14 | } 15 | 16 | func NewFactory() eosc.IExtenderDriverFactory { 17 | return drivers.NewFactory[Config](Create) 18 | } 19 | -------------------------------------------------------------------------------- /drivers/plugins/cors/factory.go: -------------------------------------------------------------------------------- 1 | package cors 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | const ( 9 | Name = "cors" 10 | ) 11 | 12 | func Register(register eosc.IExtenderDriverRegister) { 13 | err := register.RegisterExtenderDriver(Name, NewFactory()) 14 | if err != nil { 15 | return 16 | } 17 | } 18 | 19 | func NewFactory() eosc.IExtenderDriverFactory { 20 | return drivers.NewFactory[Config](Create) 21 | } 22 | -------------------------------------------------------------------------------- /drivers/plugins/counter/callback.lua: -------------------------------------------------------------------------------- 1 | -- Redis操作key 2 | local key = KEYS[1] 3 | 4 | -- 返还次数 5 | local count = tonumber(ARGV[2]) 6 | 7 | local _count = redis.call('GET',key) 8 | if _count then 9 | redis.call('INCRBY',key,count) 10 | end -------------------------------------------------------------------------------- /drivers/plugins/counter/counter.go: -------------------------------------------------------------------------------- 1 | package counter 2 | 3 | type ICounter interface { 4 | // Lock 锁定次数 5 | Lock(count int64) error 6 | // Complete 完成扣次操作 7 | Complete(count int64) error 8 | // RollBack 回滚 9 | RollBack(count int64) error 10 | } 11 | -------------------------------------------------------------------------------- /drivers/plugins/counter/decr.lua: -------------------------------------------------------------------------------- 1 | -- Redis操作key 2 | local key = KEYS[1] 3 | 4 | -- 扣减次数 5 | local count = tonumber(ARGV[1]) 6 | 7 | local _count = redis.call('GET',key) 8 | 9 | if _count then 10 | local remain = tonumber(_count) 11 | if remain < count then 12 | return -2 13 | end 14 | redis.call('INCRBY',key,-count) 15 | return 0 16 | end 17 | return -1 18 | -------------------------------------------------------------------------------- /drivers/plugins/counter/factory.go: -------------------------------------------------------------------------------- 1 | package counter 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | const ( 9 | Name = "counter" 10 | ) 11 | 12 | func Register(register eosc.IExtenderDriverRegister) { 13 | register.RegisterExtenderDriver(Name, NewFactory()) 14 | } 15 | 16 | func NewFactory() eosc.IExtenderDriverFactory { 17 | return drivers.NewFactory[Config](Create) 18 | } 19 | -------------------------------------------------------------------------------- /drivers/plugins/counter/key_test.go: -------------------------------------------------------------------------------- 1 | package counter 2 | 3 | import "testing" 4 | 5 | func TestGenerateKey(t *testing.T) { 6 | key := newKeyGenerate("a:$b:$c:d") 7 | t.Log(key.format, key.variables) 8 | } 9 | -------------------------------------------------------------------------------- /drivers/plugins/counter/matcher/match.go: -------------------------------------------------------------------------------- 1 | package matcher 2 | 3 | import ( 4 | http_service "github.com/eolinker/eosc/eocontext/http-context" 5 | ) 6 | 7 | type IMatcher interface { 8 | Match(ctx http_service.IHttpContext) bool 9 | } 10 | 11 | type MatchParam struct { 12 | Key string `json:"key"` 13 | Kind string `json:"kind" enum:"int,string,bool" default:"string"` // int|string|bool 14 | Value []string `json:"value"` 15 | } 16 | -------------------------------------------------------------------------------- /drivers/plugins/counter/matcher/statuscode.go: -------------------------------------------------------------------------------- 1 | package matcher 2 | 3 | import http_service "github.com/eolinker/eosc/eocontext/http-context" 4 | 5 | func NewStatusCodeMatcher(codes []int) IMatcher { 6 | return &statusCodeMatcher{codes: codes} 7 | } 8 | 9 | type statusCodeMatcher struct { 10 | codes []int 11 | } 12 | 13 | func (m *statusCodeMatcher) Match(ctx http_service.IHttpContext) bool { 14 | if len(m.codes) < 1 { 15 | return true 16 | } 17 | code := ctx.Response().StatusCode() 18 | for _, c := range m.codes { 19 | if c == code { 20 | return true 21 | } 22 | } 23 | return false 24 | } 25 | -------------------------------------------------------------------------------- /drivers/plugins/counter/script.go: -------------------------------------------------------------------------------- 1 | package counter 2 | 3 | import ( 4 | _ "embed" 5 | 6 | "github.com/go-redis/redis/v8" 7 | ) 8 | 9 | var ( 10 | //go:embed decr.lua 11 | lockScriptByte []byte 12 | //go:embed callback.lua 13 | callbackScriptByte []byte 14 | 15 | lockScript *redis.Script 16 | callbackScript *redis.Script 17 | ) 18 | 19 | func init() { 20 | lockScript = redis.NewScript(string(lockScriptByte)) 21 | callbackScript = redis.NewScript(string(callbackScriptByte)) 22 | } 23 | -------------------------------------------------------------------------------- /drivers/plugins/counter/separator/empty.go: -------------------------------------------------------------------------------- 1 | package separator 2 | 3 | import http_service "github.com/eolinker/eosc/eocontext/http-context" 4 | 5 | type EmptyCounter struct { 6 | } 7 | 8 | func NewEmptyCounter() *EmptyCounter { 9 | return &EmptyCounter{} 10 | } 11 | 12 | func (e *EmptyCounter) Count(ctx http_service.IHttpContext) (int64, error) { 13 | return 1, nil 14 | } 15 | 16 | func (e *EmptyCounter) Max() int64 { 17 | return 2 18 | } 19 | 20 | func (e *EmptyCounter) Name() string { 21 | return "__empty" 22 | } 23 | -------------------------------------------------------------------------------- /drivers/plugins/data-transform/config.go: -------------------------------------------------------------------------------- 1 | package data_transform 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | type Config struct { 9 | RequestTransform bool `json:"request_transform" label:"请求转换"` 10 | ResponseTransform bool `json:"response_transform" label:"响应转换"` 11 | XMLRootTag string `json:"xml_root_tag" label:"XML根标签"` 12 | XMLDeclaration map[string]string `json:"xml_declaration" label:"XML声明"` 13 | ErrorType string `json:"error_type" label:"报错数据类型" default:"json" enum:"json,xml"` 14 | } 15 | 16 | func Create(id, name string, conf *Config, workers map[eosc.RequireId]eosc.IWorker) (eosc.IWorker, error) { 17 | 18 | bc := &executor{ 19 | WorkerBase: drivers.Worker(id, name), 20 | conf: conf, 21 | } 22 | 23 | return bc, nil 24 | } 25 | -------------------------------------------------------------------------------- /drivers/plugins/data-transform/factory.go: -------------------------------------------------------------------------------- 1 | package data_transform 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | const ( 9 | Name = "data_transform" 10 | ) 11 | 12 | func Register(register eosc.IExtenderDriverRegister) { 13 | register.RegisterExtenderDriver(Name, NewFactory()) 14 | } 15 | 16 | func NewFactory() eosc.IExtenderDriverFactory { 17 | return drivers.NewFactory[Config](Create) 18 | } 19 | -------------------------------------------------------------------------------- /drivers/plugins/dubbo2-proxy-rewrite/config.go: -------------------------------------------------------------------------------- 1 | package grpc_proxy_rewrite 2 | 3 | type Config struct { 4 | Service string `json:"service" label:"服务名称"` 5 | Method string `json:"method" label:"方法名称"` 6 | Headers map[string]string `json:"headers" label:"headers"` 7 | } 8 | -------------------------------------------------------------------------------- /drivers/plugins/dubbo2-proxy-rewrite/driver.go: -------------------------------------------------------------------------------- 1 | package grpc_proxy_rewrite 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | func check(v interface{}) (*Config, error) { 9 | conf, err := drivers.Assert[Config](v) 10 | if err != nil { 11 | return nil, err 12 | } 13 | 14 | return conf, nil 15 | } 16 | 17 | func Create(id, name string, conf *Config, workers map[eosc.RequireId]eosc.IWorker) (eosc.IWorker, error) { 18 | 19 | pw := &ProxyRewrite{ 20 | WorkerBase: drivers.Worker(id, name), 21 | headers: conf.Headers, 22 | service: conf.Service, 23 | method: conf.Method, 24 | } 25 | 26 | return pw, nil 27 | } 28 | -------------------------------------------------------------------------------- /drivers/plugins/dubbo2-proxy-rewrite/factory.go: -------------------------------------------------------------------------------- 1 | package grpc_proxy_rewrite 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | const ( 9 | Name = "dubbo2-proxy-rewrite" 10 | ) 11 | 12 | func Register(register eosc.IExtenderDriverRegister) { 13 | register.RegisterExtenderDriver(Name, NewFactory()) 14 | } 15 | 16 | func NewFactory() eosc.IExtenderDriverFactory { 17 | return drivers.NewFactory[Config](Create) 18 | } 19 | -------------------------------------------------------------------------------- /drivers/plugins/dubbo2-to-http/config.go: -------------------------------------------------------------------------------- 1 | package dubbo2_to_http 2 | 3 | type Config struct { 4 | Method string `json:"method" label:"方法" enum:"POST,GET,HEAD,PUT,PATCH,DELETE,CONNECT,OPTIONS,TRACE" required:"true"` //get/post 5 | Path string `json:"path" label:"转发路径" required:"true"` 6 | ContentType string `json:"content_type" label:"ContentType" enum:"application/json" required:"true"` // application/json 只支持json格式传输 7 | Params []Param `json:"params" label:"参数解析" required:"true"` 8 | } 9 | type Param struct { 10 | ClassName string `json:"class_name" label:"class_name" required:"true"` //对应Java中类的class_name 11 | FieldName string `json:"field_name" label:"字段名"` //用于http传输中body中的key名 12 | } 13 | -------------------------------------------------------------------------------- /drivers/plugins/dubbo2-to-http/factory.go: -------------------------------------------------------------------------------- 1 | package dubbo2_to_http 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | "github.com/eolinker/eosc/log" 7 | ) 8 | 9 | const ( 10 | Name = "dubbo2_to_http" 11 | ) 12 | 13 | func Register(register eosc.IExtenderDriverRegister) { 14 | err := register.RegisterExtenderDriver(Name, NewFactory()) 15 | if err != nil { 16 | log.Warnf("register %s:%s", Name, err) 17 | return 18 | } 19 | } 20 | 21 | func NewFactory() eosc.IExtenderDriverFactory { 22 | return drivers.NewFactory[Config](Create) 23 | } 24 | -------------------------------------------------------------------------------- /drivers/plugins/dubbo2-to-http/http.go: -------------------------------------------------------------------------------- 1 | package dubbo2_to_http 2 | 3 | import ( 4 | "bytes" 5 | "io" 6 | "net/http" 7 | "time" 8 | ) 9 | 10 | var client = http.DefaultClient 11 | 12 | type Client struct { 13 | method string 14 | body []byte 15 | path string 16 | } 17 | 18 | func NewClient(method string, body []byte, path string) *Client { 19 | return &Client{method: method, body: body, path: path} 20 | } 21 | 22 | func (h *Client) dial(address string, timeout time.Duration) ([]byte, error) { 23 | 24 | client.Timeout = timeout 25 | request, err := http.NewRequest(h.method, address, bytes.NewReader(h.body)) 26 | 27 | path := h.path 28 | if path != "" { 29 | if path[:1] != "/" { 30 | path = "/" + path 31 | } 32 | request.URL.Path = path 33 | } 34 | 35 | if err != nil { 36 | return nil, err 37 | } 38 | resp, err := client.Do(request) 39 | if err != nil { 40 | return nil, err 41 | } 42 | defer resp.Body.Close() 43 | resBody, err := io.ReadAll(resp.Body) 44 | if err != nil { 45 | return nil, err 46 | } 47 | 48 | return resBody, nil 49 | } 50 | -------------------------------------------------------------------------------- /drivers/plugins/extra-params/driver.go: -------------------------------------------------------------------------------- 1 | package extra_params 2 | 3 | import ( 4 | "reflect" 5 | 6 | "github.com/eolinker/eosc" 7 | ) 8 | 9 | type Driver struct { 10 | profession string 11 | name string 12 | label string 13 | desc string 14 | configType reflect.Type 15 | } 16 | 17 | func Check(conf *Config, workers map[eosc.RequireId]eosc.IWorker) error { 18 | 19 | return conf.doCheck() 20 | } 21 | 22 | func check(v interface{}) (*Config, error) { 23 | conf, ok := v.(*Config) 24 | if !ok { 25 | return nil, eosc.ErrorConfigType 26 | } 27 | err := conf.doCheck() 28 | if err != nil { 29 | return nil, err 30 | } 31 | 32 | return conf, nil 33 | } 34 | 35 | func Create(id, name string, conf *Config, workers map[eosc.RequireId]eosc.IWorker) (eosc.IWorker, error) { 36 | 37 | err := Check(conf, workers) 38 | if err != nil { 39 | return nil, err 40 | } 41 | 42 | ep := &ExtraParams{ 43 | 44 | params: conf.Params, 45 | errorType: conf.ErrorType, 46 | } 47 | 48 | return ep, nil 49 | } 50 | -------------------------------------------------------------------------------- /drivers/plugins/extra-params/factory.go: -------------------------------------------------------------------------------- 1 | package extra_params 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | const ( 9 | Name = "extra_params" 10 | ) 11 | 12 | func Register(register eosc.IExtenderDriverRegister) { 13 | register.RegisterExtenderDriver(Name, NewFactory()) 14 | } 15 | func NewFactory() eosc.IExtenderDriverFactory { 16 | return drivers.NewFactory[Config](Create) 17 | } 18 | -------------------------------------------------------------------------------- /drivers/plugins/extra-params_v2/dynamic-params/concat/concat.go: -------------------------------------------------------------------------------- 1 | package concat 2 | 3 | import ( 4 | "errors" 5 | "strings" 6 | 7 | dynamic_params "github.com/eolinker/apinto/drivers/plugins/extra-params_v2/dynamic-params" 8 | http_service "github.com/eolinker/eosc/eocontext/http-context" 9 | ) 10 | 11 | type Config struct { 12 | *dynamic_params.Param 13 | } 14 | 15 | func (c *Config) Generate(ctx http_service.IHttpContext, contentType string, args ...interface{}) (interface{}, error) { 16 | result, err := c.Param.Generate(ctx, contentType, args...) 17 | if err != nil { 18 | return nil, err 19 | } 20 | v, ok := result.(string) 21 | if !ok { 22 | return nil, errors.New("concat value is not string") 23 | } 24 | if !strings.HasPrefix(c.Name(), "__") { 25 | v = strings.ToUpper(v) 26 | } 27 | return v, nil 28 | } 29 | 30 | func NewConcat(name string, value []string) *Config { 31 | return &Config{ 32 | Param: dynamic_params.NewParam(name, value), 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /drivers/plugins/extra-params_v2/dynamic-params/concat/factory.go: -------------------------------------------------------------------------------- 1 | package concat 2 | 3 | import dynamic_params "github.com/eolinker/apinto/drivers/plugins/extra-params_v2/dynamic-params" 4 | 5 | const name = "$concat" 6 | 7 | func Register() { 8 | dynamic_params.Register(name, NewFactory()) 9 | } 10 | 11 | func NewFactory() *Factory { 12 | return &Factory{} 13 | } 14 | 15 | type Factory struct { 16 | } 17 | 18 | func (f *Factory) Create(name string, value []string) (dynamic_params.IDynamicDriver, error) { 19 | return NewConcat(name, value), nil 20 | } 21 | -------------------------------------------------------------------------------- /drivers/plugins/extra-params_v2/dynamic-params/datetime/datetime.go: -------------------------------------------------------------------------------- 1 | package datetime 2 | 3 | import ( 4 | "time" 5 | 6 | http_service "github.com/eolinker/eosc/eocontext/http-context" 7 | ) 8 | 9 | const ( 10 | defaultValue = "2006-01-02 15:04:05" 11 | ) 12 | 13 | type Datetime struct { 14 | name string 15 | value string 16 | } 17 | 18 | func NewDatetime(name string, value string) *Datetime { 19 | return &Datetime{name: name, value: value} 20 | } 21 | 22 | func (d *Datetime) Name() string { 23 | return d.name 24 | } 25 | 26 | func (d *Datetime) Generate(ctx http_service.IHttpContext, contentType string, args ...interface{}) (interface{}, error) { 27 | return time.Now().Format(d.value), nil 28 | } 29 | -------------------------------------------------------------------------------- /drivers/plugins/extra-params_v2/dynamic-params/datetime/factory.go: -------------------------------------------------------------------------------- 1 | package datetime 2 | 3 | import dynamic_params "github.com/eolinker/apinto/drivers/plugins/extra-params_v2/dynamic-params" 4 | 5 | const name = "$datetime" 6 | 7 | func Register() { 8 | dynamic_params.Register(name, NewFactory()) 9 | } 10 | 11 | func NewFactory() *Factory { 12 | return &Factory{} 13 | } 14 | 15 | type Factory struct { 16 | } 17 | 18 | func (f *Factory) Create(name string, value []string) (dynamic_params.IDynamicDriver, error) { 19 | v := defaultValue 20 | if len(value) > 0 { 21 | v = value[0] 22 | } 23 | return NewDatetime(name, v), nil 24 | } 25 | -------------------------------------------------------------------------------- /drivers/plugins/extra-params_v2/dynamic-params/dynamic.go: -------------------------------------------------------------------------------- 1 | package dynamic_params 2 | 3 | import ( 4 | "github.com/eolinker/eosc/eocontext/http-context" 5 | ) 6 | 7 | type IDynamicFactory interface { 8 | Create(name string, value []string) (IDynamicDriver, error) 9 | } 10 | 11 | type IDynamicDriver interface { 12 | Name() string 13 | Generate(ctx http_context.IHttpContext, contentType string, args ...interface{}) (interface{}, error) 14 | } 15 | -------------------------------------------------------------------------------- /drivers/plugins/extra-params_v2/dynamic-params/hmac-sha256/factory.go: -------------------------------------------------------------------------------- 1 | package hmac_sha256 2 | 3 | import dynamic_params "github.com/eolinker/apinto/drivers/plugins/extra-params_v2/dynamic-params" 4 | 5 | const name = "$hmac-sha256" 6 | 7 | func Register() { 8 | dynamic_params.Register(name, NewFactory()) 9 | } 10 | 11 | func NewFactory() *Factory { 12 | return &Factory{} 13 | } 14 | 15 | type Factory struct { 16 | } 17 | 18 | func (f *Factory) Create(name string, value []string) (dynamic_params.IDynamicDriver, error) { 19 | return NewExecutor(name, value), nil 20 | } 21 | -------------------------------------------------------------------------------- /drivers/plugins/extra-params_v2/dynamic-params/md5/factory.go: -------------------------------------------------------------------------------- 1 | package md5 2 | 3 | import dynamic_params "github.com/eolinker/apinto/drivers/plugins/extra-params_v2/dynamic-params" 4 | 5 | const name = "$md5" 6 | 7 | func Register() { 8 | dynamic_params.Register(name, NewFactory()) 9 | } 10 | 11 | func NewFactory() *Factory { 12 | return &Factory{} 13 | } 14 | 15 | type Factory struct { 16 | } 17 | 18 | func (f *Factory) Create(name string, value []string) (dynamic_params.IDynamicDriver, error) { 19 | return NewMD5(name, value), nil 20 | } 21 | -------------------------------------------------------------------------------- /drivers/plugins/extra-params_v2/dynamic-params/timestamp/factory.go: -------------------------------------------------------------------------------- 1 | package timestamp 2 | 3 | import dynamic_params "github.com/eolinker/apinto/drivers/plugins/extra-params_v2/dynamic-params" 4 | 5 | const name = "$timestamp" 6 | 7 | func Register() { 8 | dynamic_params.Register(name, NewFactory()) 9 | } 10 | 11 | func NewFactory() *Factory { 12 | return &Factory{} 13 | } 14 | 15 | type Factory struct { 16 | } 17 | 18 | func (f *Factory) Create(name string, value []string) (dynamic_params.IDynamicDriver, error) { 19 | v := defaultValue 20 | if len(value) > 0 { 21 | v = value[0] 22 | } 23 | return NewTimestamp(name, v), nil 24 | } 25 | -------------------------------------------------------------------------------- /drivers/plugins/extra-params_v2/dynamic-params/timestamp/timestamp.go: -------------------------------------------------------------------------------- 1 | package timestamp 2 | 3 | import ( 4 | "strconv" 5 | "time" 6 | 7 | http_service "github.com/eolinker/eosc/eocontext/http-context" 8 | ) 9 | 10 | const ( 11 | defaultValue = "string" 12 | ) 13 | 14 | type Timestamp struct { 15 | name string 16 | value string 17 | } 18 | 19 | func NewTimestamp(name, value string) *Timestamp { 20 | return &Timestamp{name: name, value: value} 21 | } 22 | 23 | func (t *Timestamp) Name() string { 24 | return t.name 25 | } 26 | 27 | func (t *Timestamp) Generate(ctx http_service.IHttpContext, contentType string, args ...interface{}) (interface{}, error) { 28 | switch t.value { 29 | case "string": 30 | return strconv.FormatInt(time.Now().Unix(), 10), nil 31 | case "int": 32 | return time.Now().Unix(), nil 33 | } 34 | return strconv.FormatInt(time.Now().Unix(), 10), nil 35 | } 36 | -------------------------------------------------------------------------------- /drivers/plugins/extra-params_v2/dynamic-params/uuid/factory.go: -------------------------------------------------------------------------------- 1 | package uuid 2 | 3 | import dynamic_params "github.com/eolinker/apinto/drivers/plugins/extra-params_v2/dynamic-params" 4 | 5 | const name = "$uuid" 6 | 7 | func Register() { 8 | dynamic_params.Register(name, NewFactory()) 9 | } 10 | 11 | func NewFactory() *Factory { 12 | return &Factory{} 13 | } 14 | 15 | type Factory struct { 16 | } 17 | 18 | func (f *Factory) Create(name string, value []string) (dynamic_params.IDynamicDriver, error) { 19 | v := defaultValue 20 | if len(value) > 0 { 21 | v = value[0] 22 | } 23 | return NewUuid(name, v), nil 24 | } 25 | -------------------------------------------------------------------------------- /drivers/plugins/extra-params_v2/dynamic-params/uuid/uuid.go: -------------------------------------------------------------------------------- 1 | package uuid 2 | 3 | import ( 4 | "github.com/google/uuid" 5 | 6 | http_service "github.com/eolinker/eosc/eocontext/http-context" 7 | ) 8 | 9 | const ( 10 | defaultValue = "string" 11 | ) 12 | 13 | type Uuid struct { 14 | name string 15 | value string 16 | } 17 | 18 | func NewUuid(name, value string) *Uuid { 19 | return &Uuid{name: name, value: value} 20 | } 21 | 22 | func (t *Uuid) Name() string { 23 | return t.name 24 | } 25 | 26 | func (t *Uuid) Generate(ctx http_service.IHttpContext, contentType string, args ...interface{}) (interface{}, error) { 27 | switch t.value { 28 | case "string": 29 | return uuid.New().String(), nil 30 | case "int": 31 | return uuid.New().ID(), nil 32 | } 33 | return uuid.New().String(), nil 34 | } 35 | -------------------------------------------------------------------------------- /drivers/plugins/extra-params_v2/factory.go: -------------------------------------------------------------------------------- 1 | package extra_params_v2 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | const ( 9 | Name = "extra_params_v2" 10 | ) 11 | 12 | func Register(register eosc.IExtenderDriverRegister) { 13 | register.RegisterExtenderDriver(Name, NewFactory()) 14 | } 15 | func NewFactory() eosc.IExtenderDriverFactory { 16 | return drivers.NewFactory[Config](Create, Check) 17 | } 18 | -------------------------------------------------------------------------------- /drivers/plugins/extra-params_v2/util.go: -------------------------------------------------------------------------------- 1 | package extra_params_v2 2 | 3 | import ( 4 | "encoding/json" 5 | "errors" 6 | "fmt" 7 | ) 8 | 9 | const ( 10 | positionQuery = "query" 11 | positionHeader = "header" 12 | positionBody = "body" 13 | 14 | paramConvert string = "convert" 15 | paramError string = "error" 16 | paramOrigin string = "origin" 17 | 18 | clientErrStatusCode = 400 19 | successStatusCode = 200 20 | ) 21 | 22 | var ( 23 | paramPositionErrInfo = `[plugin extra-params config err] param position must be in the set ["query","header",body]. err position: %s ` 24 | paramNameErrInfo = `[plugin extra-params config err] param name must be not null. ` 25 | ) 26 | 27 | func encodeErr(ent string, origin string, statusCode int) error { 28 | if ent == "json" { 29 | tmp := map[string]interface{}{ 30 | "message": origin, 31 | "status_code": statusCode, 32 | } 33 | info, _ := json.Marshal(tmp) 34 | return fmt.Errorf("%s", info) 35 | } 36 | return errors.New(origin) 37 | } 38 | -------------------------------------------------------------------------------- /drivers/plugins/gRPC-to-http/config.go: -------------------------------------------------------------------------------- 1 | package grpc_to_http 2 | 3 | import "github.com/eolinker/eosc" 4 | 5 | type Config struct { 6 | Path string `json:"path" label:"请求路径"` 7 | Method string `json:"method" label:"请求方式" enum:"POST,PUT,PATCH"` 8 | ProtobufID eosc.RequireId `json:"protobuf_id" required:"true" label:"Protobuf ID" skill:"github.com/eolinker/apinto/grpc-transcode.transcode.IDescriptor"` 9 | Headers map[string]string `json:"headers" label:"额外头部"` 10 | Query map[string]string `json:"query" label:"query参数"` 11 | } 12 | -------------------------------------------------------------------------------- /drivers/plugins/gRPC-to-http/factory.go: -------------------------------------------------------------------------------- 1 | package grpc_to_http 2 | 3 | import ( 4 | "fmt" 5 | "github.com/eolinker/eosc/log" 6 | "sync" 7 | 8 | "github.com/eolinker/apinto/drivers" 9 | "github.com/eolinker/eosc" 10 | ) 11 | 12 | const ( 13 | Name = "grpc_to_http" 14 | ) 15 | 16 | var ( 17 | once = sync.Once{} 18 | worker eosc.IWorkers 19 | ) 20 | 21 | func Register(register eosc.IExtenderDriverRegister) { 22 | err := register.RegisterExtenderDriver(Name, NewFactory()) 23 | if err != nil { 24 | log.Warnf("register %s %s", Name, err) 25 | return 26 | } 27 | } 28 | 29 | func NewFactory() eosc.IExtenderDriverFactory { 30 | return drivers.NewFactory[Config](Create, Check) 31 | } 32 | 33 | func Check(cfg *Config, workers map[eosc.RequireId]eosc.IWorker) error { 34 | if cfg.ProtobufID == "" { 35 | return fmt.Errorf("protobuf id is empty") 36 | } 37 | 38 | return nil 39 | } 40 | -------------------------------------------------------------------------------- /drivers/plugins/grpc-proxy-rewrite/config.go: -------------------------------------------------------------------------------- 1 | package grpc_proxy_rewrite 2 | 3 | type Config struct { 4 | Service string `json:"service" label:"服务名称"` 5 | Method string `json:"method" label:"方法名称"` 6 | Authority string `json:"authority" label:"虚拟主机域名(Authority)"` 7 | Headers map[string]string `json:"headers" label:"请求头部"` 8 | } 9 | -------------------------------------------------------------------------------- /drivers/plugins/grpc-proxy-rewrite/driver.go: -------------------------------------------------------------------------------- 1 | package grpc_proxy_rewrite 2 | 3 | import ( 4 | "strings" 5 | 6 | "github.com/eolinker/apinto/drivers" 7 | "github.com/eolinker/eosc" 8 | ) 9 | 10 | func check(v interface{}) (*Config, error) { 11 | conf, err := drivers.Assert[Config](v) 12 | if err != nil { 13 | return nil, err 14 | } 15 | conf.Authority = strings.TrimSpace(conf.Authority) 16 | 17 | return conf, nil 18 | } 19 | 20 | func Create(id, name string, conf *Config, workers map[eosc.RequireId]eosc.IWorker) (eosc.IWorker, error) { 21 | 22 | pw := &ProxyRewrite{ 23 | WorkerBase: drivers.Worker(id, name), 24 | headers: conf.Headers, 25 | service: conf.Service, 26 | method: conf.Method, 27 | authority: strings.TrimSpace(conf.Authority), 28 | } 29 | 30 | return pw, nil 31 | } 32 | -------------------------------------------------------------------------------- /drivers/plugins/grpc-proxy-rewrite/factory.go: -------------------------------------------------------------------------------- 1 | package grpc_proxy_rewrite 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | const ( 9 | Name = "grpc-proxy_write" 10 | ) 11 | 12 | func Register(register eosc.IExtenderDriverRegister) { 13 | register.RegisterExtenderDriver(Name, NewFactory()) 14 | } 15 | 16 | func NewFactory() eosc.IExtenderDriverFactory { 17 | return drivers.NewFactory[Config](Create) 18 | } 19 | -------------------------------------------------------------------------------- /drivers/plugins/gzip/config.go: -------------------------------------------------------------------------------- 1 | package gzip 2 | 3 | import "errors" 4 | 5 | var ( 6 | ErrorMinLengthError = errors.New("the min_length field should > 0") 7 | ) 8 | 9 | type Config struct { 10 | Types []string `json:"types" label:"content-type列表" description:"需要压缩的响应content-type类型列表"` 11 | MinLength int `json:"min_length" label:"长度" description:"待压缩内容的最小长度" ` 12 | Vary bool `json:"vary" label:"是否加上Vary头部"` 13 | } 14 | 15 | func (c *Config) doCheck() error { 16 | if c.MinLength < 0 { 17 | return ErrorMinLengthError 18 | } 19 | if c.MinLength == 0 { 20 | // 设置默认值 21 | c.MinLength = 1 22 | } 23 | return nil 24 | } 25 | -------------------------------------------------------------------------------- /drivers/plugins/gzip/driver.go: -------------------------------------------------------------------------------- 1 | package gzip 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | func Check(conf *Config, workers map[eosc.RequireId]eosc.IWorker) error { 9 | 10 | return conf.doCheck() 11 | } 12 | 13 | func check(v interface{}) (*Config, error) { 14 | conf, err := drivers.Assert[Config](v) 15 | if err != nil { 16 | return nil, err 17 | } 18 | 19 | err = conf.doCheck() 20 | if err != nil { 21 | return nil, err 22 | } 23 | return conf, nil 24 | } 25 | 26 | func Create(id, name string, conf *Config, workers map[eosc.RequireId]eosc.IWorker) (eosc.IWorker, error) { 27 | 28 | err := Check(conf, workers) 29 | if err != nil { 30 | return nil, err 31 | } 32 | c := &Gzip{ 33 | WorkerBase: drivers.Worker(id, name), 34 | conf: conf, 35 | } 36 | return c, nil 37 | } 38 | -------------------------------------------------------------------------------- /drivers/plugins/gzip/factory.go: -------------------------------------------------------------------------------- 1 | package gzip 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | const ( 9 | Name = "gzip" 10 | ) 11 | 12 | func Register(register eosc.IExtenderDriverRegister) { 13 | err := register.RegisterExtenderDriver(Name, NewFactory()) 14 | if err != nil { 15 | return 16 | } 17 | } 18 | 19 | func NewFactory() eosc.IExtenderDriverFactory { 20 | return drivers.NewFactory[Config](Create) 21 | } 22 | -------------------------------------------------------------------------------- /drivers/plugins/http-to-dubbo2/config.go: -------------------------------------------------------------------------------- 1 | package http_to_dubbo2 2 | 3 | type Config struct { 4 | Service string `json:"service" label:"服务名称" required:"true"` 5 | Method string `json:"method" label:"方法名称" required:"true"` 6 | Params []*Param `json:"params" label:"参数" required:"true"` 7 | } 8 | 9 | type Param struct { 10 | ClassName string `json:"class_name" label:"class_name" required:"true"` //对应Java中类的class_name 11 | FieldName string `json:"field_name" label:"根字段名"` //读取body中json的根字段名 12 | } 13 | -------------------------------------------------------------------------------- /drivers/plugins/http-to-dubbo2/factory.go: -------------------------------------------------------------------------------- 1 | package http_to_dubbo2 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | const ( 9 | Name = "http_to_dubbo2" 10 | ) 11 | 12 | func Register(register eosc.IExtenderDriverRegister) { 13 | register.RegisterExtenderDriver(Name, NewFactory()) 14 | } 15 | 16 | func NewFactory() eosc.IExtenderDriverFactory { 17 | return drivers.NewFactory[Config](Create) 18 | } 19 | -------------------------------------------------------------------------------- /drivers/plugins/http-to-gRPC/config.go: -------------------------------------------------------------------------------- 1 | package http_to_grpc 2 | 3 | import "github.com/eolinker/eosc" 4 | 5 | type Config struct { 6 | Service string `json:"service" label:"服务名称"` 7 | Method string `json:"method" label:"方法名称"` 8 | Authority string `json:"authority" label:"虚拟主机域名(Authority)"` 9 | Format string `json:"format" label:"数据格式" enum:"json"` 10 | Reflect bool `json:"reflect" label:"反射"` 11 | ProtobufID eosc.RequireId `json:"protobuf_id" required:"false" label:"Protobuf ID" skill:"github.com/eolinker/apinto/grpc-transcode.transcode.IDescriptor" switch:"reflect === false"` 12 | Headers map[string]string `json:"headers" label:"额外头部"` 13 | } 14 | -------------------------------------------------------------------------------- /drivers/plugins/http-to-gRPC/factory.go: -------------------------------------------------------------------------------- 1 | package http_to_grpc 2 | 3 | import ( 4 | "sync" 5 | 6 | "github.com/eolinker/apinto/drivers" 7 | "github.com/eolinker/eosc" 8 | ) 9 | 10 | const ( 11 | Name = "http_to_grpc" 12 | ) 13 | 14 | var ( 15 | once = sync.Once{} 16 | worker eosc.IWorkers 17 | ) 18 | 19 | func Register(register eosc.IExtenderDriverRegister) { 20 | register.RegisterExtenderDriver(Name, NewFactory()) 21 | } 22 | 23 | func NewFactory() eosc.IExtenderDriverFactory { 24 | return drivers.NewFactory[Config](Create) 25 | } 26 | -------------------------------------------------------------------------------- /drivers/plugins/http_mocking/config.go: -------------------------------------------------------------------------------- 1 | package http_mocking 2 | 3 | type Config struct { 4 | ResponseStatus int `json:"response_status" default:"200" label:"响应状态码" description:"仅http路由有效"` 5 | ContentType string `json:"content_type" label:"响应 Content-Type" enum:"application/json"` 6 | ResponseExample string `json:"response_example" format:"text" label:"响应Body" description:"与Json Schema字段二选一"` 7 | ResponseSchema string `json:"response_schema" format:"text" label:"Json Schema" description:"Mock生成的Json Schema语法数据,与响应Body字段二选一"` 8 | ResponseHeader map[string]string `json:"response_header" label:"响应头"` 9 | } 10 | 11 | const ( 12 | contentTypeJson = "application/json" 13 | ) 14 | -------------------------------------------------------------------------------- /drivers/plugins/http_mocking/factory.go: -------------------------------------------------------------------------------- 1 | package http_mocking 2 | 3 | import ( 4 | "sync" 5 | 6 | "github.com/eolinker/apinto/drivers" 7 | "github.com/eolinker/eosc" 8 | ) 9 | 10 | const ( 11 | Name = "http-mocking" 12 | ) 13 | 14 | var ( 15 | once = sync.Once{} 16 | worker eosc.IWorkers 17 | ) 18 | 19 | func Register(register eosc.IExtenderDriverRegister) { 20 | register.RegisterExtenderDriver(Name, NewFactory()) 21 | } 22 | 23 | func NewFactory() eosc.IExtenderDriverFactory { 24 | return drivers.NewFactory[Config](Create) 25 | } 26 | -------------------------------------------------------------------------------- /drivers/plugins/ip-restriction/driver.go: -------------------------------------------------------------------------------- 1 | package ip_restriction 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | func Check(v *Config, workers map[eosc.RequireId]eosc.IWorker) error { 9 | 10 | return v.doCheck() 11 | } 12 | func check(v interface{}) (*Config, error) { 13 | conf, err := drivers.Assert[Config](v) 14 | if err != nil { 15 | return nil, err 16 | } 17 | err = conf.doCheck() 18 | if err != nil { 19 | return nil, err 20 | } 21 | return conf, nil 22 | } 23 | 24 | func Create(id, name string, conf *Config, workers map[eosc.RequireId]eosc.IWorker) (eosc.IWorker, error) { 25 | 26 | err := conf.doCheck() 27 | if err != nil { 28 | return nil, err 29 | } 30 | h := &IPHandler{ 31 | WorkerBase: drivers.Worker(id, name), 32 | filter: conf.genFilter(), 33 | } 34 | return h, nil 35 | } 36 | -------------------------------------------------------------------------------- /drivers/plugins/ip-restriction/factory.go: -------------------------------------------------------------------------------- 1 | package ip_restriction 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | const ( 9 | Name = "ip_restriction" 10 | ) 11 | 12 | func Register(register eosc.IExtenderDriverRegister) { 13 | register.RegisterExtenderDriver(Name, NewFactory()) 14 | } 15 | func NewFactory() eosc.IExtenderDriverFactory { 16 | return drivers.NewFactory[Config](Create, Check) 17 | } 18 | -------------------------------------------------------------------------------- /drivers/plugins/js-inject/config.go: -------------------------------------------------------------------------------- 1 | package js_inject 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | type Config struct { 9 | Variables []Variable `json:"variables" label:"变量列表"` 10 | InjectCode string `json:"inject" label:"注入代码"` 11 | MatchContentType []string `json:"match_content_type" label:"匹配的Content-Type"` 12 | } 13 | 14 | type Variable struct { 15 | Key string `json:"key" label:"变量名"` 16 | Value string `json:"value" label:"变量值"` 17 | } 18 | 19 | func Create(id, name string, conf *Config, workers map[eosc.RequireId]eosc.IWorker) (eosc.IWorker, error) { 20 | e := &executor{ 21 | WorkerBase: drivers.Worker(id, name), 22 | } 23 | e.reset(conf) 24 | return e, nil 25 | } 26 | -------------------------------------------------------------------------------- /drivers/plugins/js-inject/factory.go: -------------------------------------------------------------------------------- 1 | package js_inject 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | const ( 9 | Name = "js_inject" 10 | ) 11 | 12 | func Register(register eosc.IExtenderDriverRegister) { 13 | register.RegisterExtenderDriver(Name, NewFactory()) 14 | } 15 | 16 | func NewFactory() eosc.IExtenderDriverFactory { 17 | return drivers.NewFactory[Config](Create) 18 | } 19 | -------------------------------------------------------------------------------- /drivers/plugins/monitor/config.go: -------------------------------------------------------------------------------- 1 | package monitor 2 | 3 | import "github.com/eolinker/eosc" 4 | 5 | type Config struct { 6 | Output []eosc.RequireId `json:"output" skill:"github.com/eolinker/apinto/monitor-entry.monitor-entry.IOutput" label:"输出器列表"` 7 | } 8 | -------------------------------------------------------------------------------- /drivers/plugins/oauth2-introspection/factory.go: -------------------------------------------------------------------------------- 1 | package oauth2_introspection 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/apinto/drivers/app/manager" 6 | "github.com/eolinker/eosc" 7 | "github.com/eolinker/eosc/common/bean" 8 | "sync" 9 | ) 10 | 11 | const ( 12 | Name = "oauth2-introspection" 13 | ) 14 | 15 | var ( 16 | ones sync.Once 17 | appManager manager.IManager 18 | ) 19 | 20 | func Register(register eosc.IExtenderDriverRegister) { 21 | register.RegisterExtenderDriver(Name, NewFactory()) 22 | } 23 | 24 | func NewFactory() eosc.IExtenderDriverFactory { 25 | ones.Do(func() { 26 | bean.Autowired(&appManager) 27 | }) 28 | return drivers.NewFactory[Config](Create) 29 | } 30 | 31 | func Create(id, name string, conf *Config, workers map[eosc.RequireId]eosc.IWorker) (eosc.IWorker, error) { 32 | err := Check(conf) 33 | if err != nil { 34 | return nil, err 35 | } 36 | e := &executor{ 37 | WorkerBase: drivers.Worker(id, name), 38 | } 39 | err = e.reset(conf) 40 | if err != nil { 41 | return nil, err 42 | } 43 | return e, nil 44 | } 45 | -------------------------------------------------------------------------------- /drivers/plugins/oauth2/factory.go: -------------------------------------------------------------------------------- 1 | package oauth2 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | "github.com/eolinker/eosc/router" 7 | ) 8 | 9 | const ( 10 | Name = "oauth2" 11 | ) 12 | 13 | func Register(register eosc.IExtenderDriverRegister) { 14 | register.RegisterExtenderDriver(Name, NewFactory()) 15 | } 16 | 17 | func NewFactory() eosc.IExtenderDriverFactory { 18 | h := NewTokenHandler() 19 | router.SetPath("oauth2_token_handler", "/oauth_tokens/", h) 20 | return drivers.NewFactory[Config](Create) 21 | } 22 | -------------------------------------------------------------------------------- /drivers/plugins/params-check/check_test.go: -------------------------------------------------------------------------------- 1 | package params_check 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/ohler55/ojg/oj" 7 | 8 | "github.com/eolinker/apinto/checker" 9 | ) 10 | 11 | func TestParamCheck(t *testing.T) { 12 | data := `{ 13 | "code":"HWJXH_DEPTCOMPLEX_CSGLJ_HWJXHXT_XLJXHZYL_1.0", 14 | "isPage":true, 15 | "index":1, 16 | "size":10, 17 | "apiType":"deptCOMPLEX", 18 | "userName":"APIFXJCXT", 19 | "psd":"5190649892064f8c9bf387c3d30ce021", 20 | "apiId":"d1d3f080f18448fcb5354f67b93e54e9", 21 | "search":[{"param":"F_SECTIONNAME","type":"String","val":""}] 22 | }` 23 | 24 | c, err := checker.Parse("**") 25 | if err != nil { 26 | t.Fatal(err) 27 | } 28 | checkers := []*paramChecker{ 29 | { 30 | name: "$.search[0].val", 31 | Checker: c, 32 | }, 33 | } 34 | o, err := oj.ParseString(data) 35 | if err != nil { 36 | t.Fatal(err) 37 | } 38 | for _, ck := range checkers { 39 | 40 | err = jsonChecker(o, ck) 41 | if err != nil { 42 | t.Fatal(err) 43 | } 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /drivers/plugins/params-check/config.go: -------------------------------------------------------------------------------- 1 | package params_check 2 | 3 | type Config struct { 4 | Params []*Param `json:"params" label:"参数列表"` 5 | } 6 | 7 | type Param struct { 8 | Name string `json:"name" label:"参数名"` 9 | Position string `json:"position" label:"参数位置" enum:"query,header,body"` 10 | MatchText string `json:"match_text" label:"匹配文本"` 11 | } 12 | -------------------------------------------------------------------------------- /drivers/plugins/params-transformer/factory.go: -------------------------------------------------------------------------------- 1 | package params_transformer 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | "github.com/eolinker/eosc/log" 7 | ) 8 | 9 | const ( 10 | Name = "params_transformer" 11 | ) 12 | 13 | func Register(register eosc.IExtenderDriverRegister) { 14 | log.Debug("register params_transformer is ", Name) 15 | register.RegisterExtenderDriver(Name, NewFactory()) 16 | } 17 | func NewFactory() eosc.IExtenderDriverFactory { 18 | return drivers.NewFactory[Config](Create, Check) 19 | } 20 | -------------------------------------------------------------------------------- /drivers/plugins/prometheus/config.go: -------------------------------------------------------------------------------- 1 | package prometheus 2 | 3 | import "github.com/eolinker/eosc" 4 | 5 | type Config struct { 6 | Output []eosc.RequireId `json:"output" skill:"github.com/eolinker/apinto/metric-entry.metric-entry.IMetrics" label:"prometheus Output列表"` 7 | Metrics []string `json:"metrics" yaml:"metrics" label:"指标名列表"` 8 | } 9 | 10 | const ( 11 | globalScopeName = "prometheus" 12 | ) 13 | -------------------------------------------------------------------------------- /drivers/plugins/prometheus/error.go: -------------------------------------------------------------------------------- 1 | package prometheus 2 | 3 | import "errors" 4 | 5 | var ( 6 | errNullMetric = errors.New("Check config fail. metric can't be null. ") 7 | 8 | errNotImpEntryFormat = "%s:worker not implement IMetricOutput" 9 | ) 10 | -------------------------------------------------------------------------------- /drivers/plugins/prometheus/factory.go: -------------------------------------------------------------------------------- 1 | package prometheus 2 | 3 | import ( 4 | "sync" 5 | 6 | "github.com/eolinker/apinto/drivers" 7 | "github.com/eolinker/eosc" 8 | "github.com/eolinker/eosc/common/bean" 9 | ) 10 | 11 | const ( 12 | Name = "prometheus" 13 | ) 14 | 15 | var ( 16 | workers eosc.IWorkers 17 | 18 | once sync.Once 19 | ) 20 | 21 | func Register(register eosc.IExtenderDriverRegister) { 22 | register.RegisterExtenderDriver(Name, NewFactory()) 23 | } 24 | 25 | type Factory struct { 26 | eosc.IExtenderDriverFactory 27 | } 28 | 29 | func NewFactory() *Factory { 30 | return &Factory{ 31 | IExtenderDriverFactory: drivers.NewFactory[Config](Create, Check), 32 | } 33 | } 34 | 35 | func (f *Factory) Create(profession string, name string, label string, desc string, params map[string]interface{}) (eosc.IExtenderDriver, error) { 36 | once.Do(func() { 37 | bean.Autowired(&workers) 38 | }) 39 | 40 | return f.IExtenderDriverFactory.Create(profession, name, label, desc, params) 41 | } 42 | -------------------------------------------------------------------------------- /drivers/plugins/proxy-mirror/driver.go: -------------------------------------------------------------------------------- 1 | package proxy_mirror 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | "time" 7 | ) 8 | 9 | func Check(v *Config, workers map[eosc.RequireId]eosc.IWorker) error { 10 | return v.doCheck() 11 | } 12 | 13 | func check(v interface{}) (*Config, error) { 14 | 15 | conf, err := drivers.Assert[Config](v) 16 | if err != nil { 17 | return nil, err 18 | } 19 | err = conf.doCheck() 20 | if err != nil { 21 | return nil, err 22 | } 23 | 24 | return conf, nil 25 | } 26 | 27 | func Create(id, name string, conf *Config, workers map[eosc.RequireId]eosc.IWorker) (eosc.IWorker, error) { 28 | 29 | err := conf.doCheck() 30 | if err != nil { 31 | return nil, err 32 | } 33 | 34 | pm := &proxyMirror{ 35 | WorkerBase: drivers.Worker(id, name), 36 | randomRange: conf.SampleConf.RandomRange, 37 | randomPivot: conf.SampleConf.RandomPivot, 38 | service: newMirrorService(conf.Addr, conf.PassHost, conf.Host, time.Duration(conf.Timeout)), 39 | conf: conf, 40 | } 41 | 42 | return pm, nil 43 | } 44 | -------------------------------------------------------------------------------- /drivers/plugins/proxy-mirror/error.go: -------------------------------------------------------------------------------- 1 | package proxy_mirror 2 | 3 | import "github.com/pkg/errors" 4 | 5 | var ( 6 | errUnsupportedContextType = errors.New("send mirror proxy fail. Unsupported Context Type") 7 | errHostNull = errors.New("host can't be null when pass_host is rewrite. ") 8 | errUnsupportedPassHost = errors.New("unsupported pass_host. ") 9 | 10 | errRandomRangeNum = errors.New("random_range should be bigger than 0. ") 11 | errRandomPivotNum = errors.New("random_pivot should be bigger than 0. ") 12 | errRandomPivot = errors.New("random_pivot should be smaller than random_range. ") 13 | 14 | errAddr = errors.New("addr is illegal. ") 15 | ) 16 | -------------------------------------------------------------------------------- /drivers/plugins/proxy-mirror/factory.go: -------------------------------------------------------------------------------- 1 | package proxy_mirror 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/apinto/drivers/discovery/static" 6 | "github.com/eolinker/eosc" 7 | ) 8 | 9 | const ( 10 | Name = "proxy_mirror" 11 | ) 12 | 13 | var ( 14 | defaultProxyDiscovery = static.CreateAnonymous(&static.Config{ 15 | Health: nil, 16 | HealthOn: false, 17 | }) 18 | ) 19 | 20 | func Register(register eosc.IExtenderDriverRegister) { 21 | register.RegisterExtenderDriver(Name, NewFactory()) 22 | } 23 | 24 | func NewFactory() eosc.IExtenderDriverFactory { 25 | return drivers.NewFactory[Config](Create, Check) 26 | } 27 | -------------------------------------------------------------------------------- /drivers/plugins/proxy-mirror/handler.go: -------------------------------------------------------------------------------- 1 | package proxy_mirror 2 | 3 | import ( 4 | "github.com/eolinker/eosc/eocontext" 5 | "github.com/eolinker/eosc/log" 6 | ) 7 | 8 | type proxyMirrorCompleteHandler struct { 9 | orgComplete eocontext.CompleteHandler 10 | service *mirrorService 11 | } 12 | 13 | func newMirrorHandler(eoCtx eocontext.EoContext, service *mirrorService) (eocontext.CompleteHandler, error) { 14 | handler := &proxyMirrorCompleteHandler{ 15 | orgComplete: eoCtx.GetComplete(), 16 | service: service, 17 | } 18 | 19 | return handler, nil 20 | } 21 | 22 | func (p *proxyMirrorCompleteHandler) Complete(ctx eocontext.EoContext) error { 23 | 24 | //先执行原始Complete, 再执行镜像请求的Complete 25 | orgErr := p.orgComplete.Complete(ctx) 26 | cloneCtx, err := ctx.Clone() 27 | if err != nil { 28 | log.Warn(err) 29 | return orgErr 30 | } 31 | 32 | cloneCtx.SetBalance(p.service) 33 | cloneCtx.SetUpstreamHostHandler(p.service) 34 | 35 | go func() { 36 | err = p.orgComplete.Complete(cloneCtx) 37 | if err != nil { 38 | log.Error(err) 39 | } 40 | }() 41 | 42 | return orgErr 43 | } 44 | -------------------------------------------------------------------------------- /drivers/plugins/proxy-rewrite/config.go: -------------------------------------------------------------------------------- 1 | package proxy_rewrite 2 | 3 | import "fmt" 4 | 5 | type Config struct { 6 | URI string `json:"uri" label:"路径"` 7 | RegexURI []string `json:"regex_uri" label:"正则替换路径(regex_uri)" description:"该数组需要配置两个正则,第一个是匹配正则,第二个是替换正则。"` 8 | Host string `json:"host" label:"Host"` 9 | Headers map[string]string `json:"headers" label:"请求头部" description:"可对转发请求的头部进行新增,修改,删除。配置的kv对,不存在则新增,已存在则进行覆盖重写,但需要注意特殊头部字段只能在后面添加新值而不能覆盖。value为空字符串表示删除。"` 10 | } 11 | 12 | func (c *Config) doCheck() error { 13 | 14 | lenRegURI := len(c.RegexURI) 15 | 16 | //RegexURI切片要么为空,要么只有两个值,第一个值为正则匹配值,第二个是用于替换的正则字符串 17 | if lenRegURI > 0 && lenRegURI != 2 { 18 | return fmt.Errorf(regexpURIErrInfo, c.RegexURI) 19 | } 20 | 21 | return nil 22 | } 23 | -------------------------------------------------------------------------------- /drivers/plugins/proxy-rewrite/factory.go: -------------------------------------------------------------------------------- 1 | package proxy_rewrite 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | const ( 9 | Name = "proxy_rewrite" 10 | ) 11 | 12 | func Register(register eosc.IExtenderDriverRegister) { 13 | register.RegisterExtenderDriver(Name, NewFactory()) 14 | } 15 | 16 | func NewFactory() eosc.IExtenderDriverFactory { 17 | return drivers.NewFactory[Config](Create, Check) 18 | } 19 | -------------------------------------------------------------------------------- /drivers/plugins/proxy-rewrite/host.go: -------------------------------------------------------------------------------- 1 | package proxy_rewrite 2 | 3 | import ( 4 | "github.com/eolinker/eosc/eocontext" 5 | ) 6 | 7 | type upstreamHostRewrite string 8 | 9 | func (u upstreamHostRewrite) PassHost() (eocontext.PassHostMod, string) { 10 | return eocontext.ReWriteHost, string(u) 11 | } 12 | -------------------------------------------------------------------------------- /drivers/plugins/proxy-rewrite/util.go: -------------------------------------------------------------------------------- 1 | package proxy_rewrite 2 | 3 | var ( 4 | regexpURIErrInfo = `[plugin proxy-rewrite config err] regex_uri's length must be 0 or 2. err regexURI: %s ` 5 | regexpErrInfo = `[plugin proxy-rewrite config err] compile regex_uri fail. err regexp: %s ` 6 | ) 7 | -------------------------------------------------------------------------------- /drivers/plugins/proxy_rewrite_v2/factory.go: -------------------------------------------------------------------------------- 1 | package proxy_rewrite_v2 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | const ( 9 | Name = "proxy_rewrite_v2" 10 | ) 11 | 12 | func Register(register eosc.IExtenderDriverRegister) { 13 | register.RegisterExtenderDriver(Name, NewFactory()) 14 | } 15 | 16 | func NewFactory() eosc.IExtenderDriverFactory { 17 | return drivers.NewFactory[Config](Create, Check) 18 | } 19 | -------------------------------------------------------------------------------- /drivers/plugins/proxy_rewrite_v2/host.go: -------------------------------------------------------------------------------- 1 | package proxy_rewrite_v2 2 | 3 | import ( 4 | "github.com/eolinker/eosc/eocontext" 5 | ) 6 | 7 | type upstreamHostRewrite string 8 | 9 | func (u upstreamHostRewrite) PassHost() (eocontext.PassHostMod, string) { 10 | return eocontext.ReWriteHost, string(u) 11 | } 12 | -------------------------------------------------------------------------------- /drivers/plugins/rate-limiting/config.go: -------------------------------------------------------------------------------- 1 | package rate_limiting 2 | 3 | type Config struct { 4 | Second int64 `json:"second,omitempty" label:"每秒请求次数限制"` // 每秒请求次数限制 5 | Minute int64 `json:"minute,omitempty" label:"每分钟请求次数限制"` // 每分钟请求次数限制 6 | Hour int64 `json:"hour,omitempty" label:"每小时请求次数限制"` // 每小时请求次数限制 7 | Day int64 `json:"day,omitempty" label:"每天请求次数限制"` // 每天请求次数限制 8 | HideClientHeader bool `json:"hide_client_header" label:"是否隐藏流控信息"` // 请求结果是否隐藏流控信息 9 | ResponseType string `json:"response_type" label:"报错格式" enum:"text,json"` // 插件返回报错的类型 10 | } 11 | -------------------------------------------------------------------------------- /drivers/plugins/rate-limiting/driver.go: -------------------------------------------------------------------------------- 1 | package rate_limiting 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | "reflect" 7 | ) 8 | 9 | type Driver struct { 10 | profession string 11 | name string 12 | label string 13 | desc string 14 | configType reflect.Type 15 | } 16 | 17 | func Create(id, name string, conf *Config, workers map[eosc.RequireId]eosc.IWorker) (eosc.IWorker, error) { 18 | 19 | l := &RateLimiting{ 20 | WorkerBase: drivers.Worker(id, name), 21 | rateInfo: CreateRateInfo(conf), 22 | hideClientHeader: conf.HideClientHeader, 23 | responseType: conf.ResponseType, 24 | } 25 | return l, nil 26 | } 27 | -------------------------------------------------------------------------------- /drivers/plugins/rate-limiting/factory.go: -------------------------------------------------------------------------------- 1 | package rate_limiting 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | const ( 9 | Name = "rate_limiting" 10 | ) 11 | 12 | func Register(register eosc.IExtenderDriverRegister) { 13 | register.RegisterExtenderDriver(Name, NewFactory()) 14 | } 15 | 16 | func NewFactory() eosc.IExtenderDriverFactory { 17 | return drivers.NewFactory[Config](Create) 18 | } 19 | -------------------------------------------------------------------------------- /drivers/plugins/request-file-parse/config.go: -------------------------------------------------------------------------------- 1 | package request_file_parse 2 | 3 | type Config struct { 4 | FileKey string `json:"file_key" label:"文件Key"` 5 | FileSuffix []string `json:"file_suffix" label:"文件有效后缀列表"` 6 | LargeWarn int64 `json:"large_warn" label:"文件大小警告阈值"` 7 | LargeWarnText string `json:"large_warn_text" label:"文件大小警告标签值"` 8 | } 9 | -------------------------------------------------------------------------------- /drivers/plugins/request-interception/factory.go: -------------------------------------------------------------------------------- 1 | package request_interception 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | const ( 9 | Name = "request_interception" 10 | ) 11 | 12 | func Register(register eosc.IExtenderDriverRegister) { 13 | register.RegisterExtenderDriver(Name, NewFactory()) 14 | } 15 | 16 | func NewFactory() eosc.IExtenderDriverFactory { 17 | return drivers.NewFactory[Config](Create) 18 | } 19 | -------------------------------------------------------------------------------- /drivers/plugins/response-file-parse/config.go: -------------------------------------------------------------------------------- 1 | package response_file_parse 2 | 3 | type Config struct { 4 | FileKey string `json:"file_key" label:"文件Key"` 5 | FileSuffix []string `json:"file_suffix" label:"文件有效后缀列表"` 6 | LargeWarn int64 `json:"large_warn" label:"文件大小警告阈值"` 7 | LargeWarnText string `json:"large_warn_text" label:"文件大小警告标签值"` 8 | } 9 | -------------------------------------------------------------------------------- /drivers/plugins/response-filter/config.go: -------------------------------------------------------------------------------- 1 | package response_filter 2 | 3 | type Config struct { 4 | BodyFilter []string `json:"body_filter" label:"响应体过滤字段"` 5 | HeaderFilter []string `json:"header_filter" label:"响应头过滤字段"` 6 | } 7 | -------------------------------------------------------------------------------- /drivers/plugins/response-rewrite/factory.go: -------------------------------------------------------------------------------- 1 | package response_rewrite 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | const ( 9 | Name = "response_rewrite" 10 | ) 11 | 12 | func Register(register eosc.IExtenderDriverRegister) { 13 | register.RegisterExtenderDriver(Name, NewFactory()) 14 | } 15 | 16 | func NewFactory() eosc.IExtenderDriverFactory { 17 | return drivers.NewFactory[Config](Create, Check) 18 | } 19 | -------------------------------------------------------------------------------- /drivers/plugins/response-rewrite_v2/factory.go: -------------------------------------------------------------------------------- 1 | package response_rewrite_v2 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | const ( 9 | Name = "response_rewrite_v2" 10 | ) 11 | 12 | func Register(register eosc.IExtenderDriverRegister) { 13 | register.RegisterExtenderDriver(Name, NewFactory()) 14 | } 15 | 16 | func NewFactory() eosc.IExtenderDriverFactory { 17 | return drivers.NewFactory[Config](Create) 18 | } 19 | -------------------------------------------------------------------------------- /drivers/plugins/response-rewrite_v2/rewrite_test.go: -------------------------------------------------------------------------------- 1 | package response_rewrite_v2 2 | 3 | import ( 4 | "log" 5 | "regexp" 6 | "testing" 7 | ) 8 | 9 | func TestRewrite(t *testing.T) { 10 | re := regexp.MustCompile(`\{([^}]+)\}`) 11 | log.Println(re.ReplaceAllString("abc{a}def{b}ghi", "%s")) 12 | } 13 | -------------------------------------------------------------------------------- /drivers/plugins/rsa-filter/config.go: -------------------------------------------------------------------------------- 1 | package rsa_filter 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | type Config struct { 9 | PrivateKey string `json:"private_key" label:"私钥" description:"对请求体进行解密,对响应体进行签名"` 10 | PublicKey string `json:"public_key" label:"公钥" description:"对请求体进行验签,对响应体进行加密"` 11 | RequestSignHeader string `json:"request_sign_header" label:"请求签名头"` 12 | ResponseSignHeader string `json:"response_sign_header" label:"响应签名头"` 13 | Format string `json:"format" label:"密钥格式" enum:"origin,base64"` 14 | } 15 | 16 | func Create(id, name string, conf *Config, workers map[eosc.RequireId]eosc.IWorker) (eosc.IWorker, error) { 17 | e := &executor{ 18 | WorkerBase: drivers.Worker(id, name), 19 | } 20 | e.reset(conf) 21 | return e, nil 22 | } 23 | -------------------------------------------------------------------------------- /drivers/plugins/rsa-filter/factory.go: -------------------------------------------------------------------------------- 1 | package rsa_filter 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | const ( 9 | Name = "rsa" 10 | ) 11 | 12 | func Register(register eosc.IExtenderDriverRegister) { 13 | register.RegisterExtenderDriver(Name, NewFactory()) 14 | } 15 | 16 | func NewFactory() eosc.IExtenderDriverFactory { 17 | return drivers.NewFactory[Config](Create) 18 | } 19 | -------------------------------------------------------------------------------- /drivers/plugins/script-handler/factory.go: -------------------------------------------------------------------------------- 1 | package script_handler 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | const ( 9 | Name = "script_handler" 10 | ) 11 | 12 | func Register(register eosc.IExtenderDriverRegister) { 13 | register.RegisterExtenderDriver(Name, NewFactory()) 14 | } 15 | 16 | func NewFactory() eosc.IExtenderDriverFactory { 17 | return drivers.NewFactory(Create) 18 | } 19 | -------------------------------------------------------------------------------- /drivers/plugins/strategy/cache/driver.go: -------------------------------------------------------------------------------- 1 | package cache 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | "github.com/eolinker/eosc/common/bean" 7 | ) 8 | 9 | var ( 10 | workers eosc.IWorkers 11 | ) 12 | 13 | func init() { 14 | bean.Autowired(&workers) 15 | } 16 | 17 | type Config struct { 18 | Cache eosc.RequireId `json:"cache" skill:"github.com/eolinker/apinto/resources.resources.ICache" required:"false" label:"缓存位置"` 19 | } 20 | 21 | func Create(id, name string, conf *Config, workers map[eosc.RequireId]eosc.IWorker) (eosc.IWorker, error) { 22 | 23 | return &Strategy{ 24 | WorkerBase: drivers.Worker(id, name), 25 | redisID: string(conf.Cache), 26 | }, nil 27 | } 28 | -------------------------------------------------------------------------------- /drivers/plugins/strategy/cache/factory.go: -------------------------------------------------------------------------------- 1 | package cache 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | "github.com/eolinker/eosc/utils/schema" 7 | "reflect" 8 | ) 9 | 10 | const ( 11 | Name = "strategy-plugin-cache" 12 | ) 13 | 14 | var ( 15 | configType = reflect.TypeOf((*Config)(nil)) 16 | render, _ = schema.Generate(configType, nil) 17 | ) 18 | 19 | func Register(register eosc.IExtenderDriverRegister) { 20 | register.RegisterExtenderDriver(Name, NewFactory()) 21 | } 22 | func NewFactory() eosc.IExtenderDriverFactory { 23 | return drivers.NewFactory[Config](Create) 24 | } 25 | -------------------------------------------------------------------------------- /drivers/plugins/strategy/data-mask/driver.go: -------------------------------------------------------------------------------- 1 | package data_mask 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | type Config struct { 9 | } 10 | 11 | func Create(id, name string, conf *Config, workers map[eosc.RequireId]eosc.IWorker) (eosc.IWorker, error) { 12 | return &Strategy{ 13 | WorkerBase: drivers.Worker(id, name), 14 | }, nil 15 | } 16 | -------------------------------------------------------------------------------- /drivers/plugins/strategy/data-mask/factory.go: -------------------------------------------------------------------------------- 1 | package data_mask 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | const ( 9 | Name = "strategy-plugin-data_mask" 10 | ) 11 | 12 | func Register(register eosc.IExtenderDriverRegister) { 13 | register.RegisterExtenderDriver(Name, NewFactory()) 14 | } 15 | func NewFactory() eosc.IExtenderDriverFactory { 16 | return drivers.NewFactory[Config](Create) 17 | } 18 | -------------------------------------------------------------------------------- /drivers/plugins/strategy/data-mask/strategy.go: -------------------------------------------------------------------------------- 1 | package data_mask 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | data_mask_strategy "github.com/eolinker/apinto/drivers/strategy/data-mask-strategy" 6 | "github.com/eolinker/eosc" 7 | eoscContext "github.com/eolinker/eosc/eocontext" 8 | ) 9 | 10 | type Strategy struct { 11 | drivers.WorkerBase 12 | } 13 | 14 | func (s *Strategy) DoFilter(ctx eoscContext.EoContext, next eoscContext.IChain) (err error) { 15 | return data_mask_strategy.DoStrategy(ctx, next) 16 | } 17 | 18 | func (s *Strategy) Destroy() { 19 | return 20 | } 21 | 22 | func (s *Strategy) Start() error { 23 | return nil 24 | } 25 | 26 | func (s *Strategy) Reset(conf interface{}, workers map[eosc.RequireId]eosc.IWorker) error { 27 | return nil 28 | } 29 | 30 | func (s *Strategy) Stop() error { 31 | return nil 32 | } 33 | 34 | func (s *Strategy) CheckSkill(skill string) bool { 35 | return eoscContext.FilterSkillName == skill 36 | } 37 | -------------------------------------------------------------------------------- /drivers/plugins/strategy/fuse/driver.go: -------------------------------------------------------------------------------- 1 | package fuse 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | "github.com/eolinker/eosc/common/bean" 7 | ) 8 | 9 | var ( 10 | workers eosc.IWorkers 11 | ) 12 | 13 | func init() { 14 | bean.Autowired(&workers) 15 | } 16 | 17 | type Config struct { 18 | Cache eosc.RequireId `json:"cache" skill:"github.com/eolinker/apinto/resources.resources.ICache" required:"false" label:"缓存位置"` 19 | } 20 | 21 | func Create(id, name string, cfg *Config, workers map[eosc.RequireId]eosc.IWorker) (eosc.IWorker, error) { 22 | 23 | return &Strategy{ 24 | 25 | WorkerBase: drivers.Worker(id, name), 26 | redisID: string(cfg.Cache), 27 | }, nil 28 | 29 | } 30 | -------------------------------------------------------------------------------- /drivers/plugins/strategy/fuse/factory.go: -------------------------------------------------------------------------------- 1 | package fuse 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | const ( 9 | Name = "strategy-plugin-fuse" 10 | ) 11 | 12 | func Register(register eosc.IExtenderDriverRegister) { 13 | register.RegisterExtenderDriver(Name, NewFactory()) 14 | } 15 | func NewFactory() eosc.IExtenderDriverFactory { 16 | return drivers.NewFactory[Config](Create) 17 | } 18 | -------------------------------------------------------------------------------- /drivers/plugins/strategy/grey/driver.go: -------------------------------------------------------------------------------- 1 | package grey 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | type Config struct { 9 | } 10 | 11 | func Create(id, name string, conf *Config, workers map[eosc.RequireId]eosc.IWorker) (eosc.IWorker, error) { 12 | 13 | return &Strategy{ 14 | WorkerBase: drivers.Worker(id, name), 15 | }, nil 16 | } 17 | -------------------------------------------------------------------------------- /drivers/plugins/strategy/grey/factory.go: -------------------------------------------------------------------------------- 1 | package grey 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | const ( 9 | Name = "strategy-plugin-grey" 10 | ) 11 | 12 | func Register(register eosc.IExtenderDriverRegister) { 13 | register.RegisterExtenderDriver(Name, NewFactory()) 14 | } 15 | func NewFactory() eosc.IExtenderDriverFactory { 16 | return drivers.NewFactory[Config](Create) 17 | } 18 | -------------------------------------------------------------------------------- /drivers/plugins/strategy/grey/strategy.go: -------------------------------------------------------------------------------- 1 | package grey 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | grey_strategy "github.com/eolinker/apinto/drivers/strategy/grey-strategy" 6 | "github.com/eolinker/eosc" 7 | eoscContext "github.com/eolinker/eosc/eocontext" 8 | ) 9 | 10 | type Strategy struct { 11 | drivers.WorkerBase 12 | } 13 | 14 | func (s *Strategy) DoFilter(ctx eoscContext.EoContext, next eoscContext.IChain) (err error) { 15 | return grey_strategy.DoStrategy(ctx, next) 16 | } 17 | 18 | func (s *Strategy) Destroy() { 19 | return 20 | } 21 | 22 | func (s *Strategy) Start() error { 23 | return nil 24 | } 25 | 26 | func (s *Strategy) Reset(conf interface{}, workers map[eosc.RequireId]eosc.IWorker) error { 27 | return nil 28 | } 29 | 30 | func (s *Strategy) Stop() error { 31 | return nil 32 | } 33 | 34 | func (s *Strategy) CheckSkill(skill string) bool { 35 | return eoscContext.FilterSkillName == skill 36 | } 37 | -------------------------------------------------------------------------------- /drivers/plugins/strategy/limiting/driver.go: -------------------------------------------------------------------------------- 1 | package limiting 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | type Config struct { 9 | Cache eosc.RequireId `json:"cache" skill:"github.com/eolinker/apinto/resources.resources.ICache" required:"false" label:"缓存位置"` 10 | } 11 | 12 | func Create(id, name string, cfg *Config, workers map[eosc.RequireId]eosc.IWorker) (eosc.IWorker, error) { 13 | 14 | return &Strategy{ 15 | 16 | WorkerBase: drivers.Worker(id, name), 17 | redisID: string(cfg.Cache), 18 | }, nil 19 | } 20 | -------------------------------------------------------------------------------- /drivers/plugins/strategy/limiting/factory.go: -------------------------------------------------------------------------------- 1 | package limiting 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | const ( 9 | Name = "strategy-plugin-limiting" 10 | ) 11 | 12 | func Register(register eosc.IExtenderDriverRegister) { 13 | _ = register.RegisterExtenderDriver(Name, NewFactory()) 14 | } 15 | func NewFactory() eosc.IExtenderDriverFactory { 16 | return drivers.NewFactory[Config](Create) 17 | } 18 | -------------------------------------------------------------------------------- /drivers/plugins/strategy/visit/driver.go: -------------------------------------------------------------------------------- 1 | package visit 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | type Config struct { 9 | } 10 | 11 | func Create(id, name string, conf *Config, workers map[eosc.RequireId]eosc.IWorker) (eosc.IWorker, error) { 12 | return &Strategy{ 13 | WorkerBase: drivers.Worker(id, name), 14 | }, nil 15 | } 16 | -------------------------------------------------------------------------------- /drivers/plugins/strategy/visit/factory.go: -------------------------------------------------------------------------------- 1 | package visit 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | const ( 9 | Name = "strategy-plugin-visit" 10 | ) 11 | 12 | func Register(register eosc.IExtenderDriverRegister) { 13 | register.RegisterExtenderDriver(Name, NewFactory()) 14 | } 15 | func NewFactory() eosc.IExtenderDriverFactory { 16 | return drivers.NewFactory[Config](Create) 17 | } 18 | -------------------------------------------------------------------------------- /drivers/plugins/strategy/visit/strategy.go: -------------------------------------------------------------------------------- 1 | package visit 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | visit_strategy "github.com/eolinker/apinto/drivers/strategy/visit-strategy" 6 | "github.com/eolinker/eosc" 7 | eoscContext "github.com/eolinker/eosc/eocontext" 8 | ) 9 | 10 | type Strategy struct { 11 | drivers.WorkerBase 12 | } 13 | 14 | func (s *Strategy) DoFilter(ctx eoscContext.EoContext, next eoscContext.IChain) (err error) { 15 | return visit_strategy.DoStrategy(ctx, next) 16 | } 17 | 18 | func (s *Strategy) Destroy() { 19 | return 20 | } 21 | 22 | func (s *Strategy) Start() error { 23 | return nil 24 | } 25 | 26 | func (s *Strategy) Reset(conf interface{}, workers map[eosc.RequireId]eosc.IWorker) error { 27 | return nil 28 | } 29 | 30 | func (s *Strategy) Stop() error { 31 | return nil 32 | } 33 | 34 | func (s *Strategy) CheckSkill(skill string) bool { 35 | return eoscContext.FilterSkillName == skill 36 | } 37 | -------------------------------------------------------------------------------- /drivers/resources/datasource/influxdbv2/config.go: -------------------------------------------------------------------------------- 1 | package influxdbv2 2 | 3 | type Config struct { 4 | Scopes []string `json:"scopes" label:"作用域"` 5 | Url string `json:"url"` 6 | Org string `json:"org"` 7 | Bucket string `json:"bucket"` 8 | Token string `json:"token"` 9 | } 10 | 11 | func checkConfig(v interface{}) (*Config, error) { 12 | cfg, ok := v.(*Config) 13 | if !ok { 14 | return nil, errorConfigType 15 | } 16 | return cfg, nil 17 | } 18 | -------------------------------------------------------------------------------- /drivers/resources/datasource/influxdbv2/driver.go: -------------------------------------------------------------------------------- 1 | package influxdbv2 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | 7 | "github.com/eolinker/apinto/drivers" 8 | "github.com/eolinker/eosc" 9 | ) 10 | 11 | func Create(id, name string, v *Config, workers map[eosc.RequireId]eosc.IWorker) (eosc.IWorker, error) { 12 | client := NewClient(v) 13 | _, err := client.Ping(context.Background()) 14 | if err != nil { 15 | return nil, fmt.Errorf("connect influxdb error: %w", err) 16 | } 17 | client.Close() 18 | ctx, cancel := context.WithCancel(context.Background()) 19 | return &output{ 20 | WorkerBase: drivers.Worker(id, name), 21 | cfg: v, 22 | ctx: ctx, 23 | cancel: cancel, 24 | }, nil 25 | } 26 | -------------------------------------------------------------------------------- /drivers/resources/datasource/influxdbv2/error.go: -------------------------------------------------------------------------------- 1 | package influxdbv2 2 | 3 | import "errors" 4 | 5 | var errorConfigType = errors.New("error config type") 6 | -------------------------------------------------------------------------------- /drivers/resources/datasource/influxdbv2/factory.go: -------------------------------------------------------------------------------- 1 | package influxdbv2 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | "github.com/eolinker/eosc/utils/schema" 7 | "reflect" 8 | ) 9 | 10 | var ( 11 | configType = reflect.TypeOf(new(Config)) 12 | render interface{} 13 | ) 14 | 15 | func init() { 16 | render, _ = schema.Generate(configType, nil) 17 | } 18 | 19 | func Register(register eosc.IExtenderDriverRegister) { 20 | register.RegisterExtenderDriver("influxdbv2", NewFactory()) 21 | } 22 | 23 | // NewFactory 创建service_http驱动工厂 24 | func NewFactory() eosc.IExtenderDriverFactory { 25 | 26 | return drivers.NewFactory[Config](Create) 27 | } 28 | -------------------------------------------------------------------------------- /drivers/resources/redis/driver.go: -------------------------------------------------------------------------------- 1 | package redis 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | func Create(id, name string, v *Config, workers map[eosc.RequireId]eosc.IWorker) (eosc.IWorker, error) { 9 | 10 | w := &Worker{ 11 | WorkerBase: drivers.Worker(id, name), 12 | ICache: &Empty{}, 13 | IVectors: &Empty{}, 14 | config: nil, 15 | client: nil, 16 | } 17 | err := w.Reset(v, workers) 18 | if err != nil { 19 | return nil, err 20 | } 21 | return w, nil 22 | } 23 | -------------------------------------------------------------------------------- /drivers/resources/redis/factory.go: -------------------------------------------------------------------------------- 1 | package redis 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | "github.com/eolinker/eosc/utils/schema" 7 | "reflect" 8 | ) 9 | 10 | var ( 11 | configType = reflect.TypeOf(new(Config)) 12 | render interface{} 13 | ) 14 | 15 | func init() { 16 | render, _ = schema.Generate(configType, nil) 17 | 18 | } 19 | 20 | func Register(register eosc.IExtenderDriverRegister) { 21 | register.RegisterExtenderDriver("redis", NewFactory()) 22 | } 23 | 24 | // NewFactory 创建service_http驱动工厂 25 | func NewFactory() eosc.IExtenderDriverFactory { 26 | 27 | return drivers.NewFactory[Config](Create) 28 | } 29 | -------------------------------------------------------------------------------- /drivers/router/dubbo2-router/finish.go: -------------------------------------------------------------------------------- 1 | package dubbo2_router 2 | 3 | import ( 4 | "github.com/eolinker/eosc/eocontext" 5 | ) 6 | 7 | type finishHandler struct { 8 | } 9 | 10 | func newFinishHandler() *finishHandler { 11 | return &finishHandler{} 12 | } 13 | 14 | func (f *finishHandler) Finish(org eocontext.EoContext) error { 15 | 16 | return nil 17 | } 18 | -------------------------------------------------------------------------------- /drivers/router/dubbo2-router/manager/append.go: -------------------------------------------------------------------------------- 1 | package manager 2 | 3 | import ( 4 | "github.com/eolinker/apinto/router" 5 | ) 6 | 7 | type AppendRule = router.AppendRule 8 | -------------------------------------------------------------------------------- /drivers/router/dubbo2-router/manager/endpoint.go: -------------------------------------------------------------------------------- 1 | package manager 2 | 3 | import "github.com/eolinker/apinto/router" 4 | 5 | type Router struct { 6 | Id string 7 | Port int 8 | Service string 9 | Method string 10 | Appends []AppendRule 11 | Router router.IRouterHandler 12 | } 13 | -------------------------------------------------------------------------------- /drivers/router/dubbo2-router/manager/error.go: -------------------------------------------------------------------------------- 1 | package manager 2 | 3 | import ( 4 | "dubbo.apache.org/dubbo-go/v3/protocol" 5 | "dubbo.apache.org/dubbo-go/v3/protocol/dubbo/impl" 6 | ) 7 | 8 | func Dubbo2ErrorResult(err error) protocol.RPCResult { 9 | payload := impl.NewResponsePayload(nil, err, nil) 10 | return protocol.RPCResult{ 11 | Attrs: payload.Attachments, 12 | Err: payload.Exception, 13 | Rest: payload.RspObj, 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /drivers/router/grpc-router/finish.go: -------------------------------------------------------------------------------- 1 | package grpc_router 2 | 3 | import ( 4 | "github.com/eolinker/eosc/eocontext" 5 | grpc_context "github.com/eolinker/eosc/eocontext/grpc-context" 6 | ) 7 | 8 | var defaultFinisher = &Finisher{} 9 | 10 | type Finisher struct { 11 | } 12 | 13 | func (f *Finisher) Finish(org eocontext.EoContext) error { 14 | ctx, err := grpc_context.Assert(org) 15 | if err != nil { 16 | return err 17 | } 18 | return ctx.FastFinish() 19 | } 20 | -------------------------------------------------------------------------------- /drivers/router/grpc-router/manager/append.go: -------------------------------------------------------------------------------- 1 | package manager 2 | 3 | import "github.com/eolinker/apinto/router" 4 | 5 | type AppendRule = router.AppendRule 6 | -------------------------------------------------------------------------------- /drivers/router/grpc-router/manager/endpoint.go: -------------------------------------------------------------------------------- 1 | package manager 2 | 3 | import "github.com/eolinker/apinto/router" 4 | 5 | type Router struct { 6 | Id string 7 | Port int 8 | Hosts []string 9 | Service string 10 | Method string 11 | Appends []AppendRule 12 | GrpcRouter router.IRouterHandler 13 | } 14 | -------------------------------------------------------------------------------- /drivers/router/http-router/finish.go: -------------------------------------------------------------------------------- 1 | package http_router 2 | 3 | import ( 4 | "github.com/eolinker/eosc/eocontext" 5 | http_context "github.com/eolinker/eosc/eocontext/http-context" 6 | ) 7 | 8 | var defaultFinisher = &Finisher{} 9 | 10 | type Finisher struct { 11 | } 12 | 13 | func (f *Finisher) Finish(org eocontext.EoContext) error { 14 | ctx, err := http_context.Assert(org) 15 | if err != nil { 16 | return err 17 | } 18 | ctx.SetLabel("current_running", "false") 19 | ctx.FastFinish() 20 | 21 | return nil 22 | } 23 | -------------------------------------------------------------------------------- /drivers/router/http-router/manager/append.go: -------------------------------------------------------------------------------- 1 | package manager 2 | 3 | import ( 4 | http_router "github.com/eolinker/apinto/router" 5 | ) 6 | 7 | type AppendRule = http_router.AppendRule 8 | -------------------------------------------------------------------------------- /drivers/router/http-router/manager/endpoint.go: -------------------------------------------------------------------------------- 1 | package manager 2 | 3 | import "github.com/eolinker/apinto/router" 4 | 5 | type Router struct { 6 | Id string 7 | Port int 8 | Protocols []string 9 | Hosts []string 10 | Method []string 11 | Path string 12 | Appends []AppendRule 13 | HttpHandler router.IRouterHandler 14 | } 15 | -------------------------------------------------------------------------------- /drivers/router/http-router/manager/export.go: -------------------------------------------------------------------------------- 1 | package manager 2 | 3 | import "github.com/eolinker/apinto/router" 4 | 5 | func Set(id string, port int, hosts []string, method []string, path string, append []AppendRule, router router.IRouterHandler) error { 6 | return routerManager.Set(id, port, nil, hosts, method, path, append, router) 7 | } 8 | func Delete(id string) { 9 | routerManager.Delete(id) 10 | } 11 | func AddPreRouter(id string, method []string, path string, handler router.IRouterPreHandler) { 12 | routerManager.AddPreRouter(id, method, path, handler) 13 | } 14 | func DeletePreRouter(id string) { 15 | routerManager.DeletePreRouter(id) 16 | } 17 | -------------------------------------------------------------------------------- /drivers/router/http-router/stream/complete.go: -------------------------------------------------------------------------------- 1 | package stream 2 | -------------------------------------------------------------------------------- /drivers/service/driver.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | //Create 创建service_http驱动的实例 9 | func Create(id, name string, v *Config, workers map[eosc.RequireId]eosc.IWorker) (eosc.IWorker, error) { 10 | 11 | w := &serviceWorker{ 12 | WorkerBase: drivers.Worker(id, name), 13 | Service: Service{}, 14 | } 15 | 16 | err := w.Reset(v, workers) 17 | if err != nil { 18 | return nil, err 19 | } 20 | 21 | return w, nil 22 | } 23 | -------------------------------------------------------------------------------- /drivers/service/factory.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/apinto/drivers/discovery/static" 6 | iphash "github.com/eolinker/apinto/upstream/ip-hash" 7 | roundrobin "github.com/eolinker/apinto/upstream/round-robin" 8 | "github.com/eolinker/eosc" 9 | "github.com/eolinker/eosc/log" 10 | ) 11 | 12 | var DriverName = "service_http" 13 | var ( 14 | defaultHttpDiscovery = static.CreateAnonymous(&static.Config{ 15 | Health: nil, 16 | HealthOn: false, 17 | }) 18 | ) 19 | 20 | // Register 注册service_http驱动工厂 21 | func Register(register eosc.IExtenderDriverRegister) { 22 | err := register.RegisterExtenderDriver(DriverName, NewFactory()) 23 | if err != nil { 24 | log.Errorf("register %s %s", DriverName, err) 25 | return 26 | 27 | } 28 | } 29 | 30 | // NewFactory 创建service_http驱动工厂 31 | func NewFactory() eosc.IExtenderDriverFactory { 32 | roundrobin.Register() 33 | iphash.Register() 34 | return drivers.NewFactory[Config](Create) 35 | } 36 | -------------------------------------------------------------------------------- /drivers/service/worker.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "errors" 5 | 6 | "github.com/eolinker/apinto/drivers" 7 | "github.com/eolinker/apinto/service" 8 | ) 9 | 10 | var ( 11 | ErrorNeedUpstream = errors.New("need upstream") 12 | 13 | ErrorInvalidDiscovery = errors.New("invalid Discovery") 14 | ) 15 | 16 | var _ service.IService = (*serviceWorker)(nil) 17 | 18 | type serviceWorker struct { 19 | drivers.WorkerBase 20 | Service 21 | } 22 | 23 | func (s *serviceWorker) Start() error { 24 | return nil 25 | } 26 | 27 | func (s *serviceWorker) Stop() error { 28 | if s.app != nil { 29 | s.app.Close() 30 | s.app = nil 31 | } 32 | return nil 33 | } 34 | 35 | func (s *serviceWorker) Destroy() error { 36 | if s.app != nil { 37 | s.app.Close() 38 | s.app = nil 39 | } 40 | return nil 41 | } 42 | 43 | // CheckSkill 检查目标能力是否存在 44 | func (s *serviceWorker) CheckSkill(skill string) bool { 45 | return service.CheckSkill(skill) 46 | } 47 | -------------------------------------------------------------------------------- /drivers/strategy/cache-strategy/config.go: -------------------------------------------------------------------------------- 1 | package cache_strategy 2 | 3 | import "github.com/eolinker/apinto/strategy" 4 | 5 | type Config struct { 6 | Name string `json:"name" skip:"skip"` 7 | Description string `json:"description" skip:"skip"` 8 | Stop bool `json:"stop" label:"禁用"` 9 | Priority int `json:"priority" label:"优先级" description:"1-999"` 10 | Filters strategy.FilterConfig `json:"filters" label:"过滤规则"` 11 | ValidTime int `json:"valid_time" label:"有效期" description:"有效期"` 12 | } 13 | -------------------------------------------------------------------------------- /drivers/strategy/cache-strategy/handler.go: -------------------------------------------------------------------------------- 1 | package cache_strategy 2 | 3 | import ( 4 | "github.com/eolinker/apinto/strategy" 5 | ) 6 | 7 | type CacheValidTimeHandler struct { 8 | name string 9 | filter strategy.IFilter 10 | validTime int 11 | priority int 12 | stop bool 13 | } 14 | 15 | func NewCacheValidTimeHandler(conf *Config) (*CacheValidTimeHandler, error) { 16 | filter, err := strategy.ParseFilter(conf.Filters) 17 | if err != nil { 18 | return nil, err 19 | } 20 | 21 | return &CacheValidTimeHandler{ 22 | name: conf.Name, 23 | filter: filter, 24 | validTime: conf.ValidTime, 25 | priority: conf.Priority, 26 | stop: conf.Stop, 27 | }, nil 28 | } 29 | -------------------------------------------------------------------------------- /drivers/strategy/data-mask-strategy/config.go: -------------------------------------------------------------------------------- 1 | package data_mask_strategy 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers/strategy/data-mask-strategy/mask" 5 | "github.com/eolinker/apinto/strategy" 6 | ) 7 | 8 | type Config struct { 9 | Name string `json:"name" skip:"skip"` 10 | Description string `json:"description" skip:"skip"` 11 | //Stop bool `json:"stop"` 12 | Priority int `json:"priority" label:"优先级" description:"1-999"` 13 | Filters strategy.FilterConfig `json:"filters" label:"过滤规则"` 14 | DataMask mask.DataMask `json:"data_mask" label:"规则"` 15 | } 16 | -------------------------------------------------------------------------------- /drivers/strategy/data-mask-strategy/mask/entity.go: -------------------------------------------------------------------------------- 1 | package mask 2 | 3 | type DataMask struct { 4 | Rules []*Rule `json:"rules"` 5 | } 6 | 7 | type Rule struct { 8 | Match *BasicItem `json:"match"` 9 | Mask *Mask `json:"mask"` 10 | } 11 | 12 | type BasicItem struct { 13 | Type string `json:"type"` 14 | Value string `json:"value"` 15 | } 16 | 17 | type Mask struct { 18 | Type string `json:"type"` 19 | Begin int `json:"begin"` 20 | Length int `json:"length"` 21 | Replace *BasicItem `json:"replace"` 22 | } 23 | -------------------------------------------------------------------------------- /drivers/strategy/data-mask-strategy/mask/inner/name.go: -------------------------------------------------------------------------------- 1 | package inner 2 | 3 | import ( 4 | "encoding/json" 5 | 6 | "github.com/eolinker/apinto/drivers/strategy/data-mask-strategy/mask" 7 | ) 8 | 9 | type nameMaskDriver struct { 10 | maskFunc mask.MaskFunc 11 | } 12 | 13 | func NewNameMaskDriver(maskFunc mask.MaskFunc) mask.IInnerMask { 14 | return &nameMaskDriver{maskFunc: maskFunc} 15 | } 16 | 17 | func (i *nameMaskDriver) Exec(body []byte) ([]byte, error) { 18 | if i.maskFunc == nil { 19 | // 未设置脱敏方法,不做处理 20 | return body, nil 21 | } 22 | var jsonData interface{} 23 | err := json.Unmarshal(body, &jsonData) 24 | if err == nil { 25 | traverseAndModify(jsonData, []string{ 26 | "name", "cname", 27 | }, i.maskFunc) 28 | 29 | return json.Marshal(jsonData) 30 | } 31 | return body, nil 32 | } 33 | -------------------------------------------------------------------------------- /drivers/strategy/data-mask-strategy/mask/inner/phone.go: -------------------------------------------------------------------------------- 1 | package inner 2 | 3 | import ( 4 | "regexp" 5 | 6 | "github.com/eolinker/apinto/drivers/strategy/data-mask-strategy/mask" 7 | ) 8 | 9 | var ( 10 | phoneRegx = regexp.MustCompile(`1[3-9]\d{9}`) 11 | fatherPhoneRegx = regexp.MustCompile(`[a-zA-Z0-9]{0,1}\d{11}[a-zA-Z0-9]{0,1}`) 12 | ) 13 | 14 | func newPhoneMaskDriver(maskFunc mask.MaskFunc) mask.IInnerMask { 15 | return &phoneMaskDriver{ 16 | MaskFunc: maskFunc, 17 | } 18 | } 19 | 20 | type phoneMaskDriver struct { 21 | mask.MaskFunc 22 | } 23 | 24 | func (i *phoneMaskDriver) Exec(body []byte) ([]byte, error) { 25 | if i.MaskFunc == nil { 26 | return body, nil 27 | } 28 | 29 | body = fatherPhoneRegx.ReplaceAllFunc(body, func(b []byte) []byte { 30 | if len(b) > 11 || !phoneRegx.Match(b) { 31 | return b 32 | } 33 | 34 | return []byte(i.MaskFunc(string(b))) 35 | }) 36 | return body, nil 37 | } 38 | -------------------------------------------------------------------------------- /drivers/strategy/data-mask-strategy/mask/manager.go: -------------------------------------------------------------------------------- 1 | package mask 2 | 3 | import ( 4 | "github.com/eolinker/eosc" 5 | ) 6 | 7 | var ( 8 | maskManager = NewMaskManager() 9 | ) 10 | 11 | type IMaskFactory interface { 12 | Create(cfg *Rule, maskFunc MaskFunc) (IMaskDriver, error) 13 | } 14 | 15 | type MaskManager struct { 16 | factories eosc.Untyped[string, IMaskFactory] 17 | } 18 | 19 | func NewMaskManager() *MaskManager { 20 | return &MaskManager{ 21 | factories: eosc.BuildUntyped[string, IMaskFactory](), 22 | } 23 | } 24 | 25 | func (m *MaskManager) Register(name string, driver IMaskFactory) { 26 | m.factories.Set(name, driver) 27 | } 28 | 29 | func (m *MaskManager) Get(name string) (IMaskFactory, bool) { 30 | return m.factories.Get(name) 31 | } 32 | 33 | func (m *MaskManager) Del(name string) { 34 | m.factories.Del(name) 35 | } 36 | 37 | func RegisterMaskFactory(name string, factory IMaskFactory) { 38 | maskManager.Register(name, factory) 39 | } 40 | 41 | func GetMaskFactory(name string) (IMaskFactory, bool) { 42 | return maskManager.Get(name) 43 | } 44 | -------------------------------------------------------------------------------- /drivers/strategy/data-mask-strategy/mask/match.go: -------------------------------------------------------------------------------- 1 | package mask 2 | 3 | const ( 4 | MatchInner = "inner" 5 | MatchKeyword = "keyword" 6 | MatchRegex = "regex" 7 | MatchJsonPath = "json_path" 8 | ) 9 | 10 | const ( 11 | MatchInnerValueName = "name" 12 | MatchInnerValuePhone = "phone" 13 | MatchInnerValueIDCard = "id-card" 14 | MatchInnerValueBankCard = "bank-card" 15 | MatchInnerValueDate = "date" 16 | MatchInnerValueAmount = "amount" 17 | ) 18 | 19 | type IInnerMask interface { 20 | Exec(body []byte) ([]byte, error) 21 | } 22 | -------------------------------------------------------------------------------- /drivers/strategy/fuse-strategy/driver.go: -------------------------------------------------------------------------------- 1 | package fuse_strategy 2 | 3 | import ( 4 | "fmt" 5 | "github.com/eolinker/apinto/drivers" 6 | "github.com/eolinker/apinto/strategy" 7 | "github.com/eolinker/eosc" 8 | ) 9 | 10 | func checkConfig(conf *Config) error { 11 | if conf.Priority > 999 || conf.Priority < 1 { 12 | return fmt.Errorf("priority value %d not allow ", conf.Priority) 13 | } 14 | 15 | _, err := strategy.ParseFilter(conf.Filters) 16 | if err != nil { 17 | return err 18 | } 19 | 20 | return nil 21 | } 22 | 23 | func Check(cfg *Config, workers map[eosc.RequireId]eosc.IWorker) error { 24 | 25 | return checkConfig(cfg) 26 | } 27 | 28 | func Create(id, name string, v *Config, workers map[eosc.RequireId]eosc.IWorker) (eosc.IWorker, error) { 29 | if err := Check(v, workers); err != nil { 30 | return nil, err 31 | } 32 | 33 | lg := &Fuse{ 34 | WorkerBase: drivers.Worker(id, name), 35 | } 36 | 37 | err := lg.Reset(v, workers) 38 | if err != nil { 39 | return nil, err 40 | } 41 | 42 | controller.Store(id) 43 | return lg, nil 44 | } 45 | -------------------------------------------------------------------------------- /drivers/strategy/grey-strategy/match-robin.go: -------------------------------------------------------------------------------- 1 | package grey_strategy 2 | 3 | import "github.com/eolinker/eosc/eocontext" 4 | 5 | type greyFlow struct { 6 | flowRobin *Robin 7 | } 8 | 9 | // Match 按流量计算 10 | func (r *greyFlow) Match(ctx eocontext.EoContext) bool { 11 | flow := r.flowRobin.Select() 12 | return flow.GetId() == 1 13 | } 14 | -------------------------------------------------------------------------------- /drivers/strategy/limiting-strategy/actuator-handle.go: -------------------------------------------------------------------------------- 1 | package limiting_strategy 2 | 3 | import ( 4 | "github.com/eolinker/eosc/eocontext" 5 | ) 6 | 7 | type ActuatorsHandler interface { 8 | Assert(ctx eocontext.EoContext) bool 9 | Check(ctx eocontext.EoContext, handlers []*LimitingHandler, scalars *Scalars) error 10 | } 11 | 12 | var ( 13 | actuatorsHandlers []ActuatorsHandler 14 | ) 15 | 16 | func RegisterActuator(handler ActuatorsHandler) { 17 | 18 | actuatorsHandlers = append(actuatorsHandlers, handler) 19 | } 20 | func getActuatorsHandlers() []ActuatorsHandler { 21 | 22 | return actuatorsHandlers 23 | } 24 | -------------------------------------------------------------------------------- /drivers/strategy/limiting-strategy/driver.go: -------------------------------------------------------------------------------- 1 | package limiting_strategy 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/apinto/strategy" 6 | "github.com/eolinker/eosc" 7 | ) 8 | 9 | func Check(cfg *Config, workers map[eosc.RequireId]eosc.IWorker) error { 10 | 11 | return checkConfig(cfg) 12 | } 13 | 14 | func checkConfig(conf *Config) error { 15 | //if conf.Priority > 999 || conf.Priority < 1 { 16 | // return fmt.Errorf("priority value %d not allow ", conf.Priority) 17 | //} 18 | _, err := strategy.ParseFilter(conf.Filters) 19 | if err != nil { 20 | return err 21 | } 22 | 23 | return nil 24 | } 25 | 26 | func Create(id, name string, v *Config, workers map[eosc.RequireId]eosc.IWorker) (eosc.IWorker, error) { 27 | if err := Check(v, workers); err != nil { 28 | return nil, err 29 | } 30 | 31 | lg := &Limiting{ 32 | WorkerBase: drivers.Worker(id, name), 33 | } 34 | 35 | err := lg.Reset(v, workers) 36 | if err != nil { 37 | return nil, err 38 | } 39 | 40 | controller.Store(id) 41 | return lg, nil 42 | } 43 | -------------------------------------------------------------------------------- /drivers/strategy/visit-strategy/config.go: -------------------------------------------------------------------------------- 1 | package visit_strategy 2 | 3 | import "github.com/eolinker/apinto/strategy" 4 | 5 | type VisitRule string 6 | 7 | const ( 8 | // VisitRuleAllow 访问策略访问规则 9 | VisitRuleAllow VisitRule = "allow" //允许访问 10 | VisitRuleRefuse VisitRule = "refuse" //拒绝访问 11 | ) 12 | 13 | type Config struct { 14 | Name string `json:"name" skip:"skip"` 15 | Description string `json:"description" skip:"skip"` 16 | Stop bool `json:"stop"` 17 | Priority int `json:"priority" label:"优先级" description:"1-999"` 18 | Filters strategy.FilterConfig `json:"filters" label:"过滤规则"` 19 | Rule Rule `json:"visit" label:"规则"` 20 | } 21 | 22 | type Rule struct { 23 | VisitRule VisitRule `json:"visit_rule" label:"访问规则"` 24 | InfluenceSphere strategy.FilterConfig `json:"influence_sphere" label:"生效范围"` 25 | Continue bool `json:"continue" label:"继续匹配其他访问策略"` 26 | } 27 | -------------------------------------------------------------------------------- /drivers/template/config.go: -------------------------------------------------------------------------------- 1 | package template 2 | 3 | import "github.com/eolinker/apinto/plugin" 4 | 5 | type Config struct { 6 | Plugins plugin.Plugins `json:"plugins" label:"插件配置"` 7 | } 8 | -------------------------------------------------------------------------------- /drivers/template/driver.go: -------------------------------------------------------------------------------- 1 | package template 2 | 3 | import ( 4 | "github.com/eolinker/eosc" 5 | ) 6 | 7 | func Create(id, name string, v *Config, workers map[eosc.RequireId]eosc.IWorker) (eosc.IWorker, error) { 8 | t := NewTemplate(id, name) 9 | err := t.Reset(v, workers) 10 | if err != nil { 11 | return nil, err 12 | } 13 | return t, nil 14 | } 15 | -------------------------------------------------------------------------------- /drivers/template/factory.go: -------------------------------------------------------------------------------- 1 | package template 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/apinto/plugin" 6 | "github.com/eolinker/eosc/common/bean" 7 | 8 | "github.com/eolinker/eosc" 9 | ) 10 | 11 | var DriverName = "plugin_template" 12 | var ( 13 | pluginManger plugin.IPluginManager 14 | ) 15 | 16 | //Register 注册service_http驱动工厂 17 | func Register(register eosc.IExtenderDriverRegister) { 18 | bean.Autowired(&pluginManger) 19 | register.RegisterExtenderDriver(DriverName, NewFactory()) 20 | } 21 | 22 | //NewFactory 创建service_http驱动工厂 23 | func NewFactory() eosc.IExtenderDriverFactory { 24 | return drivers.NewFactory[Config](Create) 25 | } 26 | -------------------------------------------------------------------------------- /drivers/transcode/protobuf/config.go: -------------------------------------------------------------------------------- 1 | package protocbuf 2 | 3 | import ( 4 | "encoding/json" 5 | 6 | "github.com/eolinker/eosc" 7 | ) 8 | 9 | // Config protobuf驱动配置 10 | type Config struct { 11 | ProtoFiles eosc.EoFiles `json:"proto_files" label:"proto文件列表"` 12 | } 13 | 14 | func (c *Config) String() string { 15 | data, _ := json.Marshal(c) 16 | return string(data) 17 | } 18 | -------------------------------------------------------------------------------- /drivers/transcode/protobuf/driver.go: -------------------------------------------------------------------------------- 1 | package protocbuf 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | // Create 创建service_http驱动的实例 9 | func Create(id, name string, v *Config, workers map[eosc.RequireId]eosc.IWorker) (eosc.IWorker, error) { 10 | 11 | source, err := parseFiles(v.ProtoFiles) 12 | if err != nil { 13 | return nil, err 14 | } 15 | 16 | return &Worker{ 17 | WorkerBase: drivers.Worker(id, name), 18 | source: source, 19 | }, nil 20 | } 21 | -------------------------------------------------------------------------------- /drivers/transcode/protobuf/factory.go: -------------------------------------------------------------------------------- 1 | package protocbuf 2 | 3 | import ( 4 | "github.com/eolinker/apinto/drivers" 5 | "github.com/eolinker/eosc" 6 | ) 7 | 8 | var DriverName = "protobuf_transcode" 9 | 10 | // Register 注册protobuf驱动工厂 11 | func Register(register eosc.IExtenderDriverRegister) { 12 | register.RegisterExtenderDriver(DriverName, NewFactory()) 13 | } 14 | 15 | // NewFactory 创建service_http驱动工厂 16 | func NewFactory() eosc.IExtenderDriverFactory { 17 | 18 | return drivers.NewFactory[Config](Create) 19 | } 20 | -------------------------------------------------------------------------------- /encoder/br.go: -------------------------------------------------------------------------------- 1 | package encoder 2 | 3 | import ( 4 | "bytes" 5 | "io" 6 | 7 | "github.com/andybalholm/brotli" 8 | ) 9 | 10 | func init() { 11 | encoderManger.Set("br", &Br{}) 12 | } 13 | 14 | type Br struct { 15 | } 16 | 17 | func (b *Br) ToUTF8(data []byte) ([]byte, error) { 18 | reader := brotli.NewReader(bytes.NewReader(data)) 19 | return io.ReadAll(reader) 20 | } 21 | -------------------------------------------------------------------------------- /encoder/encoder.go: -------------------------------------------------------------------------------- 1 | package encoder 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/eolinker/eosc" 7 | ) 8 | 9 | type IEncoder interface { 10 | ToUTF8([]byte) ([]byte, error) 11 | } 12 | 13 | type encoder struct { 14 | encoders eosc.Untyped[string, IEncoder] 15 | } 16 | 17 | func newEncoder() *encoder { 18 | return &encoder{encoders: eosc.BuildUntyped[string, IEncoder]()} 19 | } 20 | 21 | func (e *encoder) Set(name string, encoder IEncoder) { 22 | e.encoders.Set(name, encoder) 23 | } 24 | 25 | func (e *encoder) ToUTF8(name string, data []byte) ([]byte, error) { 26 | enc, ok := e.encoders.Get(name) 27 | if !ok { 28 | return nil, fmt.Errorf("encoder %s not found", name) 29 | } 30 | return enc.ToUTF8(data) 31 | } 32 | 33 | var encoderManger = newEncoder() 34 | 35 | func ToUTF8(name string, data []byte) ([]byte, error) { 36 | return encoderManger.ToUTF8(name, data) 37 | } 38 | -------------------------------------------------------------------------------- /encoder/gzip.go: -------------------------------------------------------------------------------- 1 | package encoder 2 | 3 | import ( 4 | "github.com/valyala/bytebufferpool" 5 | "github.com/valyala/fasthttp" 6 | ) 7 | 8 | func init() { 9 | encoderManger.Set("gzip", &Gzip{}) 10 | } 11 | 12 | type Gzip struct { 13 | } 14 | 15 | func (g *Gzip) ToUTF8(data []byte) ([]byte, error) { 16 | var bb bytebufferpool.ByteBuffer 17 | _, err := fasthttp.WriteGunzip(&bb, data) 18 | if err != nil { 19 | return nil, err 20 | } 21 | return bb.B, nil 22 | // 创建一个gzip reader 23 | //reader, err := gzip.NewReader(bytes.NewReader(data)) 24 | //if err != nil { 25 | // return nil, err 26 | //} 27 | //defer reader.Close() 28 | // 29 | //// 读取解压后的数据 30 | //var buf bytes.Buffer 31 | //_, err = io.Copy(&buf, reader) 32 | //if err != nil { 33 | // return nil, err 34 | //} 35 | // 36 | //// 返回解压后的数据 37 | //// 注意:这里假设解压后的数据已经是UTF-8编码 38 | //// 如果需要处理其他编码转UTF-8,需要额外的转换步骤 39 | //return buf.Bytes(), nil 40 | } 41 | -------------------------------------------------------------------------------- /entries/ctx_key/ctx_key.go: -------------------------------------------------------------------------------- 1 | package ctx_key 2 | 3 | const ( 4 | CtxKeyRetry = "retry" 5 | CtxKeyTimeout = "timeout" 6 | ) 7 | -------------------------------------------------------------------------------- /entries/metric-entry/proxy-reader.go: -------------------------------------------------------------------------------- 1 | package metric_entry 2 | 3 | import ( 4 | http_context "github.com/eolinker/eosc/eocontext/http-context" 5 | ) 6 | 7 | type proxyCollectorReadFunc func(request http_context.IProxy) (float64, bool) 8 | 9 | var proxyColRead = map[string]proxyCollectorReadFunc{ 10 | "proxy_total": func(proxy http_context.IProxy) (float64, bool) { 11 | return 1, true 12 | }, 13 | "proxy_timing": func(proxy http_context.IProxy) (float64, bool) { 14 | return float64(proxy.ResponseTime()), true 15 | }, 16 | "proxy_req": func(proxy http_context.IProxy) (float64, bool) { 17 | return float64(proxy.ContentLength()), true 18 | }, 19 | "proxy_resp": func(proxy http_context.IProxy) (float64, bool) { 20 | return float64(proxy.ResponseLength()), true 21 | }, 22 | } 23 | -------------------------------------------------------------------------------- /entries/monitor-entry/client.go: -------------------------------------------------------------------------------- 1 | package monitor_entry 2 | 3 | type IClient interface { 4 | ID() string 5 | Write(point IPoint) error 6 | Close() 7 | } 8 | -------------------------------------------------------------------------------- /entries/monitor-entry/output.go: -------------------------------------------------------------------------------- 1 | package monitor_entry 2 | 3 | const Skill = "github.com/eolinker/apinto/monitor-entry.monitor-entry.IOutput" 4 | 5 | type IOutput interface { 6 | Output(point ...IPoint) 7 | } 8 | -------------------------------------------------------------------------------- /entries/monitor-entry/point.go: -------------------------------------------------------------------------------- 1 | package monitor_entry 2 | 3 | import "time" 4 | 5 | var _ IPoint = (*Point)(nil) 6 | 7 | type IPoint interface { 8 | Table() string 9 | Tags() map[string]string 10 | Fields() map[string]interface{} 11 | Time() time.Time 12 | } 13 | 14 | func NewPoint(table string, tags map[string]string, fields map[string]interface{}, pointTime time.Time) *Point { 15 | return &Point{table: table, tags: tags, fields: fields, pointTime: pointTime} 16 | } 17 | 18 | type Point struct { 19 | table string 20 | tags map[string]string 21 | fields map[string]interface{} 22 | pointTime time.Time 23 | } 24 | 25 | func (p *Point) Table() string { 26 | return p.table 27 | } 28 | 29 | func (p *Point) Tags() map[string]string { 30 | return p.tags 31 | } 32 | 33 | func (p *Point) Fields() map[string]interface{} { 34 | return p.fields 35 | } 36 | 37 | func (p *Point) Time() time.Time { 38 | return p.pointTime 39 | } 40 | -------------------------------------------------------------------------------- /entries/router/router.go: -------------------------------------------------------------------------------- 1 | package router 2 | 3 | import "time" 4 | 5 | const ( 6 | DefaultRetry = 0 7 | DefaultTimeout = time.Second * 30 8 | ) 9 | -------------------------------------------------------------------------------- /example/dubbo2/client/flag.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "flag" 4 | 5 | var ( 6 | address = "127.0.0.1:8099" 7 | ) 8 | 9 | func init() { 10 | flag.StringVar(&address, "addr", "172.28.187.118:8099", "The address to connect dubbo2 server.") 11 | flag.Parse() 12 | } 13 | -------------------------------------------------------------------------------- /example/dubbo2/model/server.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import "time" 4 | 5 | type Server struct { 6 | Id int64 7 | Name string 8 | Age int 9 | Email string 10 | } 11 | 12 | type ComplexServer struct { 13 | Addr string 14 | Time time.Time 15 | Server Server 16 | } 17 | -------------------------------------------------------------------------------- /example/dubbo2/server/dubbogo.yaml: -------------------------------------------------------------------------------- 1 | dubbo: 2 | registry: none 3 | protocols: 4 | dubbo: 5 | name: dubbo 6 | port: 20000 7 | provider: 8 | services: 9 | Server: 10 | interface: "api.Server" 11 | -------------------------------------------------------------------------------- /example/dubbo2/server/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | _ "dubbo.apache.org/dubbo-go/v3/common/extension" 5 | "dubbo.apache.org/dubbo-go/v3/config" 6 | _ "dubbo.apache.org/dubbo-go/v3/imports" 7 | ) 8 | 9 | func main() { 10 | config.SetProviderService(&Server{}) 11 | err := config.Load(config.WithPath("./dubbogo.yaml")) 12 | if err != nil { 13 | panic(err) 14 | } 15 | select {} 16 | } 17 | -------------------------------------------------------------------------------- /example/grpc/client/.gitignore: -------------------------------------------------------------------------------- 1 | /client 2 | -------------------------------------------------------------------------------- /example/grpc/client/flag.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "flag" 4 | 5 | var ( 6 | address = "127.0.0.1:8099" 7 | authority = "" 8 | keyFile = "" 9 | certFIle = "" 10 | serverName = "" 11 | insecureVerify = false 12 | ) 13 | 14 | func Parse() { 15 | flag.StringVar(&address, "addr", "127.0.0.1:8099", "The address to connect grpc server.") 16 | flag.StringVar(&authority, "authority", "", "Authority will be verified by grpc server.") 17 | flag.StringVar(&serverName, "servername", "", "Override server name when validating TLS certificate.") 18 | flag.StringVar(&keyFile, "key", "", "File containing client private key, to present to the server.") 19 | flag.StringVar(&certFIle, "cert", "", "File containing client certificate (public key).") 20 | flag.BoolVar(&insecureVerify, "insecure", false, "Skip server certificate and domain verification. (NOT SECURE!).") 21 | flag.Parse() 22 | } 23 | -------------------------------------------------------------------------------- /example/grpc/client/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "log" 4 | 5 | func main() { 6 | Parse() 7 | conn, client, err := NewClient() 8 | if err != nil { 9 | log.Println("create grpc client error:", err) 10 | return 11 | } 12 | grpcClient := &Client{ 13 | client: client, 14 | conn: conn, 15 | } 16 | defer grpcClient.Close() 17 | md := map[string]string{ 18 | "app": "apinto", 19 | } 20 | names := []string{ 21 | "apinto", 22 | "eolink", 23 | } 24 | grpcClient.CurrentRequest(names, md) 25 | grpcClient.StreamRequest(names, md) 26 | grpcClient.StreamResponse(names, md) 27 | grpcClient.AllStream(names, md) 28 | } 29 | -------------------------------------------------------------------------------- /example/grpc/client/options.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "crypto/tls" 5 | 6 | "google.golang.org/grpc/credentials" 7 | "google.golang.org/grpc/credentials/insecure" 8 | 9 | "google.golang.org/grpc" 10 | ) 11 | 12 | func genDialOptions() ([]grpc.DialOption, error) { 13 | var opts []grpc.DialOption 14 | if insecureVerify { 15 | opts = append(opts, grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{InsecureSkipVerify: true}))) 16 | } else { 17 | if certFIle != "" { 18 | certs, err := credentials.NewClientTLSFromFile(certFIle, "") 19 | if err != nil { 20 | return nil, err 21 | } 22 | opts = append(opts, grpc.WithTransportCredentials(certs)) 23 | } else { 24 | opts = append(opts, grpc.WithTransportCredentials(insecure.NewCredentials())) 25 | } 26 | } 27 | if authority != "" { 28 | opts = append(opts, grpc.WithAuthority(authority)) 29 | } 30 | return opts, nil 31 | } 32 | -------------------------------------------------------------------------------- /example/grpc/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/eolinker/apinto/example/grpc 2 | 3 | go 1.19 4 | 5 | require ( 6 | github.com/golang/protobuf v1.5.3 7 | github.com/grpc-ecosystem/grpc-gateway v1.16.0 8 | golang.org/x/net v0.10.0 9 | google.golang.org/grpc v1.55.0 10 | google.golang.org/protobuf v1.30.0 11 | ) 12 | 13 | require ( 14 | golang.org/x/sys v0.8.0 // indirect 15 | golang.org/x/text v0.9.0 // indirect 16 | google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect 17 | ) 18 | -------------------------------------------------------------------------------- /example/grpc/grpc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | 4 | OUT_DIR=demo_service 5 | 6 | set -e 7 | 8 | mkdir -p $OUT_DIR 9 | 10 | protoc --grpc-gateway_opt logtostderr=true \ 11 | --grpc-gateway_opt paths=source_relative \ 12 | --grpc-gateway_opt generate_unbound_methods=true \ 13 | --grpc-gateway_out=$OUT_DIR \ 14 | --go_out=$OUT_DIR --go_opt=paths=source_relative \ 15 | --go-grpc_out=$OUT_DIR --go-grpc_opt=paths=source_relative *.proto -------------------------------------------------------------------------------- /example/grpc/msg.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | option go_package = "github.com/eolinker/apinto/example/grpc/demo_service"; 4 | 5 | package Service; 6 | 7 | // HelloRequest 请求 8 | message HelloRequest { 9 | string name = 1; 10 | int32 num=2; 11 | string isUser=3; 12 | } 13 | 14 | // HelloResponse 响应,成功消息时,msg为json数据 15 | message HelloResponse { 16 | string msg = 1; 17 | string err = 2; 18 | } 19 | 20 | -------------------------------------------------------------------------------- /example/grpc/server/.gitignore: -------------------------------------------------------------------------------- 1 | /grpcServer 2 | -------------------------------------------------------------------------------- /example/grpc/server/flag.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "flag" 4 | 5 | var ( 6 | ListenPort = 9001 7 | BindIP = "" 8 | TlsKey = "" 9 | TlsPem = "" 10 | ) 11 | 12 | func Parse() { 13 | flag.IntVar(&ListenPort, "p", 9001, "please provide listen port") 14 | flag.StringVar(&BindIP, "ip", "", "Please provide bind ip") 15 | flag.StringVar(&TlsKey, "key", "", "if tls,key is required") 16 | flag.StringVar(&TlsPem, "cert", "", "if tls,cert is required") 17 | flag.Parse() 18 | } 19 | -------------------------------------------------------------------------------- /example/grpc/service.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | option go_package = "github.com/eolinker/apinto/example/grpc/demo_service"; 4 | import "msg.proto"; 5 | 6 | package Service; 7 | 8 | service Hello { 9 | rpc Hello(HelloRequest) returns (HelloResponse){}; 10 | rpc StreamRequest(stream HelloRequest) returns (HelloResponse){}; 11 | rpc StreamResponse(HelloRequest) returns (stream HelloResponse) {}; 12 | rpc AllStream(stream HelloRequest)returns (stream HelloResponse) {}; 13 | } -------------------------------------------------------------------------------- /grpc-descriptor/transcode.go: -------------------------------------------------------------------------------- 1 | package grpc_descriptor 2 | 3 | import ( 4 | "github.com/fullstorydev/grpcurl" 5 | ) 6 | 7 | const ( 8 | Skill = "github.com/eolinker/apinto/grpc-transcode.transcode.IDescriptor" 9 | ) 10 | 11 | type IDescriptor interface { 12 | Descriptor() grpcurl.DescriptorSource 13 | } 14 | 15 | // CheckSkill 检查目标能力是否符合 16 | func CheckSkill(skill string) bool { 17 | return skill == Skill 18 | } 19 | -------------------------------------------------------------------------------- /health-check-http/agent.go: -------------------------------------------------------------------------------- 1 | package health_check_http 2 | -------------------------------------------------------------------------------- /health-check-http/config.go: -------------------------------------------------------------------------------- 1 | package health_check_http 2 | 3 | import "time" 4 | 5 | //Config healthCheck所需配置 6 | type Config struct { 7 | Protocol string 8 | Method string 9 | URL string 10 | SuccessCode int 11 | Period time.Duration 12 | Timeout time.Duration 13 | } 14 | -------------------------------------------------------------------------------- /health-check-http/health_check_http.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eolinker/apinto/417bdff6d9b83e7d9ab59698c648a90ea7a24ae6/health-check-http/health_check_http.png -------------------------------------------------------------------------------- /health-check-http/health_check_http_usage.md: -------------------------------------------------------------------------------- 1 | # HealthCheckHTTP用法: 2 | 3 | * 用法一:自身实现了IHealthChecker接口,可在服务发现创建app时作为healthChecker传入。 4 | * 用法二:HTTPCheck作为健康检查中心,可生成agent,每个agent作为app的healthChecker 5 | 6 | #### 用法一: 7 | 8 | 相当于为每个app启动一个协程,定时检查该app中所有的不健康节点 9 | 10 | #### 用法二: 11 | 12 | HTTPCheck作为检测中心,生成的agent作为每个app的healthChecker。当app的节点出问题时,agent充当搬运工,把节点通过通道传给HTTPCheck,交由HTTPCheck进行定时检测。相当于只为服务发现启动一个协程。 13 | 14 | 15 | ![avatar](healthcheckhttp/health_check_http.png) 16 | -------------------------------------------------------------------------------- /monitor-manager/concurrent.go: -------------------------------------------------------------------------------- 1 | package monitor_manager 2 | 3 | import "sync/atomic" 4 | 5 | type concurrency struct { 6 | count int32 7 | } 8 | 9 | func (c *concurrency) Add(count int32) { 10 | atomic.AddInt32(&c.count, count) 11 | } 12 | 13 | func (c *concurrency) Get() int32 { 14 | return atomic.LoadInt32(&c.count) 15 | } 16 | -------------------------------------------------------------------------------- /node/.gitignore: -------------------------------------------------------------------------------- 1 | *.DS_Store 2 | -------------------------------------------------------------------------------- /node/dubbo2-context/response.go: -------------------------------------------------------------------------------- 1 | package dubbo2_context 2 | 3 | import ( 4 | dubbo2_context "github.com/eolinker/eosc/eocontext/dubbo2-context" 5 | "time" 6 | ) 7 | 8 | var _ dubbo2_context.IResponse = (*Response)(nil) 9 | 10 | type Response struct { 11 | responseError error 12 | timeout time.Duration 13 | duration time.Duration 14 | body interface{} 15 | } 16 | 17 | func (r *Response) ResponseError() error { 18 | return r.responseError 19 | } 20 | 21 | func (r *Response) SetResponseTime(duration time.Duration) { 22 | r.duration = duration 23 | } 24 | 25 | func (r *Response) ResponseTime() time.Duration { 26 | return r.duration 27 | } 28 | 29 | func (r *Response) GetBody() interface{} { 30 | return r.body 31 | } 32 | 33 | func (r *Response) SetBody(body interface{}) { 34 | r.body = body 35 | } 36 | -------------------------------------------------------------------------------- /node/fasthttp-client/client_test.go: -------------------------------------------------------------------------------- 1 | package fasthttp_client 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/valyala/fasthttp" 7 | ) 8 | 9 | func TestMyselfProxyTimeout(t *testing.T) { 10 | //addr := "https://gw.kuaidizs.cn" 11 | addr := "http://127.0.0.1:8099" 12 | req := fasthttp.AcquireRequest() 13 | resp := fasthttp.AcquireResponse() 14 | req.URI().SetPath("/open/api") 15 | req.URI().SetQueryString("test=1") 16 | req.URI().SetHost("127.0.0.1:8099") 17 | req.Header.SetMethod("POST") 18 | req.Header.SetContentType("application/json") 19 | t.Log(string(req.URI().RequestURI()), req.URI().String(), string(req.URI().Host()), string(req.URI().Scheme())) 20 | req.SetBody([]byte(`{"cpCode":"YTO","province":"广东省","city":"广州市"}`)) 21 | err := defaultClient.ProxyTimeout(addr, "", req, resp, 0) 22 | if err != nil { 23 | t.Error(err) 24 | } 25 | t.Log(string(resp.Body())) 26 | return 27 | } 28 | -------------------------------------------------------------------------------- /node/grpc-context/addr.go: -------------------------------------------------------------------------------- 1 | package grpc_context 2 | 3 | import "net" 4 | 5 | var zeroTCPAddr = &net.TCPAddr{ 6 | IP: net.IPv4zero, 7 | } 8 | 9 | func addrToIP(addr net.Addr) net.IP { 10 | x, ok := addr.(*net.TCPAddr) 11 | if !ok { 12 | return net.IPv4zero 13 | } 14 | return x.IP 15 | } 16 | -------------------------------------------------------------------------------- /node/grpc-context/response.go: -------------------------------------------------------------------------------- 1 | package grpc_context 2 | 3 | import ( 4 | grpc_context "github.com/eolinker/eosc/eocontext/grpc-context" 5 | "github.com/jhump/protoreflect/dynamic" 6 | "google.golang.org/grpc/metadata" 7 | ) 8 | 9 | var _ grpc_context.IResponse = (*Response)(nil) 10 | 11 | type Response struct { 12 | header metadata.MD 13 | trailer metadata.MD 14 | msg *dynamic.Message 15 | err error 16 | } 17 | 18 | func (r *Response) SetErr(err error) { 19 | r.err = err 20 | } 21 | 22 | func (r *Response) Error() error { 23 | return r.err 24 | } 25 | 26 | func (r *Response) Write(msg *dynamic.Message) { 27 | r.msg = msg 28 | } 29 | 30 | func NewResponse() *Response { 31 | return &Response{ 32 | header: metadata.New(map[string]string{}), 33 | trailer: metadata.New(map[string]string{}), 34 | msg: nil, 35 | } 36 | } 37 | 38 | func (r *Response) Headers() metadata.MD { 39 | return r.header 40 | } 41 | 42 | func (r *Response) Message() *dynamic.Message { 43 | return r.msg 44 | } 45 | 46 | func (r *Response) Trailer() metadata.MD { 47 | return r.trailer 48 | } 49 | -------------------------------------------------------------------------------- /node/http-context/error.go: -------------------------------------------------------------------------------- 1 | package http_context 2 | 3 | import "errors" 4 | 5 | var ( 6 | ErrorNotForm = errors.New("contentType is not Form") 7 | ErrorNotMultipart = errors.New("contentType is not Multipart") 8 | ErrorNotAllowRaw = errors.New("contentType is not allow Raw") 9 | ErrorNotSend = errors.New("not send") 10 | ) 11 | -------------------------------------------------------------------------------- /node/http-context/pool.go: -------------------------------------------------------------------------------- 1 | package http_context 2 | 3 | import ( 4 | "sync" 5 | 6 | http_service "github.com/eolinker/eosc/eocontext/http-context" 7 | ) 8 | 9 | var ( 10 | pool = sync.Pool{ 11 | New: newContext, 12 | } 13 | copyPool = sync.Pool{ 14 | New: newCopyContext, 15 | } 16 | ) 17 | 18 | func newContext() interface{} { 19 | h := new(HttpContext) 20 | h.proxyRequests = make([]http_service.IProxy, 0, 5) 21 | return h 22 | } 23 | 24 | func newCopyContext() interface{} { 25 | h := new(cloneContext) 26 | h.proxyRequests = make([]http_service.IProxy, 0, 5) 27 | return h 28 | } 29 | -------------------------------------------------------------------------------- /output/.gitignore: -------------------------------------------------------------------------------- 1 | *.DS_Store 2 | -------------------------------------------------------------------------------- /output/http-transport/config.go: -------------------------------------------------------------------------------- 1 | package http_transport 2 | 3 | import "net/http" 4 | 5 | type Config struct { 6 | Method string 7 | Url string 8 | Headers http.Header 9 | HandlerCount int 10 | } 11 | -------------------------------------------------------------------------------- /output/http-transport/transporter.go: -------------------------------------------------------------------------------- 1 | package http_transport 2 | 3 | import ( 4 | "github.com/eolinker/eosc/formatter" 5 | ) 6 | 7 | type Transporter struct { 8 | writer *_HttpWriter 9 | } 10 | 11 | func (t *Transporter) Close() error { 12 | return t.writer.Close() 13 | } 14 | 15 | func (t *Transporter) Write(data []byte) error { 16 | _, err := t.writer.Write(data) 17 | return err 18 | } 19 | 20 | func CreateTransporter(conf *Config) (formatter.ITransport, error) { 21 | 22 | httpWriter := newHttpWriter() 23 | transport := &Transporter{ 24 | writer: httpWriter, 25 | } 26 | transport.writer.reset(conf) 27 | 28 | return transport, nil 29 | } 30 | -------------------------------------------------------------------------------- /output/metrics.go: -------------------------------------------------------------------------------- 1 | package output 2 | 3 | import ( 4 | "github.com/eolinker/eosc" 5 | ) 6 | 7 | const Skill = "github.com/eolinker/apinto/metric-entry.metric-entry.IMetrics" 8 | 9 | type IMetrics interface { 10 | Collect(metrics []string, entry eosc.IMetricEntry) 11 | } 12 | -------------------------------------------------------------------------------- /output/output.go: -------------------------------------------------------------------------------- 1 | package output 2 | 3 | import "github.com/eolinker/eosc" 4 | 5 | const OutputSkill = "github.com/eolinker/apinto/http-entry.http-entry.IOutput" 6 | 7 | type IEntryOutput interface { 8 | Output(entry eosc.IEntry) error 9 | } 10 | 11 | //CheckSkill 检查能力 12 | func CheckSkill(skill string) bool { 13 | return skill == OutputSkill 14 | } 15 | -------------------------------------------------------------------------------- /resources/cache-local_test.go: -------------------------------------------------------------------------------- 1 | package resources 2 | 3 | import ( 4 | "fmt" 5 | "github.com/coocood/freecache" 6 | ) 7 | 8 | func ExampleFreeCache() { 9 | key := []byte("test") 10 | value := []byte("value") 11 | 12 | client := freecache.NewCache(0) 13 | set, err := client.GetOrSet(key, value, 100) 14 | if err != nil { 15 | fmt.Println(err) 16 | return 17 | } 18 | fmt.Printf("value1=%s\n", string(set)) 19 | set, err = client.GetOrSet(key, value, 100) 20 | if err != nil { 21 | fmt.Println(err) 22 | return 23 | } 24 | fmt.Printf("value=%s\n", string(set)) 25 | // output: 26 | //value1= 27 | //value=value 28 | 29 | } 30 | -------------------------------------------------------------------------------- /resources/cache_test.go: -------------------------------------------------------------------------------- 1 | package resources 2 | 3 | import "testing" 4 | 5 | func TestReplace(t *testing.T) { 6 | type args struct { 7 | caches []ICache 8 | } 9 | tests := []struct { 10 | name string 11 | args args 12 | }{ 13 | { 14 | name: "nil", 15 | args: args{nil}, 16 | }, 17 | } 18 | for _, tt := range tests { 19 | t.Run(tt.name, func(t *testing.T) { 20 | }) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /resources/metrics.go: -------------------------------------------------------------------------------- 1 | package resources 2 | 3 | type Metrics interface { 4 | Send(labels map[string]string, fields map[string]interface{}) 5 | } 6 | -------------------------------------------------------------------------------- /resources/vector.go: -------------------------------------------------------------------------------- 1 | package resources 2 | 3 | import "time" 4 | 5 | // 通过滑动窗口实现的平滑计数器 6 | const VectorsSkill = "github.com/eolinker/apinto/resources.resources.IVectors" 7 | 8 | type IVectors interface { 9 | BuildVector(name string, uni, step time.Duration) (Vector, error) 10 | } 11 | 12 | type Vector interface { 13 | Add(key string, delta int64) 14 | CompareAndAdd(key string, threshold, delta int64) bool 15 | Get(key string) int64 16 | } 17 | -------------------------------------------------------------------------------- /router/match.go: -------------------------------------------------------------------------------- 1 | package router 2 | 3 | import ( 4 | eoscContext "github.com/eolinker/eosc/eocontext" 5 | ) 6 | 7 | type IMatcher interface { 8 | Match(port int, request interface{}) (IRouterHandler, bool) 9 | } 10 | 11 | type IRouterHandler interface { 12 | Serve(ctx eoscContext.EoContext) 13 | } 14 | 15 | type IRouterPreHandler interface { 16 | Server(ctx eoscContext.EoContext) (isContinue bool) 17 | } 18 | -------------------------------------------------------------------------------- /scope-manager/auto.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023. Lorem ipsum dolor sit amet, consectetur adipiscing elit. 3 | * Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan. 4 | * Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna. 5 | * Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus. 6 | * Vestibulum commodo. Ut rhoncus gravida arcu. 7 | */ 8 | 9 | package scope_manager 10 | 11 | import ( 12 | "github.com/eolinker/eosc" 13 | "github.com/eolinker/eosc/common/bean" 14 | ) 15 | 16 | var ( 17 | workers eosc.IWorkers 18 | ) 19 | 20 | func init() { 21 | bean.Autowired(&workers) 22 | } 23 | 24 | func Auto[T any](requireId string, scope string) IProxyOutput[T] { 25 | if requireId == "" { 26 | return Get[T](scope) 27 | } 28 | w, has := workers.Get(requireId) 29 | if !has { 30 | return Get[T](requireId) 31 | } 32 | return NewProxy(w.(T)) 33 | } 34 | -------------------------------------------------------------------------------- /service/service.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "github.com/eolinker/eosc" 5 | eoscContext "github.com/eolinker/eosc/eocontext" 6 | ) 7 | 8 | const ( 9 | ServiceSkill = "github.com/eolinker/apinto/service.service.IService" 10 | ) 11 | 12 | type IService interface { 13 | eosc.IWorker 14 | eoscContext.BalanceHandler 15 | eoscContext.UpstreamHostHandler 16 | Title() string 17 | } 18 | 19 | // CheckSkill 检查目标技能是否符合 20 | func CheckSkill(skill string) bool { 21 | return skill == ServiceSkill 22 | } 23 | -------------------------------------------------------------------------------- /strategy/manager.go: -------------------------------------------------------------------------------- 1 | package strategy 2 | -------------------------------------------------------------------------------- /strategy/strategy.go: -------------------------------------------------------------------------------- 1 | package strategy 2 | 3 | import eoscContext "github.com/eolinker/eosc/eocontext" 4 | 5 | type IStrategyHandler interface { 6 | Strategy(ctx eoscContext.EoContext, next eoscContext.IChain) error 7 | } 8 | 9 | type IFilter interface { 10 | Check(ctx eoscContext.EoContext) bool 11 | } 12 | 13 | type IFilters []IFilter 14 | 15 | func (fs IFilters) Check(ctx eoscContext.EoContext) bool { 16 | for _, f := range fs { 17 | if !f.Check(ctx) { 18 | return false 19 | } 20 | } 21 | return true 22 | } 23 | -------------------------------------------------------------------------------- /template/template.go: -------------------------------------------------------------------------------- 1 | package template 2 | 3 | import ( 4 | "github.com/eolinker/apinto/plugin" 5 | "github.com/eolinker/eosc" 6 | eoscContext "github.com/eolinker/eosc/eocontext" 7 | ) 8 | 9 | const ( 10 | TemplateSkill = "github.com/eolinker/apinto/template.template.ITemplate" 11 | ) 12 | 13 | type ITemplate interface { 14 | eosc.IWorker 15 | Create(id string, conf map[string]*plugin.Config) eoscContext.IChainPro 16 | } 17 | 18 | func CheckSkill(skill string) bool { 19 | return skill == TemplateSkill 20 | } 21 | -------------------------------------------------------------------------------- /utils/aes_test.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestAes(t *testing.T) { 8 | } 9 | -------------------------------------------------------------------------------- /utils/clone/block.go: -------------------------------------------------------------------------------- 1 | package clone 2 | 3 | import ( 4 | "io" 5 | "sync" 6 | ) 7 | 8 | const BuffSize = 4096 9 | 10 | var ( 11 | poolBuff = sync.Pool{ 12 | New: func() any { 13 | return &block{ 14 | buf: make([]byte, BuffSize), 15 | } 16 | }, 17 | } 18 | ) 19 | 20 | type block struct { 21 | buf []byte 22 | n int 23 | err error 24 | } 25 | 26 | func readBlock(r io.Reader) *block { 27 | b := acquireBlock() 28 | b.n, b.err = r.Read(b.buf) 29 | return b 30 | } 31 | func (b *block) Release() { 32 | b.n = 0 33 | b.err = nil 34 | poolBuff.Put(b) 35 | } 36 | func (b *block) Clone() *block { 37 | c := acquireBlock() 38 | copy(b.buf, c.buf) 39 | c.n, c.err = b.n, b.err 40 | return c 41 | } 42 | func (b *block) Data() ([]byte, int, error) { 43 | 44 | return b.buf[:b.n], b.n, b.err 45 | } 46 | func acquireBlock() *block { 47 | return poolBuff.Get().(*block) 48 | } 49 | -------------------------------------------------------------------------------- /utils/float.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import "math/rand" 4 | 5 | func RandFloats(min, max float64) float64 { 6 | return min + rand.Float64()*(max-min) 7 | } 8 | -------------------------------------------------------------------------------- /utils/function_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021. Lorem ipsum dolor sit amet, consectetur adipiscing elit. 3 | * Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan. 4 | * Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna. 5 | * Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus. 6 | * Vestibulum commodo. Ut rhoncus gravida arcu. 7 | */ 8 | 9 | package utils 10 | 11 | import "testing" 12 | 13 | func BenchmarkV1(b *testing.B) { 14 | for n := 0; n < b.N; n++ { 15 | GetRandomString(16) // run fib(30) b.N times 16 | } 17 | } 18 | func BenchmarkV2(b *testing.B) { 19 | for n := 0; n < b.N; n++ { 20 | //GetRandomStringV2(16) // run fib(30) b.N times 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /utils/globalID/uuid.go: -------------------------------------------------------------------------------- 1 | package globalID 2 | 3 | import ( 4 | "encoding/binary" 5 | "encoding/hex" 6 | "strings" 7 | "sync" 8 | "time" 9 | ) 10 | 11 | var ( 12 | locker = sync.Mutex{} 13 | lastID int64 14 | 15 | start int64 16 | ) 17 | 18 | func init() { 19 | s, _ := time.Parse("2020-01-02T15:04:05Z07:00", time.RFC3339) 20 | start = s.UnixNano() 21 | } 22 | 23 | //GenerateID 生成id 24 | func GenerateID() int64 { 25 | id := time.Now().UnixNano() - start 26 | locker.Lock() 27 | defer locker.Unlock() 28 | 29 | for id <= lastID { 30 | id++ 31 | } 32 | lastID = id 33 | return id 34 | } 35 | 36 | //GenerateIDString 生成id字符串 37 | func GenerateIDString() string { 38 | id := GenerateID() 39 | data := make([]byte, 8) 40 | binary.BigEndian.PutUint64(data, uint64(id)) 41 | return strings.ToUpper(hex.EncodeToString(data)) 42 | } 43 | -------------------------------------------------------------------------------- /utils/globalID/uuid_test.go: -------------------------------------------------------------------------------- 1 | package globalID 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | func TestGenerateIDString(t *testing.T) { 9 | 10 | tests := []struct { 11 | }{ 12 | {}, 13 | {}, 14 | {}, 15 | {}, 16 | {}, 17 | {}, 18 | } 19 | for i := range tests { 20 | t.Run(fmt.Sprintf("GenerateIDString-%d", i), func(t *testing.T) { 21 | t.Logf("GenerateID() = %0X", GenerateID()) 22 | d := GenerateIDString() 23 | t.Logf("GenerateIDString() = %s[%d]", d, len(d)) 24 | }) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /utils/header.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "net/http" 5 | "strings" 6 | ) 7 | 8 | //HeaderToString 将header转成字符串 9 | func HeaderToString(h http.Header) string { 10 | if h == nil { 11 | return "" 12 | } 13 | s := &strings.Builder{} 14 | h.Write(s) 15 | return s.String() 16 | } 17 | -------------------------------------------------------------------------------- /utils/hmac.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "crypto/hmac" 5 | "crypto/sha256" 6 | "encoding/hex" 7 | ) 8 | 9 | //HMacBySha256 HMacBySha256 10 | func HMacBySha256(key, toSign string) string { 11 | hash := hmac.New(sha256.New, []byte(key)) // 创建对应的sha256哈希加密算法 12 | hash.Write([]byte(toSign)) // 写入加密数据 13 | 14 | return hex.EncodeToString(hash.Sum(nil)) 15 | } 16 | 17 | //HexEncode HexEncode 18 | func HexEncode(body []byte) string { 19 | h := sha256.New() 20 | h.Write(body) 21 | return hex.EncodeToString(h.Sum(nil)) 22 | } 23 | -------------------------------------------------------------------------------- /utils/int.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import "math/rand" 4 | 5 | func RandInt64(min, max int64) int64 { 6 | if min >= max || min == 0 || max == 0 { 7 | return max 8 | } 9 | return rand.Int63n(max-min) + min 10 | } 11 | -------------------------------------------------------------------------------- /utils/map.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | func CopyMaps[K comparable, T any](maps map[K]T) map[K]T { 4 | 5 | temp := make(map[K]T, len(maps)) 6 | for k, t := range maps { 7 | temp[k] = t 8 | } 9 | 10 | return temp 11 | } 12 | -------------------------------------------------------------------------------- /utils/must.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import "encoding/json" 4 | 5 | //MustSliceString 断言输入的参数为字符串切片 6 | func MustSliceString(v interface{}) ([]string, error) { 7 | 8 | data, err := json.Marshal(v) 9 | if err != nil { 10 | return nil, err 11 | } 12 | var rs []string 13 | err = json.Unmarshal(data, &rs) 14 | if err != nil { 15 | return nil, err 16 | } 17 | return rs, nil 18 | } 19 | -------------------------------------------------------------------------------- /utils/version.go: -------------------------------------------------------------------------------- 1 | package utils 2 | -------------------------------------------------------------------------------- /utils/version/version.go: -------------------------------------------------------------------------------- 1 | package version 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | 7 | "github.com/urfave/cli/v2" 8 | ) 9 | 10 | // These should be set via go build -ldflags -X 'xxxx'. 11 | var Version = "unknown" 12 | var goVersion = "unknown" 13 | var gitCommit = "unknown" 14 | var buildTime = "unknown" 15 | var buildUser = "unknown" 16 | var eoscVersion = "unknown" 17 | 18 | var profileInfo []byte 19 | 20 | func init() { 21 | buffer := &bytes.Buffer{} 22 | fmt.Fprintf(buffer, "Apinto version: %s\n", Version) 23 | fmt.Fprintf(buffer, "Golang version: %s\n", goVersion) 24 | fmt.Fprintf(buffer, "Git commit hash: %s\n", gitCommit) 25 | fmt.Fprintf(buffer, "Built on: %s\n", buildTime) 26 | fmt.Fprintf(buffer, "Built by: %s\n", buildUser) 27 | fmt.Fprintf(buffer, "Built by eosc version: %s\n", eoscVersion) 28 | profileInfo = buffer.Bytes() 29 | } 30 | 31 | func Build() *cli.Command { 32 | return &cli.Command{ 33 | Name: "version", 34 | Action: func(context *cli.Context) error { 35 | fmt.Print(string(profileInfo)) 36 | return nil 37 | }, 38 | } 39 | } 40 | --------------------------------------------------------------------------------