├── .github └── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── .gitignore ├── .travis.yml ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── config ├── application-local.yml ├── application.yml ├── i18n │ ├── en-US │ │ └── en-US.ini │ ├── zh-CN │ │ └── zh-CN.ini │ └── zh-HK │ │ ├── first-cn-HK.ini │ │ └── second-cn-HK.ini ├── keygen.sh ├── logo.txt └── ssl │ ├── app.rsa │ └── app.rsa.pub ├── doc.go ├── doc_test.go ├── examples ├── cli │ ├── README.md │ ├── advanced │ │ ├── cmd │ │ │ ├── bar.go │ │ │ ├── foo.go │ │ │ ├── root.go │ │ │ ├── root_test.go │ │ │ └── second.go │ │ ├── config │ │ │ ├── autoconfigure.go │ │ │ ├── autoconfigure_test.go │ │ │ └── foo │ │ │ │ ├── bar │ │ │ │ ├── application-foo.yml │ │ │ │ ├── application-local.yml │ │ │ │ └── application.yml │ │ │ │ └── baz │ │ │ │ └── application-baz.yml │ │ ├── main.go │ │ ├── main_test.go │ │ └── model │ │ │ ├── foo.go │ │ │ └── foo_test.go │ ├── crypto │ │ ├── cmd │ │ │ ├── crypto.go │ │ │ └── crypto_test.go │ │ ├── main.go │ │ └── main_test.go │ ├── doc.go │ ├── doc_test.go │ └── hello │ │ ├── main.go │ │ └── main_test.go └── web │ ├── autoconfig │ ├── config │ │ ├── application-bar-foo.yml │ │ ├── application-bar.yml │ │ ├── application-foo.yml │ │ ├── application.yml │ │ ├── configuration.go │ │ └── properties.go │ ├── main.go │ └── main_test.go │ ├── depinj │ ├── bar │ │ └── foo │ │ │ └── test.go │ ├── foo │ │ └── test.go │ ├── main.go │ └── main_test.go │ ├── doc.go │ ├── doc_test.go │ ├── helloworld │ ├── main.go │ └── main_test.go │ ├── httpserver │ ├── hello │ │ ├── main.go │ │ ├── main_test.go │ │ └── static │ │ │ ├── hello.txt │ │ │ ├── img │ │ │ └── hiboot.png │ │ │ └── index.html │ └── statik │ │ ├── README.md │ │ ├── main.go │ │ ├── main_test.go │ │ ├── static │ │ ├── hello.txt │ │ ├── img │ │ │ └── hiboot.png │ │ └── index.html │ │ └── statik │ │ └── statik.go │ ├── jwt │ ├── README.md │ ├── config │ │ ├── application-fake.yaml │ │ ├── application-local.yml │ │ ├── application.yml │ │ ├── i18n │ │ │ ├── en-US │ │ │ │ └── en-US.ini │ │ │ ├── zh-CN │ │ │ │ └── zh-CN.ini │ │ │ └── zh-HK │ │ │ │ ├── first-cn-HK.ini │ │ │ │ └── second-cn-HK.ini │ │ ├── keygen.sh │ │ └── ssl │ │ │ ├── app.rsa │ │ │ └── app.rsa.pub │ ├── controller │ │ ├── bar.go │ │ ├── bar_test.go │ │ ├── foo.go │ │ ├── foo_test.go │ │ ├── login.go │ │ ├── login_test.go │ │ ├── websocket.go │ │ └── websocket_test.go │ ├── main.go │ ├── main_test.go │ └── service │ │ ├── counthandler.go │ │ └── statushandler.go │ ├── middleware │ ├── controller │ │ ├── controller.go │ │ └── controller_test.go │ ├── logging │ │ └── middleware.go │ ├── main.go │ └── main_test.go │ ├── router │ ├── main.go │ └── main_test.go │ ├── swagger │ ├── greeting-server │ │ ├── README.md │ │ ├── config │ │ │ └── application.yml │ │ ├── controller │ │ │ ├── hello.go │ │ │ └── hello_test.go │ │ ├── main.go │ │ └── main_test.go │ └── simple-server │ │ ├── README.md │ │ ├── config │ │ ├── application-bar.yml │ │ ├── application-dev.yml │ │ ├── application-foo.yml │ │ ├── application-local.yml │ │ ├── application.yml │ │ ├── i18n │ │ │ ├── en-US │ │ │ │ └── en-US.ini │ │ │ ├── zh-CN │ │ │ │ └── zh-CN.ini │ │ │ └── zh-HK │ │ │ │ ├── first-cn-HK.ini │ │ │ │ └── second-cn-HK.ini │ │ ├── keygen.sh │ │ └── ssl │ │ │ ├── app.rsa │ │ │ └── app.rsa.pub │ │ ├── main.go │ │ └── main_test.go │ └── websocket │ ├── controller │ ├── websocket.go │ └── websocket_test.go │ ├── main.go │ ├── main_test.go │ └── service │ ├── counthandler.go │ └── statushandler.go ├── go.mod ├── go.sum ├── hiboot.png ├── pkg ├── app │ ├── application.go │ ├── application_test.go │ ├── autoconfigure.go │ ├── autoconfigure_test.go │ ├── cli │ │ ├── README.md │ │ ├── application.go │ │ ├── application_test.go │ │ ├── command.go │ │ ├── command_test.go │ │ ├── doc.go │ │ ├── properties.go │ │ └── testapplication.go │ ├── doc.go │ ├── doc_test.go │ ├── fake │ │ ├── application.go │ │ └── applicatoin_test.go │ ├── postprocessor.go │ ├── postprocessor_test.go │ ├── properties.go │ └── web │ │ ├── application.go │ │ ├── application_test.go │ │ ├── autoconfigure.go │ │ ├── context.go │ │ ├── context │ │ └── context.go │ │ ├── context_test.go │ │ ├── controller.go │ │ ├── defaultconfig.go │ │ ├── defaultconfig_test.go │ │ ├── dispatcher.go │ │ ├── doc.go │ │ ├── doc_test.go │ │ ├── handler.go │ │ ├── handler_test.go │ │ ├── method_subscriber.go │ │ ├── properties.go │ │ ├── server │ │ └── property.go │ │ ├── static │ │ ├── hello.txt │ │ └── index.html │ │ ├── statik │ │ └── statik.go │ │ ├── testapplication.go │ │ └── webutils │ │ ├── utils.go │ │ └── utils_test.go ├── at │ ├── annotation.go │ ├── application.go │ ├── authorization.go │ ├── component.go │ ├── conditional.go │ ├── configuration.go │ ├── doc.go │ ├── healthcheck.go │ ├── init.go │ ├── middleware.go │ ├── qualifier.go │ ├── qualifier_test.go │ ├── request.go │ ├── response.go │ ├── restcontroller.go │ ├── restcontroller_test.go │ ├── scheduler.go │ ├── scope.go │ ├── swagger.go │ ├── swagger_test.go │ └── tag.go ├── factory │ ├── autoconfigure │ │ ├── configurable.go │ │ └── configurable_test.go │ ├── depends │ │ ├── bar │ │ │ ├── configure.go │ │ │ └── configure_test.go │ │ ├── depresolver.go │ │ ├── depresolver_test.go │ │ ├── deptree.go │ │ ├── deptree_test.go │ │ ├── fake │ │ │ ├── configure.go │ │ │ └── configure_test.go │ │ └── foo │ │ │ ├── configure.go │ │ │ └── configure_test.go │ ├── doc.go │ ├── doc_test.go │ ├── factory.go │ ├── factory_test.go │ ├── instantiate │ │ ├── instance.go │ │ ├── instantiate.go │ │ ├── instantiate_test.go │ │ ├── scoped.go │ │ └── scoped_test.go │ ├── metadata.go │ └── metadata_test.go ├── inject │ ├── annotation │ │ ├── annotation.go │ │ └── annotation_test.go │ ├── defaulttag.go │ ├── doc.go │ ├── doc_test.go │ ├── inject.go │ ├── inject_test.go │ ├── injecttag.go │ ├── tag.go │ ├── tag_test.go │ └── valuetag.go ├── log │ ├── doc.go │ ├── doc_test.go │ ├── logging.go │ └── logging_test.go ├── model │ ├── data.go │ ├── doc.go │ ├── doc_test.go │ ├── request.go │ ├── response.go │ └── response_test.go ├── starter │ ├── actuator │ │ ├── autoconfigure.go │ │ ├── autoconfigure_test.go │ │ ├── health.go │ │ └── health_test.go │ ├── cors │ │ ├── autoconfigure.go │ │ ├── autoconfigure_test.go │ │ ├── middleware.go │ │ └── properties.go │ ├── doc.go │ ├── doc_test.go │ ├── jwt │ │ ├── autoconfigure.go │ │ ├── autoconfigure_test.go │ │ ├── controller.go │ │ ├── controller_test.go │ │ ├── jwtmiddleware.go │ │ ├── jwtmiddleware_test.go │ │ ├── postProcessor.go │ │ ├── properties.go │ │ └── token.go │ ├── locale │ │ ├── autoconfigure.go │ │ ├── autoconfigure_test.go │ │ └── properties.go │ ├── logging │ │ ├── autoconfigure.go │ │ ├── autoconfigure_test.go │ │ └── properties.go │ ├── swagger │ │ ├── autoconfigure.go │ │ ├── controller.go │ │ ├── controller_test.go │ │ ├── doc.go │ │ ├── info_builder.go │ │ ├── metohd_subscriber.go │ │ └── paths_builder.go │ └── websocket │ │ ├── autoconfigure.go │ │ ├── connection.go │ │ ├── handler.go │ │ ├── properties.go │ │ └── ws │ │ ├── AUTHORS │ │ ├── LICENSE │ │ ├── client.go │ │ ├── client.js │ │ ├── client.min.js │ │ ├── client.ts │ │ ├── config.go │ │ ├── connection.go │ │ ├── emitter.go │ │ ├── message.go │ │ ├── server.go │ │ └── websocket.go ├── system │ ├── autoconfigure.go │ ├── builder.go │ ├── builder_test.go │ ├── config │ │ ├── .yaml │ │ ├── application-dev.yml │ │ ├── application-local.yml │ │ ├── application-mock.yml │ │ ├── application.yml │ │ ├── dev │ │ │ └── application-mars.yml │ │ ├── dummy.txt │ │ ├── foo │ │ └── test-file.yml │ ├── doc.go │ ├── doc_test.go │ ├── env.go │ ├── errors.go │ ├── errors_test.go │ ├── properties.go │ ├── property_builder.go │ ├── property_builder_test.go │ ├── scheduler │ │ ├── scheduler.go │ │ └── scheduler_test.go │ ├── types │ │ ├── types.go │ │ └── types_test.go │ ├── yaml.go │ └── yaml_test.go ├── types │ └── reflect.go └── utils │ ├── cmap │ ├── concurrent_map.go │ ├── concurrent_map_bench_test.go │ └── concurrent_map_test.go │ ├── copier │ ├── copier.go │ └── copier_test.go │ ├── crypto │ ├── aes │ │ ├── aes.go │ │ └── aes_test.go │ ├── base64 │ │ ├── base64.go │ │ └── base64_test.go │ ├── doc.go │ ├── errors.go │ ├── errors_test.go │ ├── md5 │ │ ├── md5.go │ │ └── md5_test.go │ └── rsa │ │ ├── rsa.go │ │ └── rsa_test.go │ ├── doc.go │ ├── doc_test.go │ ├── gotest │ ├── gotest.go │ └── gotest_test.go │ ├── idgen │ ├── idgen.go │ └── idgen_test.go │ ├── io │ ├── io.go │ └── io_test.go │ ├── mapstruct │ ├── mapstruct.go │ └── mapstruct_test.go │ ├── reflector │ ├── reflect.go │ ├── reflect_test.go │ └── tester │ │ ├── foo.go │ │ └── foo_test.go │ ├── replacer │ ├── replacer.go │ └── replacer_test.go │ ├── sort │ ├── slice.go │ └── slice_test.go │ ├── str │ ├── camel.go │ ├── camel_test.go │ ├── number.go │ ├── snake.go │ ├── snake_test.go │ ├── strings.go │ └── strings_test.go │ ├── structtag │ ├── tags.go │ └── tags_test.go │ └── validator │ └── validator.go └── static ├── hello.txt ├── img └── hiboot.png └── index.html /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | 5 | --- 6 | 7 | **Describe the bug** 8 | {{ Succinctly describe the bug }} 9 | 10 | **Expected behavior** 11 | {{ What did you expect to happen? }} 12 | 13 | **Steps to reproduce the bug** 14 | {{ Minimal steps to reproduce the behavior }} 15 | 16 | **Version** 17 | {{ What version of Hiboot are you using? }} 18 | 19 | **Environment** 20 | {{ Which environment, cloud vendor, OS, etc are you using? }} 21 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | 5 | --- 6 | 7 | **Describe the feature request** 8 | {{ Succinctly describe your request }} 9 | 10 | **Describe alternatives you've considered** 11 | {{ Describe alternative solutions or workarounds you've considered. }} 12 | 13 | **Additional context** 14 | {{ Add any other context about the feature request here }} 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.dll 4 | *.so 5 | *.dylib 6 | *.jar 7 | *.db 8 | *.log 9 | 10 | # Test binary, build with `go test -c` 11 | *.test 12 | application-fake.yml 13 | 14 | # Output of the go coverage tool, specifically when used with LiteIDE 15 | *.out 16 | 17 | # Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736 18 | .glide/ 19 | 20 | .idea/ 21 | vendor/ 22 | debug/ 23 | .vscode/ 24 | !/pkg/app/web/application.go 25 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | 3 | go: 4 | - "1.16.x" 5 | 6 | git: 7 | depth: 1 8 | 9 | branches: 10 | only: 11 | - master 12 | - v2 13 | 14 | go_import_path: github.com/hidevopsio/hiboot 15 | 16 | env: 17 | - GO111MODULE=on APP_PROFILES_ACTIVE=local GOPROXY=https://goproxy.cn 18 | 19 | install: true 20 | 21 | script: 22 | - env GO111MODULE=on go test -p 1 -v ./... -coverprofile=coverage.out -covermode=atomic 23 | 24 | after_success: 25 | - bash <(curl -s https://codecov.io/bash) -t ${CODECOV_TOKEN} 26 | 27 | -------------------------------------------------------------------------------- /config/application-local.yml: -------------------------------------------------------------------------------- 1 | # config file for testing 2 | 3 | server: 4 | port: 8080 5 | 6 | logging: 7 | level: debug -------------------------------------------------------------------------------- /config/application.yml: -------------------------------------------------------------------------------- 1 | # config file for testing 2 | # filename should be application.yml 3 | 4 | app: 5 | project: hidevopsio 6 | name: hiboot 7 | 8 | logging: 9 | level: info 10 | 11 | magic: 12 | number: 666 -------------------------------------------------------------------------------- /config/i18n/en-US/en-US.ini: -------------------------------------------------------------------------------- 1 | success = Success 2 | failed = Failed 3 | hello = Hello, World -------------------------------------------------------------------------------- /config/i18n/zh-CN/zh-CN.ini: -------------------------------------------------------------------------------- 1 | success = 成功 2 | failed = 失败 3 | hello = 你好, 世界 4 | -------------------------------------------------------------------------------- /config/i18n/zh-HK/first-cn-HK.ini: -------------------------------------------------------------------------------- 1 | success = 成功 2 | failed = 失败 3 | -------------------------------------------------------------------------------- /config/i18n/zh-HK/second-cn-HK.ini: -------------------------------------------------------------------------------- 1 | hello = 您好,世界 2 | -------------------------------------------------------------------------------- /config/keygen.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Copyright 2018 John Deng (hi.devops.io@gmail.com). 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http:#www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | mkdir -p ssl 17 | 18 | openssl genrsa -out ssl/app.rsa 1024 19 | openssl rsa -in ssl/app.rsa -pubout > ssl/app.rsa.pub -------------------------------------------------------------------------------- /config/logo.txt: -------------------------------------------------------------------------------- 1 | 2 | .:++/. 3 | -/oooooooo/-` 4 | `-/oooooooooooooo/-` 5 | `-/oooooooo+::/oooooooo+-` 6 | `:+ooooooooooo- `ooooooooooo+:` 7 | -+ooooooooo/-``o- `o- .:+oooooooo+- 8 | +oooooooo:` `-o- `o/. -+ooooooo+ 9 | +ooooooo. `/ooo- `oooo: /oooooo+ 10 | +oooooo. -ooooo- `ooooo+` /ooooo+ 11 | +ooooo/ `oooooo- `oooooo/ .ooooo+ 12 | +ooooo- .oooooo/..:ooooooo `ooooo+ 13 | +ooooo/ `oooooooooooooooo/ .ooooo+ 14 | +oooooo. .oooooooooooooo/ /ooooo+ 15 | +ooooooo. `:oooooooooo+- `/oooooo+ 16 | +oooooooo:` .::///:-` -+ooooooo+ 17 | -+ooooooooo/-` `.:+oooooooo+- 18 | `-+oooooooooo+////++ooooooooo+:` 19 | `-/oooooooooooooooooooo+-` 20 | `-/oooooooooooooo/-` 21 | -/oooooooo/- 22 | .:++/. 23 | -------------------------------------------------------------------------------- /config/ssl/app.rsa: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIICWwIBAAKBgQC2rhCF8UNzU6aSaHa2ht1deIaw5sDpuoRBvkQOc0GZCn3HXP+J 3 | lqaUmDKYHSfS4jXbJNgWr7VGExcygQWCRuom+mfXKhhfI7TDYnd7DcCldwyPqGkk 4 | jCQ40v/jvJeMUmXzU/WxpCftIM7Qaqxb9yrLZJP9jfEAl26Q8SXth7E0NwIDAQAB 5 | AoGAb8xfOFnK2c2b54YfAN3Qo9+bLrBJ58DKKCH1LJLE1pBhIZ18lguors/mRsmx 6 | EZJ3O0J1LI0j91q/m5zybiRQL7mZgMcrJG8t6ZSk+T9Ujh22pdjF5XXJF03adTUE 7 | PBgJrWrsMqa+NFg84J2OM5Oz45JD4LH8PwwoiYPRodoh5WECQQDiwp65vIpjGJGd 8 | sFv6FBaRQaeoQje96FW9E2CPWciibMIFssiW7svtMGzdFlnpAo+Zy1fo9nv6EUCq 9 | owXJgj0VAkEAzjxZZS02wFcAGCvn7YTmMwtzm7Beuiz+2DrFaFys6XVDqKGLQdzd 10 | wi0nNSdmdPLaTP7oPjxOE+hr8ucNjlB3GwJAAixDQRxhZxmxK4WpG/hdTv8GEEKy 11 | Lguv5qPs5PLDTWslYNCZw3h+U8OHB4dTTTxNC/g622yhO4A20mvFfmzVEQJAAm0d 12 | VB5jDYI4gxBJKzcsCh+xXXyGsMQEv4B5gA/PDPQPNrWn0L+LcFRdqLds8iVFQjCh 13 | hNHqzTsnwfTL6QezTwJAMIZylH9hdOiIifw/TkQNEBTSTGDoNIi4MpR31/zlaEea 14 | MVe6NBHZVAizhTzITREPV6FCUUMTEbdozxFnLwVIEg== 15 | -----END RSA PRIVATE KEY----- 16 | -------------------------------------------------------------------------------- /config/ssl/app.rsa.pub: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC2rhCF8UNzU6aSaHa2ht1deIaw 3 | 5sDpuoRBvkQOc0GZCn3HXP+JlqaUmDKYHSfS4jXbJNgWr7VGExcygQWCRuom+mfX 4 | KhhfI7TDYnd7DcCldwyPqGkkjCQ40v/jvJeMUmXzU/WxpCftIM7Qaqxb9yrLZJP9 5 | jfEAl26Q8SXth7E0NwIDAQAB 6 | -----END PUBLIC KEY----- 7 | -------------------------------------------------------------------------------- /doc_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package hiboot_test 16 | 17 | import ( 18 | "github.com/hidevopsio/hiboot/pkg/app/web" 19 | "github.com/hidevopsio/hiboot/pkg/at" 20 | ) 21 | 22 | // This is a simple hello world example 23 | func Example() { 24 | // the web application entry 25 | web.NewApplication(new(Controller)).Run() 26 | } 27 | 28 | // Controller is the RESTful Controller, derived from at.RestController. 29 | // The context path of this controller is '/' by default 30 | // if you name it HelloController, then the default context path will be /hello 31 | // which the context path of this controller is hello 32 | type Controller struct { 33 | at.RestController 34 | } 35 | 36 | // Get method, the context mapping of this method is '/' by default 37 | // the Method name Get means that the http request method is GET 38 | func (c *Controller) Get() string { 39 | // response data 40 | return "Hello world" 41 | } 42 | -------------------------------------------------------------------------------- /examples/cli/README.md: -------------------------------------------------------------------------------- 1 | # cli application examples 2 | 3 | ## Integrate with promptui 4 | 5 | It's easy to integrate promptui into Hiboot cli application 6 | 7 | ```go 8 | // declare main package 9 | package main 10 | 11 | // import cli starter and fmt 12 | import ( 13 | "github.com/hidevopsio/hiboot/pkg/starter/cli" 14 | "github.com/manifoldco/promptui" 15 | "fmt" 16 | ) 17 | 18 | // define the command 19 | type PromptuiCommand struct { 20 | cli.RootCommand 21 | } 22 | 23 | // Init constructor 24 | func (c *PromptuiCommand) Init() { 25 | c.Use = "promptui" 26 | c.Short = "promptui command" 27 | c.Long = "run promptui command for getting started" 28 | 29 | } 30 | 31 | // Run run the command 32 | func (c *PromptuiCommand) Run(args []string) error { 33 | // define selections 34 | prompt := promptui.Select{ 35 | Label: "Select Day", 36 | Items: []string{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}, 37 | } 38 | 39 | // call prompt.Run() to get users selection 40 | _, result, err := prompt.Run() 41 | 42 | if err != nil { 43 | fmt.Printf("Prompt failed %v\n", err) 44 | return fmt.Errorf("Prompt failed %v\n", err) 45 | } 46 | 47 | fmt.Printf("You choose %q\n", result) 48 | 49 | return nil 50 | } 51 | 52 | // main function 53 | func main() { 54 | // create new cli application and run it 55 | cli.NewApplication(new(PromptuiCommand)).Run() 56 | } 57 | 58 | ``` -------------------------------------------------------------------------------- /examples/cli/advanced/cmd/bar.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package cmd 16 | 17 | import ( 18 | "github.com/hidevopsio/hiboot/pkg/app" 19 | "github.com/hidevopsio/hiboot/pkg/app/cli" 20 | "github.com/hidevopsio/hiboot/pkg/log" 21 | ) 22 | 23 | type barCommand struct { 24 | cli.SubCommand 25 | } 26 | 27 | func init() { 28 | app.Register(newBarCommand) 29 | } 30 | 31 | func newBarCommand() *barCommand { 32 | c := new(barCommand) 33 | c.Use = "bar" 34 | c.Short = "bar command" 35 | c.Long = "Run bar command" 36 | return c 37 | } 38 | 39 | // OnBaz run command bar baz, return true means it won't run next action, in this case is method Run(args []string) 40 | func (c *barCommand) OnBaz(args []string) bool { 41 | log.Infof("on baz command") 42 | return true 43 | } 44 | 45 | // OnBuz run command bar buz, return true means it won't run next action, in this case is method Run(args []string) 46 | func (c *barCommand) OnBuz(args []string) bool { 47 | log.Infof("on buz command") 48 | return true 49 | } 50 | 51 | // Run run bar command 52 | func (c *barCommand) Run(args []string) error { 53 | log.Info("handle bar command") 54 | return nil 55 | } 56 | -------------------------------------------------------------------------------- /examples/cli/advanced/cmd/foo.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package cmd 16 | 17 | import ( 18 | "github.com/hidevopsio/hiboot/examples/cli/advanced/model" 19 | "github.com/hidevopsio/hiboot/pkg/app" 20 | "github.com/hidevopsio/hiboot/pkg/app/cli" 21 | "github.com/hidevopsio/hiboot/pkg/log" 22 | ) 23 | 24 | type fooCommand struct { 25 | cli.SubCommand 26 | 27 | foo *model.Foo 28 | } 29 | 30 | func newFooCommand(foo *model.Foo) *fooCommand { 31 | c := &fooCommand{ 32 | foo: foo, 33 | } 34 | c.Use = "foo" 35 | c.Short = "foo command" 36 | c.Long = "Run foo command" 37 | 38 | return c 39 | } 40 | 41 | func init() { 42 | app.Register(newFooCommand, new(model.Foo)) 43 | } 44 | 45 | func (c *fooCommand) Run(args []string) error { 46 | log.Info("handle foo command") 47 | return nil 48 | } 49 | -------------------------------------------------------------------------------- /examples/cli/advanced/cmd/root.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package cmd 16 | 17 | import ( 18 | "github.com/hidevopsio/hiboot/pkg/app/cli" 19 | "github.com/hidevopsio/hiboot/pkg/log" 20 | ) 21 | 22 | // RootCommand is the root command 23 | type RootCommand struct { 24 | cli.RootCommand 25 | 26 | profile string 27 | timeout int 28 | 29 | MagicNumber int `value:"${magic.number}"` 30 | } 31 | 32 | // NewRootCommand the root command 33 | func NewRootCommand(second *secondCommand) *RootCommand { 34 | c := new(RootCommand) 35 | c.Use = "first" 36 | c.Short = "first command" 37 | c.Long = "Run first command" 38 | c.ValidArgs = []string{"baz"} 39 | pf := c.PersistentFlags() 40 | pf.StringVarP(&c.profile, "profile", "p", "dev", "e.g. --profile=test") 41 | pf.IntVarP(&c.timeout, "timeout", "t", 1, "e.g. --timeout=1") 42 | c.Add(second) 43 | return c 44 | } 45 | 46 | // Run root command handler 47 | func (c *RootCommand) Run(args []string) error { 48 | log.Debugf("root: %v", args) 49 | log.Infof("handle first command: profile=%v, timeout=%v, magic.number=%v", c.profile, c.timeout, c.MagicNumber) 50 | return nil 51 | } 52 | -------------------------------------------------------------------------------- /examples/cli/advanced/cmd/second.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package cmd 16 | 17 | import ( 18 | "github.com/hidevopsio/hiboot/pkg/app" 19 | "github.com/hidevopsio/hiboot/pkg/app/cli" 20 | "github.com/hidevopsio/hiboot/pkg/log" 21 | ) 22 | 23 | type secondCommand struct { 24 | cli.SubCommand 25 | } 26 | 27 | func init() { 28 | app.Register(newSecondCommand) 29 | } 30 | 31 | func newSecondCommand(foo *fooCommand, bar *barCommand) *secondCommand { 32 | c := new(secondCommand) 33 | c.Use = "second" 34 | c.Short = "second command" 35 | c.Long = "Run second command" 36 | c.Add(foo, bar) 37 | return c 38 | } 39 | 40 | func (c *secondCommand) Run(args []string) error { 41 | log.Info("handle second command") 42 | return nil 43 | } 44 | -------------------------------------------------------------------------------- /examples/cli/advanced/config/autoconfigure.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import ( 4 | "github.com/hidevopsio/hiboot/examples/cli/advanced/model" 5 | "github.com/hidevopsio/hiboot/pkg/app" 6 | ) 7 | 8 | // Profile is the configuration name 9 | const Profile = "config" 10 | 11 | type configuration struct { 12 | app.Configuration 13 | } 14 | 15 | func init() { 16 | app.Register(newConfiguration) 17 | } 18 | 19 | func newConfiguration() *configuration { 20 | return new(configuration) 21 | } 22 | 23 | func (c *configuration) Foo() *model.Foo { 24 | return &model.Foo{Name: "foo"} 25 | } 26 | 27 | func (c *configuration) FooBar() *model.Foo { 28 | return &model.Foo{Name: "foobar"} 29 | } 30 | -------------------------------------------------------------------------------- /examples/cli/advanced/config/autoconfigure_test.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import ( 4 | "github.com/stretchr/testify/assert" 5 | "testing" 6 | ) 7 | 8 | func TestConfig(t *testing.T) { 9 | 10 | c := newConfiguration() 11 | 12 | assert.NotEqual(t, nil, c.Foo()) 13 | assert.NotEqual(t, nil, c.FooBar()) 14 | 15 | } 16 | -------------------------------------------------------------------------------- /examples/cli/advanced/config/foo/bar/application-foo.yml: -------------------------------------------------------------------------------- 1 | # config file for testing 2 | 3 | 4 | logging: 5 | level: debug 6 | 7 | magic: 8 | number: 999 -------------------------------------------------------------------------------- /examples/cli/advanced/config/foo/bar/application-local.yml: -------------------------------------------------------------------------------- 1 | # config file for testing 2 | 3 | 4 | logging: 5 | level: error 6 | 7 | magic: 8 | number: 888 -------------------------------------------------------------------------------- /examples/cli/advanced/config/foo/bar/application.yml: -------------------------------------------------------------------------------- 1 | # config file for testing 2 | # filename should be application.yml 3 | 4 | app: 5 | project: hidevopsio 6 | name: hiboot-cmd 7 | profiles: 8 | include: 9 | - foo 10 | 11 | logging: 12 | level: info 13 | 14 | magic: 15 | number: 666 -------------------------------------------------------------------------------- /examples/cli/advanced/config/foo/baz/application-baz.yml: -------------------------------------------------------------------------------- 1 | # config file for testing 2 | 3 | 4 | logging: 5 | level: debug 6 | 7 | magic: 8 | number: 999 -------------------------------------------------------------------------------- /examples/cli/advanced/main.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package main 16 | 17 | import ( 18 | "embed" 19 | 20 | "github.com/hidevopsio/hiboot/examples/cli/advanced/cmd" 21 | "github.com/hidevopsio/hiboot/examples/cli/advanced/config" 22 | "github.com/hidevopsio/hiboot/pkg/app" 23 | "github.com/hidevopsio/hiboot/pkg/app/cli" 24 | "github.com/hidevopsio/hiboot/pkg/starter/logging" 25 | ) 26 | 27 | //go:embed config/foo 28 | var embedFS embed.FS 29 | 30 | func main() { 31 | // create new cli application and run it 32 | cli.NewApplication(cmd.NewRootCommand). 33 | SetProperty(app.BannerDisabled, true). 34 | SetProperty(app.Config, &embedFS). 35 | SetProperty(logging.Level, logging.LevelError). 36 | SetProperty(app.ProfilesInclude, config.Profile, logging.Profile). 37 | Run() 38 | } 39 | -------------------------------------------------------------------------------- /examples/cli/advanced/main_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Line 1: main package 16 | package main 17 | 18 | import ( 19 | "sync" 20 | "testing" 21 | ) 22 | 23 | var mu sync.Mutex 24 | 25 | func TestRunMain(t *testing.T) { 26 | mu.Lock() 27 | go main() 28 | mu.Unlock() 29 | } 30 | -------------------------------------------------------------------------------- /examples/cli/advanced/model/foo.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | // Foo is the test model 4 | type Foo struct { 5 | Name string `json:"name"` 6 | } 7 | -------------------------------------------------------------------------------- /examples/cli/advanced/model/foo_test.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import "testing" 4 | 5 | func TestDummy(t *testing.T) { 6 | 7 | } 8 | -------------------------------------------------------------------------------- /examples/cli/crypto/cmd/crypto_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package cmd 16 | 17 | import ( 18 | "github.com/stretchr/testify/assert" 19 | "github.com/hidevopsio/hiboot/pkg/app/cli" 20 | "github.com/hidevopsio/hiboot/pkg/log" 21 | "testing" 22 | ) 23 | 24 | func init() { 25 | log.SetLevel(log.DebugLevel) 26 | } 27 | 28 | func TestCryptoCommands(t *testing.T) { 29 | testApp := cli.NewTestApplication(t, newCryptoCommand) 30 | 31 | t.Run("should run crypto rsa -e", func(t *testing.T) { 32 | _, err := testApp.Run("rsa", "-e", "-s", "hello") 33 | assert.Equal(t, nil, err) 34 | }) 35 | 36 | t.Run("should run crypto rsa -d ", func(t *testing.T) { 37 | _, err := testApp.Run("rsa", "-d", "-s", "Rprrfl5LX9NRmWKEqJW8ckObVjznnMmq8i7x6Pv6n1GSoEL9dUomNKOr6Pgj7RuVzCc/I7Hya20BZO1PbzTquBMp/G5rcF2Vy7HF1UKr8buHtppB+n3ycTxFvPxQB2vMvLyMtDBc29QtGe3HHD8TS+3h1pSK5WZS+CMKPHT4sho=") 38 | assert.Equal(t, nil, err) 39 | }) 40 | } 41 | -------------------------------------------------------------------------------- /examples/cli/crypto/main.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // declare main package 16 | 17 | package main 18 | 19 | // import cli starter and fmt 20 | import ( 21 | _ "github.com/hidevopsio/hiboot/examples/cli/crypto/cmd" 22 | "github.com/hidevopsio/hiboot/pkg/app/cli" 23 | ) 24 | 25 | // main function 26 | func main() { 27 | // create new cli application and run it 28 | cli.NewApplication().Run() 29 | } 30 | -------------------------------------------------------------------------------- /examples/cli/crypto/main_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Line 1: main package 16 | package main 17 | 18 | import ( 19 | "sync" 20 | "testing" 21 | ) 22 | 23 | var mu sync.Mutex 24 | 25 | func TestRunMain(t *testing.T) { 26 | mu.Lock() 27 | go main() 28 | mu.Unlock() 29 | } 30 | -------------------------------------------------------------------------------- /examples/cli/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Package cli provides hiboot command line application examples 16 | package cli 17 | -------------------------------------------------------------------------------- /examples/cli/doc_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package cli_test 16 | -------------------------------------------------------------------------------- /examples/cli/hello/main.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // declare main package 16 | 17 | package main 18 | 19 | // import cli starter and fmt 20 | import ( 21 | "fmt" 22 | "github.com/hidevopsio/hiboot/pkg/app" 23 | "github.com/hidevopsio/hiboot/pkg/app/cli" 24 | ) 25 | 26 | // define the command 27 | type rootCommand struct { 28 | cli.RootCommand 29 | 30 | // flag to 31 | to string 32 | } 33 | 34 | func newRootCommand() *rootCommand { 35 | c := new(rootCommand) 36 | c.Use = "hello" 37 | c.Short = "hello command" 38 | c.Long = "run hello command for getting started" 39 | c.Example = ` 40 | hello -h : help 41 | hello -t John : say hello to John 42 | ` 43 | c.PersistentFlags().StringVarP(&c.to, "to", "t", "world", "e.g. --to=world or -t world") 44 | return c 45 | } 46 | 47 | // Run run the command 48 | func (c *rootCommand) Run(args []string) error { 49 | fmt.Printf("Hello, %v\n", c.to) 50 | return nil 51 | } 52 | 53 | // main function 54 | func main() { 55 | // create new cli application and run it 56 | cli.NewApplication(newRootCommand). 57 | SetProperty(app.BannerDisabled, true). 58 | Run() 59 | } 60 | -------------------------------------------------------------------------------- /examples/cli/hello/main_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Line 1: main package 16 | package main 17 | 18 | import ( 19 | "github.com/stretchr/testify/assert" 20 | "github.com/hidevopsio/hiboot/pkg/app/cli" 21 | "sync" 22 | "testing" 23 | ) 24 | 25 | var mu sync.Mutex 26 | func TestRunMain(t *testing.T) { 27 | mu.Lock() 28 | go main() 29 | mu.Unlock() 30 | } 31 | 32 | func TestHelloCommands(t *testing.T) { 33 | testApp := cli.NewTestApplication(t, newRootCommand) 34 | 35 | t.Run("should run hello command", func(t *testing.T) { 36 | _, err := testApp.Run("--to", "${app.name}-cmd") 37 | assert.Equal(t, nil, err) 38 | }) 39 | } 40 | -------------------------------------------------------------------------------- /examples/web/autoconfig/config/application-bar-foo.yml: -------------------------------------------------------------------------------- 1 | # config file for testing 2 | # filename should be application.yml 3 | 4 | app: 5 | project: hidevopsio 6 | name: hiboot 7 | 8 | logging: 9 | level: debug 10 | 11 | config: 12 | enabled: true 13 | name: bar-foo -------------------------------------------------------------------------------- /examples/web/autoconfig/config/application-bar.yml: -------------------------------------------------------------------------------- 1 | # config file for testing 2 | # filename should be application.yml 3 | 4 | app: 5 | project: hidevopsio 6 | name: hiboot 7 | 8 | logging: 9 | level: debug 10 | 11 | config: 12 | enabled: true 13 | name: bar -------------------------------------------------------------------------------- /examples/web/autoconfig/config/application-foo.yml: -------------------------------------------------------------------------------- 1 | # config file for testing 2 | # filename should be application.yml 3 | 4 | app: 5 | project: hidevopsio 6 | name: hiboot 7 | 8 | logging: 9 | level: debug 10 | 11 | config: 12 | enabled: true 13 | name: foo -------------------------------------------------------------------------------- /examples/web/autoconfig/config/application.yml: -------------------------------------------------------------------------------- 1 | # config file for testing 2 | # filename should be application.yml 3 | 4 | app: 5 | project: hidevopsio 6 | name: hiboot 7 | 8 | logging: 9 | level: debug 10 | 11 | config: 12 | enabled: true 13 | name: bar -------------------------------------------------------------------------------- /examples/web/autoconfig/config/properties.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import "github.com/hidevopsio/hiboot/pkg/at" 4 | 5 | type properties struct { 6 | at.ConfigurationProperties `value:"config"` 7 | 8 | Enabled bool `json:"enabled"` 9 | 10 | Name string `json:"name" default:"foo"` 11 | 12 | DefaultName string `json:"default_name" default:"foo"` 13 | } 14 | -------------------------------------------------------------------------------- /examples/web/depinj/bar/foo/test.go: -------------------------------------------------------------------------------- 1 | package foo 2 | 3 | import "github.com/hidevopsio/hiboot/pkg/app" 4 | 5 | type TestService struct { 6 | Name string `value:"${foo.bar.baz:.bar}"` 7 | } 8 | 9 | func newTestService() *TestService { 10 | return &TestService{} 11 | } 12 | 13 | func init() { 14 | app.Register(newTestService) 15 | } 16 | -------------------------------------------------------------------------------- /examples/web/depinj/foo/test.go: -------------------------------------------------------------------------------- 1 | package foo 2 | 3 | import "github.com/hidevopsio/hiboot/pkg/app" 4 | 5 | type TestService struct { 6 | Name string `value:"${foo.bar.foz:.foo}"` 7 | } 8 | 9 | func newTestService() *TestService { 10 | return &TestService{} 11 | } 12 | 13 | func init() { 14 | app.Register(newTestService) 15 | } 16 | -------------------------------------------------------------------------------- /examples/web/depinj/main_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Line 1: main package 16 | package main 17 | 18 | import ( 19 | "net/http" 20 | "sync" 21 | "testing" 22 | "time" 23 | 24 | "github.com/hidevopsio/hiboot/pkg/app" 25 | "github.com/hidevopsio/hiboot/pkg/app/web" 26 | "github.com/hidevopsio/hiboot/pkg/starter/actuator" 27 | "github.com/hidevopsio/hiboot/pkg/starter/swagger" 28 | ) 29 | 30 | var mu sync.Mutex 31 | 32 | func TestRunMain(t *testing.T) { 33 | mu.Lock() 34 | go main() 35 | mu.Unlock() 36 | } 37 | 38 | func TestController(t *testing.T) { 39 | mu.Lock() 40 | 41 | time.Sleep(2 * time.Second) 42 | 43 | app.Register( 44 | newController, 45 | swagger.ApiInfoBuilder(). 46 | Title("HiBoot Example - Hello world"). 47 | Description("This is an example that demonstrate the basic usage")) 48 | 49 | web.NewTestApp(t). 50 | SetProperty("server.port", "8081"). 51 | SetProperty(app.ProfilesInclude, swagger.Profile, web.Profile, actuator.Profile). 52 | Run(t). 53 | Get("/"). 54 | Expect().Status(http.StatusOK) 55 | 56 | mu.Unlock() 57 | } 58 | -------------------------------------------------------------------------------- /examples/web/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Package web provides hiboot web application examples 16 | package web 17 | -------------------------------------------------------------------------------- /examples/web/doc_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package web_test 16 | -------------------------------------------------------------------------------- /examples/web/helloworld/main_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Line 1: main package 16 | package main 17 | 18 | import ( 19 | "net/http" 20 | "sync" 21 | "testing" 22 | "time" 23 | 24 | "github.com/hidevopsio/hiboot/pkg/app" 25 | "github.com/hidevopsio/hiboot/pkg/app/web" 26 | "github.com/hidevopsio/hiboot/pkg/starter/actuator" 27 | "github.com/hidevopsio/hiboot/pkg/starter/swagger" 28 | ) 29 | 30 | var mu sync.Mutex 31 | func TestRunMain(t *testing.T) { 32 | mu.Lock() 33 | go main() 34 | mu.Unlock() 35 | } 36 | 37 | func TestController(t *testing.T) { 38 | mu.Lock() 39 | 40 | time.Sleep(2 * time.Second) 41 | 42 | app.Register(swagger.ApiInfoBuilder(). 43 | Title("HiBoot Example - Hello world"). 44 | Description("This is an example that demonstrate the basic usage")) 45 | 46 | web.NewTestApp(t, new(Controller)). 47 | SetProperty("server.port", "8081"). 48 | SetProperty(app.ProfilesInclude, swagger.Profile, web.Profile, actuator.Profile). 49 | Run(t). 50 | Get("/"). 51 | Expect().Status(http.StatusOK) 52 | 53 | mu.Unlock() 54 | } 55 | -------------------------------------------------------------------------------- /examples/web/httpserver/hello/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | // import web starter from hiboot 4 | import ( 5 | "github.com/hidevopsio/hiboot/pkg/app" 6 | "github.com/hidevopsio/hiboot/pkg/app/web" 7 | "github.com/hidevopsio/hiboot/pkg/starter/actuator" 8 | "github.com/hidevopsio/hiboot/pkg/starter/logging" 9 | ) 10 | 11 | // main function 12 | func main() { 13 | web.NewApplication(). 14 | SetProperty(app.ProfilesInclude, logging.Profile, actuator.Profile). 15 | SetProperty(web.ViewEnabled, true). 16 | Run() 17 | } 18 | -------------------------------------------------------------------------------- /examples/web/httpserver/hello/main_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/hidevopsio/hiboot/pkg/app/web" 5 | "net/http" 6 | "sync" 7 | "testing" 8 | "time" 9 | ) 10 | 11 | var mu sync.Mutex 12 | func TestRunMain(t *testing.T) { 13 | mu.Lock() 14 | go main() 15 | mu.Unlock() 16 | } 17 | 18 | func TestController(t *testing.T) { 19 | time.Sleep(time.Second) 20 | web.NewTestApp(). 21 | SetProperty(web.ViewEnabled, true). 22 | Run(t). 23 | Get("/"). 24 | Expect().Status(http.StatusOK) 25 | } 26 | -------------------------------------------------------------------------------- /examples/web/httpserver/hello/static/hello.txt: -------------------------------------------------------------------------------- 1 | Hello World 2 | 3 | -------------------------------------------------------------------------------- /examples/web/httpserver/hello/static/img/hiboot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hidevopsio/hiboot/22ce8a9ec8036736d752bf7b9984d8b344ed287c/examples/web/httpserver/hello/static/img/hiboot.png -------------------------------------------------------------------------------- /examples/web/httpserver/hello/static/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Hiboot Web Application Example 5 | 6 | 7 | 8 |

Hello, Hiboot

9 |

Hiboot Web Application Example

10 | 11 | 12 | -------------------------------------------------------------------------------- /examples/web/httpserver/statik/README.md: -------------------------------------------------------------------------------- 1 | # How to run? 2 | 3 | Run `go generate` to create a statik package that embeds the binary data underneath the public directory. 4 | 5 | $ go generate 6 | 7 | Once the statik package is generated, run the web server: 8 | 9 | $ go run main.go 10 | 11 | Visit [http://localhost:8080/public/hello.txt](http://localhost:8080/public/hello.txt) to see the file. 12 | -------------------------------------------------------------------------------- /examples/web/httpserver/statik/main.go: -------------------------------------------------------------------------------- 1 | //go:generate statik -src=./static 2 | 3 | package main 4 | 5 | import ( 6 | _ "github.com/hidevopsio/hiboot/examples/web/httpserver/statik/statik" 7 | "github.com/hidevopsio/hiboot/pkg/app" 8 | "github.com/hidevopsio/hiboot/pkg/app/web" 9 | "github.com/hidevopsio/hiboot/pkg/app/web/context" 10 | "github.com/hidevopsio/hiboot/pkg/at" 11 | "github.com/hidevopsio/hiboot/pkg/starter/actuator" 12 | "github.com/hidevopsio/hiboot/pkg/starter/logging" 13 | ) 14 | 15 | type controller struct { 16 | at.RestController 17 | at.RequestMapping `value:"/public"` 18 | } 19 | 20 | func init() { 21 | app.Register(newStaticController) 22 | } 23 | 24 | func newStaticController() *controller { 25 | return &controller{} 26 | } 27 | 28 | // UI serve static resource via context StaticResource method 29 | func (c *controller) UI(at struct{ at.GetMapping `value:"/ui/*"`; at.FileServer `value:"/ui"` }, ctx context.Context) { 30 | return 31 | } 32 | 33 | // UI serve static resource via context StaticResource method 34 | func (c *controller) UIIndex(at struct{ at.GetMapping `value:"/ui"`; at.FileServer `value:"/ui"` }, ctx context.Context) { 35 | return 36 | } 37 | 38 | // Before run go build, run go generate. 39 | // Then, run the main program and visit below urls: 40 | // http://localhost:8080/public/ui 41 | // http://localhost:8080/public/ui/hello.txt 42 | // http://localhost:8080/public/ui/img/hiboot.png 43 | 44 | func main() { 45 | web.NewApplication(newStaticController). 46 | SetProperty(app.ProfilesInclude, actuator.Profile, logging.Profile). 47 | Run() 48 | } 49 | -------------------------------------------------------------------------------- /examples/web/httpserver/statik/main_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "net/http" 5 | "sync" 6 | "testing" 7 | 8 | "github.com/hidevopsio/hiboot/pkg/app/web" 9 | ) 10 | var mu sync.Mutex 11 | 12 | func TestController(t *testing.T) { 13 | mu.Lock() 14 | testApp := web.NewTestApp(t).SetProperty("server.port", "8081").Run(t) 15 | 16 | t.Run("should get index.html ", func(t *testing.T) { 17 | testApp.Get("/public/ui"). 18 | Expect().Status(http.StatusOK) 19 | }) 20 | 21 | t.Run("should get hello.txt ", func(t *testing.T) { 22 | testApp.Get("/public/ui/hello.txt"). 23 | Expect().Status(http.StatusOK) 24 | }) 25 | mu.Unlock() 26 | } 27 | 28 | 29 | func TestRunMain(t *testing.T) { 30 | mu.Lock() 31 | go main() 32 | mu.Unlock() 33 | } -------------------------------------------------------------------------------- /examples/web/httpserver/statik/static/hello.txt: -------------------------------------------------------------------------------- 1 | Hello World 2 | 3 | -------------------------------------------------------------------------------- /examples/web/httpserver/statik/static/img/hiboot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hidevopsio/hiboot/22ce8a9ec8036736d752bf7b9984d8b344ed287c/examples/web/httpserver/statik/static/img/hiboot.png -------------------------------------------------------------------------------- /examples/web/httpserver/statik/static/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Hiboot Web Application Example 5 | 6 | 7 | 8 |

Hello, Hiboot

9 |

Hiboot Web Application Example

10 | 11 | 12 | -------------------------------------------------------------------------------- /examples/web/jwt/README.md: -------------------------------------------------------------------------------- 1 | # Web Application with JWT 2 | 3 | This is the web application with JWT. 4 | 5 | 6 | #### main.go 7 | ```go 8 | package main 9 | 10 | import ( 11 | "github.com/hidevopsio/hiboot/pkg/starter/web" 12 | _ "github.com/hidevopsio/hiboot/examples/web/jwt/controllers" 13 | ) 14 | 15 | func main() { 16 | // create new web application and run it 17 | web.NewApplication().Run() 18 | } 19 | ``` 20 | 21 | #### run unit test 22 | ```bash 23 | go test ./... 24 | ``` 25 | 26 | #### run the example code 27 | ```bash 28 | go run main.go 29 | ``` 30 | 31 | ```bash 32 | curl -H 'Accept-Language: cn-ZH' -H """Authorization: Bearer $(curl -d '{"username":"test","password":"123"}' -H "Content-Type: application/json" -X POST http://localhost:8080/foo/login 2>/dev/null | jq -r '.data') """ http://localhost:8080/bars/sayHello 33 | 34 | # here is the output 35 | {"code":200,"message":"成功","data":{"Greeting":"hello bar"}} 36 | ``` -------------------------------------------------------------------------------- /examples/web/jwt/config/application-fake.yaml: -------------------------------------------------------------------------------- 1 | fake: 2 | name: foo 3 | nickname: ${app.name} ${fake.name} 4 | username: ${unknown.name:bar} 5 | -------------------------------------------------------------------------------- /examples/web/jwt/config/application-local.yml: -------------------------------------------------------------------------------- 1 | # config file for testing 2 | 3 | server: 4 | port: 8080 5 | 6 | logging: 7 | level: debug -------------------------------------------------------------------------------- /examples/web/jwt/config/application.yml: -------------------------------------------------------------------------------- 1 | # config file for testing 2 | # filename should be application.yml 3 | 4 | app: 5 | project: hidevopsio 6 | name: jwt-example 7 | profiles: 8 | include: 9 | - locale 10 | - logging 11 | - jwt 12 | - websocket 13 | 14 | logging: 15 | level: info 16 | 17 | 18 | -------------------------------------------------------------------------------- /examples/web/jwt/config/i18n/en-US/en-US.ini: -------------------------------------------------------------------------------- 1 | success = Success 2 | failed = Failed 3 | hello = Hello, World -------------------------------------------------------------------------------- /examples/web/jwt/config/i18n/zh-CN/zh-CN.ini: -------------------------------------------------------------------------------- 1 | success = 成功 2 | failed = 失败 3 | hello = 你好, 世界 4 | -------------------------------------------------------------------------------- /examples/web/jwt/config/i18n/zh-HK/first-cn-HK.ini: -------------------------------------------------------------------------------- 1 | success = 成功 2 | failed = 失败 3 | -------------------------------------------------------------------------------- /examples/web/jwt/config/i18n/zh-HK/second-cn-HK.ini: -------------------------------------------------------------------------------- 1 | hello = 您好,世界 2 | -------------------------------------------------------------------------------- /examples/web/jwt/config/keygen.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Copyright 2018 John Deng (hi.devops.io@gmail.com). 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http:#www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | mkdir -p ssl 17 | 18 | openssl genrsa -out ssl/app.rsa 1024 19 | openssl rsa -in ssl/app.rsa -pubout > ssl/app.rsa.pub -------------------------------------------------------------------------------- /examples/web/jwt/config/ssl/app.rsa: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIICWwIBAAKBgQC2rhCF8UNzU6aSaHa2ht1deIaw5sDpuoRBvkQOc0GZCn3HXP+J 3 | lqaUmDKYHSfS4jXbJNgWr7VGExcygQWCRuom+mfXKhhfI7TDYnd7DcCldwyPqGkk 4 | jCQ40v/jvJeMUmXzU/WxpCftIM7Qaqxb9yrLZJP9jfEAl26Q8SXth7E0NwIDAQAB 5 | AoGAb8xfOFnK2c2b54YfAN3Qo9+bLrBJ58DKKCH1LJLE1pBhIZ18lguors/mRsmx 6 | EZJ3O0J1LI0j91q/m5zybiRQL7mZgMcrJG8t6ZSk+T9Ujh22pdjF5XXJF03adTUE 7 | PBgJrWrsMqa+NFg84J2OM5Oz45JD4LH8PwwoiYPRodoh5WECQQDiwp65vIpjGJGd 8 | sFv6FBaRQaeoQje96FW9E2CPWciibMIFssiW7svtMGzdFlnpAo+Zy1fo9nv6EUCq 9 | owXJgj0VAkEAzjxZZS02wFcAGCvn7YTmMwtzm7Beuiz+2DrFaFys6XVDqKGLQdzd 10 | wi0nNSdmdPLaTP7oPjxOE+hr8ucNjlB3GwJAAixDQRxhZxmxK4WpG/hdTv8GEEKy 11 | Lguv5qPs5PLDTWslYNCZw3h+U8OHB4dTTTxNC/g622yhO4A20mvFfmzVEQJAAm0d 12 | VB5jDYI4gxBJKzcsCh+xXXyGsMQEv4B5gA/PDPQPNrWn0L+LcFRdqLds8iVFQjCh 13 | hNHqzTsnwfTL6QezTwJAMIZylH9hdOiIifw/TkQNEBTSTGDoNIi4MpR31/zlaEea 14 | MVe6NBHZVAizhTzITREPV6FCUUMTEbdozxFnLwVIEg== 15 | -----END RSA PRIVATE KEY----- 16 | -------------------------------------------------------------------------------- /examples/web/jwt/config/ssl/app.rsa.pub: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC2rhCF8UNzU6aSaHa2ht1deIaw 3 | 5sDpuoRBvkQOc0GZCn3HXP+JlqaUmDKYHSfS4jXbJNgWr7VGExcygQWCRuom+mfX 4 | KhhfI7TDYnd7DcCldwyPqGkkjCQ40v/jvJeMUmXzU/WxpCftIM7Qaqxb9yrLZJP9 5 | jfEAl26Q8SXth7E0NwIDAQAB 6 | -----END PUBLIC KEY----- 7 | -------------------------------------------------------------------------------- /examples/web/jwt/controller/bar.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package controller 16 | 17 | import ( 18 | "github.com/hidevopsio/hiboot/pkg/app" 19 | "github.com/hidevopsio/hiboot/pkg/at" 20 | "github.com/hidevopsio/hiboot/pkg/log" 21 | "github.com/hidevopsio/hiboot/pkg/model" 22 | "github.com/hidevopsio/hiboot/pkg/starter/jwt" 23 | "strings" 24 | ) 25 | 26 | type bar struct { 27 | greeting string 28 | } 29 | 30 | type barController struct { 31 | at.JwtRestController 32 | } 33 | 34 | func init() { 35 | app.Register(newBarController) 36 | } 37 | 38 | func newBarController() *barController { 39 | return &barController{} 40 | } 41 | 42 | // Get method GET /bar 43 | func (c *barController) Get(properties *jwt.TokenProperties) (response model.Response, err error) { 44 | username := properties.Get("username") 45 | password := properties.Get("password") 46 | log.Debugf("username: %v, password: %v", username, strings.Repeat("*", len(password))) 47 | log.Debug("BarController.SayHello") 48 | 49 | response = new(model.BaseResponse) 50 | response.SetData(&bar{greeting: "Hello " + username}) 51 | return 52 | } 53 | -------------------------------------------------------------------------------- /examples/web/jwt/controller/bar_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Line 1: main package 16 | package controller 17 | 18 | import ( 19 | "fmt" 20 | "github.com/hidevopsio/hiboot/pkg/app/web" 21 | "github.com/hidevopsio/hiboot/pkg/log" 22 | "github.com/hidevopsio/hiboot/pkg/starter/jwt" 23 | "github.com/hidevopsio/hiboot/pkg/utils/io" 24 | "net/http" 25 | "testing" 26 | "time" 27 | ) 28 | 29 | func genJwtToken(timeout int64) (token string) { 30 | jwtToken := jwt.NewJwtToken(&jwt.Properties{ 31 | PrivateKeyPath: "config/ssl/app.rsa", 32 | PublicKeyPath: "config/ssl/app.rsa.pub", 33 | }) 34 | pt, err := jwtToken.Generate(jwt.Map{ 35 | "username": "johndoe", 36 | "password": "PA$$W0RD", 37 | }, timeout, time.Second) 38 | if err == nil { 39 | token = fmt.Sprintf("Bearer %v", pt) 40 | } 41 | return 42 | } 43 | 44 | func TestBarWithToken(t *testing.T) { 45 | app := web.NewTestApp(t, newBarController). 46 | Run(t) 47 | 48 | log.SetLevel(log.DebugLevel) 49 | log.Println(io.GetWorkDir()) 50 | token := genJwtToken(1) 51 | if token != "" { 52 | t.Run("should pass with jwt token", func(t *testing.T) { 53 | app.Get("/bar"). 54 | WithHeader("Authorization", token). 55 | Expect().Status(http.StatusOK) 56 | }) 57 | 58 | time.Sleep(2 * time.Second) 59 | 60 | t.Run("should not pass with expired jwt token", func(t *testing.T) { 61 | app.Get("/bar"). 62 | WithHeader("Authorization", token). 63 | Expect().Status(http.StatusUnauthorized) 64 | }) 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /examples/web/jwt/controller/foo_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Line 1: main package 16 | package controller 17 | 18 | import ( 19 | "github.com/hidevopsio/hiboot/pkg/app/web" 20 | "net/http" 21 | "testing" 22 | ) 23 | 24 | func TestFooController(t *testing.T) { 25 | 26 | testApp := web.RunTestApplication(t, newFooController) 27 | 28 | t.Run("should pass GET /foo", func(t *testing.T) { 29 | testApp. 30 | Get("/foo"). 31 | WithQueryObject(fooRequestParam{Name: "Peter", Age: 18}). 32 | Expect().Status(http.StatusOK).Body().Contains("jwt-example") 33 | }) 34 | 35 | t.Run("should pass POST /foo", func(t *testing.T) { 36 | testApp. 37 | Post("/foo"). 38 | WithJSON(fooRequestBody{Name: "Mike", Age: 18}). 39 | Expect().Status(http.StatusOK) 40 | }) 41 | } 42 | -------------------------------------------------------------------------------- /examples/web/jwt/controller/login_test.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "github.com/hidevopsio/hiboot/pkg/app/web" 5 | "net/http" 6 | "testing" 7 | ) 8 | 9 | func TestFooLogin(t *testing.T) { 10 | 11 | testApp := web.RunTestApplication(t, newLoginController) 12 | 13 | testApp.Post("/login"). 14 | WithJSON(userRequest{Username: "mike", Password: "daDg83t"}). 15 | Expect().Status(http.StatusOK) 16 | } 17 | -------------------------------------------------------------------------------- /examples/web/jwt/controller/websocket.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "github.com/hidevopsio/hiboot/examples/web/jwt/service" 5 | "github.com/hidevopsio/hiboot/pkg/app" 6 | "github.com/hidevopsio/hiboot/pkg/at" 7 | "github.com/hidevopsio/hiboot/pkg/starter/websocket" 8 | ) 9 | 10 | type websocketController struct { 11 | at.JwtRestController 12 | 13 | register websocket.Register 14 | } 15 | 16 | func newWebsocketController(register websocket.Register) *websocketController { 17 | return &websocketController{register: register} 18 | } 19 | 20 | func init() { 21 | app.Register(newWebsocketController) 22 | } 23 | 24 | // Get GET /websocket 25 | func (c *websocketController) Get(handler *service.CountHandler, connection *websocket.Connection) { 26 | c.register(handler, connection) 27 | } 28 | 29 | // GetStatus GET /websocket/status 30 | func (c *websocketController) GetStatus(handler *service.StatusHandler, connection *websocket.Connection) { 31 | c.register(handler, connection) 32 | } 33 | -------------------------------------------------------------------------------- /examples/web/jwt/controller/websocket_test.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "net/http" 5 | "testing" 6 | 7 | "github.com/hidevopsio/hiboot/pkg/app/web" 8 | "github.com/hidevopsio/hiboot/pkg/app/web/context" 9 | "github.com/hidevopsio/hiboot/pkg/log" 10 | "github.com/hidevopsio/hiboot/pkg/starter/websocket" 11 | "github.com/stretchr/testify/assert" 12 | ) 13 | 14 | func TestWebSocketController(t *testing.T) { 15 | mockController := newWebsocketController(func(handler websocket.Handler, conn *websocket.Connection) { 16 | // For controller's unit testing, do nothing 17 | log.Debug("mock controller") 18 | ctx := conn.GetValue("context").(context.Context) 19 | ctx.StatusCode(http.StatusOK) 20 | }) 21 | 22 | testApp := web.NewTestApp(mockController).Run(t) 23 | assert.NotEqual(t, nil, testApp) 24 | 25 | token := genJwtToken(1000) 26 | 27 | testApp.Get("/websocket"). 28 | WithHeader("Authorization", token). 29 | Expect().Status(http.StatusOK) 30 | 31 | testApp.Get("/websocket/status"). 32 | WithHeader("Authorization", token). 33 | Expect().Status(http.StatusOK) 34 | } 35 | -------------------------------------------------------------------------------- /examples/web/jwt/main.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package main 16 | 17 | import ( 18 | _ "github.com/hidevopsio/hiboot/examples/web/jwt/controller" 19 | "github.com/hidevopsio/hiboot/pkg/app" 20 | "github.com/hidevopsio/hiboot/pkg/app/web" 21 | "github.com/hidevopsio/hiboot/pkg/starter/actuator" 22 | "github.com/hidevopsio/hiboot/pkg/starter/jwt" 23 | "github.com/hidevopsio/hiboot/pkg/starter/logging" 24 | "github.com/hidevopsio/hiboot/pkg/starter/websocket" 25 | ) 26 | 27 | func main() { 28 | // create new web application and run it 29 | web.NewApplication(). 30 | SetProperty("app.profiles.filter", true). 31 | SetProperty(app.ProfilesInclude, actuator.Profile, logging.Profile, websocket.Profile, jwt.Profile). 32 | Run() 33 | } 34 | -------------------------------------------------------------------------------- /examples/web/jwt/main_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package main 16 | 17 | import ( 18 | "sync" 19 | "testing" 20 | ) 21 | 22 | var mu sync.Mutex 23 | func TestRunMain(t *testing.T) { 24 | mu.Lock() 25 | go main() 26 | mu.Unlock() 27 | } 28 | -------------------------------------------------------------------------------- /examples/web/jwt/service/counthandler.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "fmt" 5 | "github.com/hidevopsio/hiboot/pkg/app" 6 | "github.com/hidevopsio/hiboot/pkg/at" 7 | "github.com/hidevopsio/hiboot/pkg/log" 8 | "github.com/hidevopsio/hiboot/pkg/starter/websocket" 9 | "time" 10 | ) 11 | 12 | // CountHandler is the websocket handler 13 | type CountHandler struct { 14 | at.Scope `value:"request"` 15 | connection *websocket.Connection 16 | } 17 | 18 | func newCountHandler(connection *websocket.Connection) *CountHandler { 19 | h := &CountHandler{connection: connection} 20 | return h 21 | } 22 | 23 | func init() { 24 | app.Register(newCountHandler) 25 | } 26 | 27 | // OnMessage is the websocket message handler 28 | func (h *CountHandler) OnMessage(data []byte) { 29 | message := string(data) 30 | log.Debugf("client: %v", message) 31 | var i int 32 | go func() { 33 | for { 34 | i++ 35 | h.connection.EmitMessage([]byte(fmt.Sprintf("=== %v %d ===", message, i))) 36 | time.Sleep(time.Second) 37 | } 38 | }() 39 | } 40 | 41 | // OnDisconnect is the websocket disconnection handler 42 | func (h *CountHandler) OnDisconnect() { 43 | log.Debugf("Connection with ID: %v has been disconnected!", h.connection.ID()) 44 | } 45 | 46 | // OnPing is the websocket ping handler 47 | func (h *CountHandler) OnPing() { 48 | log.Debugf("Connection with ID: %v has been pinged!", h.connection.ID()) 49 | } 50 | 51 | // OnPong is the websocket pong handler 52 | func (h *CountHandler) OnPong() { 53 | log.Debugf("Connection with ID: %v has been ponged!", h.connection.ID()) 54 | } 55 | -------------------------------------------------------------------------------- /examples/web/jwt/service/statushandler.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "fmt" 5 | "github.com/hidevopsio/hiboot/pkg/app" 6 | "github.com/hidevopsio/hiboot/pkg/at" 7 | "github.com/hidevopsio/hiboot/pkg/log" 8 | "github.com/hidevopsio/hiboot/pkg/starter/websocket" 9 | ) 10 | 11 | // StatusHandler is the websocket handler 12 | type StatusHandler struct { 13 | at.Scope `value:"request"` 14 | connection *websocket.Connection 15 | } 16 | 17 | func newStatusHandler(connection *websocket.Connection) *StatusHandler { 18 | h := &StatusHandler{connection: connection} 19 | return h 20 | } 21 | 22 | func init() { 23 | app.Register(newStatusHandler) 24 | } 25 | 26 | // OnMessage is the websocket message handler 27 | func (h *StatusHandler) OnMessage(data []byte) { 28 | message := string(data) 29 | log.Debugf("client: %v", message) 30 | 31 | h.connection.EmitMessage([]byte(fmt.Sprintf("Status: Up"))) 32 | 33 | } 34 | 35 | // OnDisconnect is the websocket disconnection handler 36 | func (h *StatusHandler) OnDisconnect() { 37 | log.Debugf("Connection with ID: %v has been disconnected!", h.connection.ID()) 38 | } 39 | 40 | // OnPing is the websocket ping handler 41 | func (h *StatusHandler) OnPing() { 42 | log.Debugf("Connection with ID: %v has been pinged!", h.connection.ID()) 43 | } 44 | 45 | // OnPong is the websocket pong handler 46 | func (h *StatusHandler) OnPong() { 47 | log.Debugf("Connection with ID: %v has been ponged!", h.connection.ID()) 48 | } 49 | -------------------------------------------------------------------------------- /examples/web/middleware/controller/controller_test.go: -------------------------------------------------------------------------------- 1 | package controller_test 2 | 3 | import ( 4 | _ "github.com/hidevopsio/hiboot/examples/web/middleware/controller" 5 | _ "github.com/hidevopsio/hiboot/examples/web/middleware/logging" 6 | "github.com/hidevopsio/hiboot/pkg/app/web" 7 | "net/http" 8 | "testing" 9 | ) 10 | 11 | func TestMiddleware(t *testing.T) { 12 | testApp := web.NewTestApp().Run(t) 13 | 14 | t.Run("should get user by id", func(t *testing.T) { 15 | testApp.Get("/user/123456"). 16 | Expect().Status(http.StatusOK). 17 | Body().Contains("123456") 18 | }) 19 | 20 | t.Run("should get user by name", func(t *testing.T) { 21 | testApp.Get("/user/name/john.deng"). 22 | Expect().Status(http.StatusOK). 23 | Body().Contains("john.deng") 24 | }) 25 | 26 | t.Run("should get user", func(t *testing.T) { 27 | testApp.Get("/user/query"). 28 | WithQuery("id", 123456). 29 | Expect().Status(http.StatusOK). 30 | Body().Contains("123456") 31 | }) 32 | 33 | t.Run("should get users", func(t *testing.T) { 34 | testApp.Get("/user"). 35 | WithQuery("page", 1). 36 | WithQuery("per_page", 10). 37 | Expect().Status(http.StatusOK) 38 | }) 39 | 40 | 41 | t.Run("should get users without page, per_page params", func(t *testing.T) { 42 | testApp.Get("/user"). 43 | Expect().Status(http.StatusBadRequest) 44 | }) 45 | 46 | t.Run("should delete user", func(t *testing.T) { 47 | testApp.Delete("/user/123456"). 48 | Expect().Status(http.StatusOK) 49 | }) 50 | } 51 | -------------------------------------------------------------------------------- /examples/web/middleware/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | _ "github.com/hidevopsio/hiboot/examples/web/middleware/controller" 5 | _ "github.com/hidevopsio/hiboot/examples/web/middleware/logging" 6 | "github.com/hidevopsio/hiboot/pkg/app" 7 | "github.com/hidevopsio/hiboot/pkg/app/web" 8 | "github.com/hidevopsio/hiboot/pkg/starter/actuator" 9 | "github.com/hidevopsio/hiboot/pkg/starter/logging" 10 | ) 11 | 12 | // HiBoot main function 13 | func main() { 14 | // create new web application and run it 15 | web.NewApplication(). 16 | SetProperty(app.ProfilesInclude, web.Profile, actuator.Profile, logging.Profile). 17 | Run() 18 | } -------------------------------------------------------------------------------- /examples/web/middleware/main_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Line 1: main package 16 | package main 17 | 18 | import ( 19 | "sync" 20 | "testing" 21 | ) 22 | 23 | var mu sync.Mutex 24 | 25 | func TestRunMain(t *testing.T) { 26 | mu.Lock() 27 | go main() 28 | mu.Unlock() 29 | } 30 | -------------------------------------------------------------------------------- /examples/web/swagger/greeting-server/README.md: -------------------------------------------------------------------------------- 1 | # How to run? 2 | 3 | Once the statik package is generated, run the web server: 4 | 5 | $ go run main.go 6 | 7 | Visit [http://localhost:8080/greeting-server/swagger-ui](http://localhost:8080/greeting-server/swagger-ui) to see the swagger ui. 8 | -------------------------------------------------------------------------------- /examples/web/swagger/greeting-server/config/application.yml: -------------------------------------------------------------------------------- 1 | 2 | #server: 3 | ## context_path: /api/v2/greeting-server -------------------------------------------------------------------------------- /examples/web/swagger/greeting-server/controller/hello_test.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "github.com/hidevopsio/hiboot/pkg/app/web" 5 | "github.com/hidevopsio/hiboot/pkg/app/web/server" 6 | "net/http" 7 | "sync" 8 | "testing" 9 | ) 10 | 11 | var mu sync.Mutex 12 | func TestController(t *testing.T) { 13 | mu.Lock() 14 | basePath := "/api/v1/my-greeting-server" 15 | testApp := web.NewTestApp(t, newHelloController). 16 | SetProperty("server.port", "8082"). 17 | SetProperty(server.ContextPath, basePath).Run(t) 18 | 19 | t.Run("should get employee ", func(t *testing.T) { 20 | testApp.Get(basePath + "/hello"). 21 | Expect().Status(http.StatusOK) 22 | }) 23 | 24 | t.Run("should get employee ", func(t *testing.T) { 25 | testApp.Get(basePath + "/hey"). 26 | Expect().Status(http.StatusOK) 27 | }) 28 | mu.Unlock() 29 | } 30 | 31 | -------------------------------------------------------------------------------- /examples/web/swagger/greeting-server/main.go: -------------------------------------------------------------------------------- 1 | //go:generate statik -src=./dist 2 | 3 | package main 4 | 5 | import ( 6 | _ "github.com/hidevopsio/hiboot/examples/web/swagger/greeting-server/controller" 7 | "github.com/hidevopsio/hiboot/pkg/app" 8 | "github.com/hidevopsio/hiboot/pkg/app/web" 9 | "github.com/hidevopsio/hiboot/pkg/app/web/server" 10 | "github.com/hidevopsio/hiboot/pkg/starter/actuator" 11 | "github.com/hidevopsio/hiboot/pkg/starter/logging" 12 | "github.com/hidevopsio/hiboot/pkg/starter/swagger" 13 | ) 14 | 15 | const ( 16 | version = "1.0.3" 17 | basePath = "/api/v1/greeting-server" 18 | ) 19 | 20 | func init() { 21 | app.Register(swagger.ApiInfoBuilder(). 22 | ContactName("John Deng"). 23 | ContactEmail("john.deng@outlook.com"). 24 | ContactURL("https://hidevops.io"). 25 | Title("HiBoot Swagger Demo Application - Greeting Server"). 26 | Description("Greeting Server is an application that demonstrate the usage of Swagger Annotations"), 27 | // alternatively, you can set below properties by using SetProperty() in main, config/application.yml or program arguments to take advantage of HiBoot DI 28 | //Version(version). 29 | //Schemes("http", "https"). 30 | //BasePath(basePath), 31 | ) 32 | } 33 | 34 | //run http://localhost:8080/api/v1/greeting-server/swagger-ui to open swagger ui 35 | func main() { 36 | web.NewApplication(). 37 | SetProperty(app.ProfilesInclude, actuator.Profile, logging.Profile, swagger.Profile). 38 | SetProperty(app.Version, version). 39 | SetProperty(server.Host, "localhost"). 40 | SetProperty(server.Port, "8080"). 41 | SetProperty(server.ContextPath, basePath). 42 | Run() 43 | } 44 | -------------------------------------------------------------------------------- /examples/web/swagger/greeting-server/main_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "sync" 5 | "testing" 6 | ) 7 | 8 | var mu sync.Mutex 9 | func TestRunMain(t *testing.T) { 10 | mu.Lock() 11 | go main() 12 | mu.Unlock() 13 | } 14 | -------------------------------------------------------------------------------- /examples/web/swagger/simple-server/README.md: -------------------------------------------------------------------------------- 1 | # simple-server 2 | 3 | simple-server is the demo application that uses HiBoot annotation to automatic generate online API docs 4 | 5 | 6 | HiBoot makes developing RESTful services ridiculously easy — and using Swagger makes documenting your RESTful services easy. 7 | 8 | [Live Demo - v1](https://hiboot-demo.apps.hidevops.io/api/v1/simple-server/swagger-ui) 9 | 10 | [Live Demo - v2](https://hiboot-demo.apps.hidevops.io/api/v2/simple-server/swagger-ui) -------------------------------------------------------------------------------- /examples/web/swagger/simple-server/config/application-bar.yml: -------------------------------------------------------------------------------- 1 | # config file for testing 2 | 3 | logging: 4 | level: debug -------------------------------------------------------------------------------- /examples/web/swagger/simple-server/config/application-dev.yml: -------------------------------------------------------------------------------- 1 | # config file for testing 2 | 3 | logging: 4 | level: debug -------------------------------------------------------------------------------- /examples/web/swagger/simple-server/config/application-foo.yml: -------------------------------------------------------------------------------- 1 | # config file for testing 2 | 3 | logging: 4 | level: debug -------------------------------------------------------------------------------- /examples/web/swagger/simple-server/config/application-local.yml: -------------------------------------------------------------------------------- 1 | # config file for testing 2 | 3 | logging: 4 | level: debug -------------------------------------------------------------------------------- /examples/web/swagger/simple-server/config/application.yml: -------------------------------------------------------------------------------- 1 | # config file for testing 2 | # filename should be application.yml 3 | 4 | app: 5 | project: examples-swagger 6 | name: simple-server 7 | 8 | logging: 9 | level: info 10 | -------------------------------------------------------------------------------- /examples/web/swagger/simple-server/config/i18n/en-US/en-US.ini: -------------------------------------------------------------------------------- 1 | success = Success 2 | failed = Failed 3 | hello = Hello, World -------------------------------------------------------------------------------- /examples/web/swagger/simple-server/config/i18n/zh-CN/zh-CN.ini: -------------------------------------------------------------------------------- 1 | success = 成功 2 | failed = 失败 3 | hello = 你好, 世界 4 | -------------------------------------------------------------------------------- /examples/web/swagger/simple-server/config/i18n/zh-HK/first-cn-HK.ini: -------------------------------------------------------------------------------- 1 | success = 成功 2 | failed = 失败 3 | -------------------------------------------------------------------------------- /examples/web/swagger/simple-server/config/i18n/zh-HK/second-cn-HK.ini: -------------------------------------------------------------------------------- 1 | hello = 您好,世界 2 | -------------------------------------------------------------------------------- /examples/web/swagger/simple-server/config/keygen.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Copyright 2018 John Deng (hi.devops.io@gmail.com). 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http:#www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | mkdir -p ssl 17 | 18 | openssl genrsa -out ssl/app.rsa 1024 19 | openssl rsa -in ssl/app.rsa -pubout > ssl/app.rsa.pub -------------------------------------------------------------------------------- /examples/web/swagger/simple-server/config/ssl/app.rsa: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIICWwIBAAKBgQC2rhCF8UNzU6aSaHa2ht1deIaw5sDpuoRBvkQOc0GZCn3HXP+J 3 | lqaUmDKYHSfS4jXbJNgWr7VGExcygQWCRuom+mfXKhhfI7TDYnd7DcCldwyPqGkk 4 | jCQ40v/jvJeMUmXzU/WxpCftIM7Qaqxb9yrLZJP9jfEAl26Q8SXth7E0NwIDAQAB 5 | AoGAb8xfOFnK2c2b54YfAN3Qo9+bLrBJ58DKKCH1LJLE1pBhIZ18lguors/mRsmx 6 | EZJ3O0J1LI0j91q/m5zybiRQL7mZgMcrJG8t6ZSk+T9Ujh22pdjF5XXJF03adTUE 7 | PBgJrWrsMqa+NFg84J2OM5Oz45JD4LH8PwwoiYPRodoh5WECQQDiwp65vIpjGJGd 8 | sFv6FBaRQaeoQje96FW9E2CPWciibMIFssiW7svtMGzdFlnpAo+Zy1fo9nv6EUCq 9 | owXJgj0VAkEAzjxZZS02wFcAGCvn7YTmMwtzm7Beuiz+2DrFaFys6XVDqKGLQdzd 10 | wi0nNSdmdPLaTP7oPjxOE+hr8ucNjlB3GwJAAixDQRxhZxmxK4WpG/hdTv8GEEKy 11 | Lguv5qPs5PLDTWslYNCZw3h+U8OHB4dTTTxNC/g622yhO4A20mvFfmzVEQJAAm0d 12 | VB5jDYI4gxBJKzcsCh+xXXyGsMQEv4B5gA/PDPQPNrWn0L+LcFRdqLds8iVFQjCh 13 | hNHqzTsnwfTL6QezTwJAMIZylH9hdOiIifw/TkQNEBTSTGDoNIi4MpR31/zlaEea 14 | MVe6NBHZVAizhTzITREPV6FCUUMTEbdozxFnLwVIEg== 15 | -----END RSA PRIVATE KEY----- 16 | -------------------------------------------------------------------------------- /examples/web/swagger/simple-server/config/ssl/app.rsa.pub: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC2rhCF8UNzU6aSaHa2ht1deIaw 3 | 5sDpuoRBvkQOc0GZCn3HXP+JlqaUmDKYHSfS4jXbJNgWr7VGExcygQWCRuom+mfX 4 | KhhfI7TDYnd7DcCldwyPqGkkjCQ40v/jvJeMUmXzU/WxpCftIM7Qaqxb9yrLZJP9 5 | jfEAl26Q8SXth7E0NwIDAQAB 6 | -----END PUBLIC KEY----- 7 | -------------------------------------------------------------------------------- /examples/web/websocket/controller/websocket.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "github.com/hidevopsio/hiboot/examples/web/websocket/service" 5 | "github.com/hidevopsio/hiboot/pkg/app" 6 | "github.com/hidevopsio/hiboot/pkg/at" 7 | "github.com/hidevopsio/hiboot/pkg/starter/websocket" 8 | ) 9 | 10 | type websocketController struct { 11 | at.RestController 12 | 13 | register websocket.Register 14 | } 15 | 16 | func newWebsocketController(interactRegister websocket.Register) *websocketController { 17 | return &websocketController{register: interactRegister} 18 | } 19 | 20 | func init() { 21 | app.Register(newWebsocketController) 22 | } 23 | 24 | // Get GET /websocket 25 | func (c *websocketController) Get(handler *service.CountHandler, connection *websocket.Connection) { 26 | c.register(handler, connection) 27 | } 28 | 29 | // GetStatus GET /websocket/status 30 | func (c *websocketController) GetStatus(handler *service.StatusHandler, connection *websocket.Connection) { 31 | c.register(handler, connection) 32 | } 33 | -------------------------------------------------------------------------------- /examples/web/websocket/controller/websocket_test.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "net/http" 5 | "testing" 6 | 7 | "github.com/hidevopsio/hiboot/pkg/app" 8 | "github.com/hidevopsio/hiboot/pkg/app/web" 9 | "github.com/hidevopsio/hiboot/pkg/app/web/context" 10 | "github.com/hidevopsio/hiboot/pkg/starter/logging" 11 | "github.com/hidevopsio/hiboot/pkg/starter/websocket" 12 | "github.com/stretchr/testify/assert" 13 | ) 14 | 15 | func TestWebSocketController(t *testing.T) { 16 | mockController := newWebsocketController(func(handler websocket.Handler, conn *websocket.Connection) { 17 | // For controller's unit testing, do nothing 18 | ctx := conn.GetValue("context").(context.Context) 19 | ctx.StatusCode(http.StatusOK) 20 | }) 21 | 22 | testApp := web.NewTestApp(mockController).SetProperty(app.ProfilesInclude, websocket.Profile, logging.Profile).Run(t) 23 | assert.NotEqual(t, nil, testApp) 24 | 25 | testApp.Get("/websocket").Expect().Status(http.StatusOK) 26 | testApp.Get("/websocket/status").Expect().Status(http.StatusOK) 27 | } 28 | -------------------------------------------------------------------------------- /examples/web/websocket/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | _ "github.com/hidevopsio/hiboot/examples/web/websocket/controller" 5 | _ "github.com/hidevopsio/hiboot/examples/web/websocket/service" 6 | "github.com/hidevopsio/hiboot/pkg/app" 7 | "github.com/hidevopsio/hiboot/pkg/app/web" 8 | "github.com/hidevopsio/hiboot/pkg/starter/websocket" 9 | ) 10 | 11 | func main() { 12 | web.NewApplication(). 13 | SetProperty(app.ProfilesInclude, websocket.Profile). 14 | Run() 15 | } 16 | -------------------------------------------------------------------------------- /examples/web/websocket/main_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Line 1: main package 16 | package main 17 | 18 | import ( 19 | "sync" 20 | "testing" 21 | ) 22 | 23 | var mu sync.Mutex 24 | func TestRunMain(t *testing.T) { 25 | mu.Lock() 26 | go main() 27 | mu.Unlock() 28 | } -------------------------------------------------------------------------------- /examples/web/websocket/service/counthandler.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "fmt" 5 | "github.com/hidevopsio/hiboot/pkg/app" 6 | "github.com/hidevopsio/hiboot/pkg/at" 7 | "github.com/hidevopsio/hiboot/pkg/log" 8 | "github.com/hidevopsio/hiboot/pkg/starter/websocket" 9 | "time" 10 | ) 11 | 12 | // CountHandler is the websocket handler 13 | type CountHandler struct { 14 | at.Scope `value:"request"` 15 | connection *websocket.Connection 16 | } 17 | 18 | func newCountHandler(connection *websocket.Connection) *CountHandler { 19 | h := &CountHandler{connection: connection} 20 | return h 21 | } 22 | 23 | func init() { 24 | app.Register(newCountHandler) 25 | } 26 | 27 | // OnMessage is the websocket message handler 28 | func (h *CountHandler) OnMessage(data []byte) { 29 | message := string(data) 30 | log.Debugf("client: %v", message) 31 | var i int 32 | go func() { 33 | for { 34 | i++ 35 | h.connection.EmitMessage([]byte(fmt.Sprintf("=== %v %d ===", message, i))) 36 | time.Sleep(time.Second) 37 | } 38 | }() 39 | } 40 | 41 | // OnDisconnect is the websocket disconnection handler 42 | func (h *CountHandler) OnDisconnect() { 43 | log.Debugf("Connection with ID: %v has been disconnected!", h.connection.ID()) 44 | } 45 | 46 | // OnPing is the websocket ping handler 47 | func (h *CountHandler) OnPing() { 48 | log.Debugf("Connection with ID: %v has been pinged!", h.connection.ID()) 49 | } 50 | 51 | // OnPong is the websocket pong handler 52 | func (h *CountHandler) OnPong() { 53 | log.Debugf("Connection with ID: %v has been ponged!", h.connection.ID()) 54 | } 55 | -------------------------------------------------------------------------------- /examples/web/websocket/service/statushandler.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "fmt" 5 | "github.com/hidevopsio/hiboot/pkg/app" 6 | "github.com/hidevopsio/hiboot/pkg/at" 7 | "github.com/hidevopsio/hiboot/pkg/log" 8 | "github.com/hidevopsio/hiboot/pkg/starter/websocket" 9 | ) 10 | 11 | // StatusHandler is the websocket handler 12 | type StatusHandler struct { 13 | at.Scope `value:"request"` 14 | connection *websocket.Connection 15 | } 16 | 17 | func newStatusHandler(connection *websocket.Connection) *StatusHandler { 18 | h := &StatusHandler{connection: connection} 19 | return h 20 | } 21 | 22 | func init() { 23 | app.Register(newStatusHandler) 24 | } 25 | 26 | // OnMessage is the websocket message handler 27 | func (h *StatusHandler) OnMessage(data []byte) { 28 | message := string(data) 29 | log.Debugf("client: %v", message) 30 | 31 | h.connection.EmitMessage([]byte(fmt.Sprintf("Status: Up"))) 32 | 33 | } 34 | 35 | // OnDisconnect is the websocket disconnection handler 36 | func (h *StatusHandler) OnDisconnect() { 37 | log.Debugf("Connection with ID: %v has been disconnected!", h.connection.ID()) 38 | } 39 | 40 | // OnPing is the websocket ping handler 41 | func (h *StatusHandler) OnPing() { 42 | log.Debugf("Connection with ID: %v has been pinged!", h.connection.ID()) 43 | } 44 | 45 | // OnPong is the websocket pong handler 46 | func (h *StatusHandler) OnPong() { 47 | log.Debugf("Connection with ID: %v has been ponged!", h.connection.ID()) 48 | } 49 | -------------------------------------------------------------------------------- /hiboot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hidevopsio/hiboot/22ce8a9ec8036736d752bf7b9984d8b344ed287c/hiboot.png -------------------------------------------------------------------------------- /pkg/app/autoconfigure_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package app 16 | 17 | import ( 18 | "github.com/stretchr/testify/assert" 19 | "testing" 20 | ) 21 | 22 | func TestDependencies(t *testing.T) { 23 | type foo struct{} 24 | 25 | Component(new(foo)) 26 | 27 | type config struct { 28 | Configuration 29 | } 30 | 31 | // should show deprecated message on Component 32 | AutoConfiguration(new(config)) 33 | 34 | c := new(config) 35 | deps := []string{"world"} 36 | c.RuntimeDeps.Set("hello", deps) 37 | 38 | assert.Equal(t, deps, c.RuntimeDeps.Get("hello")) 39 | 40 | t.Run("should report error if we pass nil to appendParams", func(t *testing.T) { 41 | _, err := appendParams(nil) 42 | assert.Equal(t, ErrInvalidObjectType, err) 43 | }) 44 | } 45 | -------------------------------------------------------------------------------- /pkg/app/cli/README.md: -------------------------------------------------------------------------------- 1 | # Hiboot cli application 2 | 3 | Hiboot cli application is built based on top of cobra with Hiboot dependency injection and auto configuration. 4 | 5 | ## Documentation 6 | 7 | * [Hiboot cli Documentation in English](https://hiboot.hidevops.io/cli-app/) 8 | * [Hiboot cli 中文文档](https://hiboot.hidevops.io/cn/cli-app/) -------------------------------------------------------------------------------- /pkg/app/cli/command_test.go: -------------------------------------------------------------------------------- 1 | package cli_test 2 | 3 | import ( 4 | "github.com/stretchr/testify/assert" 5 | "github.com/hidevopsio/hiboot/pkg/app/cli" 6 | "testing" 7 | ) 8 | 9 | func TestCommand(t *testing.T) { 10 | 11 | t.Run("should add child command and found the child", func(t *testing.T) { 12 | barCmd := newBarCommand() 13 | bazCmd := newBazCommand() 14 | fooCmd := newFooCommand(barCmd, bazCmd) 15 | fooCmd.SetName("foo") 16 | assert.Equal(t, "foo", fooCmd.FullName()) 17 | 18 | fooCmd.SetFullName("foo command") 19 | 20 | assert.Equal(t, "foo command", fooCmd.FullName()) 21 | 22 | assert.Equal(t, true, fooCmd.HasChild()) 23 | assert.Equal(t, barCmd, fooCmd.Children()[0]) 24 | 25 | assert.Equal(t, fooCmd.GetName(), barCmd.Parent().GetName()) 26 | 27 | foundCmd, err := fooCmd.Find("bar") 28 | assert.Equal(t, nil, err) 29 | assert.Equal(t, foundCmd.GetName(), barCmd.GetName()) 30 | }) 31 | 32 | t.Run("should found the command directly", func(t *testing.T) { 33 | fooCmd := new(fooCommand) 34 | fooCmd.SetName("foo") 35 | _, err := fooCmd.Find("foo") 36 | assert.Equal(t, nil, err) 37 | }) 38 | 39 | t.Run("should not found the non-exist command", func(t *testing.T) { 40 | fooCmd := new(fooCommand) 41 | fooCmd.SetName("foo") 42 | _, err := fooCmd.Find("bar") 43 | assert.Equal(t, cli.ErrCommandNotFound, err) 44 | }) 45 | 46 | t.Run("should run command handler", func(t *testing.T) { 47 | cmd := new(cli.SubCommand) 48 | err := cmd.Run(nil) 49 | assert.Equal(t, nil, err) 50 | }) 51 | 52 | t.Run("should run secondary command handler", func(t *testing.T) { 53 | cmd := new(fooCommand) 54 | 55 | res, err := cli.Dispatch(cmd, []string{"daz"}) 56 | assert.Equal(t, nil, err) 57 | assert.Equal(t, false, res.(bool)) 58 | 59 | res, err = cli.Dispatch(cmd, []string{"buzz"}) 60 | assert.Equal(t, nil, err) 61 | assert.Equal(t, true, res.(bool)) 62 | }) 63 | } 64 | -------------------------------------------------------------------------------- /pkg/app/cli/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | /* 16 | Package cli provides quick start framework for command line application. 17 | 18 | The main features of Hiboot cli application are 19 | 20 | * Dependency Injection 21 | * Struct Tag for dependency injection 22 | * Sub command handler 23 | 24 | */ 25 | package cli 26 | -------------------------------------------------------------------------------- /pkg/app/cli/properties.go: -------------------------------------------------------------------------------- 1 | package cli 2 | 3 | /* 4 | app: 5 | name: demo-cli 6 | 7 | */ 8 | -------------------------------------------------------------------------------- /pkg/app/cli/testapplication.go: -------------------------------------------------------------------------------- 1 | package cli 2 | 3 | import ( 4 | "bytes" 5 | "github.com/hidevopsio/hiboot/pkg/log" 6 | "testing" 7 | ) 8 | 9 | // TestApplication the interface of cli test application 10 | type TestApplication interface { 11 | Initialize() error 12 | SetProperty(name string, value ...interface{}) TestApplication 13 | Run(args ...string) (output string, err error) 14 | } 15 | 16 | type testApplication struct { 17 | application 18 | } 19 | 20 | // NewTestApplication is the test application constructor 21 | func NewTestApplication(t *testing.T, cmd ...interface{}) TestApplication { 22 | a := new(testApplication) 23 | err := a.initialize(cmd...) 24 | log.Debug(err) 25 | err = a.build() 26 | log.Debug(err) 27 | return a 28 | } 29 | 30 | // SetProperty set application property 31 | func (a *testApplication) SetProperty(name string, value ...interface{}) TestApplication { 32 | a.BaseApplication.SetProperty(name, value...) 33 | return a 34 | } 35 | 36 | func (a *testApplication) Run(args ...string) (output string, err error) { 37 | buf := new(bytes.Buffer) 38 | if a.root != nil { 39 | a.root.SetOutput(buf) 40 | a.root.SetArgs(args) 41 | 42 | _, err = a.root.ExecuteC() 43 | 44 | output = buf.String() 45 | } 46 | return 47 | } 48 | -------------------------------------------------------------------------------- /pkg/app/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Package app provides hiboot app application interface 16 | package app 17 | -------------------------------------------------------------------------------- /pkg/app/doc_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package app_test 16 | -------------------------------------------------------------------------------- /pkg/app/fake/application.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Package fake provides fake.ApplicationContext for unit testing 16 | package fake 17 | 18 | import ( 19 | "github.com/hidevopsio/hiboot/pkg/app/web/context" 20 | "github.com/hidevopsio/iris/core/router" 21 | ) 22 | 23 | // ApplicationContext application context 24 | type ApplicationContext struct { 25 | } 26 | 27 | // RegisterController register controller by interface 28 | func (a *ApplicationContext) RegisterController(controller interface{}) error { 29 | return nil 30 | } 31 | 32 | // Use use middleware 33 | func (a *ApplicationContext) Use(handlers ...context.Handler) { 34 | 35 | } 36 | 37 | // GetProperty get application property by name 38 | func (a *ApplicationContext) GetProperty(name string) (value interface{}, ok bool) { 39 | return 40 | } 41 | 42 | // GetInstance get application instance by name 43 | func (a *ApplicationContext) GetInstance(params ...interface{}) (instance interface{}) { 44 | return 45 | } 46 | 47 | func (a *ApplicationContext) WrapRouter(handler router.WrapperFunc) { 48 | } 49 | -------------------------------------------------------------------------------- /pkg/app/fake/applicatoin_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package fake 16 | 17 | import "testing" 18 | 19 | func TestApplicationContext(t *testing.T) { 20 | ac := new(ApplicationContext) 21 | ac.RegisterController(nil) 22 | ac.Use() 23 | ac.GetProperty("foo") 24 | ac.GetInstance("bar") 25 | type Foo struct{} 26 | ac.GetInstance(Foo{}) 27 | } 28 | -------------------------------------------------------------------------------- /pkg/app/postprocessor.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package app 16 | 17 | import ( 18 | "github.com/hidevopsio/hiboot/pkg/factory" 19 | ) 20 | 21 | // PostProcessor is the post processor 22 | type PostProcessor interface { 23 | AfterInitialization() 24 | } 25 | 26 | type postProcessor struct { 27 | factory factory.InstantiateFactory 28 | subscribes []PostProcessor 29 | } 30 | 31 | func newPostProcessor(factory factory.InstantiateFactory) *postProcessor { 32 | return &postProcessor{ 33 | factory: factory, 34 | } 35 | } 36 | 37 | var ( 38 | postProcessors []interface{} 39 | ) 40 | 41 | func init() { 42 | 43 | } 44 | 45 | // RegisterPostProcessor register post processor 46 | func RegisterPostProcessor(p ...interface{}) { 47 | postProcessors = append(postProcessors, p...) 48 | } 49 | 50 | // Init init the post processor 51 | func (p *postProcessor) Init() { 52 | for _, processor := range postProcessors { 53 | ss, err := p.factory.InjectIntoFunc(nil, processor) 54 | if err == nil { 55 | p.subscribes = append(p.subscribes, ss.(PostProcessor)) 56 | } 57 | } 58 | } 59 | 60 | // AfterInitialization post processor after initialization 61 | func (p *postProcessor) AfterInitialization() { 62 | for _, processor := range p.subscribes { 63 | p.factory.InjectIntoFunc(nil, processor) 64 | processor.AfterInitialization() 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /pkg/app/postprocessor_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package app 16 | 17 | import ( 18 | "github.com/hidevopsio/hiboot/pkg/factory" 19 | "github.com/hidevopsio/hiboot/pkg/factory/instantiate" 20 | "github.com/hidevopsio/hiboot/pkg/utils/cmap" 21 | "testing" 22 | ) 23 | 24 | type fakePostProcessor struct { 25 | } 26 | 27 | func newFakePostPrecessor() *fakePostProcessor { 28 | return new(fakePostProcessor) 29 | } 30 | 31 | func (p *fakePostProcessor) BeforeInitialization() { 32 | } 33 | 34 | func (p *fakePostProcessor) AfterInitialization() { 35 | 36 | } 37 | 38 | func TestRegisterPostProcessor(t *testing.T) { 39 | 40 | RegisterPostProcessor(newFakePostPrecessor) 41 | pp := newPostProcessor(instantiate.NewInstantiateFactory(cmap.New(), []*factory.MetaData{}, cmap.New())) 42 | pp.Init() 43 | pp.AfterInitialization() 44 | 45 | } 46 | -------------------------------------------------------------------------------- /pkg/app/properties.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package app 16 | 17 | import "github.com/hidevopsio/hiboot/pkg/system" 18 | 19 | const ( 20 | // Config is the embed config 21 | Config = system.Config 22 | 23 | // ConfigDir is the embed config dir 24 | ConfigDir = system.ConfigDir 25 | 26 | // BannerDisabled is the property that allow use to enable / disable banner display on terminal 27 | BannerDisabled = "app.banner.disabled" 28 | 29 | // ProfilesInclude is the property that allow user include profiles at runtime 30 | ProfilesInclude = "app.profiles.include" 31 | 32 | // Version is the property key of app.version 33 | Version = "app.version" 34 | ) -------------------------------------------------------------------------------- /pkg/app/web/autoconfigure.go: -------------------------------------------------------------------------------- 1 | package web 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/hidevopsio/hiboot/pkg/app" 7 | "github.com/hidevopsio/hiboot/pkg/app/web/context" 8 | "github.com/hidevopsio/hiboot/pkg/at" 9 | "github.com/hidevopsio/hiboot/pkg/log" 10 | "github.com/hidevopsio/iris" 11 | ) 12 | 13 | const Profile = "web" 14 | 15 | type configuration struct { 16 | at.AutoConfiguration 17 | 18 | Properties *properties 19 | } 20 | 21 | func newWebConfiguration() *configuration { 22 | return &configuration{} 23 | } 24 | 25 | func init() { 26 | app.IncludeProfiles(Profile) 27 | app.Register(newWebConfiguration) 28 | } 29 | 30 | // Context is the instance of context.Context 31 | func (c *configuration) Context(app *webApp) context.Context { 32 | return NewContext(app) 33 | } 34 | 35 | // DefaultView set the default view 36 | type DefaultView interface{} 37 | 38 | func (c *configuration) DefaultView(app *webApp) (view DefaultView) { 39 | 40 | if c.Properties.View.Enabled { 41 | v := c.Properties.View 42 | app.RegisterView(iris.HTML(v.ResourcePath, v.Extension)) 43 | 44 | route := app.Get(v.ContextPath, Handler(func(ctx context.Context) { 45 | ctx.View(v.DefaultPage) 46 | })) 47 | route.MainHandlerName = fmt.Sprintf("%s%s ", v.ContextPath, v.DefaultPage) 48 | log.Infof("Mapped \"%v\" onto %v", v.ContextPath, v.DefaultPage) 49 | } 50 | return 51 | } 52 | -------------------------------------------------------------------------------- /pkg/app/web/context/context.go: -------------------------------------------------------------------------------- 1 | package context 2 | 3 | import ( 4 | "net/http" 5 | 6 | "github.com/hidevopsio/iris" 7 | "github.com/hidevopsio/iris/context" 8 | ) 9 | 10 | // ExtendedContext extended context 11 | type ExtendedContext interface { 12 | ResponseString(s string) 13 | ResponseBody(message string, data interface{}) 14 | ResponseError(message string, code int) 15 | WrapHandler(h http.Handler) 16 | SetAnnotations(ann interface{}) 17 | SetURLParam(name, value string) 18 | Annotations() interface{} 19 | InitResponses() 20 | SetResponse(idx int, response interface{}) 21 | GetResponses() (responses []interface{}) 22 | GetResponse(idx int) (response interface{}) 23 | //StaticResource(system http.FileSystem) 24 | } 25 | 26 | // Context is the interface of web app context 27 | type Context interface { 28 | context.Context 29 | ExtendedContext 30 | } 31 | 32 | // Handler is the handler func type (for Middleware) 33 | type Handler func(Context) 34 | 35 | // NewHandler will convert iris handler to our handler of func(*Context), 36 | // in order to be compatible with the HTTP API. 37 | func NewHandler(h iris.Handler) Handler { 38 | return func(ctx Context) { 39 | h(ctx.(context.Context)) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /pkg/app/web/context_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package web 16 | -------------------------------------------------------------------------------- /pkg/app/web/controller.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package web 16 | 17 | import ( 18 | "github.com/hidevopsio/hiboot/pkg/at" 19 | ) 20 | 21 | // Controller is the web base controller 22 | // please use at.RestController instead 23 | type Controller struct { 24 | at.RestController 25 | } 26 | -------------------------------------------------------------------------------- /pkg/app/web/defaultconfig.go: -------------------------------------------------------------------------------- 1 | package web 2 | 3 | import "github.com/hidevopsio/iris" 4 | 5 | // DefaultConfiguration returns the default configuration for an iris station, fills the main Configuration 6 | func defaultConfiguration() iris.Configuration { 7 | return iris.Configuration{ 8 | DisableStartupLog: true, 9 | DisableInterruptHandler: false, 10 | DisablePathCorrection: false, 11 | EnablePathEscape: false, 12 | FireMethodNotAllowed: false, 13 | DisableBodyConsumptionOnUnmarshal: false, 14 | DisableAutoFireStatusCode: false, 15 | TimeFormat: "Mon, Jan 02 2006 15:04:05 GMT", 16 | Charset: "UTF-8", 17 | 18 | // PostMaxMemory is for post body max memory. 19 | // 20 | // The request body the size limit 21 | // can be set by the middleware `LimitRequestBodySize` 22 | // or `context#SetMaxRequestBodySize`. 23 | PostMaxMemory: 32 << 20, // 32MB 24 | TranslateFunctionContextKey: "app.translate", 25 | TranslateLanguageContextKey: "app.language", 26 | ViewLayoutContextKey: "app.viewLayout", 27 | ViewDataContextKey: "app.viewData", 28 | RemoteAddrHeaders: make(map[string]bool), 29 | EnableOptimizations: false, 30 | Other: make(map[string]interface{}), 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /pkg/app/web/defaultconfig_test.go: -------------------------------------------------------------------------------- 1 | package web 2 | 3 | import ( 4 | "github.com/stretchr/testify/assert" 5 | "testing" 6 | ) 7 | 8 | func TestDefaultConfiguration(t *testing.T) { 9 | dc := defaultConfiguration() 10 | assert.Equal(t, "UTF-8", dc.Charset) 11 | } 12 | -------------------------------------------------------------------------------- /pkg/app/web/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | /* 16 | Package web provides quick start framework for web application. 17 | 18 | Main features of Hiboot web application 19 | 20 | Web MVC (Model-View-Controller). 21 | 22 | Auto Configuration, pre-created instance with properties configs for dependency injection. 23 | 24 | Dependency injection with the struct tag `inject:""` or the constructor. 25 | 26 | Dependency injection in Go 27 | 28 | Dependency injection is a concept valid for any programming language. The general concept behind dependency injection is 29 | called Inversion of Control. According to this concept a struct should not configure its dependencies statically but 30 | should be configured from the outside. 31 | 32 | Dependency Injection design pattern allows us to remove the hard-coded dependencies and make our application loosely 33 | coupled, extendable and maintainable. 34 | 35 | A Go struct has a dependency on another struct, if it uses an instance of this struct. We call this a struct dependency. 36 | For example, a struct which accesses a user controller has a dependency on user service struct. 37 | 38 | Ideally Go struct should be as independent as possible from other Go struct. This increases the possibility of reusing 39 | these struct and to be able to test them independently from other struct. 40 | 41 | The following example shows a struct which has no hard dependencies. 42 | 43 | */ 44 | package web 45 | -------------------------------------------------------------------------------- /pkg/app/web/method_subscriber.go: -------------------------------------------------------------------------------- 1 | package web 2 | 3 | import "github.com/hidevopsio/hiboot/pkg/inject/annotation" 4 | 5 | // HttpMethodSubscriber 6 | type HttpMethodSubscriber interface { 7 | Subscribe(atController *annotation.Annotations, atMethod *annotation.Annotations) 8 | } -------------------------------------------------------------------------------- /pkg/app/web/properties.go: -------------------------------------------------------------------------------- 1 | package web 2 | 3 | import ( 4 | "github.com/hidevopsio/hiboot/pkg/app" 5 | "github.com/hidevopsio/hiboot/pkg/at" 6 | ) 7 | 8 | const ( 9 | // ViewEnabled is the property for enabling web view 10 | ViewEnabled = "web.view.enabled" 11 | // ContextPath is the property for setting web view context path 12 | ContextPath = "web.view.contextPath" 13 | // DefaultPage is the property for setting default page 14 | DefaultPage = "web.view.defaultPage" 15 | // ResourcePath is the property for setting resource path 16 | ResourcePath = "web.view.resourcePath" 17 | // Extension is the property for setting extension 18 | Extension = "web.view.extension" 19 | ) 20 | 21 | type view struct { 22 | // ViewEnabled is the property for enabling web view 23 | Enabled bool `json:"enabled"` 24 | // ContextPath is the property for setting web view context path 25 | ContextPath string `json:"context_path" default:"/"` 26 | // DefaultPage is the property for setting default page 27 | DefaultPage string `json:"default_page" default:"index.html"` 28 | // ResourcePath is the property for setting resource path 29 | ResourcePath string `json:"resource_path" default:"./static"` 30 | // Extension is the property for setting extension 31 | Extension string `json:"extension" default:".html"` 32 | } 33 | 34 | type properties struct { 35 | at.ConfigurationProperties `value:"web"` 36 | at.AutoWired 37 | 38 | // View is the properties for setting web view 39 | View view `json:"view"` 40 | } 41 | 42 | func init() { 43 | app.Register(new(properties)) 44 | } 45 | -------------------------------------------------------------------------------- /pkg/app/web/server/property.go: -------------------------------------------------------------------------------- 1 | package server 2 | 3 | const ( 4 | // ContextPath is the base path of application 5 | ContextPath = "server.context_path" 6 | 7 | // Host 8 | Host = "server.host" 9 | 10 | // Port 11 | Port = "server.port" 12 | 13 | // Schemes 14 | Schemes = "server.schemes" 15 | ) 16 | -------------------------------------------------------------------------------- /pkg/app/web/static/hello.txt: -------------------------------------------------------------------------------- 1 | Hello World 2 | 3 | -------------------------------------------------------------------------------- /pkg/app/web/static/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Hiboot Web Application Example 5 | 6 | 7 | 8 |

Hello, Hiboot

9 |

Hiboot Web Application Example

10 | 11 | 12 | -------------------------------------------------------------------------------- /pkg/app/web/statik/statik.go: -------------------------------------------------------------------------------- 1 | // Code generated by statik. DO NOT EDIT. 2 | 3 | // Package statik contains static assets. 4 | package statik 5 | 6 | import ( 7 | "github.com/rakyll/statik/fs" 8 | ) 9 | 10 | func init() { 11 | data := "PK\x03\x04\x14\x00\x08\x00\x08\x00\x8cX%O\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x00 \x00hello.txtUT\x05\x00\x01\xb8\xebp]\xf2H\xcd\xc9\xc9W\x08\xcf/\xcaI\xe1\xe2\x02\x04\x00\x00\xff\xffPK\x07\x08\xb4 d\x0b\x13\x00\x00\x00\x0d\x00\x00\x00PK\x03\x04\x14\x00\x08\x00\x08\x00r'\nO\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00 \x00index.htmlUT\x05\x00\x019ON]\x84\xce1\nB1\x10\x04\xd0~O1\x07\x10\xc2\xff\xf5\x12\xb0\x10\xfe\x0d\xac\x13\xff\xc2\x066n\x8a-\xf4\xf6\x12\xa2\xb5\xf5\xcc<\x865\xbae\"V)g&\x00\xe0ha\x92\x8fV\xdd\x03w\xa9\xb8\x8ea\xedQ\xa2\xf9\x13\xb7W\xe9\xc3\x84\xd3j\x11\xa7\xb5$\xae~\xbe\xbf\x82n\xf9\x103\xbf`)\x9ct\xfbE\xfb_Y\xf7\xc9.n\xfa\xf3\xe1'\x00\x00\xff\xffPK\x07\x08\xfe)|\x04m\x00\x00\x00\xa8\x00\x00\x00PK\x01\x02\x14\x03\x14\x00\x08\x00\x08\x00\x8cX%O\xb4 d\x0b\x13\x00\x00\x00\x0d\x00\x00\x00 \x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x00\x00\x00\x00hello.txtUT\x05\x00\x01\xb8\xebp]PK\x01\x02\x14\x03\x14\x00\x08\x00\x08\x00r'\nO\xfe)|\x04m\x00\x00\x00\xa8\x00\x00\x00\n\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81S\x00\x00\x00index.htmlUT\x05\x00\x019ON]PK\x05\x06\x00\x00\x00\x00\x02\x00\x02\x00\x81\x00\x00\x00\x01\x01\x00\x00\x00\x00" 12 | fs.Register(data) 13 | } 14 | -------------------------------------------------------------------------------- /pkg/app/web/webutils/utils.go: -------------------------------------------------------------------------------- 1 | package webutils 2 | 3 | import ( 4 | "github.com/hidevopsio/hiboot/pkg/at" 5 | "github.com/hidevopsio/hiboot/pkg/inject/annotation" 6 | ) 7 | 8 | func GetHttpMethod(atMethod *annotation.Annotations) (method string, path string) { 9 | // parse http method 10 | hma := annotation.Find(atMethod, at.HttpMethod{}) 11 | if hma != nil { 12 | hm := hma.Field.Value.Interface() 13 | switch hm.(type) { 14 | case at.GetMapping: 15 | httpMethod := hm.(at.GetMapping) 16 | method, path = httpMethod.AtMethod, httpMethod.AtValue 17 | case at.PostMapping: 18 | httpMethod := hm.(at.PostMapping) 19 | method, path = httpMethod.AtMethod, httpMethod.AtValue 20 | case at.PutMapping: 21 | httpMethod := hm.(at.PutMapping) 22 | method, path = httpMethod.AtMethod, httpMethod.AtValue 23 | case at.DeleteMapping: 24 | httpMethod := hm.(at.DeleteMapping) 25 | method, path = httpMethod.AtMethod, httpMethod.AtValue 26 | case at.PatchMapping: 27 | httpMethod := hm.(at.PatchMapping) 28 | method, path = httpMethod.AtMethod, httpMethod.AtValue 29 | case at.OptionsMapping: 30 | httpMethod := hm.(at.OptionsMapping) 31 | method, path = httpMethod.AtMethod, httpMethod.AtValue 32 | case at.AnyMapping: 33 | httpMethod := hm.(at.AnyMapping) 34 | method, path = httpMethod.AtMethod, httpMethod.AtValue 35 | case at.TraceMapping: 36 | httpMethod := hm.(at.TraceMapping) 37 | method, path = httpMethod.AtMethod, httpMethod.AtValue 38 | } 39 | } 40 | 41 | return 42 | } 43 | -------------------------------------------------------------------------------- /pkg/app/web/webutils/utils_test.go: -------------------------------------------------------------------------------- 1 | package webutils 2 | 3 | import ( 4 | "github.com/stretchr/testify/assert" 5 | "github.com/hidevopsio/hiboot/pkg/at" 6 | "github.com/hidevopsio/hiboot/pkg/inject/annotation" 7 | "github.com/hidevopsio/hiboot/pkg/log" 8 | "testing" 9 | ) 10 | 11 | func TestUtils(t *testing.T) { 12 | testData := []interface{}{ 13 | &struct{ at.GetMapping `value:"/"` }{}, 14 | &struct{ at.PostMapping `value:"/"` }{}, 15 | &struct{ at.PutMapping `value:"/"` }{}, 16 | &struct{ at.DeleteMapping `value:"/"` }{}, 17 | &struct{ at.PatchMapping `value:"/"` }{}, 18 | &struct{ at.OptionsMapping `value:"/"` }{}, 19 | &struct{ at.AnyMapping `value:"/"` }{}, 20 | &struct{ at.TraceMapping `value:"/"` }{}, 21 | } 22 | 23 | for _, a := range testData { 24 | ann := annotation.GetAnnotations(a) 25 | err := annotation.Inject(ann.Items[0]) 26 | assert.Equal(t, nil, err) 27 | assert.Equal(t, 1, len(ann.Items)) 28 | method, path := GetHttpMethod(ann) 29 | log.Debug(method) 30 | log.Debug(path) 31 | assert.Equal(t, "/", path) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /pkg/at/annotation.go: -------------------------------------------------------------------------------- 1 | package at 2 | 3 | // Annotation is an empty struct that indicates the struct as an annotation 4 | type Annotation struct { 5 | } 6 | 7 | // BaseAnnotation is the base of an annotation 8 | type BaseAnnotation struct { 9 | Annotation `json:"-"` 10 | 11 | AtValue string `json:"-" at:"value"` 12 | } 13 | -------------------------------------------------------------------------------- /pkg/at/application.go: -------------------------------------------------------------------------------- 1 | package at 2 | 3 | // HiBootApplication is the main entry point of the application 4 | type HiBootApplication struct { 5 | Annotation 6 | 7 | BaseAnnotation 8 | } 9 | -------------------------------------------------------------------------------- /pkg/at/authorization.go: -------------------------------------------------------------------------------- 1 | package at 2 | 3 | type Logical string 4 | 5 | const ( 6 | AND Logical = "and" 7 | OR Logical = "or" 8 | ) 9 | 10 | // RequiresLogical is the annotation that annotate the method for requires logical 11 | type RequiresLogical struct { 12 | Annotation 13 | 14 | BaseAnnotation 15 | 16 | // AtLogical is the logical operator, default value is 'and' 17 | AtLogical Logical `json:"-" at:"logical" logical:"and"` // default value is and 18 | } 19 | 20 | // RequiresAuthentication is the annotation that annotate the method for authorization 21 | type RequiresAuthentication struct { 22 | Annotation 23 | 24 | BaseAnnotation 25 | } 26 | 27 | 28 | // RequiresRoles is the annotation that annotate the method for requires roles 29 | type RequiresRoles struct { 30 | Annotation 31 | 32 | RequiresLogical 33 | } 34 | 35 | 36 | // RequiresPermissions is the annotation that annotate the method for requires permissions 37 | type RequiresPermissions struct { 38 | Annotation 39 | 40 | RequiresLogical 41 | 42 | // AtValues hold the permission values as an array, e.g. `values:"user:read,team:read"` 43 | AtValues []string `at:"values" json:"-"` 44 | 45 | // AtType is for data permission, user can specify his/her own type and then implement it in middleware, e.g. `type:"pagination"` 46 | AtType string `json:"-" at:"type"` 47 | 48 | // AtIn is the input field name of query parameters, e.g. `in:"page,per_page"`; page,per_page is the default values that indicate 49 | AtIn []string `json:"-" at:"in"` 50 | 51 | // AtOut is the output field name of query parameters, e.g. `out:"expr"` ; expr is the default value, it can be any query parameters field name 52 | AtOut []string `json:"-" at:"out"` 53 | } 54 | 55 | // RequiresUser is the annotation that annotate the method for requires users 56 | type RequiresUser struct { 57 | Annotation 58 | 59 | BaseAnnotation 60 | } 61 | 62 | 63 | // RequiresGuest is the annotation that annotate the method for requires guest 64 | type RequiresGuest struct { 65 | Annotation 66 | 67 | BaseAnnotation 68 | } 69 | 70 | -------------------------------------------------------------------------------- /pkg/at/component.go: -------------------------------------------------------------------------------- 1 | package at 2 | 3 | // Component is the annotation that the dependency is injected in app init. 4 | type Component struct { 5 | Annotation 6 | 7 | BaseAnnotation 8 | } 9 | 10 | // AutoWired is the annotation that auto inject instance to object 11 | type AutoWired struct { 12 | Annotation 13 | 14 | BaseAnnotation 15 | } 16 | -------------------------------------------------------------------------------- /pkg/at/conditional.go: -------------------------------------------------------------------------------- 1 | package at 2 | 3 | // Conditional check if the string value of any give condition of the struct 4 | // 5 | // type Example struct { 6 | // at.Conditional `value:"your-condition-express"` 7 | // 8 | // Name string 9 | // } 10 | type Conditional struct { 11 | Annotation 12 | 13 | BaseAnnotation 14 | } 15 | 16 | // ConditionalOnField annotation check if the string value of give fields of the struct 17 | // 18 | // type Example struct { 19 | // at.ConditionalOnField `value:"Namespace,Name"` 20 | // 21 | // Namespace string 22 | // Name string 23 | // } 24 | type ConditionalOnField struct { 25 | Annotation 26 | 27 | BaseAnnotation 28 | } 29 | -------------------------------------------------------------------------------- /pkg/at/configuration.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package at 16 | 17 | // AutoConfiguration is the annotation of auto configuration 18 | type AutoConfiguration struct { 19 | Annotation 20 | 21 | BaseAnnotation 22 | } 23 | 24 | // ConfigurationProperties is the annotation that annotate configuration properties 25 | type ConfigurationProperties struct { 26 | Annotation 27 | 28 | BaseAnnotation 29 | } 30 | 31 | type AllowNil struct { 32 | Annotation 33 | 34 | BaseAnnotation 35 | } 36 | -------------------------------------------------------------------------------- /pkg/at/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | //Package at provides annotations for struct, function, or method 16 | package at 17 | -------------------------------------------------------------------------------- /pkg/at/healthcheck.go: -------------------------------------------------------------------------------- 1 | package at 2 | 3 | // HealthCheckService is the annotation for health check service 4 | type HealthCheckService struct { 5 | Annotation 6 | 7 | BaseAnnotation 8 | } 9 | -------------------------------------------------------------------------------- /pkg/at/init.go: -------------------------------------------------------------------------------- 1 | package at 2 | 3 | // BeforeInit annotation in hiboot is used to init a func / method before the application is initialized 4 | // 5 | // type Example struct { 6 | // at.PostInit 7 | // ... 8 | // } 9 | // 10 | 11 | type BeforeInit struct { 12 | Annotation `json:"-"` 13 | 14 | BaseAnnotation 15 | } 16 | 17 | // AfterInit annotation in hiboot is used to init a func / method after the application is initialized 18 | // 19 | // type Example struct { 20 | // at.AfterInit 21 | // ... 22 | // } 23 | // 24 | 25 | type AfterInit struct { 26 | Annotation `json:"-"` 27 | 28 | BaseAnnotation 29 | } 30 | -------------------------------------------------------------------------------- /pkg/at/middleware.go: -------------------------------------------------------------------------------- 1 | package at 2 | 3 | // Middleware is the annotation that annotate the controller or method use middleware 4 | type Middleware struct { 5 | Annotation 6 | 7 | BaseAnnotation 8 | } 9 | 10 | // MiddlewareHandler is the annotation that annotate the controller or method use middleware 11 | type MiddlewareHandler struct { 12 | Annotation 13 | 14 | BaseAnnotation 15 | } 16 | 17 | // MiddlewarePostHandler is the annotation that annotate the controller or method use middleware 18 | type MiddlewarePostHandler struct { 19 | Annotation 20 | 21 | BaseAnnotation 22 | } 23 | 24 | // UseMiddleware is the annotation that that annotate the controller or method use middleware based on condition 25 | type UseMiddleware struct { 26 | Annotation 27 | 28 | Conditional 29 | } 30 | 31 | // UseJwt 32 | type UseJwt struct { 33 | Annotation 34 | 35 | UseMiddleware 36 | } -------------------------------------------------------------------------------- /pkg/at/qualifier.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package at 16 | 17 | // Qualifier is the annotation that used for disambiguate the references. 18 | type Qualifier struct { 19 | Annotation 20 | 21 | BaseAnnotation 22 | } 23 | -------------------------------------------------------------------------------- /pkg/at/qualifier_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package at 16 | 17 | import "testing" 18 | 19 | func TestDummy(t *testing.T) { 20 | 21 | } 22 | -------------------------------------------------------------------------------- /pkg/at/request.go: -------------------------------------------------------------------------------- 1 | package at 2 | 3 | // RequestBody the annotation RequestBody 4 | type RequestBody struct { 5 | Annotation 6 | 7 | BaseAnnotation 8 | } 9 | 10 | // RequestForm the annotation RequestForm 11 | type RequestForm struct{ 12 | Annotation 13 | 14 | BaseAnnotation 15 | } 16 | 17 | // RequestParams the annotation RequestParams 18 | type RequestParams struct { 19 | Annotation 20 | 21 | BaseAnnotation 22 | } 23 | 24 | // PathVariable the annotation PathVariable 25 | type PathVariable struct { 26 | Annotation 27 | 28 | BaseAnnotation 29 | } 30 | -------------------------------------------------------------------------------- /pkg/at/response.go: -------------------------------------------------------------------------------- 1 | package at 2 | 3 | // ResponseBody the annotation ResponseBody 4 | type ResponseBody struct { 5 | Annotation 6 | 7 | BaseAnnotation 8 | } 9 | 10 | // ResponseData the annotation ResponseData 11 | type ResponseData struct { 12 | Annotation 13 | 14 | BaseAnnotation 15 | } 16 | -------------------------------------------------------------------------------- /pkg/at/restcontroller_test.go: -------------------------------------------------------------------------------- 1 | package at 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | ) 8 | 9 | func TestRestControllerAnnotations(t *testing.T) { 10 | 11 | t.Run("should pass test for annotation RequestMapping", func(t *testing.T) { 12 | rm := RequestMapping{HttpMethod:HttpMethod{BaseAnnotation: BaseAnnotation{AtValue:"/foo"}}} 13 | 14 | assert.Equal(t, rm.BaseAnnotation.AtValue, "/foo") 15 | assert.Equal(t, rm, RequestMapping{HttpMethod:HttpMethod{BaseAnnotation: BaseAnnotation{AtValue:"/foo"}}}) 16 | }) 17 | 18 | } 19 | -------------------------------------------------------------------------------- /pkg/at/scheduler.go: -------------------------------------------------------------------------------- 1 | package at 2 | 3 | // EnableScheduling enables scheduling 4 | type EnableScheduling struct { 5 | Annotation 6 | 7 | BaseAnnotation 8 | } 9 | 10 | // Scheduled is the annotation that annotate for scheduler 11 | type Scheduled struct { 12 | Annotation 13 | 14 | BaseAnnotation 15 | 16 | // limit times 17 | AtLimit *int `at:"limit" json:"-"` 18 | 19 | // standard cron expressions 20 | AtCron *string `at:"cron" json:"-"` 21 | 22 | // number 23 | AtEvery *int `at:"every" json:"-"` 24 | // valid units are: milliseconds, seconds, minutes, hours, days, weeks, months 25 | AtUnit *string `at:"unit" json:"-"` 26 | // at 27 | AtTime *string `at:"time" json:"-"` 28 | 29 | // tag 30 | AtTag *string `at:"tag" json:"-"` 31 | 32 | // delay 33 | AtDelay *int64 `at:"delay" json:"-"` 34 | 35 | // sync 36 | AtSync *bool `at:"sync" json:"-"` 37 | } 38 | -------------------------------------------------------------------------------- /pkg/at/scope.go: -------------------------------------------------------------------------------- 1 | package at 2 | 3 | // Scope annotation in hiboot is used to define a prototype scope for an instance. In Hiboot, 4 | // an instance can have different scopes which determine the lifecycle and visibility of that 5 | // instance. The prototype scope means that a new instance of the object will be created every 6 | // time it is requested from the Hiboot container. 7 | // 8 | // type Example struct { 9 | // at.Scope `value:"singleton"` // singleton 10 | // ... 11 | // } 12 | // 13 | // type Example struct { 14 | // at.Scope `value:"prototype"` // prototype 15 | // ... 16 | // } 17 | 18 | type Scope struct { 19 | Annotation `json:"-"` 20 | 21 | BaseAnnotation 22 | } 23 | 24 | // ContextAware is the annotation that has the ability of a component to be 25 | // injected when method of Rest Controller is requested. 26 | // 27 | // type Example struct { 28 | // at.Scope `value:"request"` 29 | // ... 30 | // } 31 | // 32 | // Deprecated: use at.Scope `value:"request"` instead 33 | type ContextAware struct { 34 | Annotation 35 | 36 | Scope `value:"request"` 37 | } 38 | -------------------------------------------------------------------------------- /pkg/at/swagger_test.go: -------------------------------------------------------------------------------- 1 | package at_test 2 | 3 | import ( 4 | "encoding/json" 5 | "github.com/stretchr/testify/assert" 6 | "github.com/hidevopsio/hiboot/pkg/at" 7 | "testing" 8 | ) 9 | 10 | func TestMarshal(t *testing.T) { 11 | type Foo struct { 12 | at.Schema 13 | Name string `json:"name"` 14 | } 15 | 16 | foo := &Foo{ 17 | Name: "foo", 18 | } 19 | 20 | b, err := json.Marshal(foo) 21 | 22 | assert.Equal(t, nil, err) 23 | assert.Equal(t, `{"name":"foo"}`, string(b)) 24 | 25 | backFoo := &Foo{} 26 | 27 | err = json.Unmarshal(b, backFoo) 28 | assert.Equal(t, nil, err) 29 | assert.Equal(t, "foo", backFoo.Name) 30 | 31 | } -------------------------------------------------------------------------------- /pkg/at/tag.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018~now John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package at 15 | 16 | // Tag the annotation Tag, tell the injector that the struct implements a tag 17 | type Tag struct { 18 | Annotation 19 | 20 | BaseAnnotation 21 | } 22 | -------------------------------------------------------------------------------- /pkg/factory/depends/bar/configure.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Package bar is the test package for package depends 16 | package bar 17 | 18 | import "github.com/hidevopsio/hiboot/pkg/app" 19 | 20 | // Configuration foo.Configuration for test only 21 | type Configuration struct { 22 | app.Configuration 23 | } 24 | 25 | func NewConfiguration() *Configuration { 26 | return &Configuration{} 27 | } 28 | -------------------------------------------------------------------------------- /pkg/factory/depends/bar/configure_test.go: -------------------------------------------------------------------------------- 1 | package bar 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestDummy(t *testing.T) { 8 | } 9 | -------------------------------------------------------------------------------- /pkg/factory/depends/fake/configure.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Package fake is the test package for package depends 16 | package fake 17 | 18 | import ( 19 | "github.com/hidevopsio/hiboot/pkg/app" 20 | "github.com/hidevopsio/hiboot/pkg/factory/depends/bar" 21 | "github.com/hidevopsio/hiboot/pkg/factory/depends/foo" 22 | ) 23 | 24 | // Configuration fake.Configuration for test only 25 | type Configuration struct { 26 | app.Configuration 27 | 28 | fooCfg *foo.Configuration 29 | barCfg *bar.Configuration 30 | } 31 | 32 | func NewConfiguration(fooCfg *foo.Configuration, barCfg *bar.Configuration) *Configuration { 33 | return &Configuration{ 34 | fooCfg: fooCfg, 35 | barCfg: barCfg, 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /pkg/factory/depends/fake/configure_test.go: -------------------------------------------------------------------------------- 1 | package fake 2 | 3 | import "testing" 4 | 5 | func TestDummy(t *testing.T) { 6 | 7 | } 8 | -------------------------------------------------------------------------------- /pkg/factory/depends/foo/configure.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Package foo is the test package for package depends 16 | package foo 17 | 18 | import "github.com/hidevopsio/hiboot/pkg/app" 19 | 20 | // Configuration foo.Configuration for test only 21 | type Configuration struct { 22 | app.Configuration 23 | } 24 | 25 | // NewConfiguration is the constructor for foo.configuration 26 | func NewConfiguration() *Configuration { 27 | return new(Configuration) 28 | } 29 | -------------------------------------------------------------------------------- /pkg/factory/depends/foo/configure_test.go: -------------------------------------------------------------------------------- 1 | package foo 2 | 3 | import ( 4 | "github.com/stretchr/testify/assert" 5 | "testing" 6 | ) 7 | 8 | func TestDummy(t *testing.T) { 9 | c := NewConfiguration() 10 | assert.NotEqual(t, nil, c) 11 | } 12 | -------------------------------------------------------------------------------- /pkg/factory/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Package factory provides hiboot factory interface 16 | package factory 17 | -------------------------------------------------------------------------------- /pkg/factory/doc_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package factory_test 16 | -------------------------------------------------------------------------------- /pkg/factory/factory_test.go: -------------------------------------------------------------------------------- 1 | package factory 2 | 3 | import ( 4 | "github.com/stretchr/testify/assert" 5 | "testing" 6 | ) 7 | 8 | type config struct { 9 | Deps Deps 10 | } 11 | 12 | func (c *config) Hello() { 13 | 14 | } 15 | 16 | func TestFactory(t *testing.T) { 17 | 18 | } 19 | func TestDependencies(t *testing.T) { 20 | 21 | c := new(config) 22 | deps := []string{"world"} 23 | c.Deps.Set("Hello", deps) 24 | assert.Equal(t, deps, c.Deps.Get("Hello")) 25 | 26 | c.Deps.Set(c.Hello, deps) 27 | assert.Equal(t, deps, c.Deps.Get("Hello")) 28 | 29 | c.Deps.Set(nil, deps) 30 | var md interface{} 31 | md = NewMetaData(c) 32 | castedMd := CastMetaData(md) 33 | assert.Equal(t, md, castedMd) 34 | } 35 | -------------------------------------------------------------------------------- /pkg/factory/instantiate/instance.go: -------------------------------------------------------------------------------- 1 | package instantiate 2 | 3 | import ( 4 | "github.com/hidevopsio/hiboot/pkg/factory" 5 | "github.com/hidevopsio/hiboot/pkg/utils/cmap" 6 | ) 7 | 8 | type instance struct { 9 | instMap cmap.ConcurrentMap 10 | } 11 | 12 | func newInstanceContainer(instMap cmap.ConcurrentMap) factory.InstanceContainer { 13 | if instMap == nil { 14 | instMap = cmap.New() 15 | } 16 | return &instance{ 17 | instMap: instMap, 18 | } 19 | } 20 | 21 | // Get instanceContainer 22 | func (i *instance) Get(params ...interface{}) (retVal interface{}) { 23 | name, obj := factory.ParseParams(params...) 24 | 25 | // get from instanceContainer map if external instanceContainer map does not have it 26 | if md, ok := i.instMap.Get(name); ok { 27 | metaData := factory.CastMetaData(md) 28 | if metaData != nil { 29 | switch obj.(type) { 30 | case factory.MetaData: 31 | retVal = metaData 32 | default: 33 | // TODO: check if metaData.Instance is nil 34 | retVal = metaData.Instance 35 | } 36 | } 37 | } 38 | 39 | return 40 | } 41 | 42 | // Set save instanceContainer 43 | func (i *instance) Set(params ...interface{}) (err error) { 44 | name, inst := factory.ParseParams(params...) 45 | 46 | metaData := factory.CastMetaData(inst) 47 | if metaData == nil { 48 | metaData = factory.NewMetaData(inst) 49 | } 50 | 51 | _, ok := i.instMap.Get(name) 52 | if ok { 53 | //log.Debugf("instance %v already contains %v, you are trying to overwrite it with: %v", name, old, metaData) 54 | return 55 | } 56 | 57 | i.instMap.Set(name, metaData) 58 | return 59 | } 60 | 61 | // Items return map items 62 | func (i *instance) Items() map[string]interface{} { 63 | return i.instMap.Items() 64 | } 65 | -------------------------------------------------------------------------------- /pkg/inject/defaulttag.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package inject 16 | 17 | import ( 18 | "fmt" 19 | "github.com/hidevopsio/hiboot/pkg/at" 20 | "github.com/hidevopsio/hiboot/pkg/utils/str" 21 | "reflect" 22 | ) 23 | 24 | type defaultTag struct { 25 | at.Tag `value:"default"` 26 | BaseTag 27 | } 28 | 29 | //func init() { 30 | // AddTag(new(defaultTag)) 31 | //} 32 | 33 | func (t *defaultTag) Decode(object reflect.Value, field reflect.StructField, property string) (retVal interface{}) { 34 | tag, ok := field.Tag.Lookup(t.Tag.AtValue) 35 | if ok { 36 | //log.Debug(valueTag) 37 | 38 | // check if filed type is slice 39 | kind := field.Type.Kind() 40 | needConvert := true 41 | retVal = t.instantiateFactory.Replace(tag) 42 | switch kind { 43 | case reflect.Slice: 44 | typ := reflect.TypeOf(retVal) 45 | if retVal != tag { 46 | if typ.Kind() == reflect.Slice { 47 | needConvert = false 48 | } else if typ.Kind() == reflect.String { 49 | needConvert = false 50 | retVal = str.Convert(retVal.(string), kind) 51 | } 52 | } 53 | case reflect.String: 54 | needConvert = false 55 | } 56 | 57 | if needConvert { 58 | in := fmt.Sprintf("%v", retVal) 59 | retVal = str.Convert(in, kind) 60 | } 61 | 62 | if retVal != nil { 63 | t.instantiateFactory.SetDefaultProperty(property, retVal) 64 | } 65 | } 66 | return retVal 67 | } 68 | -------------------------------------------------------------------------------- /pkg/inject/tag_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package inject 16 | 17 | import ( 18 | "github.com/stretchr/testify/assert" 19 | "reflect" 20 | "testing" 21 | ) 22 | 23 | func TestTag(t *testing.T) { 24 | tag := new(BaseTag) 25 | 26 | t.Run("should get properties", func(t *testing.T) { 27 | p := tag.Properties() 28 | assert.NotEqual(t, nil, p) 29 | }) 30 | 31 | t.Run("should get check if it's singleton", func(t *testing.T) { 32 | s := tag.IsSingleton() 33 | assert.Equal(t, false, s) 34 | }) 35 | 36 | t.Run("should get properties", func(t *testing.T) { 37 | fakeObj := struct{ Name string }{} 38 | objVal := reflect.ValueOf(fakeObj) 39 | field := objVal.Type().Field(0) 40 | f := tag.Decode(objVal, field, "") 41 | assert.Equal(t, nil, f) 42 | }) 43 | } 44 | -------------------------------------------------------------------------------- /pkg/inject/valuetag.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package inject 16 | 17 | import ( 18 | "fmt" 19 | "github.com/hidevopsio/hiboot/pkg/at" 20 | "github.com/hidevopsio/hiboot/pkg/utils/str" 21 | "reflect" 22 | ) 23 | 24 | type valueTag struct { 25 | at.Tag `value:"value"` 26 | BaseTag 27 | } 28 | 29 | func init() { 30 | AddTag(new(valueTag)) 31 | } 32 | 33 | func (t *valueTag) Decode(object reflect.Value, field reflect.StructField, property string) (retVal interface{}) { 34 | tag, ok := field.Tag.Lookup(t.Tag.AtValue) 35 | if ok { 36 | //log.Debug(valueTag) 37 | 38 | // check if filed type is slice 39 | kind := field.Type.Kind() 40 | needConvert := true 41 | retVal = t.instantiateFactory.Replace(tag) 42 | switch kind { 43 | case reflect.Slice: 44 | if retVal != tag { 45 | needConvert = false 46 | } 47 | case reflect.String: 48 | needConvert = false 49 | } 50 | 51 | if needConvert { 52 | in := fmt.Sprintf("%v", retVal) 53 | retVal = str.Convert(in, kind) 54 | } 55 | } 56 | return retVal 57 | } 58 | -------------------------------------------------------------------------------- /pkg/log/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | /* 16 | Package log provides logging with level debug, info, warn, error, fatal. 17 | 18 | 19 | */ 20 | package log 21 | -------------------------------------------------------------------------------- /pkg/log/doc_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package log_test 16 | 17 | import "github.com/hidevopsio/hiboot/pkg/log" 18 | 19 | //This example shows the log usages 20 | func Example() { 21 | 22 | log.SetLevel(log.DebugLevel) 23 | 24 | log.Debug("this is debug prints") 25 | } 26 | -------------------------------------------------------------------------------- /pkg/model/data.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package model 16 | 17 | import "time" 18 | 19 | // BaseData specifies the base data fields for database models 20 | type BaseData struct { 21 | // IsDeleted for soft delete 22 | IsDeleted bool `json:"is_deleted,omitempty"` 23 | 24 | // CreatedAt data created time 25 | CreatedAt time.Time `json:"created_at,omitempty"` 26 | 27 | // UpdatedAt data updated time 28 | UpdatedAt time.Time `json:"updated_at,omitempty"` 29 | } -------------------------------------------------------------------------------- /pkg/model/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | /* 16 | Package model provides common request and response models. 17 | 18 | 19 | // UserRequest is the request body 20 | type UserRequest struct { 21 | model.RequestBody // annotation RequestBody 22 | Username string `validate:"required"` 23 | Password string `validate:"required"` 24 | } 25 | 26 | */ 27 | package model 28 | -------------------------------------------------------------------------------- /pkg/model/doc_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package model_test 16 | -------------------------------------------------------------------------------- /pkg/model/request.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package model 16 | 17 | import "github.com/hidevopsio/hiboot/pkg/at" 18 | 19 | var ( 20 | // RequestTypeBody means it is RequestBody 21 | RequestTypeBody = "RequestBody" 22 | // RequestTypeParams means it is RequestParams 23 | RequestTypeParams = "RequestParams" 24 | // RequestTypeForm means it is RequestForm 25 | RequestTypeForm = "RequestForm" 26 | // Context means it is Context 27 | Context = "Context" 28 | ) 29 | 30 | // RequestBody the annotation RequestBody 31 | type RequestBody struct{ 32 | at.RequestBody 33 | } 34 | 35 | // RequestForm the annotation RequestForm 36 | type RequestForm struct{ 37 | at.RequestForm 38 | } 39 | 40 | // RequestParams the annotation RequestParams 41 | type RequestParams struct{ 42 | at.RequestParams 43 | } 44 | 45 | // ListOptions specifies the optional parameters to various List methods that 46 | // support pagination. 47 | type ListOptions struct { 48 | // For paginated result sets, page of results to retrieve. 49 | Page int `url:"page,omitempty" json:"page,omitempty" validate:"min=1"` 50 | 51 | // For paginated result sets, the number of results to include per page. 52 | PerPage int `url:"per_page,omitempty" json:"per_page,omitempty" validate:"min=1"` 53 | } -------------------------------------------------------------------------------- /pkg/model/response_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package model_test 16 | 17 | 18 | import ( 19 | "github.com/stretchr/testify/assert" 20 | "github.com/hidevopsio/hiboot/pkg/model" 21 | "github.com/hidevopsio/hiboot/pkg/utils/reflector" 22 | "testing" 23 | ) 24 | 25 | func TestResponse(t *testing.T) { 26 | var response model.Response 27 | 28 | response = new(model.BaseResponse) 29 | 30 | response.SetCode(200) 31 | assert.Equal(t, 200, response.GetCode()) 32 | 33 | response.SetMessage("Hello world") 34 | assert.Equal(t, "Hello world", response.GetMessage()) 35 | 36 | response.SetData("example") 37 | assert.Equal(t, "example", response.GetData()) 38 | 39 | t.Run("should check implements specific interface", func(t *testing.T) { 40 | respInfo := new(model.BaseResponseInfo) 41 | ok := reflector.Implements(respInfo, new(model.ResponseInfo)) 42 | assert.True(t, ok) 43 | }) 44 | 45 | t.Run("should check implements specific interface", func(t *testing.T) { 46 | resp := new(model.BaseResponse) 47 | ok := reflector.Implements(resp, new(model.ResponseInfo)) 48 | assert.True(t, ok) 49 | }) 50 | 51 | t.Run("should check implements specific interface", func(t *testing.T) { 52 | resp := new(model.BaseResponseInfo) 53 | ok := reflector.Implements(resp, new(model.Response)) 54 | assert.False(t, ok) 55 | }) 56 | } 57 | -------------------------------------------------------------------------------- /pkg/starter/actuator/autoconfigure.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Package actuator provide the health check endpoint for web application 16 | package actuator 17 | 18 | import ( 19 | "github.com/hidevopsio/hiboot/pkg/app" 20 | "github.com/hidevopsio/hiboot/pkg/at" 21 | ) 22 | 23 | const ( 24 | // Profile is the profile of actuator, it should be as same as the package name 25 | Profile = "actuator" 26 | ) 27 | 28 | type properties struct { 29 | at.ConfigurationProperties `value:"actuator"` 30 | at.AutoWired 31 | } 32 | 33 | type configuration struct { 34 | at.AutoConfiguration 35 | 36 | Properties *properties 37 | } 38 | 39 | func newConfiguration() *configuration { 40 | return &configuration{} 41 | } 42 | 43 | func init() { 44 | app.Register(newConfiguration) 45 | } 46 | -------------------------------------------------------------------------------- /pkg/starter/actuator/autoconfigure_test.go: -------------------------------------------------------------------------------- 1 | package actuator 2 | 3 | import ( 4 | "github.com/stretchr/testify/assert" 5 | "testing" 6 | ) 7 | 8 | func TestConfiguration(t *testing.T) { 9 | c := newConfiguration() 10 | assert.NotEqual(t, nil, c) 11 | } 12 | -------------------------------------------------------------------------------- /pkg/starter/actuator/health_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package actuator 16 | 17 | import ( 18 | "github.com/hidevopsio/hiboot/pkg/app" 19 | "github.com/hidevopsio/hiboot/pkg/app/web" 20 | "github.com/hidevopsio/hiboot/pkg/at" 21 | "github.com/hidevopsio/hiboot/pkg/log" 22 | "github.com/hidevopsio/hiboot/pkg/starter/logging" 23 | "net/http" 24 | "testing" 25 | ) 26 | 27 | type fakeHealthCheckService struct { 28 | at.HealthCheckService 29 | } 30 | 31 | func (s *fakeHealthCheckService) Name() string { 32 | return "fake" 33 | } 34 | 35 | func (s *fakeHealthCheckService) Status() bool { 36 | return true 37 | } 38 | 39 | func newFakeHealthCheckService() HealthService { 40 | return &fakeHealthCheckService{} 41 | } 42 | 43 | func init() { 44 | app.Register(newFakeHealthCheckService) 45 | } 46 | 47 | func TestHealthController(t *testing.T) { 48 | log.SetLevel(logging.LevelDebug) 49 | web.RunTestApplication(t). 50 | Get("/health"). 51 | Expect().Status(http.StatusOK) 52 | } 53 | -------------------------------------------------------------------------------- /pkg/starter/cors/autoconfigure.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // package cors provides the hiboot starter for injectable jwt dependency 16 | package cors 17 | 18 | import ( 19 | "github.com/hidevopsio/hiboot/pkg/app" 20 | "github.com/hidevopsio/hiboot/pkg/app/web/context" 21 | "github.com/hidevopsio/hiboot/pkg/at" 22 | ) 23 | 24 | const ( 25 | // Profile is the profile of jwt, it should be as same as the package name 26 | Profile = "cors" 27 | ) 28 | 29 | type configuration struct { 30 | at.AutoConfiguration 31 | 32 | Properties *Properties 33 | } 34 | 35 | func init() { 36 | app.Register(newConfiguration) 37 | } 38 | 39 | func newConfiguration() *configuration { 40 | return &configuration{} 41 | } 42 | 43 | type Middleware struct { 44 | context.Handler 45 | } 46 | 47 | func (c *configuration) Middleware(applicationContext app.ApplicationContext) (mw *Middleware) { 48 | mw = new(Middleware) 49 | mw.Handler = NewMiddleware(c.Properties) 50 | applicationContext.Use(mw.Handler) 51 | return 52 | } 53 | -------------------------------------------------------------------------------- /pkg/starter/cors/autoconfigure_test.go: -------------------------------------------------------------------------------- 1 | package cors 2 | 3 | import ( 4 | "github.com/hidevopsio/hiboot/pkg/app" 5 | "github.com/hidevopsio/hiboot/pkg/app/web" 6 | "github.com/hidevopsio/hiboot/pkg/at" 7 | "github.com/stretchr/testify/assert" 8 | "testing" 9 | ) 10 | 11 | type FooController struct { 12 | at.RestController 13 | 14 | applicationContext app.ApplicationContext 15 | } 16 | 17 | func TestMyFunction(t *testing.T) { 18 | cfg := newConfiguration() 19 | assert.NotNil(t, cfg) 20 | 21 | testApp := web.NewTestApp(new(FooController)). 22 | Run(t) 23 | cfg.Properties = new(Properties) 24 | assert.NotNil(t, cfg.Middleware(testApp.(app.ApplicationContext))) 25 | } 26 | -------------------------------------------------------------------------------- /pkg/starter/cors/middleware.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package cors 16 | 17 | import ( 18 | "github.com/hidevopsio/hiboot/pkg/app/web/context" 19 | "github.com/hidevopsio/middleware/cors" 20 | ) 21 | 22 | // NewMiddleware 23 | func NewMiddleware(properties *Properties) (crs context.Handler) { 24 | 25 | options := cors.Options{ 26 | AllowedOrigins: properties.AllowedOrigins, 27 | AllowedHeaders: properties.AllowedHeaders, 28 | AllowedMethods: properties.AllowedMethods, 29 | ExposedHeaders: properties.ExposedHeaders, 30 | AllowCredentials: properties.AllowCredentials, 31 | Debug: properties.Debug, 32 | OptionsPassthrough: properties.OptionsPassthrough, 33 | MaxAge: properties.MaxAge, 34 | } 35 | 36 | crs = context.NewHandler(cors.New(options)) 37 | 38 | return 39 | } 40 | -------------------------------------------------------------------------------- /pkg/starter/doc_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package starter_test 16 | 17 | import ( 18 | "github.com/hidevopsio/hiboot/pkg/app" 19 | "os" 20 | ) 21 | 22 | //This example shows the guide to make customized auto configuration 23 | //for more details, see https://github.com/hidevopsio/hiboot-data/blob/master/starter/bolt/autoconfigure.go 24 | func Example() { 25 | } 26 | 27 | // properties 28 | type properties struct { 29 | Database string `json:"database" default:"hiboot.db"` 30 | Mode os.FileMode `json:"mode" default:"0600"` 31 | Timeout int64 `json:"timeout" default:"2"` 32 | } 33 | 34 | // declare boltConfiguration 35 | type boltConfiguration struct { 36 | app.Configuration 37 | // the properties member name must be Bolt if the mapstructure is bolt, 38 | // so that the reference can be parsed 39 | BoltProperties properties `mapstructure:"bolt"` 40 | } 41 | 42 | // BoltRepository 43 | type BoltRepository struct { 44 | } 45 | 46 | func init() { 47 | // register newBoltConfiguration as AutoConfiguration 48 | app.Register(newBoltConfiguration) 49 | } 50 | 51 | // boltConfiguration constructor 52 | func newBoltConfiguration() *boltConfiguration { 53 | return &boltConfiguration{} 54 | } 55 | 56 | func (c *boltConfiguration) BoltRepository() *BoltRepository { 57 | 58 | repo := &BoltRepository{} 59 | 60 | // config repo according to c.BoltProperties 61 | 62 | return repo 63 | } 64 | -------------------------------------------------------------------------------- /pkg/starter/jwt/autoconfigure_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package jwt 16 | 17 | import ( 18 | "github.com/stretchr/testify/assert" 19 | "github.com/hidevopsio/hiboot/pkg/log" 20 | "github.com/hidevopsio/hiboot/pkg/utils/io" 21 | "testing" 22 | "time" 23 | ) 24 | 25 | func init() { 26 | log.SetLevel(log.DebugLevel) 27 | io.EnsureWorkDir(1, "config/application.yml") 28 | } 29 | 30 | func TestAutoConfigure(t *testing.T) { 31 | t.Run("should create new jwt middleware", func(t *testing.T) { 32 | config := &configuration{ 33 | Properties: &Properties{ 34 | PrivateKeyPath: "config/ssl/app.rsa", 35 | PublicKeyPath: "config/ssl/app.rsa.pub", 36 | }, 37 | } 38 | 39 | token := config.Token() 40 | assert.NotEqual(t, nil, token) 41 | mw := config.Middleware(token.(*jwtToken)) 42 | assert.NotEqual(t, nil, mw) 43 | }) 44 | 45 | t.Run("should report if jwt ssl does not exist", func(t *testing.T) { 46 | config := &configuration{ 47 | Properties: &Properties{ 48 | PrivateKeyPath: "does-not-exist", 49 | PublicKeyPath: "does-not-exist", 50 | }, 51 | } 52 | 53 | token := config.Token().(*jwtToken) 54 | assert.Equal(t, false, token.jwtEnabled) 55 | 56 | err := token.Initialize(config.Properties) 57 | assert.NotEqual(t, nil, err) 58 | 59 | _, err = token.Generate(Map{ 60 | "username": "johndoe", 61 | "password": "PA$$W0RD", 62 | }, 10, time.Second) 63 | assert.NotEqual(t, nil, err) 64 | }) 65 | 66 | } 67 | -------------------------------------------------------------------------------- /pkg/starter/jwt/jwtmiddleware_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package jwt_test 16 | 17 | import ( 18 | "github.com/stretchr/testify/assert" 19 | "github.com/hidevopsio/hiboot/pkg/log" 20 | "github.com/hidevopsio/hiboot/pkg/starter/jwt" 21 | "testing" 22 | "time" 23 | ) 24 | 25 | type FakeContext struct { 26 | } 27 | 28 | func (c *FakeContext) Next() { 29 | log.Debug("FakeContext.Next()") 30 | } 31 | 32 | func (c *FakeContext) StopExecution() { 33 | log.Debug("FakeContext.Next()") 34 | } 35 | 36 | func init() { 37 | log.SetLevel(log.DebugLevel) 38 | } 39 | 40 | func TestCheckJWT(t *testing.T) { 41 | 42 | t.Run("should report error if jwt properties does not injected", func(t *testing.T) { 43 | 44 | jwtToken := jwt.NewJwtToken(&jwt.Properties{}) 45 | 46 | assert.Equal(t, nil, jwtToken) 47 | }) 48 | 49 | t.Run("should generate jwt token", func(t *testing.T) { 50 | 51 | jwtToken := jwt.NewJwtToken(&jwt.Properties{ 52 | PrivateKeyPath: "config/ssl/app.rsa", 53 | PublicKeyPath: "config/ssl/app.rsa.pub", 54 | }) 55 | 56 | token, err := jwtToken.Generate(jwt.Map{ 57 | "username": "johndoe", 58 | "password": "PA$$W0RD", 59 | }, 500, time.Millisecond) 60 | 61 | assert.Equal(t, nil, err) 62 | assert.NotEqual(t, nil, token) 63 | }) 64 | 65 | } 66 | -------------------------------------------------------------------------------- /pkg/starter/jwt/postProcessor.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package jwt 16 | 17 | import ( 18 | "github.com/hidevopsio/hiboot/pkg/app" 19 | "github.com/hidevopsio/hiboot/pkg/at" 20 | ) 21 | 22 | type postProcessor struct { 23 | applicationContext app.ApplicationContext 24 | jwtMiddleware *Middleware 25 | } 26 | 27 | func init() { 28 | // register postProcessor 29 | app.RegisterPostProcessor(newPostProcessor) 30 | } 31 | 32 | func newPostProcessor(applicationContext app.ApplicationContext, jwtMiddleware *Middleware) *postProcessor { 33 | return &postProcessor{ 34 | applicationContext: applicationContext, 35 | jwtMiddleware: jwtMiddleware, 36 | } 37 | } 38 | 39 | // AfterInitialization jwt post processing 40 | func (p *postProcessor) AfterInitialization() { 41 | //log.Debug("[jwt] AfterInitialization") 42 | 43 | // use jwt 44 | p.applicationContext.Use(p.jwtMiddleware.Serve) 45 | 46 | // finally register jwt controllers 47 | _ = p.applicationContext.RegisterController(at.JwtRestController{}) 48 | } 49 | -------------------------------------------------------------------------------- /pkg/starter/jwt/properties.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package jwt 16 | 17 | import "github.com/hidevopsio/hiboot/pkg/at" 18 | 19 | // Properties the jwt properties 20 | type Properties struct { 21 | at.ConfigurationProperties `value:"jwt"` 22 | at.AutoWired 23 | 24 | PrivateKeyPath string `json:"private_key_path" default:"config/ssl/app.rsa"` 25 | PublicKeyPath string `json:"public_key_path" default:"config/ssl/app.rsa.pub"` 26 | } 27 | -------------------------------------------------------------------------------- /pkg/starter/locale/autoconfigure_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package locale 16 | 17 | import ( 18 | "github.com/hidevopsio/hiboot/pkg/app/fake" 19 | "github.com/hidevopsio/hiboot/pkg/utils/io" 20 | "github.com/stretchr/testify/assert" 21 | "reflect" 22 | "testing" 23 | ) 24 | 25 | func TestConfiguration(t *testing.T) { 26 | c := newConfiguration(new(fake.ApplicationContext)) 27 | c.Properties = &properties{ 28 | Default: "en-US", 29 | URLParameter: "lang", 30 | LocalePath: "config/i18n/", 31 | } 32 | 33 | t.Run("should get nil handler", func(t *testing.T) { 34 | h := c.Handler() 35 | val := reflect.ValueOf(h) 36 | assert.Equal(t, true, val.IsNil()) 37 | }) 38 | 39 | t.Run("should get handler", func(t *testing.T) { 40 | io.EnsureWorkDir(1, "config/application.yml") 41 | h := c.Handler() 42 | val := reflect.ValueOf(h) 43 | assert.Equal(t, false, val.IsNil()) 44 | assert.IsType(t, reflect.Func, reflect.TypeOf(h).Kind()) 45 | }) 46 | } 47 | -------------------------------------------------------------------------------- /pkg/starter/locale/properties.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package locale 16 | 17 | import "github.com/hidevopsio/hiboot/pkg/at" 18 | 19 | type properties struct { 20 | at.ConfigurationProperties `value:"locale"` 21 | at.AutoWired 22 | 23 | Default string `json:"default" default:"en-US"` 24 | URLParameter string `json:"url_parameter" default:"lang"` 25 | LocalePath string `json:"locale_path" default:"config/i18n/"` 26 | } 27 | -------------------------------------------------------------------------------- /pkg/starter/logging/autoconfigure_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package logging 16 | 17 | import ( 18 | "github.com/stretchr/testify/assert" 19 | "github.com/hidevopsio/hiboot/pkg/app/fake" 20 | "github.com/hidevopsio/hiboot/pkg/utils/io" 21 | "reflect" 22 | "testing" 23 | ) 24 | 25 | func TestConfiguration(t *testing.T) { 26 | c := newConfiguration(new(fake.ApplicationContext)) 27 | c.Properties = &properties{ 28 | Level: "debug", 29 | } 30 | 31 | t.Run("should get nil handler", func(t *testing.T) { 32 | lh := c.LoggerHandler() 33 | assert.IsType(t, reflect.Func, reflect.TypeOf(lh).Kind()) 34 | }) 35 | 36 | t.Run("should get handler", func(t *testing.T) { 37 | io.EnsureWorkDir(1, "config/application.yml") 38 | c.LoggerHandler() 39 | }) 40 | } 41 | -------------------------------------------------------------------------------- /pkg/starter/logging/properties.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package logging 16 | 17 | import "github.com/hidevopsio/hiboot/pkg/at" 18 | 19 | // Properties is the logging properties 20 | type properties struct { 21 | at.ConfigurationProperties `value:"logging"` 22 | at.AutoWired 23 | 24 | Level string `json:"level" default:"info"` 25 | Status bool `json:"status" default:"true"` 26 | IP bool `json:"ip" default:"true"` 27 | Method bool `json:"method" default:"true"` 28 | Path bool `json:"path" default:"true"` 29 | Query bool `json:"query" default:"false"` 30 | Columns bool `json:"columns" default:"false"` 31 | ContextKeys []string `json:"context_keys" default:"logger_message"` 32 | HeaderKeys []string `json:"header_keys" default:"User-Agent"` 33 | } 34 | -------------------------------------------------------------------------------- /pkg/starter/swagger/autoconfigure.go: -------------------------------------------------------------------------------- 1 | package swagger 2 | 3 | 4 | import ( 5 | "github.com/hidevopsio/hiboot/pkg/app" 6 | "github.com/hidevopsio/hiboot/pkg/at" 7 | ) 8 | 9 | const ( 10 | // Profile is the configuration name "swagger" 11 | Profile = "swagger" 12 | ) 13 | 14 | type configuration struct { 15 | at.AutoConfiguration 16 | } 17 | 18 | func newConfiguration() *configuration { 19 | return &configuration{} 20 | } 21 | 22 | func init() { 23 | app.Register(newConfiguration) 24 | } 25 | 26 | func (c *configuration) Controller(builder *apiInfoBuilder) *controller { 27 | return newController(builder) 28 | } 29 | 30 | func (c *configuration) HttpMethodSubscriber(pathsBuilder *apiPathsBuilder) *httpMethodSubscriber { 31 | return newHttpMethodSubscriber(pathsBuilder) 32 | } 33 | 34 | func (c *configuration) ApiPathsBuilder(infoBuilder *apiInfoBuilder) *apiPathsBuilder { 35 | return newApiPathsBuilder(infoBuilder) 36 | } 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /pkg/starter/swagger/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 ~ now John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // package swagger auto serve open api doc with swagger 2.0 annotations 16 | package swagger 17 | 18 | /* 19 | 20 | // TODO: still need to use at.AutoConfiguration on swagger to be able to enable/disable it at runtime 21 | 22 | func init() { 23 | app.Register(swagger.OpenAPIDefinitionBuilder(). 24 | Version("1.0.0"). 25 | Title("HiBoot Swagger Demo Application - Greeting Server"). 26 | Description("Greeting Server is an application that demonstrate the usage of Swagger Annotations"). 27 | Schemes("http", "https"). 28 | Host("localhost:8080"). 29 | BasePath("/api/v1/greeting-server"), 30 | ) 31 | } 32 | 33 | */ -------------------------------------------------------------------------------- /pkg/starter/swagger/metohd_subscriber.go: -------------------------------------------------------------------------------- 1 | package swagger 2 | 3 | import ( 4 | "github.com/hidevopsio/hiboot/pkg/at" 5 | "github.com/hidevopsio/hiboot/pkg/inject/annotation" 6 | ) 7 | 8 | type HttpMethod interface { 9 | GetMethod() string 10 | GetPath() string 11 | } 12 | 13 | type httpMethodSubscriber struct { 14 | at.HttpMethodSubscriber `value:"swagger"` 15 | apiPathsBuilder *apiPathsBuilder 16 | } 17 | 18 | func newHttpMethodSubscriber(builder *apiPathsBuilder) *httpMethodSubscriber { 19 | return &httpMethodSubscriber{apiPathsBuilder: builder} 20 | } 21 | 22 | // TODO: use data instead of atController 23 | func (s *httpMethodSubscriber) Subscribe(atController *annotation.Annotations, atMethod *annotation.Annotations) { 24 | s.apiPathsBuilder.Build(atController, atMethod) 25 | } 26 | -------------------------------------------------------------------------------- /pkg/starter/websocket/connection.go: -------------------------------------------------------------------------------- 1 | package websocket 2 | 3 | import ( 4 | "github.com/hidevopsio/hiboot/pkg/at" 5 | "github.com/hidevopsio/hiboot/pkg/starter/websocket/ws" 6 | ) 7 | 8 | // Connection is the websocket connection 9 | type Connection struct { 10 | at.Scope `value:"request"` 11 | websocket.Connection 12 | } 13 | 14 | func newConnection(conn websocket.Connection) *Connection { 15 | return &Connection{Connection: conn} 16 | } 17 | -------------------------------------------------------------------------------- /pkg/starter/websocket/handler.go: -------------------------------------------------------------------------------- 1 | package websocket 2 | 3 | // Handler is the interface the websocket handler 4 | type Handler interface { 5 | OnMessage(data []byte) 6 | OnDisconnect() 7 | OnPing() 8 | OnPong() 9 | } 10 | 11 | // Register is the handler register 12 | type Register func(handler Handler, conn *Connection) 13 | 14 | // registerHandler is the handler for websocket 15 | func registerHandler(handler Handler, conn *Connection) { 16 | conn.OnMessage(handler.OnMessage) 17 | conn.OnPong(handler.OnPong) 18 | conn.OnPing(handler.OnPing) 19 | conn.OnDisconnect(handler.OnDisconnect) 20 | conn.Wait() 21 | } 22 | -------------------------------------------------------------------------------- /pkg/starter/websocket/ws/AUTHORS: -------------------------------------------------------------------------------- 1 | # NOTES: this package is coped form github.com/hidevopsio/iris 2 | # This is the official list of Iris Websocket authors for copyright 3 | # purposes. 4 | 5 | Gerasimos Maropoulos 6 | -------------------------------------------------------------------------------- /pkg/starter/websocket/ws/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017-2018 The Iris Websocket Authors. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | * Neither the name of Iris nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /pkg/starter/websocket/ws/emitter.go: -------------------------------------------------------------------------------- 1 | package websocket 2 | 3 | const ( 4 | // All is the string which the Emitter use to send a message to all. 5 | All = "" 6 | // Broadcast is the string which the Emitter use to send a message to all except this connection. 7 | Broadcast = ";to;all;except;me;" 8 | ) 9 | 10 | type ( 11 | // Emitter is the message/or/event manager 12 | Emitter interface { 13 | // EmitMessage sends a native websocket message 14 | EmitMessage([]byte) error 15 | // Emit sends a message on a particular event 16 | Emit(string, interface{}) error 17 | } 18 | 19 | emitter struct { 20 | conn *connection 21 | to string 22 | } 23 | ) 24 | 25 | var _ Emitter = &emitter{} 26 | 27 | func newEmitter(c *connection, to string) *emitter { 28 | return &emitter{conn: c, to: to} 29 | } 30 | 31 | func (e *emitter) EmitMessage(nativeMessage []byte) error { 32 | e.conn.server.emitMessage(e.conn.id, e.to, nativeMessage) 33 | return nil 34 | } 35 | 36 | func (e *emitter) Emit(event string, data interface{}) error { 37 | message, err := e.conn.server.messageSerializer.serialize(event, data) 38 | if err != nil { 39 | return err 40 | } 41 | e.EmitMessage(message) 42 | return nil 43 | } 44 | -------------------------------------------------------------------------------- /pkg/starter/websocket/ws/websocket.go: -------------------------------------------------------------------------------- 1 | /* 2 | Package websocket provides rich websocket support for the iris web framework. 3 | 4 | Source code and other details for the project are available at GitHub: 5 | 6 | https://github.com/hidevopsio/iris/tree/master/websocket 7 | 8 | Installation 9 | 10 | $ go get -u github.com/hidevopsio/iris/websocket 11 | 12 | Example code: 13 | 14 | package main 15 | 16 | import ( 17 | "fmt" 18 | 19 | "github.com/hidevopsio/iris" 20 | "github.com/hidevopsio/iris/context" 21 | 22 | "github.com/hidevopsio/iris/websocket" 23 | ) 24 | 25 | func main() { 26 | app := iris.New() 27 | 28 | app.Get("/", func(ctx context.Context) { 29 | ctx.ServeFile("websockets.html", false) 30 | }) 31 | 32 | setupWebsocket(app) 33 | 34 | // x2 35 | // http://localhost:8080 36 | // http://localhost:8080 37 | // write something, press submit, see the result. 38 | app.Run(iris.Addr(":8080")) 39 | } 40 | 41 | func setupWebsocket(app *iris.Application) { 42 | // create our echo websocket server 43 | ws := websocket.New(websocket.Config{ 44 | ReadBufferSize: 1024, 45 | WriteBufferSize: 1024, 46 | }) 47 | ws.OnConnection(handleConnection) 48 | 49 | // register the server's endpoint. 50 | // see the inline javascript code in the websockets.html, 51 | // this endpoint is used to connect to the server. 52 | app.Get("/echo", ws.Handler()) 53 | 54 | // serve the javascript built'n client-side library, 55 | // see websockets.html script tags, this path is used. 56 | app.Any("/iris-ws.js", func(ctx context.Context) { 57 | ctx.Write(websocket.ClientSource) 58 | }) 59 | } 60 | 61 | func handleConnection(c websocket.Connection) { 62 | // Read events from browser 63 | c.On("chat", func(msg string) { 64 | // Print the message to the console 65 | fmt.Printf("%s sent: %s\n", c.Context().RemoteAddr(), msg) 66 | // Write message back to the client message owner: 67 | // c.Emit("chat", msg) 68 | c.To(websocket.Broadcast).Emit("chat", msg) 69 | }) 70 | } 71 | */ 72 | package websocket 73 | -------------------------------------------------------------------------------- /pkg/system/autoconfigure.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package system 16 | 17 | import ( 18 | "github.com/hidevopsio/hiboot/pkg/at" 19 | ) 20 | 21 | // Configuration is the system configuration 22 | type Configuration struct { 23 | at.AutoConfiguration 24 | 25 | App *App 26 | Server *Server 27 | Logging *Logging 28 | } 29 | 30 | func NewConfiguration() *Configuration { 31 | return &Configuration{} 32 | } 33 | -------------------------------------------------------------------------------- /pkg/system/config/.yaml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hidevopsio/hiboot/22ce8a9ec8036736d752bf7b9984d8b344ed287c/pkg/system/config/.yaml -------------------------------------------------------------------------------- /pkg/system/config/application-dev.yml: -------------------------------------------------------------------------------- 1 | # config file for testing 2 | 3 | logging: 4 | level: debug 5 | 6 | mock: 7 | name: hiboot-mock-dev 8 | username: ${app.name}-user-dev 9 | 10 | star: 11 | name: Jupiter -------------------------------------------------------------------------------- /pkg/system/config/application-local.yml: -------------------------------------------------------------------------------- 1 | # config file for testing 2 | 3 | server: 4 | port: 8081 5 | 6 | logging: 7 | level: debug 8 | 9 | mock: 10 | name: hiboot-mock-local 11 | username: ${app.name}-user-local 12 | 13 | star: 14 | name: Mars -------------------------------------------------------------------------------- /pkg/system/config/application-mock.yml: -------------------------------------------------------------------------------- 1 | # config file for testing 2 | 3 | mock: 4 | name: ${app.name}-mock 5 | nickname: ${app.name}-mocking 6 | username: ${app.name}-user -------------------------------------------------------------------------------- /pkg/system/config/application.yml: -------------------------------------------------------------------------------- 1 | # default config file for testing 2 | # filename should be application.yml 3 | 4 | app: 5 | project: hidevopsio 6 | name: hiboot 7 | profiles: 8 | include: 9 | - mock 10 | - file 11 | 12 | logging: 13 | level: debug 14 | 15 | # added for test only 16 | fake: 17 | name: ${app.name} 18 | 19 | foo: foo name 20 | 21 | star: 22 | name: Earth 23 | system: solar -------------------------------------------------------------------------------- /pkg/system/config/dev/application-mars.yml: -------------------------------------------------------------------------------- 1 | # config file for testing 2 | # filename should be application.yml 3 | 4 | app: 5 | project: hidevopsio 6 | name: hiboot 7 | profiles: 8 | include: 9 | - foo 10 | 11 | star: 12 | name: Mars 13 | system: solar -------------------------------------------------------------------------------- /pkg/system/config/dummy.txt: -------------------------------------------------------------------------------- 1 | dummy txt file -------------------------------------------------------------------------------- /pkg/system/config/foo: -------------------------------------------------------------------------------- 1 | foo -------------------------------------------------------------------------------- /pkg/system/config/test-file.yml: -------------------------------------------------------------------------------- 1 | --- 2 | foo: foo name 3 | bar: bar name 4 | --- 5 | 6 | # test 7 | 8 | * test -------------------------------------------------------------------------------- /pkg/system/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | /* 16 | Package system provides system builder which response for properties dependency injection. 17 | 18 | The auto configuration composes properties object 19 | 20 | 21 | */ 22 | package system 23 | -------------------------------------------------------------------------------- /pkg/system/doc_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package system_test 16 | 17 | //This example shows how to use the system build 18 | func Example() { 19 | 20 | } 21 | -------------------------------------------------------------------------------- /pkg/system/env.go: -------------------------------------------------------------------------------- 1 | package system 2 | 3 | // Env is the name value pair of environment variable 4 | type Env struct { 5 | // env name 6 | Name string 7 | // env value 8 | Value string 9 | } 10 | -------------------------------------------------------------------------------- /pkg/system/errors.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package system 16 | 17 | import "fmt" 18 | 19 | // ErrInvalidController invalid controller 20 | type ErrInvalidController struct { 21 | Name string 22 | } 23 | 24 | func (e *ErrInvalidController) Error() string { 25 | // TODO: locale 26 | return fmt.Sprintf("%v must be derived from at.RestController", e.Name) 27 | } 28 | 29 | // ErrNotFound resource not found error 30 | type ErrNotFound struct { 31 | Name string 32 | } 33 | 34 | func (e *ErrNotFound) Error() string { 35 | // TODO: locale 36 | return fmt.Sprintf("%v is not found", e.Name) 37 | } 38 | -------------------------------------------------------------------------------- /pkg/system/errors_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package system 16 | 17 | import ( 18 | "github.com/stretchr/testify/assert" 19 | "testing" 20 | ) 21 | 22 | func TestInvalidControllerError(t *testing.T) { 23 | err := ErrInvalidController{Name: "TestController"} 24 | 25 | assert.Equal(t, "TestController must be derived from at.RestController", err.Error()) 26 | } 27 | 28 | func TestNotFoundError(t *testing.T) { 29 | err := ErrNotFound{Name: "TestObject"} 30 | 31 | assert.Equal(t, "TestObject is not found", err.Error()) 32 | } 33 | -------------------------------------------------------------------------------- /pkg/system/scheduler/scheduler_test.go: -------------------------------------------------------------------------------- 1 | package scheduler_test 2 | 3 | import ( 4 | "sync" 5 | "testing" 6 | "time" 7 | 8 | "github.com/hidevopsio/gocron" 9 | "github.com/hidevopsio/hiboot/pkg/at" 10 | "github.com/hidevopsio/hiboot/pkg/log" 11 | "github.com/hidevopsio/hiboot/pkg/system/scheduler" 12 | ) 13 | 14 | var waitGroup = sync.WaitGroup{} 15 | 16 | type myService struct { 17 | at.Scheduled `limit:"1" every:"1" unit:"seconds"` 18 | } 19 | 20 | func (s *myService) Run() { 21 | log.Info("Running Task") 22 | waitGroup.Done() 23 | } 24 | 25 | type myLimitService struct { 26 | at.Scheduled `limit:"2"` 27 | } 28 | 29 | func (s *myLimitService) Run() { 30 | log.Info("Running Task") 31 | waitGroup.Done() 32 | } 33 | 34 | func TestSchedulerService(t *testing.T) { 35 | svc := new(myService) 36 | waitGroup.Add(1) 37 | 38 | s := scheduler.NewScheduler() 39 | s.RunOnce(svc.Run) 40 | 41 | waitGroup.Wait() 42 | log.Info("Done") 43 | } 44 | 45 | func TestRunOnce(t *testing.T) { 46 | 47 | wg := sync.WaitGroup{} 48 | wg.Add(1) 49 | 50 | s := scheduler.NewScheduler() 51 | s.RunOnce(func() { 52 | wg.Done() 53 | log.Info("Running Task") 54 | }) 55 | 56 | wg.Wait() 57 | log.Info("Done") 58 | } 59 | 60 | 61 | func TestExampleJob_LimitRunsTo(t *testing.T) { 62 | count := 2 63 | wg := sync.WaitGroup{} 64 | wg.Add(count) 65 | s := gocron.NewScheduler(time.UTC) 66 | job, _ := s.Every(1).Second().Do(func() { 67 | wg.Done() 68 | log.Info("Running Task") 69 | }) 70 | job.LimitRunsTo(count) 71 | s.StartAsync() 72 | wg.Wait() 73 | } -------------------------------------------------------------------------------- /pkg/system/types/types_test.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import "testing" 4 | 5 | func TestDummy(t *testing.T) { 6 | 7 | } 8 | -------------------------------------------------------------------------------- /pkg/system/yaml.go: -------------------------------------------------------------------------------- 1 | package system 2 | 3 | import ( 4 | "bytes" 5 | "github.com/spf13/afero" 6 | "gopkg.in/yaml.v2" 7 | "strings" 8 | ) 9 | 10 | // ReadYamlFromFile read yaml from file directly 11 | func ReadYamlFromFile(file string) (prop map[string]interface{}, err error) { 12 | fs := afero.NewOsFs() 13 | var fb []byte 14 | fb, err = afero.ReadFile(fs, file) 15 | if err == nil { 16 | buf := new(bytes.Buffer) 17 | r := bytes.NewReader(fb) 18 | buf.ReadFrom(r) 19 | str := string(buf.Bytes()) 20 | s := strings.Split(str, "---") 21 | var src []byte 22 | if len(s) == 1 { 23 | src = buf.Bytes() 24 | } else { 25 | src = []byte(s[1]) 26 | } 27 | 28 | err = yaml.Unmarshal(src, &prop) 29 | } 30 | return 31 | } 32 | -------------------------------------------------------------------------------- /pkg/system/yaml_test.go: -------------------------------------------------------------------------------- 1 | package system 2 | 3 | import ( 4 | "github.com/stretchr/testify/assert" 5 | "testing" 6 | ) 7 | 8 | func TestReadYamlProperties(t *testing.T) { 9 | 10 | res, err := ReadYamlFromFile("config/test-file.yml") 11 | 12 | assert.Equal(t, nil, err) 13 | assert.Equal(t, "foo name", res["foo"]) 14 | 15 | res, err = ReadYamlFromFile("config/application.yml") 16 | 17 | assert.Equal(t, nil, err) 18 | assert.Equal(t, "foo name", res["foo"]) 19 | } 20 | -------------------------------------------------------------------------------- /pkg/types/reflect.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import "reflect" 4 | 5 | type ReflectObject struct { 6 | Interface interface{} 7 | Type reflect.Type 8 | Value reflect.Value 9 | } 10 | -------------------------------------------------------------------------------- /pkg/utils/crypto/aes/aes_test.go: -------------------------------------------------------------------------------- 1 | package aes 2 | 3 | import ( 4 | "crypto/aes" 5 | "fmt" 6 | "github.com/stretchr/testify/assert" 7 | "github.com/hidevopsio/hiboot/pkg/utils/crypto" 8 | "testing" 9 | ) 10 | 11 | func TestEncrypt(t *testing.T) { 12 | originalText := "encrypt this golang text" 13 | fmt.Println(originalText) 14 | key := []byte("example key 1234") 15 | 16 | // encrypt value to base64 17 | t.Run("should encrypt with aes protocol", func(t *testing.T) { 18 | cryptoText, err := Encrypt(key, originalText) 19 | assert.Equal(t, nil, err) 20 | assert.NotEqual(t, "", cryptoText) 21 | }) 22 | 23 | // encrypt base64 crypto to original value 24 | t.Run("should report to aes.KeySizeError(3) error", func(t *testing.T) { 25 | _, err := Encrypt([]byte("abc"), originalText) 26 | assert.Equal(t, aes.KeySizeError(3), err) 27 | }) 28 | 29 | // encrypt base64 crypto to original value 30 | t.Run("should decrypt with aes protocol", func(t *testing.T) { 31 | cryptoText, err := Encrypt(key, originalText) 32 | assert.Equal(t, nil, err) 33 | text, err := Decrypt(key, cryptoText) 34 | assert.Equal(t, nil, err) 35 | assert.Equal(t, originalText, text) 36 | }) 37 | 38 | t.Run("should decrypt with aes protocol", func(t *testing.T) { 39 | cryptoText, err := Encrypt(key, originalText) 40 | assert.Equal(t, nil, err) 41 | _, err = Decrypt(key[4:], cryptoText[40:]) 42 | assert.Equal(t, crypto.ErrCipherTooShort, err) 43 | }) 44 | 45 | // encrypt base64 crypto to original value 46 | t.Run("should decrypt with aes protocol", func(t *testing.T) { 47 | cryptoText, err := Encrypt(key, originalText) 48 | assert.Equal(t, nil, err) 49 | _, err = Decrypt([]byte("abc"), cryptoText) 50 | assert.Equal(t, aes.KeySizeError(3), err) 51 | }) 52 | } 53 | -------------------------------------------------------------------------------- /pkg/utils/crypto/base64/base64.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Package base64 provides base64 encryption/decryption utilities 16 | package base64 17 | 18 | import "encoding/base64" 19 | 20 | const ( 21 | base64Table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" 22 | ) 23 | 24 | var coder = base64.NewEncoding(base64Table) 25 | 26 | // EncodeToString encode src string to base64 format string 27 | func EncodeToString(src string) string { 28 | return coder.EncodeToString([]byte(src)) 29 | } 30 | 31 | // Encode encode src bytes to base64 format bytes 32 | func Encode(src []byte) (dst []byte) { 33 | dst = make([]byte, coder.EncodedLen(len(src))) 34 | coder.Encode(dst, src) 35 | return 36 | } 37 | 38 | // DecodeToString decode string from base64 string 39 | func DecodeToString(src string) (retVal string, err error) { 40 | retBytes, err := coder.DecodeString(src) 41 | retVal = string(retBytes) 42 | return 43 | } 44 | 45 | // Decode decode base64 bytes 46 | func Decode(src []byte) (dst []byte, err error) { 47 | size := coder.DecodedLen(len(src)) 48 | buf := make([]byte, size) 49 | _, err = coder.Decode(buf, src) 50 | dst = buf[:size-1] 51 | return 52 | } 53 | -------------------------------------------------------------------------------- /pkg/utils/crypto/base64/base64_test.go: -------------------------------------------------------------------------------- 1 | package base64 2 | 3 | import ( 4 | "github.com/stretchr/testify/assert" 5 | "github.com/hidevopsio/hiboot/pkg/log" 6 | "testing" 7 | ) 8 | 9 | func init() { 10 | log.SetLevel(log.DebugLevel) 11 | } 12 | 13 | func TestBase64String(t *testing.T) { 14 | src := "Hello world" 15 | str := EncodeToString(src) 16 | decoded, err := DecodeToString(str) 17 | assert.Equal(t, nil, err) 18 | log.Debugf("src: %v, base64: %v, decoded: %v", src, str, decoded) 19 | assert.Equal(t, src, decoded) 20 | } 21 | 22 | func TestBase64Bytes(t *testing.T) { 23 | src := []byte("Hello world") 24 | str := Encode(src) 25 | decoded, err := Decode(str) 26 | assert.Equal(t, nil, err) 27 | log.Debugf("src: %v, base64: %v, decoded: %v", src, str, decoded) 28 | assert.Equal(t, src, decoded) 29 | } 30 | -------------------------------------------------------------------------------- /pkg/utils/crypto/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Package crypto provides crypto encryption/decryption utilities 16 | package crypto 17 | -------------------------------------------------------------------------------- /pkg/utils/crypto/errors.go: -------------------------------------------------------------------------------- 1 | package crypto 2 | 3 | import "errors" 4 | 5 | var ( 6 | // ErrInvalidPublicKey invalid public key 7 | ErrInvalidPublicKey = errors.New("[crypto] invalid public key") 8 | // ErrInvalidPrivateKey invalid private key 9 | ErrInvalidPrivateKey = errors.New("[crypto] invalid private key") 10 | // ErrInvalidInput invalid input format 11 | ErrInvalidInput = errors.New("[crypto] invalid input format") 12 | // ErrCipherTooShort cipher text too short 13 | ErrCipherTooShort = errors.New("[crypto] cipher text too short") 14 | ) 15 | -------------------------------------------------------------------------------- /pkg/utils/crypto/errors_test.go: -------------------------------------------------------------------------------- 1 | package crypto 2 | 3 | import "testing" 4 | 5 | func TestDummy(t *testing.T) { 6 | 7 | } 8 | -------------------------------------------------------------------------------- /pkg/utils/crypto/md5/md5.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Package md5 provides md5 encryption utilities 16 | package md5 17 | 18 | import ( 19 | "crypto/md5" 20 | "encoding/hex" 21 | ) 22 | 23 | // Encrypt md5 encryption util 24 | func Encrypt(in string) (out string) { 25 | md5Ctx := md5.New() // md5 init 26 | n, err := md5Ctx.Write([]byte(in)) // md5 update 27 | if err == nil && n != 0 { 28 | cipherStr := md5Ctx.Sum(nil) // md5 final 29 | out = hex.EncodeToString(cipherStr) // hex digest 30 | } 31 | return 32 | } 33 | -------------------------------------------------------------------------------- /pkg/utils/crypto/md5/md5_test.go: -------------------------------------------------------------------------------- 1 | package md5 2 | 3 | import ( 4 | "github.com/stretchr/testify/assert" 5 | "testing" 6 | ) 7 | 8 | func TestMd5(t *testing.T) { 9 | src := "Hello world" 10 | str := Encrypt(src) 11 | assert.Equal(t, "3e25960a79dbc69b674cd4ec67a72c62", str) 12 | } 13 | -------------------------------------------------------------------------------- /pkg/utils/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | /* 16 | Package utils provides useful utilities 17 | 18 | 19 | 20 | */ 21 | package utils 22 | -------------------------------------------------------------------------------- /pkg/utils/doc_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package utils_test 16 | 17 | //This example shows how to use the utilities 18 | func Example() { 19 | 20 | } 21 | -------------------------------------------------------------------------------- /pkg/utils/gotest/gotest.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Package gotest provides function to check whether is running in go test mode. 16 | package gotest 17 | 18 | import ( 19 | "flag" 20 | "github.com/hidevopsio/hiboot/pkg/utils/str" 21 | "os" 22 | "strings" 23 | ) 24 | 25 | // IsRunning return true if the go test is running 26 | func IsRunning() (ok bool) { 27 | 28 | args := os.Args 29 | 30 | //log.Println("args: ", args) 31 | //log.Println("args[0]: ", args[0]) 32 | 33 | if str.InSlice("-test.v", args) || 34 | strings.Contains(args[0], ".test") { 35 | ok = true 36 | } 37 | return 38 | } 39 | 40 | // ParseArgs parse args 41 | func ParseArgs(args []string) { 42 | 43 | a := os.Args[1:] 44 | if args != nil { 45 | a = args 46 | } 47 | 48 | flag.CommandLine.Parse(a) 49 | } 50 | -------------------------------------------------------------------------------- /pkg/utils/gotest/gotest_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package gotest 16 | 17 | import ( 18 | "flag" 19 | "github.com/stretchr/testify/assert" 20 | "github.com/hidevopsio/hiboot/pkg/log" 21 | "testing" 22 | ) 23 | 24 | func init() { 25 | log.SetLevel(log.DebugLevel) 26 | } 27 | 28 | func TestIsRunning(t *testing.T) { 29 | isTestRunning := IsRunning() 30 | 31 | assert.Equal(t, true, isTestRunning) 32 | } 33 | 34 | func TestParseArgs(t *testing.T) { 35 | args := []string{"foo", "bar", "baz"} 36 | log.Debug(flag.Args()) 37 | ParseArgs(args) 38 | log.Debug(flag.Args()) 39 | } 40 | -------------------------------------------------------------------------------- /pkg/utils/idgen/idgen.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Package idgen provides unique id generation utilities that use twitter's snowflake algorithm 16 | package idgen 17 | 18 | import ( 19 | "bytes" 20 | "fmt" 21 | "github.com/sony/sonyflake" 22 | "net" 23 | "strconv" 24 | "strings" 25 | ) 26 | 27 | var sf *sonyflake.Sonyflake 28 | 29 | func init() { 30 | macAddr := getMacAddr() 31 | st := sonyflake.Settings{ 32 | MachineID: func() (uint16, error) { 33 | ma := strings.Split(macAddr, ":") 34 | mid, err := strconv.ParseInt(ma[0]+ma[1], 16, 64) 35 | return uint16(mid), err 36 | }, 37 | } 38 | sf = sonyflake.NewSonyflake(st) 39 | } 40 | 41 | func getMacAddr() (addr string) { 42 | interfaces, err := net.Interfaces() 43 | if err == nil { 44 | for _, i := range interfaces { 45 | if i.Flags&net.FlagUp != 0 && bytes.Compare(i.HardwareAddr, nil) != 0 { 46 | // Don't use random as we have a real address 47 | addr = i.HardwareAddr.String() 48 | break 49 | } 50 | } 51 | } 52 | return 53 | } 54 | 55 | // Next generates next id as an uint64 56 | func Next() (id uint64, err error) { 57 | var i uint64 58 | if sf != nil { 59 | i, err = sf.NextID() 60 | if err == nil { 61 | id = i 62 | } 63 | } 64 | return 65 | } 66 | 67 | // NextString generates next id as a string 68 | func NextString() (id string, err error) { 69 | var i uint64 70 | i, err = Next() 71 | if err == nil { 72 | id = fmt.Sprintf("%d", i) 73 | } 74 | return 75 | } 76 | -------------------------------------------------------------------------------- /pkg/utils/idgen/idgen_test.go: -------------------------------------------------------------------------------- 1 | package idgen 2 | 3 | import ( 4 | "strconv" 5 | "strings" 6 | "testing" 7 | 8 | "github.com/stretchr/testify/assert" 9 | "github.com/hidevopsio/hiboot/pkg/log" 10 | ) 11 | 12 | func TestNext(t *testing.T) { 13 | log.SetLevel(log.DebugLevel) 14 | 15 | t.Run("shoud parse mac address", func(t *testing.T) { 16 | ma := strings.Split("88:e9:fe:7a:86:a0", ":") 17 | tmp := ma[0] + ma[1] 18 | mid, err := strconv.ParseInt(tmp, 16, 64) 19 | assert.Equal(t, nil, err) 20 | assert.Equal(t, int64(35049), mid) 21 | }) 22 | 23 | t.Run("should generate id in uint", func(t *testing.T) { 24 | id, err := Next() 25 | assert.Equal(t, nil, err) 26 | log.Info(id) 27 | assert.NotEqual(t, 0, id) 28 | }) 29 | 30 | t.Run("should generate id in string", func(t *testing.T) { 31 | id, err := NextString() 32 | assert.Equal(t, nil, err) 33 | log.Info(id) 34 | assert.NotEqual(t, 0, id) 35 | }) 36 | 37 | } 38 | -------------------------------------------------------------------------------- /pkg/utils/reflector/tester/foo.go: -------------------------------------------------------------------------------- 1 | package tester 2 | 3 | // Foo is a test interface 4 | type Foo interface { 5 | } 6 | -------------------------------------------------------------------------------- /pkg/utils/reflector/tester/foo_test.go: -------------------------------------------------------------------------------- 1 | package tester 2 | 3 | import "testing" 4 | 5 | func TestDummy(t *testing.T) { 6 | 7 | } 8 | -------------------------------------------------------------------------------- /pkg/utils/sort/slice.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Package sort provides utility that sort slice by length 16 | package sort 17 | 18 | import ( 19 | "sort" 20 | ) 21 | 22 | type byLen []string 23 | 24 | // get slice length 25 | func (a byLen) Len() int { 26 | return len(a) 27 | } 28 | 29 | // Less check which element is less 30 | func (a byLen) Less(i, j int) bool { 31 | return len(a[i]) < len(a[j]) 32 | } 33 | 34 | // Swap swap elements 35 | func (a byLen) Swap(i, j int) { 36 | a[i], a[j] = a[j], a[i] 37 | } 38 | 39 | // ByLen sort by length 40 | func ByLen(s []string) { 41 | 42 | sort.Sort(byLen(s)) 43 | 44 | } 45 | -------------------------------------------------------------------------------- /pkg/utils/sort/slice_test.go: -------------------------------------------------------------------------------- 1 | package sort 2 | 3 | import ( 4 | "github.com/stretchr/testify/assert" 5 | "testing" 6 | ) 7 | 8 | func TestSortByLen(t *testing.T) { 9 | s := []string{"a", "bb", "ccc", "d", "ee", "fff"} 10 | sorted := []string{"a", "d", "bb", "ee", "ccc", "fff"} 11 | ByLen(s) 12 | assert.Equal(t, s, sorted) 13 | } 14 | -------------------------------------------------------------------------------- /pkg/utils/str/camel.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // copied from https://github.com/iancoleman/strcase 16 | 17 | package str 18 | 19 | import ( 20 | "strings" 21 | ) 22 | 23 | // Converts a string to CamelCase 24 | func toCamelInitCase(s string, initCase bool) string { 25 | s = addWordBoundariesToNumbers(s) 26 | s = strings.Trim(s, " ") 27 | n := "" 28 | capNext := initCase 29 | for _, v := range s { 30 | if v >= 'A' && v <= 'Z' { 31 | n += string(v) 32 | } 33 | if v >= '0' && v <= '9' { 34 | n += string(v) 35 | } 36 | if v >= 'a' && v <= 'z' { 37 | if capNext { 38 | n += strings.ToUpper(string(v)) 39 | } else { 40 | n += string(v) 41 | } 42 | } 43 | if v == '_' || v == ' ' || v == '-' { 44 | capNext = true 45 | } else { 46 | capNext = false 47 | } 48 | } 49 | return n 50 | } 51 | 52 | // ToCamel Converts a string to CamelCase 53 | func ToCamel(s string) string { 54 | return toCamelInitCase(s, true) 55 | } 56 | 57 | // ToLowerCamel converts a string to lowerCamelCase 58 | func ToLowerCamel(s string) string { 59 | if s == "" { 60 | return s 61 | } 62 | if r := rune(s[0]); r >= 'A' && r <= 'Z' { 63 | s = strings.ToLower(string(r)) + s[1:] 64 | } 65 | return toCamelInitCase(s, false) 66 | } 67 | -------------------------------------------------------------------------------- /pkg/utils/str/camel_test.go: -------------------------------------------------------------------------------- 1 | package str 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestToCamel(t *testing.T) { 8 | cases := [][]string{ 9 | {"test_case", "TestCase"}, 10 | {"test", "Test"}, 11 | {"TestCase", "TestCase"}, 12 | {" test case ", "TestCase"}, 13 | {"", ""}, 14 | {"many_many_words", "ManyManyWords"}, 15 | {"AnyKind of_string", "AnyKindOfString"}, 16 | {"odd-fix", "OddFix"}, 17 | {"numbers2And55with000", "Numbers2And55With000"}, 18 | } 19 | for _, i := range cases { 20 | in := i[0] 21 | out := i[1] 22 | result := ToCamel(in) 23 | if result != out { 24 | t.Error("'" + result + "' != '" + out + "'") 25 | } 26 | } 27 | } 28 | 29 | func TestToLowerCamel(t *testing.T) { 30 | cases := [][]string{ 31 | {"foo-bar", "fooBar"}, 32 | {"TestCase", "testCase"}, 33 | {"", ""}, 34 | {"AnyKind of_string", "anyKindOfString"}, 35 | } 36 | for _, i := range cases { 37 | in := i[0] 38 | out := i[1] 39 | result := ToLowerCamel(in) 40 | if result != out { 41 | t.Error("'" + result + "' != '" + out + "'") 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /pkg/utils/str/number.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // copied from https://github.com/iancoleman/strcase 16 | 17 | package str 18 | 19 | import ( 20 | "regexp" 21 | ) 22 | 23 | var numberSequence = regexp.MustCompile(`([a-zA-Z])(\d+)([a-zA-Z]?)`) 24 | var numberReplacement = []byte(`$1 $2 $3`) 25 | 26 | func addWordBoundariesToNumbers(s string) string { 27 | b := []byte(s) 28 | b = numberSequence.ReplaceAll(b, numberReplacement) 29 | return string(b) 30 | } 31 | -------------------------------------------------------------------------------- /pkg/utils/validator/validator.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 John Deng (hi.devops.io@gmail.com). 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Package validator provides data validation utilities 16 | package validator 17 | 18 | import ( 19 | "github.com/go-playground/validator/v10" 20 | ) 21 | 22 | // Validate is the instance of the validator 23 | var Validate *validator.Validate 24 | 25 | func init() { 26 | Validate = validator.New() 27 | } 28 | -------------------------------------------------------------------------------- /static/hello.txt: -------------------------------------------------------------------------------- 1 | Hello World 2 | 3 | -------------------------------------------------------------------------------- /static/img/hiboot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hidevopsio/hiboot/22ce8a9ec8036736d752bf7b9984d8b344ed287c/static/img/hiboot.png -------------------------------------------------------------------------------- /static/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Hiboot Web Application Example 5 | 6 | 7 | 8 |

Hello, Hiboot

9 |

Hiboot Web Application Example

10 | 11 | 12 | --------------------------------------------------------------------------------