├── golang-async-logging-library
├── .dockerignore
├── go.mod
├── Dockerfile
├── .gitattributes
├── README.md
├── .gitignore
├── cmd
│ └── main.go
└── module3_test.go
├── gostandard_libs
├── filemaker_demo
│ ├── filetotest.txt
│ ├── go.mod
│ └── main.go
├── args_demo
│ ├── go.mod
│ └── main.go
├── flag_demo
│ ├── go.mod
│ └── main.go
├── fmt_demo
│ ├── go.mod
│ └── main.go
├── bufio_demo
│ ├── go.mod
│ └── main.go
├── custom_type
│ ├── go.mod
│ ├── createtype.go
│ ├── customtype.go
│ ├── typesruntime.go
│ ├── functions.go
│ └── media
│ │ └── media.go
├── loger_demo
│ ├── go.mod
│ ├── log.txt
│ ├── newlog.txt
│ ├── newloger.go
│ └── main.go
├── print_demo
│ ├── go.mod
│ └── main.go
├── trace_demo
│ ├── go.mod
│ └── main.go
├── others_demo
│ ├── slice.go
│ └── primitives.go
└── time_demo
│ └── main.go
├── testinggolang
├── go.mod
├── main_test.go
├── messages
│ ├── message.go
│ └── message_test.go
└── README.md
├── microservices
├── product-api
│ ├── README.md
│ ├── go.mod
│ ├── go.sum
│ ├── main.go
│ ├── data
│ │ └── products.go
│ └── handlers
│ │ └── handlers.go
├── product-api-withswagger
│ ├── handlers
│ │ ├── utils.go
│ │ ├── post.go
│ │ ├── put.go
│ │ ├── delete.go
│ │ ├── middleware.go
│ │ ├── products.go
│ │ ├── get.go
│ │ └── docs.go
│ ├── .vscode
│ │ └── settings.json
│ ├── swagger.bat
│ ├── make.bat
│ ├── data
│ │ ├── json.go
│ │ ├── product_test.go
│ │ ├── validation.go
│ │ └── products.go
│ ├── Makefile
│ ├── README.md
│ ├── go.mod
│ └── main.go
├── .vscode
│ └── settings.json
├── product-api-gorilla
│ ├── swagger.bat
│ ├── make.bat
│ ├── data
│ │ ├── product_test.go
│ │ └── products.go
│ ├── Makefile
│ ├── swagger.yaml
│ ├── handlers
│ │ ├── docs.go
│ │ └── handlers.go
│ ├── go.mod
│ ├── README.md
│ └── main.go
└── product-api-withswagger-client
│ ├── client.bat
│ ├── main_test.go
│ ├── go.mod
│ ├── models
│ └── generic_error.go
│ └── client
│ └── products
│ ├── delete_product_responses.go
│ ├── list_products_responses.go
│ └── list_single_product_responses.go
├── pluralsight_projects
├── golang-advanced-branching
│ ├── .dockerignore
│ ├── go.mod
│ ├── Dockerfile
│ ├── .gitattributes
│ ├── feedback.json
│ └── .gitignore
├── golang-personal-budget-cli
│ ├── go.mod
│ ├── module1
│ │ └── budget_1.go
│ ├── Dockerfile
│ ├── README.md
│ ├── main.go
│ └── module2
│ │ └── budget_2.go
└── golang-fifa-world-cup-web-service
│ ├── go.mod
│ ├── .vscode
│ └── settings.json
│ ├── Dockerfile
│ ├── server.go
│ ├── handlers
│ ├── handlers_test_helpers.go
│ ├── 03_dispatch_handler_test.go
│ ├── handlers.go
│ └── 02_post_handler_test.go
│ ├── Makefile
│ ├── README.md
│ └── data
│ └── winners.json
├── grpcdemo
├── Makefile
├── cert
│ ├── client-ext.cnf
│ ├── server-ext.cnf
│ └── generate_cert.sh
├── .vscode
│ └── settings.json
├── client
│ ├── Penguins.jpg
│ ├── go.mod
│ └── Dockerfile
├── server
│ ├── go.mod
│ ├── Dockerfile
│ └── data.go
├── pb
│ └── messages.proto
└── README.md
├── pingpong
├── README.md
├── go.mod
└── main.go
├── distributedappdocker
├── .dockerignore
├── go.mod
├── teacherportal
│ ├── templates.go
│ ├── students.gohtml
│ └── student.gohtml
├── Dockerfile.logservice
├── registry
│ └── registration.go
├── Dockerfile.gradingservice
├── Dockerfile.registryservice
├── Dockerfile.teacherportalservice
├── log
│ ├── client.go
│ └── server.go
├── cmd
│ ├── registryservice
│ │ └── main.go
│ ├── logservice
│ │ └── main.go
│ ├── gradingservice
│ │ └── main.go
│ └── teacherportalservice
│ │ └── main.go
├── grades
│ ├── grades.go
│ ├── mockdata.go
│ └── server.go
├── Readme.md
└── service
│ └── service.go
├── functions
├── go.mod
└── simplemaths
│ ├── expressions.go
│ └── scemanticversion.go
├── webservice
├── go.mod
├── controllers
│ ├── front.go
│ └── user.go
├── main.go
└── models
│ └── user.go
├── distributedapp
├── go.mod
├── teacherportal
│ ├── templates.go
│ ├── students.gohtml
│ └── student.gohtml
├── Readme.md
├── registry
│ └── registration.go
├── cmd
│ ├── registryservice
│ │ └── main.go
│ ├── logservice
│ │ └── main.go
│ ├── gradingservice
│ │ └── main.go
│ └── teacherportalservice
│ │ └── main.go
├── log
│ ├── client.go
│ └── server.go
├── grades
│ ├── grades.go
│ ├── mockdata.go
│ └── server.go
└── service
│ └── service.go
├── concurrentprogram
├── go.mod
├── ChannelDemo
│ └── main.go
└── books
│ └── book.go
├── customdatatypes
├── datatypes1
│ ├── go.mod
│ ├── main.go
│ └── organisation
│ │ └── person.go
├── datatypes2
│ ├── go.mod
│ ├── main.go
│ └── organisation
│ │ └── person.go
├── datatypes3
│ ├── go.mod
│ ├── main.go
│ └── organisation
│ │ └── person.go
├── datatypes4
│ ├── go.mod
│ ├── main.go
│ └── organisation
│ │ └── person.go
└── datatypes5
│ ├── go.mod
│ ├── main.go
│ └── organisation
│ └── person.go
├── ginframeworkdemo
├── Readme.md
├── requestdemo
│ ├── public
│ │ ├── app.css
│ │ ├── index.html
│ │ └── employee.html
│ └── go.mod
├── vacationtracker
│ ├── public
│ │ ├── app.css
│ │ ├── index.html
│ │ └── employee.html
│ ├── cmd
│ │ └── vacationtrack
│ │ │ └── main_test.go
│ ├── templates
│ │ ├── index.tmpl
│ │ └── employee.tmpl
│ ├── go.mod
│ └── employee
│ │ ├── employee.go
│ │ └── data.go
└── responsedemo
│ ├── index.html
│ ├── go.mod
│ └── main.go
├── .vscode
└── settings.json
├── .gitignore
├── LICENSE
└── README.md
/golang-async-logging-library/.dockerignore:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/gostandard_libs/filemaker_demo/filetotest.txt:
--------------------------------------------------------------------------------
1 | Hello
2 | hi
--------------------------------------------------------------------------------
/testinggolang/go.mod:
--------------------------------------------------------------------------------
1 | module gotesting
2 |
3 | go 1.17
4 |
--------------------------------------------------------------------------------
/golang-async-logging-library/go.mod:
--------------------------------------------------------------------------------
1 | module alog
2 |
3 | go 1.14
4 |
--------------------------------------------------------------------------------
/microservices/product-api/README.md:
--------------------------------------------------------------------------------
1 | ### Product API Standard Library
--------------------------------------------------------------------------------
/pluralsight_projects/golang-advanced-branching/.dockerignore:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/grpcdemo/Makefile:
--------------------------------------------------------------------------------
1 | cert:
2 | cd cert; ./generate_cert.sh;cd ..
3 | .PHONY: cert
--------------------------------------------------------------------------------
/microservices/product-api-withswagger/handlers/utils.go:
--------------------------------------------------------------------------------
1 | package handlers
2 |
--------------------------------------------------------------------------------
/pingpong/README.md:
--------------------------------------------------------------------------------
1 | ### A ping pong application using Goroutine and Channels.
--------------------------------------------------------------------------------
/distributedappdocker/.dockerignore:
--------------------------------------------------------------------------------
1 | #Removing exe file copy built locally.
2 | *.exe
3 | *.md
--------------------------------------------------------------------------------
/functions/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/erankitcs/golang_learning/functions
2 |
3 | go 1.17
4 |
--------------------------------------------------------------------------------
/pingpong/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/erankitcs/golang_learning/pingpong
2 |
3 | go 1.17
4 |
--------------------------------------------------------------------------------
/webservice/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/erankitcs/golang_learning/webservice
2 |
3 | go 1.17
4 |
--------------------------------------------------------------------------------
/microservices/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "makefile.extensionOutputFolder": "./.vscode"
3 | }
--------------------------------------------------------------------------------
/pluralsight_projects/golang-advanced-branching/go.mod:
--------------------------------------------------------------------------------
1 | module vehicle-rating
2 |
3 | go 1.13
4 |
--------------------------------------------------------------------------------
/pluralsight_projects/golang-personal-budget-cli/go.mod:
--------------------------------------------------------------------------------
1 | module personal-budget
2 |
3 | go 1.13
4 |
--------------------------------------------------------------------------------
/distributedapp/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/erankitcs/golang_learning/distributedapp
2 |
3 | go 1.17
4 |
--------------------------------------------------------------------------------
/grpcdemo/cert/client-ext.cnf:
--------------------------------------------------------------------------------
1 | subjectAltName=DNS:*.gogrpcclient.com,IP:0.0.0.0,IP:172.0.0.1,DNS:localhost
--------------------------------------------------------------------------------
/grpcdemo/cert/server-ext.cnf:
--------------------------------------------------------------------------------
1 | subjectAltName=DNS:*.gogrpcserver.com,IP:0.0.0.0,IP:127.0.0.1,DNS:localhost
--------------------------------------------------------------------------------
/concurrentprogram/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/erankitcs/golang_learning/concurrentprogram
2 |
3 | go 1.17
4 |
--------------------------------------------------------------------------------
/distributedappdocker/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/erankitcs/golang_learning/distributedapp
2 |
3 | go 1.17
4 |
--------------------------------------------------------------------------------
/grpcdemo/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "go.formatTool": "goimports",
3 | "editor.formatOnSave": true
4 | }
--------------------------------------------------------------------------------
/grpcdemo/client/Penguins.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/erankitcs/golang_learning/HEAD/grpcdemo/client/Penguins.jpg
--------------------------------------------------------------------------------
/gostandard_libs/args_demo/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/erankitcs/golang_learning/gostandard_libs/args_demo
2 |
3 | go 1.17
4 |
--------------------------------------------------------------------------------
/gostandard_libs/flag_demo/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/erankitcs/golang_learning/gostandard_libs/flag_demo
2 |
3 | go 1.17
4 |
--------------------------------------------------------------------------------
/gostandard_libs/fmt_demo/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/erankitcs/golang_learning/gostandard_libs/fmt_demo
2 |
3 | go 1.17
4 |
--------------------------------------------------------------------------------
/microservices/product-api-withswagger/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "makefile.extensionOutputFolder": "./.vscode"
3 | }
--------------------------------------------------------------------------------
/pluralsight_projects/golang-fifa-world-cup-web-service/go.mod:
--------------------------------------------------------------------------------
1 | module golang-fifa-world-cup-web-service
2 |
3 | go 1.13
4 |
--------------------------------------------------------------------------------
/customdatatypes/datatypes1/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/erankitcs/golang_learning/customdatatypes/datatypes1
2 |
3 | go 1.17
4 |
--------------------------------------------------------------------------------
/customdatatypes/datatypes2/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/erankitcs/golang_learning/customdatatypes/datatypes2
2 |
3 | go 1.17
4 |
--------------------------------------------------------------------------------
/customdatatypes/datatypes3/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/erankitcs/golang_learning/customdatatypes/datatypes3
2 |
3 | go 1.17
4 |
--------------------------------------------------------------------------------
/customdatatypes/datatypes4/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/erankitcs/golang_learning/customdatatypes/datatypes4
2 |
3 | go 1.17
4 |
--------------------------------------------------------------------------------
/customdatatypes/datatypes5/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/erankitcs/golang_learning/customdatatypes/datatypes5
2 |
3 | go 1.17
4 |
--------------------------------------------------------------------------------
/gostandard_libs/bufio_demo/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/erankitcs/golang_learning/gostandard_libs/bufio_demo
2 |
3 | go 1.17
4 |
--------------------------------------------------------------------------------
/gostandard_libs/custom_type/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/erankitcs/golang_learning/gostandard_libs/custom_type
2 |
3 | go 1.17
4 |
--------------------------------------------------------------------------------
/gostandard_libs/loger_demo/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/erankitcs/golang_learning/gostandard_libs/loger_demo
2 |
3 | go 1.17
4 |
--------------------------------------------------------------------------------
/gostandard_libs/print_demo/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/erankitcs/golang_learning/gostandard_libs/print_demo
2 |
3 | go 1.17
4 |
--------------------------------------------------------------------------------
/gostandard_libs/trace_demo/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/erankitcs/golang_learning/gostandard_libs/trace_demo
2 |
3 | go 1.17
4 |
--------------------------------------------------------------------------------
/microservices/product-api/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/erankitcs/golang_learning/microservices/product-api
2 |
3 | go 1.17
4 |
5 |
--------------------------------------------------------------------------------
/gostandard_libs/filemaker_demo/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/erankitcs/golang_learning/gostandard_libs/filemaker_demo
2 |
3 | go 1.17
4 |
--------------------------------------------------------------------------------
/ginframeworkdemo/Readme.md:
--------------------------------------------------------------------------------
1 | ## Working with Gin Framework
2 |
3 | ### Installing Gin
4 | ```
5 | go get -u github.com/gin-gonic/gin
6 | ```
--------------------------------------------------------------------------------
/pluralsight_projects/golang-fifa-world-cup-web-service/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "makefile.extensionOutputFolder": "./.vscode"
3 | }
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "go.toolsEnvVars": {
3 | "GOROOT": "C:\\Program Files\\Go"
4 | },
5 | "go.alternateTools": {
6 | }
7 | }
--------------------------------------------------------------------------------
/microservices/product-api-gorilla/swagger.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 | echo.
3 | docker run --rm -it --env GOPATH=/go -v %CD%:/go/src -w /go/src quay.io/goswagger/swagger generate spec -o ./swagger.yaml --scan-models
--------------------------------------------------------------------------------
/microservices/product-api-withswagger/swagger.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 | echo.
3 | docker run --rm -it --env GOPATH=/go -v %CD%:/go/src -w /go/src quay.io/goswagger/swagger generate spec -o ./swagger.yaml --scan-models
--------------------------------------------------------------------------------
/gostandard_libs/others_demo/slice.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "reflect"
6 | )
7 |
8 | func main() {
9 |
10 | v := reflect.TypeOf(123)
11 | fmt.Println(reflect.SliceOf(v))
12 | }
13 |
--------------------------------------------------------------------------------
/microservices/product-api-gorilla/make.bat:
--------------------------------------------------------------------------------
1 | @ECHO off
2 | WHERE /q swagger
3 | IF %ERRORLEVEL% NEQ 0 go get -u github.com/go-swagger/go-swagger/cmd/swagger
4 |
5 | swagger generate spec -o ./swagger.yaml --scan-models
--------------------------------------------------------------------------------
/microservices/product-api-withswagger/make.bat:
--------------------------------------------------------------------------------
1 | @ECHO off
2 | WHERE /q swagger
3 | IF %ERRORLEVEL% NEQ 0 go get -u github.com/go-swagger/go-swagger/cmd/swagger
4 |
5 | swagger generate spec -o ./swagger.yaml --scan-models
--------------------------------------------------------------------------------
/testinggolang/main_test.go:
--------------------------------------------------------------------------------
1 | package main_test
2 |
3 | import (
4 | "testing"
5 | )
6 |
7 | func TestAddition(t *testing.T) {
8 | got := 2 + 3
9 | expected := 4
10 | if got != expected {
11 | t.Errorf("Did not get expected result.")
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/testinggolang/messages/message.go:
--------------------------------------------------------------------------------
1 | package messages
2 |
3 | import "fmt"
4 |
5 | func Greet(name string) string {
6 | return fmt.Sprintf("Hello, %v!", name)
7 | }
8 |
9 | func depart(name string) string {
10 | return fmt.Sprintf("Goodbye, %v", name)
11 | }
12 |
--------------------------------------------------------------------------------
/gostandard_libs/loger_demo/log.txt:
--------------------------------------------------------------------------------
1 | INFO: 2022/04/09 17:51:50 main.go:37: this is an information message!
2 | WARNING: 2022/04/09 17:51:50 main.go:40: this is a warning
3 | ERROR: 2022/04/09 17:51:50 main.go:43: this is an error
4 | FATAL: 2022/04/09 17:51:50 main.go:46: we crashed
5 |
--------------------------------------------------------------------------------
/ginframeworkdemo/requestdemo/public/app.css:
--------------------------------------------------------------------------------
1 | body {
2 | width: 600px;
3 | }
4 | table {
5 | border-collapse: collapse;
6 | }
7 |
8 | tr > :is(th, td) {
9 | border: 1px solid black;
10 | padding: 5px;
11 | }
12 |
13 | tr > :is(th, td):not(:first-child) {
14 | text-align: center;
15 | }
--------------------------------------------------------------------------------
/ginframeworkdemo/vacationtracker/public/app.css:
--------------------------------------------------------------------------------
1 | body {
2 | width: 600px;
3 | }
4 | table {
5 | border-collapse: collapse;
6 | }
7 |
8 | tr > :is(th, td) {
9 | border: 1px solid black;
10 | padding: 5px;
11 | }
12 |
13 | tr > :is(th, td):not(:first-child) {
14 | text-align: center;
15 | }
--------------------------------------------------------------------------------
/pluralsight_projects/golang-personal-budget-cli/module1/budget_1.go:
--------------------------------------------------------------------------------
1 | package module1
2 |
3 | // Budget stores budget information
4 | type Budget struct {
5 | Max float32
6 | Items []Item
7 | }
8 |
9 | // Item stores item information
10 | type Item struct {
11 | Description string
12 | Price float32
13 | }
14 |
--------------------------------------------------------------------------------
/golang-async-logging-library/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM golang:1.14.0
2 |
3 | ENV CGO_ENABLED 0
4 |
5 | WORKDIR /src/app
6 |
7 | RUN addgroup --system projects && adduser --system projects --ingroup projects
8 |
9 | RUN chown -R projects:projects /src/app
10 |
11 | USER projects
12 |
13 | COPY . .
14 |
15 | RUN go install -v ./...
16 |
--------------------------------------------------------------------------------
/microservices/product-api-gorilla/data/product_test.go:
--------------------------------------------------------------------------------
1 | package data
2 |
3 | import "testing"
4 |
5 | func TestProductValidate(t *testing.T) {
6 | p := &Product{
7 | Name: "Tea",
8 | Price: 1.00,
9 | SKU: "sss-vggvgv-vttv",
10 | }
11 | err := p.Validate()
12 | if err != nil {
13 | t.Fatal(err)
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/gostandard_libs/loger_demo/newlog.txt:
--------------------------------------------------------------------------------
1 | INFO: 07:58:18.785601 D:/Tech/GoLang/golang_learning/gostandard_libs/loger_demo/newloger.go:30: This is info
2 | WARNING: 2022/04/09 17:58:18 newloger.go:31: This is warning.
3 | ERROR: 2022/04/09 17:58:18 newloger.go:32: This is error
4 | FATAL: 2022/04/09 17:58:18 newloger.go:33: This is fetal error.
5 |
--------------------------------------------------------------------------------
/microservices/product-api-withswagger-client/client.bat:
--------------------------------------------------------------------------------
1 | @ECHO off
2 | WHERE /q swagger
3 | IF %ERRORLEVEL% NEQ 0 go get -u github.com/go-swagger/go-swagger/cmd/swagger
4 | go mod init github.com/erankitcs/golang_learning/microservices/productapiclient
5 | swagger generate client -f ./../product-api-withswagger/swagger.yaml -A productapi
6 | go mod tidy
--------------------------------------------------------------------------------
/pluralsight_projects/golang-advanced-branching/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM golang:1.13.0
2 |
3 | ENV CGO_ENABLED 0
4 |
5 | WORKDIR /src/app
6 |
7 | RUN addgroup --system projects && adduser --system projects --ingroup projects
8 |
9 | RUN chown -R projects:projects /src/app
10 |
11 | USER projects
12 |
13 | COPY . .
14 |
15 | RUN go install -v ./...
16 |
--------------------------------------------------------------------------------
/pluralsight_projects/golang-personal-budget-cli/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM golang:1.13
2 |
3 | ENV CGO_ENABLED 0
4 |
5 | WORKDIR /src/app
6 |
7 | RUN addgroup --system projects && adduser --system projects --ingroup projects
8 |
9 | RUN chown -R projects:projects /src/app
10 |
11 | USER projects
12 |
13 | COPY . .
14 |
15 | RUN go install -v ./...
16 |
--------------------------------------------------------------------------------
/pluralsight_projects/golang-fifa-world-cup-web-service/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM golang:1.13
2 |
3 | ENV CGO_ENABLED 0
4 |
5 | WORKDIR /src/app
6 |
7 | RUN addgroup --system projects && adduser --system projects --ingroup projects
8 |
9 | RUN chown -R projects:projects /src/app
10 |
11 | USER projects
12 |
13 | COPY . .
14 |
15 | RUN go install -v ./...
16 |
--------------------------------------------------------------------------------
/golang-async-logging-library/.gitattributes:
--------------------------------------------------------------------------------
1 | # From https://help.github.com/en/articles/configuring-git-to-handle-line-endings
2 | # Set the default behavior, in case people don't have core.autocrlf set.
3 | * text=auto
4 |
5 | # Explicitly declare text files you want to always be normalized and converted
6 | # to native line endings on checkout.
7 | *.go text
8 |
9 |
--------------------------------------------------------------------------------
/microservices/product-api-withswagger/data/json.go:
--------------------------------------------------------------------------------
1 | package data
2 |
3 | import (
4 | "encoding/json"
5 | "io"
6 | )
7 |
8 | func ToJSON(i interface{}, w io.Writer) error {
9 | e := json.NewEncoder(w)
10 | return e.Encode(i)
11 | }
12 |
13 | func FromJSON(i interface{}, r io.Reader) error {
14 | e := json.NewDecoder(r)
15 | return e.Decode(i)
16 | }
17 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Binaries for programs and plugins
2 | *.exe
3 | *.exe~
4 | *.dll
5 | *.so
6 | *.dylib
7 |
8 | # Test binary, built with `go test -c`
9 | *.test
10 |
11 | # Output of the go coverage tool, specifically when used with LiteIDE
12 | *.out
13 |
14 | # Dependency directories (remove the comment below to include it)
15 | # vendor/
16 | *.log
17 | *.pem
18 | *.key
19 | *.srl
--------------------------------------------------------------------------------
/microservices/product-api-withswagger/data/product_test.go:
--------------------------------------------------------------------------------
1 | package data
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/stretchr/testify/assert"
7 | )
8 |
9 | func TestProductMissingNameReturnsErr(t *testing.T) {
10 | p := &Product{
11 | Price: 1.00,
12 | }
13 | //err := p.Validate()
14 | v := NewValidation()
15 | err := v.Validate(p)
16 | assert.Len(t, err, 1)
17 | }
18 |
--------------------------------------------------------------------------------
/webservice/controllers/front.go:
--------------------------------------------------------------------------------
1 | package controllers
2 |
3 | import (
4 | "encoding/json"
5 | "io"
6 | "net/http"
7 | )
8 |
9 | func RegisterControllers() {
10 | uc := newUserController()
11 | http.Handle("/users", *uc)
12 | http.Handle("/users/", *uc)
13 | }
14 |
15 | func encodeResponseAsJSON(data interface{}, w io.Writer) {
16 | enc := json.NewEncoder(w)
17 | enc.Encode(data)
18 | }
19 |
--------------------------------------------------------------------------------
/webservice/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "net/http"
5 |
6 | "github.com/erankitcs/golang_learning/webservice/controllers"
7 | )
8 |
9 | func main() {
10 | // u := models.User{
11 | // ID: 2,
12 | // FirstName: "Ankit",
13 | // LastName: "Singh",
14 | // }
15 | // fmt.Println(u)
16 | controllers.RegisterControllers()
17 | http.ListenAndServe(":3000", nil)
18 | }
19 |
--------------------------------------------------------------------------------
/gostandard_libs/bufio_demo/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "bufio"
5 | "fmt"
6 | "os"
7 | "runtime"
8 | )
9 |
10 | func main() {
11 | reader := bufio.NewReader(os.Stdin)
12 | fmt.Println("Wahts your name ?")
13 | text, _ := reader.ReadString('\n')
14 | fmt.Printf("Hello %v", text)
15 | fmt.Printf("We are using Go %v running in %v", runtime.Version(), runtime.GOOS)
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/distributedapp/teacherportal/templates.go:
--------------------------------------------------------------------------------
1 | package teacherportal
2 |
3 | import "html/template"
4 |
5 | var rootTemplate *template.Template
6 |
7 | func ImportTemplates() error {
8 | var err error
9 | rootTemplate, err = template.ParseFiles(
10 | "teacherportal/students.gohtml",
11 | "teacherportal/student.gohtml",
12 | )
13 | if err != nil {
14 | return err
15 | }
16 |
17 | return nil
18 | }
19 |
--------------------------------------------------------------------------------
/distributedappdocker/teacherportal/templates.go:
--------------------------------------------------------------------------------
1 | package teacherportal
2 |
3 | import "html/template"
4 |
5 | var rootTemplate *template.Template
6 |
7 | func ImportTemplates() error {
8 | var err error
9 | rootTemplate, err = template.ParseFiles(
10 | "teacherportal/students.gohtml",
11 | "teacherportal/student.gohtml",
12 | )
13 | if err != nil {
14 | return err
15 | }
16 |
17 | return nil
18 | }
19 |
--------------------------------------------------------------------------------
/microservices/product-api-gorilla/Makefile:
--------------------------------------------------------------------------------
1 | .DEFAULT_GOAL := swagger
2 |
3 | install_swagger:
4 | go get -u github.com/go-swagger/go-swagger/cmd/swagger
5 |
6 | swagger:
7 | @echo Ensure you have the swagger CLI or this command will fail.
8 | @echo You can install the swagger CLI with: go get -u github.com/go-swagger/go-swagger/cmd/swagger
9 | @echo ....
10 |
11 | swagger generate spec -o ./swagger.yaml --scan-models
--------------------------------------------------------------------------------
/pluralsight_projects/golang-fifa-world-cup-web-service/server.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "golang-fifa-world-cup-web-service/data"
5 | "golang-fifa-world-cup-web-service/handlers"
6 | "net/http"
7 | )
8 |
9 | func main() {
10 | data.PrintUsage()
11 |
12 | http.HandleFunc("/", handlers.RootHandler)
13 | http.HandleFunc("/winners", handlers.WinnersHandler)
14 | http.ListenAndServe(":8000", nil)
15 | }
16 |
--------------------------------------------------------------------------------
/microservices/product-api-withswagger/Makefile:
--------------------------------------------------------------------------------
1 | .DEFAULT_GOAL := swagger
2 |
3 | install_swagger:
4 | go get -u github.com/go-swagger/go-swagger/cmd/swagger
5 |
6 | swagger:
7 | @echo Ensure you have the swagger CLI or this command will fail.
8 | @echo You can install the swagger CLI with: go get -u github.com/go-swagger/go-swagger/cmd/swagger
9 | @echo ....
10 |
11 | swagger generate spec -o ./swagger.yaml --scan-models
--------------------------------------------------------------------------------
/pluralsight_projects/golang-fifa-world-cup-web-service/handlers/handlers_test_helpers.go:
--------------------------------------------------------------------------------
1 | package handlers
2 |
3 | import (
4 | "golang-fifa-world-cup-web-service/data"
5 | "path"
6 | "path/filepath"
7 | )
8 |
9 | // reloads JSON into memory to ensure
10 | // proper winner count during tests.
11 | func setup() {
12 | p, _ := filepath.Abs("./../data/")
13 | fullpath := path.Join(p, "winners.json")
14 | data.LoadFromJSON(fullpath)
15 | }
16 |
--------------------------------------------------------------------------------
/ginframeworkdemo/responsedemo/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Book list
8 |
9 |
10 | A Tale Of Two Cities
11 | Great Expectations
12 |
13 |
--------------------------------------------------------------------------------
/microservices/product-api/go.sum:
--------------------------------------------------------------------------------
1 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
2 | github.com/nicholasjackson/env v0.6.0 h1:6xdio52m7cKRtgZPER6NFeBZxicR88rx5a+5Jl4/qus=
3 | github.com/nicholasjackson/env v0.6.0/go.mod h1:/GtSb9a/BDUCLpcnpauN0d/Bw5ekSI1vLC1b9Lw0Vyk=
4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
5 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
6 |
--------------------------------------------------------------------------------
/gostandard_libs/flag_demo/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "flag"
5 | "fmt"
6 | )
7 |
8 | func main() {
9 | bitsStr := flag.String("arch", "x86", "CPU Arch")
10 | flag.Parse()
11 |
12 | switch *bitsStr {
13 | case "x86":
14 | {
15 | fmt.Println("running in 32 bit mode")
16 | }
17 | case "AMD64":
18 | {
19 | fmt.Println("Running in 64 bit mode")
20 | }
21 | case "IA64":
22 | {
23 | fmt.Println("Remember IA64?")
24 | }
25 |
26 | }
27 | fmt.Println("Ran our process!")
28 | }
29 |
--------------------------------------------------------------------------------
/microservices/product-api-gorilla/swagger.yaml:
--------------------------------------------------------------------------------
1 | basePath: /
2 | consumes:
3 | - application/json
4 | host: localhost
5 | info:
6 | contact:
7 | email: er.ankit.cs@gmail.com
8 | description: The purpose of this API is to provide list of products, add new product
9 | and update the existing product.
10 | license:
11 | name: MIT
12 | url: http://opensource.org/licenses/MIT
13 | title: API.
14 | version: 0.0.1
15 | paths: {}
16 | produces:
17 | - application/json
18 | schemes:
19 | - http
20 | swagger: "2.0"
21 |
--------------------------------------------------------------------------------
/grpcdemo/client/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/erankitcs/golang_learning/grpcdemo/client
2 |
3 | go 1.17
4 |
5 | require (
6 | google.golang.org/grpc v1.47.0
7 | google.golang.org/protobuf v1.28.0
8 | )
9 |
10 | require (
11 | github.com/golang/protobuf v1.5.2 // indirect
12 | golang.org/x/net v0.0.0-20201021035429-f5854403a974 // indirect
13 | golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4 // indirect
14 | golang.org/x/text v0.3.3 // indirect
15 | google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 // indirect
16 | )
17 |
--------------------------------------------------------------------------------
/grpcdemo/server/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/erankitcs/golang_learning/grpcdemo/server
2 |
3 | go 1.17
4 |
5 | require (
6 | google.golang.org/grpc v1.47.0
7 | google.golang.org/protobuf v1.28.0
8 | )
9 |
10 | require (
11 | github.com/golang/protobuf v1.5.2 // indirect
12 | golang.org/x/net v0.0.0-20201021035429-f5854403a974 // indirect
13 | golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4 // indirect
14 | golang.org/x/text v0.3.3 // indirect
15 | google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 // indirect
16 | )
17 |
--------------------------------------------------------------------------------
/customdatatypes/datatypes1/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/erankitcs/golang_learning/customdatatypes/datatypes1/organisation"
7 | )
8 |
9 | func main() {
10 | fmt.Println("Custom Type Demo 1")
11 | p := organisation.NewPerson("Ankit", "Singh")
12 | err := p.SetTwitterHandler("@ankit63")
13 | if err != nil {
14 | fmt.Printf("An error occurred while setting handler %s", err.Error())
15 | }
16 |
17 | fmt.Println(p.FullName())
18 | fmt.Println(p.TwitterHandler())
19 | fmt.Println(p.ID())
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/microservices/product-api-gorilla/handlers/docs.go:
--------------------------------------------------------------------------------
1 | // Package Product API.
2 | //
3 | // The purpose of this API is to provide list of products, add new product and update the existing product.
4 | // Schemes: http
5 | // Host: localhost
6 | // BasePath: /
7 | // Version: 0.0.1
8 | // License: MIT http://opensource.org/licenses/MIT
9 | // Contact: er.ankit.cs@gmail.com
10 | // Consumes:
11 | // - application/json
12 | //
13 | // Produces:
14 | // - application/json
15 | // swagger:meta
16 | package handlers
17 |
--------------------------------------------------------------------------------
/ginframeworkdemo/vacationtracker/cmd/vacationtrack/main_test.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "net/http"
5 | "net/http/httptest"
6 | "testing"
7 |
8 | "github.com/gin-gonic/gin"
9 | )
10 |
11 | func TestAPIEmployees(t *testing.T) {
12 | rec := httptest.NewRecorder()
13 | req := httptest.NewRequest(http.MethodGet, "/api/employees/", nil)
14 |
15 | r := gin.Default()
16 | registerRoutes(r)
17 |
18 | r.ServeHTTP(rec, req)
19 |
20 | res := rec.Result()
21 |
22 | if res.StatusCode != http.StatusOK {
23 | t.Fail()
24 | }
25 | t.Log(rec.Body.String())
26 | }
27 |
--------------------------------------------------------------------------------
/distributedapp/Readme.md:
--------------------------------------------------------------------------------
1 | ## Distributed Application in Golang ( A Teacher Portal)
2 |
3 | 1. Build and Start Registry service
4 | ```
5 | go build cmd\registryservice
6 | .\registryservice.exe
7 |
8 | ```
9 |
10 | 2. Build and Start Loggin service
11 | ```
12 | go build cmd\logservice
13 | .\logservice.exe
14 |
15 | ```
16 |
17 | 3. Build and Start Grading service
18 | ```
19 | go build cmd\gradingservice
20 | .\gradingservice.exe
21 |
22 | ```
23 |
24 | 4. Build and Start Teacher Portal
25 | ```
26 | go build cmd\teacherportalservice
27 | .\teacherportalservice.exe
28 |
29 | ```
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/pluralsight_projects/golang-advanced-branching/.gitattributes:
--------------------------------------------------------------------------------
1 | # From https://help.github.com/en/articles/configuring-git-to-handle-line-endings
2 | # Set the default behavior, in case people don't have core.autocrlf set.
3 | * text=auto
4 |
5 | # Explicitly declare text files you want to always be normalized and converted
6 | # to native line endings on checkout.
7 | *.c text
8 | *.h text
9 |
10 | # Declare files that will always have CRLF line endings on checkout.
11 | *.sln text eol=crlf
12 |
13 | # Denote all files that are truly binary and should not be modified.
14 | *.png binary
15 | *.jpg binary
16 |
--------------------------------------------------------------------------------
/microservices/product-api-withswagger/handlers/post.go:
--------------------------------------------------------------------------------
1 | package handlers
2 |
3 | import (
4 | "net/http"
5 |
6 | "github.com/erankitcs/golang_learning/microservices/product-api-withswagger/data"
7 | )
8 |
9 | // swagger:route POST /products products createProduct
10 | // Create a new product.
11 | // responses:
12 | // 200: productsResponse
13 | // 422: errorValidation
14 | // 400: errorResponse
15 | func (p *Products) Create(rw http.ResponseWriter, r *http.Request) {
16 | prod := r.Context().Value(KeyProduct{}).(*data.Product)
17 | p.l.Printf("[DEBUG] Inserting product: %#v\n", prod)
18 | data.AddProduct(prod)
19 | }
20 |
--------------------------------------------------------------------------------
/microservices/product-api-gorilla/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/erankitcs/golang_learning/microservices/product-api-gorilla
2 |
3 | go 1.17
4 |
5 | require (
6 | github.com/go-playground/locales v0.14.0 // indirect
7 | github.com/go-playground/universal-translator v0.18.0 // indirect
8 | github.com/go-playground/validator/v10 v10.11.0 // indirect
9 | github.com/gorilla/mux v1.8.0 // indirect
10 | github.com/leodido/go-urn v1.2.1 // indirect
11 | golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 // indirect
12 | golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069 // indirect
13 | golang.org/x/text v0.3.7 // indirect
14 | )
15 |
--------------------------------------------------------------------------------
/microservices/product-api-withswagger-client/main_test.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/erankitcs/golang_learning/microservices/productapiclient/client"
7 | "github.com/erankitcs/golang_learning/microservices/productapiclient/client/products"
8 | )
9 |
10 | func TestProductAPIClient(t *testing.T) {
11 | cfg := client.DefaultTransportConfig().WithHost("localhost:9090")
12 | c := client.NewHTTPClientWithConfig(nil, cfg)
13 | param := products.NewListProductsParams()
14 | prods, err := c.Products.ListProducts(param)
15 | if err != nil {
16 | t.Fatal(err.Error())
17 | }
18 | t.Log(prods.Payload)
19 | }
20 |
--------------------------------------------------------------------------------
/customdatatypes/datatypes2/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/erankitcs/golang_learning/customdatatypes/datatypes2/organisation"
7 | )
8 |
9 | func main() {
10 | fmt.Println("Custom Type Demo 1")
11 | p := organisation.NewPerson("Ankit", "Singh")
12 | err := p.SetTwitterHandler("@ankit63")
13 | fmt.Printf("%T\n", organisation.TwitterHandler("test"))
14 | if err != nil {
15 | fmt.Printf("An error occurred while setting handler %s", err.Error())
16 | }
17 |
18 | fmt.Println(p.TwitterHandler())
19 | fmt.Println(p.TwitterHandler().RedirectURL())
20 | fmt.Println(p.FullName())
21 | fmt.Println(p.ID())
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/pluralsight_projects/golang-fifa-world-cup-web-service/Makefile:
--------------------------------------------------------------------------------
1 | GOCMD=go
2 | GOTEST=$(GOCMD) test
3 | GORUN=${GOCMD} run
4 |
5 | all: test
6 |
7 | start:
8 | ${GORUN} server.go
9 | test:
10 | $(GOTEST) -v ./handlers/*
11 | test-1:
12 | $(GOTEST) -v ./handlers/handlers.go \
13 | ./handlers/handlers_test_helpers.go \
14 | ./handlers/01_get_handler_test.go
15 |
16 | test-2:
17 | $(GOTEST) -v ./handlers/handlers.go \
18 | ./handlers/handlers_test_helpers.go \
19 | ./handlers/02_post_handler_test.go
20 |
21 | test-3:
22 | $(GOTEST) -v ./handlers/handlers.go \
23 | ./handlers/handlers_test_helpers.go \
24 | ./handlers/03_dispatch_handler_test.go
--------------------------------------------------------------------------------
/distributedapp/registry/registration.go:
--------------------------------------------------------------------------------
1 | package registry
2 |
3 | type Registration struct {
4 | ServiceName ServiceName
5 | ServiceURL string
6 | RequiredServices []ServiceName
7 | ServiceUpdateURL string
8 | HeartbeatURL string
9 | }
10 |
11 | type ServiceName string
12 |
13 | const (
14 | LogService = ServiceName("LogService")
15 | GradingService = ServiceName("GradingService")
16 | TeacherPortalService = ServiceName("TeacherPortalService")
17 | )
18 |
19 | type patchEntry struct {
20 | Name ServiceName
21 | URL string
22 | }
23 |
24 | type patch struct {
25 | Added []patchEntry
26 | Removed []patchEntry
27 | }
28 |
--------------------------------------------------------------------------------
/distributedappdocker/Dockerfile.logservice:
--------------------------------------------------------------------------------
1 | FROM golang:1.17-alpine as build
2 |
3 | # Set necessary environmet variables needed for our image
4 | ENV GO111MODULE=on \
5 | CGO_ENABLED=0 \
6 | GOOS=linux \
7 | GOARCH=amd64
8 |
9 | # Move to working directory /build
10 | WORKDIR /build
11 |
12 | ADD . /build/
13 |
14 | RUN go mod tidy
15 | # Move to registry service directory
16 | WORKDIR /build/cmd/logservice
17 |
18 | RUN mkdir -p /dist
19 |
20 | RUN go build -o /dist .
21 |
22 | ##
23 | ## Deploy
24 | ##
25 |
26 | FROM alpine:latest
27 |
28 | WORKDIR /app
29 |
30 | COPY --from=build /dist .
31 |
32 | EXPOSE 4000
33 |
34 | CMD [ "./logservice" ]
--------------------------------------------------------------------------------
/distributedappdocker/registry/registration.go:
--------------------------------------------------------------------------------
1 | package registry
2 |
3 | type Registration struct {
4 | ServiceName ServiceName
5 | ServiceURL string
6 | RequiredServices []ServiceName
7 | ServiceUpdateURL string
8 | HeartbeatURL string
9 | }
10 |
11 | type ServiceName string
12 |
13 | const (
14 | LogService = ServiceName("LogService")
15 | GradingService = ServiceName("GradingService")
16 | TeacherPortalService = ServiceName("TeacherPortalService")
17 | )
18 |
19 | type patchEntry struct {
20 | Name ServiceName
21 | URL string
22 | }
23 |
24 | type patch struct {
25 | Added []patchEntry
26 | Removed []patchEntry
27 | }
28 |
--------------------------------------------------------------------------------
/distributedappdocker/Dockerfile.gradingservice:
--------------------------------------------------------------------------------
1 | FROM golang:1.17-alpine as build
2 |
3 | # Set necessary environmet variables needed for our image
4 | ENV GO111MODULE=on \
5 | CGO_ENABLED=0 \
6 | GOOS=linux \
7 | GOARCH=amd64
8 |
9 | # Move to working directory /build
10 | WORKDIR /build
11 |
12 | ADD . /build/
13 |
14 | RUN go mod tidy
15 | # Move to registry service directory
16 | WORKDIR /build/cmd/gradingservice
17 |
18 | RUN mkdir -p /dist
19 |
20 | RUN go build -o /dist .
21 |
22 | ##
23 | ## Deploy
24 | ##
25 |
26 | FROM alpine:latest
27 |
28 | WORKDIR /app
29 |
30 | COPY --from=build /dist .
31 |
32 | EXPOSE 4000
33 |
34 | CMD [ "./gradingservice" ]
--------------------------------------------------------------------------------
/distributedappdocker/Dockerfile.registryservice:
--------------------------------------------------------------------------------
1 | FROM golang:1.17-alpine as build
2 |
3 | # Set necessary environmet variables needed for our image
4 | ENV GO111MODULE=on \
5 | CGO_ENABLED=0 \
6 | GOOS=linux \
7 | GOARCH=amd64
8 |
9 | # Move to working directory /build
10 | WORKDIR /build
11 |
12 | ADD . /build/
13 |
14 | RUN go mod tidy
15 | # Move to registry service directory
16 | WORKDIR /build/cmd/registryservice
17 |
18 | RUN mkdir -p /dist
19 |
20 | RUN go build -o /dist .
21 |
22 | ##
23 | ## Deploy
24 | ##
25 |
26 | FROM alpine:latest
27 |
28 | WORKDIR /app
29 |
30 | COPY --from=build /dist .
31 |
32 | EXPOSE 3000
33 |
34 | CMD [ "./registryservice" ]
--------------------------------------------------------------------------------
/gostandard_libs/time_demo/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "time"
6 | )
7 |
8 | func main() {
9 |
10 | t := time.Now()
11 | year := t.Year()
12 | month := t.Month()
13 | day := t.Day()
14 |
15 | fmt.Printf("Today is %d/%d/%d", month, day, year)
16 |
17 | time.Sleep(1 * time.Second)
18 | elapsed := time.Since(t)
19 | fmt.Printf("\nElasped time is %s \n", elapsed)
20 |
21 | // Reference time:
22 | // Mon Jan 2 15:04:05 MST 2006
23 | fmt.Printf("Current Time %v \n", t.Format("15:04:05"))
24 | fmt.Printf("Current Date %v \n", t.Format("Monday 02, Jan-2006"))
25 | fmt.Printf("Today is %v \n", t.Format("Monday 02, Jan-2006 at 15:04:05"))
26 | }
27 |
--------------------------------------------------------------------------------
/gostandard_libs/others_demo/primitives.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "reflect"
6 | )
7 |
8 | func main() {
9 | var amount int32
10 |
11 | amount = 32
12 | typename := reflect.TypeOf(amount).Name()
13 | fmt.Printf("The name of the type is %v \n", typename)
14 | fmt.Printf("The type is %v\n", reflect.TypeOf(amount))
15 | fmt.Printf("The kind is %v\n", reflect.TypeOf(amount).Kind())
16 | fmt.Printf("The value is %v\n", reflect.ValueOf(amount))
17 |
18 | newValue := GetReflectedValue(reflect.TypeOf(amount))
19 | fmt.Print(newValue)
20 | //test := reflect.New(newValue)
21 | }
22 |
23 | func GetReflectedValue(t reflect.Type) reflect.Value {
24 | return reflect.Zero(t)
25 | }
26 |
--------------------------------------------------------------------------------
/grpcdemo/server/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM golang:1.17-alpine as build
2 |
3 | # Set necessary environmet variables needed for our image
4 | ENV GO111MODULE=on \
5 | CGO_ENABLED=0 \
6 | GOOS=linux \
7 | GOARCH=amd64
8 |
9 | # Move to working directory /build
10 |
11 | ADD . /build/
12 | WORKDIR /build
13 | ADD server /build/
14 |
15 | WORKDIR /build/server
16 | RUN go mod tidy
17 |
18 | RUN mkdir -p /dist
19 |
20 | RUN go build -o /dist .
21 |
22 | ##
23 | ## Deploy
24 | ##
25 |
26 | FROM alpine:latest
27 | ENV tls=""
28 | WORKDIR /cert
29 | ADD cert .
30 | WORKDIR /app
31 | COPY --from=build /dist .
32 |
33 | EXPOSE 9000
34 | RUN echo "Running GRPC Server with mTLS as $mtls"
35 | CMD ./server -"$tls"
--------------------------------------------------------------------------------
/pluralsight_projects/golang-personal-budget-cli/README.md:
--------------------------------------------------------------------------------
1 | ## Golang Personal Budget CLI
2 |
3 | Demo app for the Golang Personal Budget CLI Project.
4 |
5 | ## Running tests
6 |
7 | A proper Go environment is required in order to run this project.
8 | Once setup, tests can be run with the following command:
9 |
10 | `go test -v ./module1/ ./module2/`
11 |
12 | ### Running with Docker
13 |
14 | To build the image from the Dockerfile, run:
15 |
16 | `docker build -t project-budget-app .`
17 |
18 | To start an interactive shell, run:
19 |
20 | `docker run -it --rm --name run-budget project-budget-app`
21 |
22 | From inside the shell, run the tests with:
23 |
24 | `go test -v ./module1/ ./module2/`
25 |
26 |
--------------------------------------------------------------------------------
/distributedappdocker/Dockerfile.teacherportalservice:
--------------------------------------------------------------------------------
1 | FROM golang:1.17-alpine as build
2 |
3 | # Set necessary environmet variables needed for our image
4 | ENV GO111MODULE=on \
5 | CGO_ENABLED=0 \
6 | GOOS=linux \
7 | GOARCH=amd64
8 |
9 | # Move to working directory /build
10 | WORKDIR /build
11 |
12 | ADD . /build/
13 |
14 | RUN go mod tidy
15 | # Move to service directory
16 | WORKDIR /build/cmd/teacherportalservice
17 |
18 | RUN mkdir -p /dist
19 |
20 | RUN go build -o /dist .
21 |
22 | ##
23 | ## Deploy
24 | ##
25 |
26 | FROM alpine:latest
27 |
28 | WORKDIR /app
29 |
30 | COPY --from=build /dist .
31 |
32 | COPY teacherportal/*.gohtml teacherportal/
33 |
34 | EXPOSE 5000
35 |
36 | CMD [ "./teacherportalservice" ]
--------------------------------------------------------------------------------
/functions/simplemaths/expressions.go:
--------------------------------------------------------------------------------
1 | package simplemaths
2 |
3 | import "errors"
4 |
5 | // Variadic function...slice of type as inputs. It can be only last parameter.
6 | func Sum(values ...float64) float64 {
7 | total := 0.0
8 | for _, value := range values {
9 | total += value
10 | }
11 | return total
12 | }
13 |
14 | func Add(p1, p2 float64) float64 {
15 | return p1 + p2
16 | }
17 |
18 | func Subtract(p1, p2 float64) float64 {
19 | return p1 - p2
20 | }
21 |
22 | func Multiply(p1, p2 float64) float64 {
23 | return p1 * p2
24 | }
25 |
26 | // Naming return value.
27 | func Devide(p1, p2 float64) (answer float64, err error) {
28 | if p2 == 0 {
29 | err = errors.New("cant devide by 0")
30 | }
31 | answer = p1 / p2
32 | return
33 | }
34 |
--------------------------------------------------------------------------------
/gostandard_libs/custom_type/createtype.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "reflect"
6 | )
7 |
8 | type employee struct {
9 | empId int
10 | firstName string
11 | lastName string
12 | }
13 |
14 | func main() {
15 | emps := make([]employee, 3)
16 | emps = append(emps, employee{1, "Ankit", "Singh"})
17 | emps = append(emps, employee{2, "Nikhil", "Karkara"})
18 | emps = append(emps, employee{3, "Anuj", "Agr"})
19 |
20 | eType := reflect.TypeOf(emps)
21 | fmt.Printf("Emp Type %s \n", eType)
22 | newEmpList := reflect.MakeSlice(eType, 0, 0)
23 | newEmpList = reflect.Append(newEmpList, reflect.ValueOf(employee{4, "NewEmp", "here"}))
24 | fmt.Printf("First List %v \n", emps)
25 | fmt.Printf("New List %v \n", newEmpList)
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/microservices/product-api-gorilla/README.md:
--------------------------------------------------------------------------------
1 | ### Product API Gorilla Toolkit
2 |
3 | ### Usage
4 |
5 | 1. Get Products API-
6 | ```
7 | http://localhost:9090/
8 | ```
9 | 2. Add a Product
10 | ```
11 | http://localhost:9090/
12 | Body-
13 | {"id":3,"name":"tea","description":"A Tea","price":111.21,"sku":"ssdff-sfff-sfff"}
14 | ```
15 | 3. Update a Product
16 | ```
17 | http://localhost:9090/3
18 | Body-
19 | {"id":3,"name":"tea","description":"A Tea of new type","price":122.21,"sku":"ssdff-sfff-sfff"}
20 | ```
21 |
22 | ### Swagger Documentation
23 | - With Docker on Windows.
24 | ```
25 | docker pull quay.io/goswagger/swagger
26 | ./swagger.bat
27 | ```
28 | - Without Docker on Windows.
29 | ```
30 | ./make.bat
31 | ```
32 | - Without Docker on Linux/Mac.
33 | ```
34 | ./make.bat
35 | ```
--------------------------------------------------------------------------------
/microservices/product-api-withswagger/README.md:
--------------------------------------------------------------------------------
1 | ### Product API Gorilla Toolkit
2 |
3 | ### Usage
4 |
5 | 1. Get Products API-
6 | ```
7 | http://localhost:9090/
8 | ```
9 | 2. Add a Product
10 | ```
11 | http://localhost:9090/
12 | Body-
13 | {"id":3,"name":"tea","description":"A Tea","price":111.21,"sku":"ssdff-sfff-sfff"}
14 | ```
15 | 3. Update a Product
16 | ```
17 | http://localhost:9090/3
18 | Body-
19 | {"id":3,"name":"tea","description":"A Tea of new type","price":122.21,"sku":"ssdff-sfff-sfff"}
20 | ```
21 |
22 | ### Swagger Documentation
23 | - With Docker on Windows.
24 | ```
25 | docker pull quay.io/goswagger/swagger
26 | ./swagger.bat
27 | ```
28 | - Without Docker on Windows.
29 | ```
30 | ./make.bat
31 | ```
32 | - Without Docker on Linux/Mac.
33 | ```
34 | ./make.bat
35 | ```
--------------------------------------------------------------------------------
/pingpong/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "time"
6 | )
7 |
8 | func pinger(ping <-chan string, pong chan<- string) {
9 | for m := range ping {
10 | printAndDelay(m)
11 | pong <- "PlayerA- pong"
12 | }
13 | }
14 |
15 | func ponger(pong <-chan string, ping chan<- string) {
16 | for m := range pong {
17 | printAndDelay(m)
18 | ping <- "PlayerB- ping"
19 | }
20 | }
21 |
22 | func printAndDelay(msg string) {
23 | fmt.Println(msg)
24 | time.Sleep(time.Second)
25 | }
26 |
27 | func main() {
28 | fmt.Println("Starting pingpong game.")
29 | ping := make(chan string)
30 | pong := make(chan string)
31 |
32 | // Creating two player
33 | go pinger(ping, pong)
34 | go ponger(pong, ping)
35 |
36 | // starting the game.
37 | ping <- "ping"
38 |
39 | for {
40 |
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/customdatatypes/datatypes3/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/erankitcs/golang_learning/customdatatypes/datatypes3/organisation"
7 | )
8 |
9 | func main() {
10 | fmt.Println("Custom Type Demo 3")
11 | p := organisation.NewPerson("Ankit", "Singh", organisation.NewEuropeanUnionIdentifier("123-45-33", "UK"))
12 | err := p.SetTwitterHandler("@ankit63")
13 | fmt.Printf("%T\n", organisation.TwitterHandler("test"))
14 | if err != nil {
15 | fmt.Printf("An error occurred while setting handler %s", err.Error())
16 | }
17 | p.First = "NewName"
18 | println(p.First)
19 | println(p.Name.First)
20 | fmt.Println(p.TwitterHandler())
21 | fmt.Println(p.TwitterHandler().RedirectURL())
22 | fmt.Println(p.FullName())
23 | fmt.Println(p.ID())
24 | println(p.Country())
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/distributedapp/cmd/registryservice/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "context"
5 | "fmt"
6 | "log"
7 | "net/http"
8 |
9 | "github.com/erankitcs/golang_learning/distributedapp/registry"
10 | )
11 |
12 | func main() {
13 | registry.SetupRegistryService()
14 | http.Handle("/services", ®istry.RegistryService{})
15 | ctx, cancle := context.WithCancel(context.Background())
16 | defer cancle()
17 | var srv http.Server
18 | srv.Addr = registry.ServerPort
19 |
20 | go func() {
21 | log.Println(srv.ListenAndServe())
22 | cancle()
23 | }()
24 |
25 | go func() {
26 | fmt.Println("Registry Service Started. Press any key to stop.")
27 | var s string
28 | fmt.Scanln(&s)
29 | srv.Shutdown(ctx)
30 | cancle()
31 | }()
32 | <-ctx.Done()
33 | fmt.Println("Shutting down registry service.")
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/grpcdemo/client/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM golang:1.17-alpine as build
2 |
3 | # Set necessary environmet variables needed for our image
4 | ENV GO111MODULE=on \
5 | CGO_ENABLED=0 \
6 | GOOS=linux \
7 | GOARCH=amd64
8 |
9 | # Move to working directory /build
10 |
11 | ADD . /build/
12 | WORKDIR /build
13 | ADD client /build/
14 |
15 | WORKDIR /build/client
16 | RUN go mod tidy
17 |
18 | RUN mkdir -p /dist
19 |
20 | RUN go build -o /dist .
21 |
22 | ##
23 | ## Deploy
24 | ##
25 |
26 | FROM alpine:latest
27 | ENV tls=tls
28 | ENV opt=1
29 | ENV serverhost=""
30 | ENV serverport=9000
31 |
32 | WORKDIR /cert
33 | ADD cert .
34 | WORKDIR /app
35 | COPY --from=build /dist .
36 | RUN echo "Running GRPC client with option $opt , tls as $tls and mTLS as $mtls"
37 | CMD ./client -o $opt -$tls -serverhost $serverhost -serverport $serverport
--------------------------------------------------------------------------------
/grpcdemo/server/data.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "github.com/erankitcs/golang_learning/grpcdemo/server/pb/messages"
5 | )
6 |
7 | var employees = []messages.Employee{
8 | {
9 | Id: 1,
10 | BadgeNumber: 2080,
11 | FirstName: "Grace",
12 | LastName: "Decker",
13 | VacationAccrualRate: 2,
14 | VacationAccrued: 30,
15 | },
16 | {
17 | Id: 2,
18 | BadgeNumber: 7538,
19 | FirstName: "Amity",
20 | LastName: "Fuller",
21 | VacationAccrualRate: 2.3,
22 | VacationAccrued: 23.4,
23 | },
24 | {
25 | Id: 3,
26 | BadgeNumber: 5144,
27 | FirstName: "Keaton",
28 | LastName: "Willis",
29 | VacationAccrualRate: 3,
30 | VacationAccrued: 31.7,
31 | },
32 | }
33 |
--------------------------------------------------------------------------------
/gostandard_libs/trace_demo/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "log"
6 | "math/rand"
7 | "os"
8 | "runtime/trace"
9 | "time"
10 | )
11 |
12 | func main() {
13 | f, err := os.Create("trace.out")
14 | if err != nil {
15 | log.Fatalf("failed to create trace output file: %v", err)
16 | }
17 | defer func() {
18 | if err := f.Close(); err != nil {
19 | log.Fatalf("failed to close trace file: %v", err)
20 | }
21 | }()
22 |
23 | if err := trace.Start(f); err != nil {
24 | log.Fatalf("failed to start trace: %v", err)
25 | }
26 | defer trace.Stop()
27 |
28 | AddRandomNumbers()
29 | }
30 |
31 | func AddRandomNumbers() {
32 |
33 | firstNumber := rand.Intn(100)
34 | secondNumber := rand.Intn(100)
35 |
36 | time.Sleep(2 * time.Second)
37 |
38 | var result = firstNumber * secondNumber
39 |
40 | fmt.Printf("Result of 2 numbers is %d\n", result)
41 | }
42 |
--------------------------------------------------------------------------------
/golang-async-logging-library/README.md:
--------------------------------------------------------------------------------
1 | To use the test runner:
2 |
3 | * navigate into the ./cmd directory
4 | * if run with the defaults (`go run .`), the application will run in asynchronous mode and write it's output directly to the shell
5 | * the `-out` flag allows a destination file to be specified
6 | * the `-async` flag determines if the logger will asynchronously or not. It is async by default, which will not work properly in the application's initial condition.
7 |
8 | To run the tests
9 |
10 | * use the `go test` command from the command line
11 | * to focus on a specific test, use the `-run` flag followed by a pattern that matches the test name
12 | * e.g. `go test -run MessageChannel` will run the first test of the first module
13 | * all tests for a given module can be run by passing the module identifier to the `-run` command
14 | * e.g. `go test -v -run Module1`
15 |
--------------------------------------------------------------------------------
/microservices/product-api-withswagger/handlers/put.go:
--------------------------------------------------------------------------------
1 | package handlers
2 |
3 | import (
4 | "net/http"
5 |
6 | "github.com/erankitcs/golang_learning/microservices/product-api-withswagger/data"
7 | )
8 |
9 | // swagger:route PUT /products products updateProduct
10 | // Update a products details
11 | //
12 | // responses:
13 | // 201: noContentResponse
14 | // 404: errorResponse
15 | // 422: errorValidation
16 | func (p *Products) Update(rw http.ResponseWriter, r *http.Request) {
17 | prod := r.Context().Value(KeyProduct{}).(*data.Product)
18 | p.l.Printf("[DEBUG] Updating product for id: %#v\n", prod.ID)
19 | err := data.UpdateProduct(prod)
20 | if err == data.ErrorProductNotFound {
21 | p.l.Println("[ERROR] product not found", err)
22 |
23 | rw.WriteHeader(http.StatusNotFound)
24 | data.ToJSON(&GenericError{Message: "Product not found in database"}, rw)
25 | return
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/distributedapp/log/client.go:
--------------------------------------------------------------------------------
1 | package log
2 |
3 | import (
4 | "bytes"
5 | "fmt"
6 | stlog "log"
7 | "net/http"
8 |
9 | "github.com/erankitcs/golang_learning/distributedapp/registry"
10 | )
11 |
12 | func SetClientLogger(serviceURL string, clientService registry.ServiceName) {
13 | stlog.SetPrefix(fmt.Sprintf("[%v] - ", clientService))
14 | stlog.SetFlags(0)
15 | stlog.SetOutput(&clientLogger{url: serviceURL})
16 | }
17 |
18 | type clientLogger struct {
19 | url string
20 | }
21 |
22 | func (cl clientLogger) Write(data []byte) (int, error) {
23 | b := bytes.NewBuffer([]byte(data))
24 | res, err := http.Post(cl.url+"/log", "text/plan", b)
25 | if err != nil {
26 | return 0, err
27 | }
28 | if res.StatusCode != http.StatusOK {
29 | return 0, fmt.Errorf("Failed to send the log message."+
30 | "Service responded with code: %v", res.StatusCode)
31 | }
32 | return len(data), nil
33 | }
34 |
--------------------------------------------------------------------------------
/distributedappdocker/log/client.go:
--------------------------------------------------------------------------------
1 | package log
2 |
3 | import (
4 | "bytes"
5 | "fmt"
6 | stlog "log"
7 | "net/http"
8 |
9 | "github.com/erankitcs/golang_learning/distributedapp/registry"
10 | )
11 |
12 | func SetClientLogger(serviceURL string, clientService registry.ServiceName) {
13 | stlog.SetPrefix(fmt.Sprintf("[%v] - ", clientService))
14 | stlog.SetFlags(0)
15 | stlog.SetOutput(&clientLogger{url: serviceURL})
16 | }
17 |
18 | type clientLogger struct {
19 | url string
20 | }
21 |
22 | func (cl clientLogger) Write(data []byte) (int, error) {
23 | b := bytes.NewBuffer([]byte(data))
24 | res, err := http.Post(cl.url+"/log", "text/plan", b)
25 | if err != nil {
26 | return 0, err
27 | }
28 | if res.StatusCode != http.StatusOK {
29 | return 0, fmt.Errorf("Failed to send the log message."+
30 | "Service responded with code: %v", res.StatusCode)
31 | }
32 | return len(data), nil
33 | }
34 |
--------------------------------------------------------------------------------
/distributedappdocker/cmd/registryservice/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "context"
5 | "fmt"
6 | "log"
7 | "net/http"
8 |
9 | "github.com/erankitcs/golang_learning/distributedapp/registry"
10 | )
11 |
12 | func main() {
13 | registry.SetupRegistryService()
14 | http.Handle("/services", ®istry.RegistryService{})
15 | ctx, cancle := context.WithCancel(context.Background())
16 | defer cancle()
17 | var srv http.Server
18 | srv.Addr = registry.ServerPort
19 |
20 | go func() {
21 | log.Println(srv.ListenAndServe())
22 | cancle()
23 | }()
24 |
25 | go func() {
26 | fmt.Println("Registry Service Started. Press key- s key to stop.")
27 | var s string
28 | fmt.Scanln(&s)
29 | if s == "s" {
30 | fmt.Println("Stop requested by user")
31 | srv.Shutdown(ctx)
32 | cancle()
33 |
34 | }
35 | }()
36 | <-ctx.Done()
37 | fmt.Println("Shutting down registry service.")
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/distributedapp/teacherportal/students.gohtml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Students
7 |
8 |
9 | Grade Book
10 | {{if len .}}
11 |
12 |
13 | | Name |
14 | Average [%] |
15 |
16 | {{range .}}
17 |
18 | |
19 | {{.LastName}}, {{.FirstName}}
20 | |
21 |
22 | {{printf "%.1f%%" .Average}}
23 | |
24 |
25 | {{end}}
26 |
27 | {{else}}
28 | No students found
29 | {{end}}
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/distributedappdocker/teacherportal/students.gohtml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Students
7 |
8 |
9 | Grade Book
10 | {{if len .}}
11 |
12 |
13 | | Name |
14 | Average [%] |
15 |
16 | {{range .}}
17 |
18 | |
19 | {{.LastName}}, {{.FirstName}}
20 | |
21 |
22 | {{printf "%.1f%%" .Average}}
23 | |
24 |
25 | {{end}}
26 |
27 | {{else}}
28 | No students found
29 | {{end}}
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/ginframeworkdemo/vacationtracker/templates/index.tmpl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Employee Vacation Tracker
8 |
9 |
10 |
11 | Employee Vacation Tracker
12 |
13 |
14 | | ID |
15 | Last Name |
16 | First Name |
17 | Total PTO |
18 | PTO Events |
19 |
20 | {{ range . }}
21 |
22 | | {{.ID}} |
23 | {{.LastName}} |
24 | {{.FirstName}} |
25 | {{.TotalPTO}} |
26 | {{.TimeOff | len}} |
27 |
28 | {{ end }}
29 |
30 |
31 |
--------------------------------------------------------------------------------
/gostandard_libs/loger_demo/newloger.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "log"
5 | "os"
6 | )
7 |
8 | var (
9 | WarningLogger *log.Logger
10 | InfoLogger *log.Logger
11 | ErrorLogger *log.Logger
12 | FatalLogger *log.Logger
13 | )
14 |
15 | func init() {
16 |
17 | file, err := os.OpenFile("newlog.txt", os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0666)
18 | if err != nil {
19 | log.Fatal(err)
20 | }
21 |
22 | InfoLogger = log.New(file, "INFO: ", log.LUTC|log.Lmicroseconds|log.Llongfile)
23 | WarningLogger = log.New(file, "WARNING: ", log.Ldate|log.Ltime|log.Lshortfile)
24 | ErrorLogger = log.New(file, "ERROR: ", log.Ldate|log.Ltime|log.Lshortfile)
25 | FatalLogger = log.New(file, "FATAL: ", log.Ldate|log.Ltime|log.Lshortfile)
26 | }
27 |
28 | func main() {
29 |
30 | InfoLogger.Println("This is info")
31 | WarningLogger.Println("This is warning.")
32 | ErrorLogger.Println("This is error")
33 | FatalLogger.Println("This is fetal error.")
34 | }
35 |
--------------------------------------------------------------------------------
/distributedapp/log/server.go:
--------------------------------------------------------------------------------
1 | package log
2 |
3 | import (
4 | "io/ioutil"
5 | stlog "log"
6 | "net/http"
7 | "os"
8 | )
9 |
10 | var log *stlog.Logger
11 |
12 | type fileLog string
13 |
14 | func (fl fileLog) Write(data []byte) (int, error) {
15 | f, err := os.OpenFile(string(fl), os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600)
16 | if err != nil {
17 | return 0, err
18 | }
19 | defer f.Close()
20 | return f.Write(data)
21 | //fmt.Println(string(data))
22 | //return 1, nil
23 | }
24 |
25 | func Run(destination string) {
26 | log = stlog.New(fileLog(destination), "", stlog.LstdFlags)
27 | }
28 |
29 | func RegisterHandler() {
30 | http.HandleFunc("/log", func(rw http.ResponseWriter, r *http.Request) {
31 | msg, err := ioutil.ReadAll(r.Body)
32 | if err != nil && len(msg) == 0 {
33 | rw.WriteHeader(http.StatusBadRequest)
34 | return
35 | }
36 | write(string(msg))
37 | })
38 | }
39 |
40 | func write(msg string) {
41 | log.Printf("%v\n", msg)
42 | }
43 |
--------------------------------------------------------------------------------
/distributedappdocker/log/server.go:
--------------------------------------------------------------------------------
1 | package log
2 |
3 | import (
4 | "io/ioutil"
5 | stlog "log"
6 | "net/http"
7 | "os"
8 | )
9 |
10 | var log *stlog.Logger
11 |
12 | type fileLog string
13 |
14 | func (fl fileLog) Write(data []byte) (int, error) {
15 | f, err := os.OpenFile(string(fl), os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600)
16 | if err != nil {
17 | return 0, err
18 | }
19 | defer f.Close()
20 | return f.Write(data)
21 | //fmt.Println(string(data))
22 | //return 1, nil
23 | }
24 |
25 | func Run(destination string) {
26 | log = stlog.New(fileLog(destination), "", stlog.LstdFlags)
27 | }
28 |
29 | func RegisterHandler() {
30 | http.HandleFunc("/log", func(rw http.ResponseWriter, r *http.Request) {
31 | msg, err := ioutil.ReadAll(r.Body)
32 | if err != nil && len(msg) == 0 {
33 | rw.WriteHeader(http.StatusBadRequest)
34 | return
35 | }
36 | write(string(msg))
37 | })
38 | }
39 |
40 | func write(msg string) {
41 | log.Printf("%v\n", msg)
42 | }
43 |
--------------------------------------------------------------------------------
/pluralsight_projects/golang-advanced-branching/feedback.json:
--------------------------------------------------------------------------------
1 | {
2 |
3 | "values": [
4 | {
5 | "model":"Sonata" ,
6 | "feedback": [
7 | "This is the most pathetic support I have ever received. My product is still to be shipped and I am totally frustrated with the response time.",
8 | "This is to say thanks to the service advisor",
9 | "What a wonderful service fantastic department you have. The advisor provided the best support that I have ever received. I am very impressed and it will be a pleasure to order again from your company."
10 | ]
11 | },
12 | {
13 | "model":"CRV" ,
14 | "feedback": [
15 | "This is a generic feedback about the CRV."
16 | ]
17 | },
18 | {
19 | "model":"Camry" ,
20 | "feedback": [
21 | "I guess your employees do know how to provide support. I am happy and satisfied with the level of response that I got.",
22 | "The support was fine and my service issues were resolved on timely basis."
23 | ]
24 | }
25 | ]
26 | }
27 |
--------------------------------------------------------------------------------
/distributedapp/cmd/logservice/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "context"
5 | "fmt"
6 | stlog "log"
7 |
8 | "github.com/erankitcs/golang_learning/distributedapp/log"
9 | "github.com/erankitcs/golang_learning/distributedapp/registry"
10 | "github.com/erankitcs/golang_learning/distributedapp/service"
11 | )
12 |
13 | func main() {
14 | log.Run("./app.log")
15 | var r registry.Registration
16 | hostname, port := "localhost", "4000"
17 | serviceURL := fmt.Sprintf("http://%v:%v", hostname, port)
18 | r.ServiceName = registry.LogService
19 | r.ServiceURL = serviceURL
20 | r.RequiredServices = make([]registry.ServiceName, 0)
21 | r.ServiceUpdateURL = r.ServiceURL + "/services"
22 | r.HeartbeatURL = r.ServiceURL + "/heartbeat"
23 |
24 | ctx, err := service.Start(
25 | context.Background(),
26 | r,
27 | hostname,
28 | port,
29 | log.RegisterHandler,
30 | )
31 |
32 | if err != nil {
33 | stlog.Fatal(err)
34 | }
35 | <-ctx.Done()
36 | fmt.Println("Shutting down log service.")
37 | }
38 |
--------------------------------------------------------------------------------
/gostandard_libs/args_demo/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "os"
6 | "strconv"
7 | )
8 |
9 | func main() {
10 | // Slicing to include first read which is nothing but file name
11 | // Args are list of string be default.
12 | args := os.Args[1:]
13 | //fmt.Println(args)
14 | if len(args) == 1 && args[0] == "/help" {
15 | fmt.Println("Usage: Dinner Total ")
16 | fmt.Println("args_demo 10 5")
17 | } else {
18 | if len(args) != 2 {
19 | fmt.Println("Please enter some inputs. Type /help for more details abt input.")
20 | } else {
21 | // Business Logic here.
22 | mealTotal, _ := strconv.ParseFloat(args[0], 32)
23 | tipAmount, _ := strconv.ParseFloat(args[1], 32)
24 | fmt.Printf("Your total bill is %.2f", calculateTotal(float32(mealTotal), float32(tipAmount)))
25 | }
26 | }
27 | }
28 |
29 | func calculateTotal(mealTotal float32, tipAmount float32) float32 {
30 | totalPrice := mealTotal + (mealTotal * (tipAmount / 100))
31 | return totalPrice
32 | }
33 |
--------------------------------------------------------------------------------
/customdatatypes/datatypes1/organisation/person.go:
--------------------------------------------------------------------------------
1 | package organisation
2 |
3 | import (
4 | "errors"
5 | "fmt"
6 | "strings"
7 | )
8 |
9 | type Identifiable interface {
10 | ID() string
11 | }
12 |
13 | type Person struct {
14 | firstName string
15 | lastName string
16 | twitterHandler string
17 | }
18 |
19 | func NewPerson(firstName, lastName string) Person {
20 | return Person{
21 | firstName: firstName,
22 | lastName: lastName,
23 | }
24 | }
25 |
26 | func (p *Person) SetTwitterHandler(handler string) error {
27 | if len(handler) == 0 {
28 | p.twitterHandler = handler
29 | } else if !strings.HasPrefix(handler, "@") {
30 | return errors.New("twitter handle must start with @ in text")
31 | }
32 | p.twitterHandler = handler
33 | return nil
34 | }
35 |
36 | func (p *Person) FullName() string {
37 | return fmt.Sprintf("%s %s", p.firstName, p.lastName)
38 | }
39 |
40 | func (p *Person) ID() string {
41 | return "123"
42 | }
43 |
44 | func (p *Person) TwitterHandler() string {
45 | return p.twitterHandler
46 | }
47 |
--------------------------------------------------------------------------------
/pluralsight_projects/golang-fifa-world-cup-web-service/README.md:
--------------------------------------------------------------------------------
1 | # FIFA World Cup Winners
2 |
3 | This project exposes a Web API for accessing historic data from
4 | the FIFA World Cup championship.
5 |
6 | ## Running tests
7 |
8 | A proper Go environment is required in order to run this project.
9 | Once setup, tests can be run with the following command:
10 |
11 | `go test -v ./handlers/`
12 |
13 | ## Running the server
14 |
15 | Once all tests are passing, the server can be started with
16 | the `go run server.go` command.
17 |
18 | ## Testing the API manually
19 |
20 | Start the server with `go run server.go` and then
21 | use the example commands printed to the console to
22 | test the program.
23 |
24 | ### Running with Docker
25 |
26 | To build the image from the Dockerfile, run:
27 |
28 | `docker build -t project-fifa-world-cup .`
29 |
30 | To start an interactive shell, run:
31 |
32 | `docker run -it --rm --name run-fifa project-fifa-world-cup`
33 |
34 | From inside the shell, run the tests with:
35 |
36 | `go test handlers/*`
37 |
--------------------------------------------------------------------------------
/distributedapp/grades/grades.go:
--------------------------------------------------------------------------------
1 | package grades
2 |
3 | import (
4 | "fmt"
5 | "sync"
6 | )
7 |
8 | type Student struct {
9 | ID int
10 | FirstName string
11 | LastName string
12 | Grades []Grade
13 | }
14 |
15 | func (s Student) Average() float32 {
16 | var gradeSum float32
17 | for _, grade := range s.Grades {
18 | gradeSum += grade.Score
19 | }
20 | return gradeSum / float32(len(s.Grades))
21 |
22 | }
23 |
24 | type Students []Student
25 |
26 | func (s Students) GetByID(id int) (*Student, error) {
27 | for i := range s {
28 | if s[i].ID == id {
29 | return &s[i], nil
30 | }
31 | }
32 | return nil, fmt.Errorf("Student with ID: %v not found", id)
33 |
34 | }
35 |
36 | var (
37 | students Students
38 | studentsMutex sync.Mutex
39 | )
40 |
41 | type GradeType string
42 |
43 | const (
44 | GradeTest = GradeType("Test")
45 | GradeHomework = GradeType("Homework")
46 | GradeQuiz = GradeType("Quiz")
47 | )
48 |
49 | type Grade struct {
50 | Title string
51 | Type GradeType
52 | Score float32
53 | }
54 |
--------------------------------------------------------------------------------
/microservices/product-api-withswagger/handlers/delete.go:
--------------------------------------------------------------------------------
1 | package handlers
2 |
3 | import (
4 | "net/http"
5 |
6 | "github.com/erankitcs/golang_learning/microservices/product-api-withswagger/data"
7 | )
8 |
9 | // swagger:route DELETE /products/{id} products deleteProduct
10 | // Delete a product from database
11 | // responses:
12 | // 201: noContentResponse
13 | func (p *Products) Delete(rw http.ResponseWriter, r *http.Request) {
14 | id := getProductID(r)
15 | p.l.Println("[DEBUG] deleting record id", id)
16 | err := data.DeleteProduct(id)
17 |
18 | if err == data.ErrorProductNotFound {
19 | p.l.Println("[ERROR] deleting record id does not exist")
20 |
21 | rw.WriteHeader(http.StatusNotFound)
22 | data.ToJSON(&GenericError{Message: err.Error()}, rw)
23 | return
24 | }
25 |
26 | if err != nil {
27 | p.l.Println("[ERROR] deleting record", err)
28 |
29 | rw.WriteHeader(http.StatusInternalServerError)
30 | data.ToJSON(&GenericError{Message: err.Error()}, rw)
31 | return
32 | }
33 | rw.WriteHeader(http.StatusNoContent)
34 | }
35 |
--------------------------------------------------------------------------------
/distributedappdocker/grades/grades.go:
--------------------------------------------------------------------------------
1 | package grades
2 |
3 | import (
4 | "fmt"
5 | "sync"
6 | )
7 |
8 | type Student struct {
9 | ID int
10 | FirstName string
11 | LastName string
12 | Grades []Grade
13 | }
14 |
15 | func (s Student) Average() float32 {
16 | var gradeSum float32
17 | for _, grade := range s.Grades {
18 | gradeSum += grade.Score
19 | }
20 | return gradeSum / float32(len(s.Grades))
21 |
22 | }
23 |
24 | type Students []Student
25 |
26 | func (s Students) GetByID(id int) (*Student, error) {
27 | for i := range s {
28 | if s[i].ID == id {
29 | return &s[i], nil
30 | }
31 | }
32 | return nil, fmt.Errorf("Student with ID: %v not found", id)
33 |
34 | }
35 |
36 | var (
37 | students Students
38 | studentsMutex sync.Mutex
39 | )
40 |
41 | type GradeType string
42 |
43 | const (
44 | GradeTest = GradeType("Test")
45 | GradeHomework = GradeType("Homework")
46 | GradeQuiz = GradeType("Quiz")
47 | )
48 |
49 | type Grade struct {
50 | Title string
51 | Type GradeType
52 | Score float32
53 | }
54 |
--------------------------------------------------------------------------------
/distributedappdocker/cmd/logservice/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "context"
5 | "fmt"
6 | stlog "log"
7 |
8 | "github.com/erankitcs/golang_learning/distributedapp/log"
9 | "github.com/erankitcs/golang_learning/distributedapp/registry"
10 | "github.com/erankitcs/golang_learning/distributedapp/service"
11 | )
12 |
13 | func main() {
14 | log.Run("./app.log")
15 | var r registry.Registration
16 | hostname, port := "logservice", "4000"
17 | serviceURL := fmt.Sprintf("http://%v:%v", hostname, port)
18 | globalServiceURL := fmt.Sprintf("http://logservice:%v", port)
19 | r.ServiceName = registry.LogService
20 | r.ServiceURL = serviceURL
21 | r.RequiredServices = make([]registry.ServiceName, 0)
22 | r.ServiceUpdateURL = globalServiceURL + "/services"
23 | r.HeartbeatURL = globalServiceURL + "/heartbeat"
24 |
25 | ctx, err := service.Start(
26 | context.Background(),
27 | r,
28 | hostname,
29 | port,
30 | log.RegisterHandler,
31 | )
32 |
33 | if err != nil {
34 | stlog.Fatal(err)
35 | }
36 | <-ctx.Done()
37 | fmt.Println("Shutting down log service.")
38 | }
39 |
--------------------------------------------------------------------------------
/pluralsight_projects/golang-fifa-world-cup-web-service/data/winners.json:
--------------------------------------------------------------------------------
1 | {
2 | "winners": [
3 | { "country": "France", "year": 2018 },
4 | { "country": "Germany", "year": 2014 },
5 | { "country": "Spain", "year": 2010 },
6 | { "country": "Italy", "year": 2006 },
7 | { "country": "Brazil", "year": 2002 },
8 | { "country": "France", "year": 1998 },
9 | { "country": "Brazil", "year": 1994 },
10 | { "country": "West Germany", "year": 1990 },
11 | { "country": "Argentina", "year": 1986 },
12 | { "country": "Italy", "year": 1982 },
13 | { "country": "Argentina", "year": 1978 },
14 | { "country": "West Germany", "year": 1974 },
15 | { "country": "Brazil", "year": 1970 },
16 | { "country": "England", "year": 1966 },
17 | { "country": "Brazil", "year": 1962 },
18 | { "country": "Brazil", "year": 1958 },
19 | { "country": "West Germany", "year": 1954 },
20 | { "country": "Uruguay", "year": 1950 },
21 | { "country": "Italy", "year": 1938 },
22 | { "country": "Italy", "year": 1934 },
23 | { "country": "Uruguay", "year": 1930 }
24 | ]
25 | }
26 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Ankit K Singh
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/ginframeworkdemo/responsedemo/go.mod:
--------------------------------------------------------------------------------
1 | module gindemo
2 |
3 | go 1.17
4 |
5 | require github.com/gin-gonic/gin v1.8.1
6 |
7 | require (
8 | github.com/gin-contrib/sse v0.1.0 // indirect
9 | github.com/go-playground/locales v0.14.0 // indirect
10 | github.com/go-playground/universal-translator v0.18.0 // indirect
11 | github.com/go-playground/validator/v10 v10.10.0 // indirect
12 | github.com/goccy/go-json v0.9.7 // indirect
13 | github.com/json-iterator/go v1.1.12 // indirect
14 | github.com/leodido/go-urn v1.2.1 // indirect
15 | github.com/mattn/go-isatty v0.0.14 // indirect
16 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
17 | github.com/modern-go/reflect2 v1.0.2 // indirect
18 | github.com/pelletier/go-toml/v2 v2.0.1 // indirect
19 | github.com/ugorji/go/codec v1.2.7 // indirect
20 | golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 // indirect
21 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 // indirect
22 | golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069 // indirect
23 | golang.org/x/text v0.3.6 // indirect
24 | google.golang.org/protobuf v1.28.0 // indirect
25 | gopkg.in/yaml.v2 v2.4.0 // indirect
26 | )
27 |
--------------------------------------------------------------------------------
/gostandard_libs/print_demo/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | func main() {
6 | var age = 42
7 |
8 | var out, _ = fmt.Print("I am ", age, " Year old.\n")
9 | print("Bytes written - ", out)
10 |
11 | var name = "Jeremy"
12 |
13 | fmt.Printf("\nMy name is %s and I am %d years old\n", name, age)
14 |
15 | var pi float32 = 3.141592
16 |
17 | fmt.Printf("Pi is %f\n", pi)
18 | fmt.Printf("Pi is %2.2f\n", pi)
19 |
20 | test := fmt.Sprintf("|%7.2f|%7.2f|%7.2f|\n", 23.3774, 577.45, 1234.56)
21 | print(test)
22 | fmt.Printf("|%7.2f|%7.2f|%7.2f|\n", 98.999, 12.3456, 12.01)
23 |
24 | fmt.Printf("|%-7s|%-7s|%-7s|\n", "foo", "bar", "go")
25 | fmt.Printf("|%-7s|%-7s|%-7d|\n", "a", "ab", 100)
26 |
27 | type point struct {
28 | x, y int
29 | }
30 |
31 | p := point{1, 2}
32 | fmt.Printf("%v\n", p)
33 |
34 | type Person struct {
35 | firstName string
36 | lastName string
37 | age int
38 | }
39 |
40 | newPerson := Person{"Ankit", "Singh", 42}
41 |
42 | fmt.Printf("%T\n", newPerson)
43 |
44 | var isCool = true
45 | fmt.Printf("Value is %t\n", isCool)
46 | fmt.Printf("Value is %T\n", isCool)
47 |
48 | fmt.Printf("%c\n", 3)
49 | }
50 |
--------------------------------------------------------------------------------
/distributedappdocker/Readme.md:
--------------------------------------------------------------------------------
1 | ### Distributed App built using Golang.
2 |
3 | #### Create a user defined network
4 | ```
5 | docker network create teacherportal
6 | ```
7 |
8 | #### Registry service
9 | ```
10 | docker build -f Dockerfile.registryservice -t registryservice .
11 | docker run -p 3000:3000 --name registryservice --network=teacherportal -d registryservice
12 | ```
13 |
14 | #### Log service
15 | ```
16 | docker build -f Dockerfile.logservice -t logservice .
17 | docker run -p 4000:4000 --name logservice --network=teacherportal -d logservice
18 | ```
19 |
20 | #### Grading service
21 | ```
22 | docker build -f Dockerfile.gradingservice -t gradingservice .
23 | docker run -p 6000:6000 --name gradingservice --network=teacherportal -d gradingservice
24 | ```
25 |
26 | #### Teacher Portal service
27 | ```
28 | docker build -f Dockerfile.teacherportalservice -t teacherportalservice .
29 | docker run -p 5000:5000 --name teacherportalservice --network=teacherportal -d teacherportalservice
30 | ```
31 |
32 | #### Application URL
33 | http://localhost:5000
34 |
35 |
36 | #### Useful links
37 | 1. https://marcofranssen.nl/docker-tips-and-tricks-for-your-go-projects
38 |
39 |
--------------------------------------------------------------------------------
/ginframeworkdemo/requestdemo/go.mod:
--------------------------------------------------------------------------------
1 | module gindemo
2 |
3 | go 1.17
4 |
5 | require (
6 | github.com/gin-gonic/gin v1.8.1
7 | github.com/go-playground/validator/v10 v10.11.0
8 | )
9 |
10 | require (
11 | github.com/gin-contrib/sse v0.1.0 // indirect
12 | github.com/go-playground/locales v0.14.0 // indirect
13 | github.com/go-playground/universal-translator v0.18.0 // indirect
14 | github.com/goccy/go-json v0.9.10 // indirect
15 | github.com/json-iterator/go v1.1.12 // indirect
16 | github.com/leodido/go-urn v1.2.1 // indirect
17 | github.com/mattn/go-isatty v0.0.14 // indirect
18 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
19 | github.com/modern-go/reflect2 v1.0.2 // indirect
20 | github.com/pelletier/go-toml/v2 v2.0.2 // indirect
21 | github.com/ugorji/go/codec v1.2.7 // indirect
22 | golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa // indirect
23 | golang.org/x/net v0.0.0-20220805013720-a33c5aa5df48 // indirect
24 | golang.org/x/sys v0.0.0-20220804214406-8e32c043e418 // indirect
25 | golang.org/x/text v0.3.7 // indirect
26 | google.golang.org/protobuf v1.28.1 // indirect
27 | gopkg.in/yaml.v2 v2.4.0 // indirect
28 | )
29 |
--------------------------------------------------------------------------------
/ginframeworkdemo/requestdemo/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Employee Vacation Tracker
8 |
9 |
10 |
11 | Employee Vacation Tracker
12 |
13 |
14 | | ID |
15 | Last Name |
16 | First Name |
17 | Total PTO |
18 | PTO Events |
19 |
20 |
21 | | 176158 |
22 | Jane |
23 | Allison |
24 | 20 |
25 | 3 |
26 |
27 |
28 | | 160898 |
29 | Uppal |
30 | Aakar |
31 | 20 |
32 | 0 |
33 |
34 |
35 | | 297365 |
36 | Anderson |
37 | Jonathon |
38 | 30 |
39 | 0 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/ginframeworkdemo/vacationtracker/go.mod:
--------------------------------------------------------------------------------
1 | module vacationtracker
2 |
3 | go 1.17
4 |
5 | require github.com/gin-gonic/gin v1.8.1
6 |
7 | require (
8 | github.com/gin-contrib/sse v0.1.0 // indirect
9 | github.com/go-playground/locales v0.14.0 // indirect
10 | github.com/go-playground/universal-translator v0.18.0 // indirect
11 | github.com/go-playground/validator/v10 v10.10.0 // indirect
12 | github.com/goccy/go-json v0.9.7 // indirect
13 | github.com/json-iterator/go v1.1.12 // indirect
14 | github.com/leodido/go-urn v1.2.1 // indirect
15 | github.com/mattn/go-isatty v0.0.14 // indirect
16 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
17 | github.com/modern-go/reflect2 v1.0.2 // indirect
18 | github.com/pelletier/go-toml/v2 v2.0.1 // indirect
19 | github.com/ugorji/go/codec v1.2.7 // indirect
20 | golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 // indirect
21 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 // indirect
22 | golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069 // indirect
23 | golang.org/x/text v0.3.6 // indirect
24 | google.golang.org/protobuf v1.28.0 // indirect
25 | gopkg.in/yaml.v2 v2.4.0 // indirect
26 | )
27 |
--------------------------------------------------------------------------------
/ginframeworkdemo/vacationtracker/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Employee Vacation Tracker
8 |
9 |
10 |
11 | Employee Vacation Tracker
12 |
13 |
14 | | ID |
15 | Last Name |
16 | First Name |
17 | Total PTO |
18 | PTO Events |
19 |
20 |
21 | | 176158 |
22 | Jane |
23 | Allison |
24 | 20 |
25 | 3 |
26 |
27 |
28 | | 160898 |
29 | Uppal |
30 | Aakar |
31 | 20 |
32 | 0 |
33 |
34 |
35 | | 297365 |
36 | Anderson |
37 | Jonathon |
38 | 30 |
39 | 0 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/golang-async-logging-library/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Runtime data
9 | pids
10 | *.pid
11 | *.seed
12 | *.pid.lock
13 |
14 | # Directory for instrumented libs generated by jscoverage/JSCover
15 | lib-cov
16 |
17 | # Coverage directory used by tools like istanbul
18 | coverage
19 |
20 | # nyc test coverage
21 | .nyc_output
22 |
23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
24 | .grunt
25 |
26 | # Bower dependency directory (https://bower.io/)
27 | bower_components
28 |
29 | # node-waf configuration
30 | .lock-wscript
31 |
32 | # Compiled binary addons (https://nodejs.org/api/addons.html)
33 | build/Release
34 |
35 | # Dependency directories
36 | node_modules/
37 | jspm_packages/
38 |
39 | # TypeScript v1 declaration files
40 | typings/
41 |
42 | # Optional npm cache directory
43 | .npm
44 |
45 | # Optional eslint cache
46 | .eslintcache
47 |
48 | # Optional REPL history
49 | .node_repl_history
50 |
51 | # Output of 'npm pack'
52 | *.tgz
53 |
54 | # Yarn Integrity file
55 | .yarn-integrity
56 |
57 | # dotenv environment variables file
58 | .env
59 |
60 | # next.js build output
61 | .next
62 |
--------------------------------------------------------------------------------
/gostandard_libs/filemaker_demo/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "bufio"
5 | "fmt"
6 | "os"
7 | "strings"
8 | )
9 |
10 | func main() {
11 | fmt.Println("This program creates a file.")
12 | // Getting filename from input args.
13 | args := os.Args[1:]
14 | if len(args) == 0 || args[0] == "/help" {
15 | fmt.Println("Usage : filemaker_demo.exe ")
16 | } else {
17 | fmt.Println("How would you like to see this text ??")
18 | fmt.Println("1: All caps")
19 | fmt.Println("2: Title Case")
20 | fmt.Println("3: lowercase")
21 |
22 | var option int
23 |
24 | _, err := fmt.Scanf("%d", &option)
25 | if err != nil {
26 | fmt.Println(err)
27 | }
28 |
29 | file, err := os.Open(args[0])
30 | if err != nil {
31 | fmt.Println(err)
32 | }
33 | defer file.Close()
34 |
35 | scanner := bufio.NewScanner(file)
36 |
37 | for scanner.Scan() {
38 | switch option {
39 | case 1:
40 | fmt.Println(strings.ToUpper(scanner.Text()))
41 | case 2:
42 | fmt.Println(strings.Title(scanner.Text()))
43 | case 3:
44 | fmt.Println(strings.ToLower(scanner.Text()))
45 | }
46 | }
47 | if err := scanner.Err(); err != nil {
48 | fmt.Println(err)
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/pluralsight_projects/golang-advanced-branching/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Runtime data
9 | pids
10 | *.pid
11 | *.seed
12 | *.pid.lock
13 |
14 | # Directory for instrumented libs generated by jscoverage/JSCover
15 | lib-cov
16 |
17 | # Coverage directory used by tools like istanbul
18 | coverage
19 |
20 | # nyc test coverage
21 | .nyc_output
22 |
23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
24 | .grunt
25 |
26 | # Bower dependency directory (https://bower.io/)
27 | bower_components
28 |
29 | # node-waf configuration
30 | .lock-wscript
31 |
32 | # Compiled binary addons (https://nodejs.org/api/addons.html)
33 | build/Release
34 |
35 | # Dependency directories
36 | node_modules/
37 | jspm_packages/
38 |
39 | # TypeScript v1 declaration files
40 | typings/
41 |
42 | # Optional npm cache directory
43 | .npm
44 |
45 | # Optional eslint cache
46 | .eslintcache
47 |
48 | # Optional REPL history
49 | .node_repl_history
50 |
51 | # Output of 'npm pack'
52 | *.tgz
53 |
54 | # Yarn Integrity file
55 | .yarn-integrity
56 |
57 | # dotenv environment variables file
58 | .env
59 |
60 | # next.js build output
61 | .next
62 |
--------------------------------------------------------------------------------
/gostandard_libs/loger_demo/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "log"
5 | "os"
6 | )
7 |
8 | type messageType int
9 |
10 | const (
11 | INFO messageType = 0 + iota
12 | WARNING
13 | ERROR
14 | FATAL
15 | )
16 |
17 | /*func main() {
18 | writeLog(INFO, "this is an information message!")
19 | writeLog(WARNING, "this is a warning")
20 | writeLog(ERROR, "this is an error")
21 | writeLog(FATAL, "we crashed")
22 | writeLog(INFO, "you'll never see this message!")
23 |
24 | }*/
25 |
26 | func writeLog(messagetype messageType, message string) {
27 |
28 | file, err := os.OpenFile("log.txt", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0666)
29 |
30 | if err != nil {
31 | log.Fatal(err)
32 | }
33 |
34 | switch messagetype {
35 | case INFO:
36 | logger := log.New(file, "INFO: ", log.Ldate|log.Ltime|log.Lshortfile)
37 | logger.Println(message)
38 | case WARNING:
39 | logger := log.New(file, "WARNING: ", log.Ldate|log.Ltime|log.Lshortfile)
40 | logger.Println(message)
41 | case ERROR:
42 | logger := log.New(file, "ERROR: ", log.Ldate|log.Ltime|log.Lshortfile)
43 | logger.Println(message)
44 | case FATAL:
45 | logger := log.New(file, "FATAL: ", log.Ldate|log.Ltime|log.Lshortfile)
46 | logger.Fatal(message)
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/concurrentprogram/ChannelDemo/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "sync"
6 | )
7 |
8 | func main() {
9 | println("Channel Demo..")
10 | wg := &sync.WaitGroup{}
11 | //ch := make(chan int)
12 | //Buffered channel
13 | ch := make(chan int, 2)
14 | wg.Add(2)
15 | /* go func(ch chan int, wg *sync.WaitGroup) {
16 | fmt.Println("Channel Reader..")
17 | fmt.Println(<-ch)
18 | fmt.Println(<-ch)
19 | wg.Done()
20 | }(ch, wg)
21 |
22 | go func(ch chan int, wg *sync.WaitGroup) {
23 | ch <- 2
24 | ch <- 5
25 | wg.Done()
26 | }(ch, wg) */
27 |
28 | //Different channel type
29 |
30 | go func(ch <-chan int, wg *sync.WaitGroup) {
31 | fmt.Println("Channel Reader Recieve only..")
32 | //fmt.Println(<-ch)
33 | //fmt.Println(<-ch)
34 | //Better way to read from channel.
35 | //if msg, ok := <-ch; ok {
36 | // fmt.Println(msg)
37 | //}
38 |
39 | for i := range ch {
40 | fmt.Println(i)
41 | }
42 |
43 | wg.Done()
44 | }(ch, wg)
45 |
46 | go func(ch chan<- int, wg *sync.WaitGroup) {
47 | //Channel push only
48 | for i := 0; i < 10; i++ {
49 | ch <- i
50 | }
51 | //only normal channel or push only channel can close the channel.
52 | //close(ch)
53 | wg.Done()
54 | }(ch, wg)
55 | wg.Wait()
56 | }
57 |
--------------------------------------------------------------------------------
/functions/simplemaths/scemanticversion.go:
--------------------------------------------------------------------------------
1 | package simplemaths
2 |
3 | import "fmt"
4 |
5 | /// Method Declarations
6 | type SemanticVersion struct {
7 | // private variables . Small letter.
8 | major, minor, patch int
9 | }
10 |
11 | func NewSemanticVersion(major, minor, patch int) SemanticVersion {
12 | return SemanticVersion{
13 | major: major,
14 | minor: minor,
15 | patch: patch,
16 | }
17 | }
18 |
19 | //General way.
20 | func AnotherString(sv SemanticVersion) string {
21 | return fmt.Sprintf("%d.%d.%d", sv.major, sv.minor, sv.patch)
22 | }
23 |
24 | // This is a method for semantic version type.
25 | func (sv SemanticVersion) String() string {
26 | return fmt.Sprintf("%d.%d.%d", sv.major, sv.minor, sv.patch)
27 | }
28 |
29 | // Value based Reciever. You have to always create a copy of object then call again for state update.
30 | //func (sv SemanticVersion) IncrementMajor() SemanticVersion {
31 | // sv.major += 1
32 | // return sv
33 | //}
34 |
35 | // Pointer based method reciever.
36 |
37 | func (sv *SemanticVersion) IncrementMajor() {
38 | sv.major += 1
39 | }
40 |
41 | func (sv *SemanticVersion) IncrementMinor() {
42 | sv.minor += 1
43 | }
44 |
45 | func (sv *SemanticVersion) IncrementPatch() {
46 | sv.patch += 1
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/testinggolang/README.md:
--------------------------------------------------------------------------------
1 | #### Go Testing Commands
2 |
3 | 1. Run all test
4 | ```
5 | go test
6 | ```
7 | 2. Test Specific package
8 | ```
9 | go test {pkg1} {pkg2}...
10 | ```
11 | 3. Run tests in current and decendent directory
12 | ```
13 | go test ./...
14 | ```
15 | 4. Generate verbose output
16 | ```
17 | go test -v
18 | ```
19 | 5. Run only tests matching
20 | ```
21 | go test -run {regexp}
22 | ```
23 | 6. Generate Test Coverage
24 | ```
25 | go test -cover
26 | ```
27 | 7. Generatge test cover profile to find exact functions missing test coverage.
28 | ```
29 | go test -coverprofile cover.out
30 | go tool cover -func cover.out
31 | go tool cover -html cover.out
32 | go test -coverprofile count.out -covermode count
33 | go tool cover -html cover.out
34 | ```
35 |
36 | 8. Benchmark testing including other test
37 | ```
38 | go test -bench .
39 | go test -bench . -benchtime 10s
40 |
41 | ```
42 | 9. Profile testing - block, cover, cpu, mem, mutex
43 | ```
44 | go test -bench . -benchmem
45 | go test -bench SHA1 -benchmem
46 | go test -trace {trace.out}
47 | go test -{type}profile {file}
48 | go test -bench Alloc -memprofile profile.out
49 | ## install choco install graphviz for graph
50 | go tool pprof profile.out
51 | type help to more info. like run svg
52 | ```
--------------------------------------------------------------------------------
/ginframeworkdemo/vacationtracker/employee/employee.go:
--------------------------------------------------------------------------------
1 | package employee
2 |
3 | import (
4 | "fmt"
5 | "time"
6 | )
7 |
8 | type Employee struct {
9 | ID int
10 | FirstName string
11 | LastName string
12 | StartDate time.Time
13 | Position string
14 | TotalPTO float32
15 | Status string
16 | TimeOff []TimeOff
17 | }
18 |
19 | type TimeOff struct {
20 | Type TimeoffType
21 | Amount float32 `form:"amount" json:"amount" binding:"required"`
22 | StartDate time.Time `form:"date" json:"date" binding:"required" time_format:"2006-01-02"`
23 | Status TimeoffStatus
24 | }
25 |
26 | type TimeoffStatus string
27 | type TimeoffType string
28 |
29 | const (
30 | TimeoffStatusRequested TimeoffStatus = "Requested"
31 | TimeoffStatusScheduled TimeoffStatus = "Scheduled"
32 | TimeoffStatusTaken TimeoffStatus = "Taken"
33 | )
34 |
35 | const (
36 | TimeoffTypeHoliday TimeoffType = "Holiday"
37 | TimeoffTypePTO TimeoffType = "PTO"
38 | )
39 |
40 | func Get(id int) (*Employee, error) {
41 | for i := range employees {
42 | if employees[i].ID == id {
43 | return &employees[i], nil
44 | }
45 | }
46 | return nil, fmt.Errorf("employee with id %v not found", id)
47 | }
48 |
49 | func GetAll() []Employee {
50 | return employees
51 | }
52 |
--------------------------------------------------------------------------------
/gostandard_libs/custom_type/customtype.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/erankitcs/golang_learning/gostandard_libs/custom_type/media"
7 | )
8 |
9 | func main() {
10 | fmt.Println("My Fav movies")
11 | //myMov := media.Movie{}
12 | //myMov.Title = "Top Gun"
13 | //myMov.Rating = media.R
14 | //myMov.BoxOffice = 43.2
15 | //fmt.Printf("My fav movie is : %s \n", myMov.Title)
16 | //fmt.Printf("its rating is : %s \n", myMov.Rating)
17 | //fmt.Printf("It made %f in the box office. \n", myMov.BoxOffice)
18 |
19 | //myMov := media.NewMovie("Top Gun", media.R, 43.2)
20 | //fmt.Printf("My fav movie is : %s \n", myMov.GetTitle())
21 | //fmt.Printf("its rating is : %s \n", myMov.GetRating())
22 | //fmt.Printf("It made %f in the box office. \n", myMov.GetBoxOffice())
23 | //myMov.SetTitle("New Top Gun")
24 | //fmt.Printf("My fav movie is : %s \n", myMov.GetTitle())
25 |
26 | var myMov media.Catalogable = &media.Movie{}
27 | myMov.NewMovie("Top Gun", media.PG, 32.8)
28 | fmt.Printf("My fav movie is : %s \n", myMov.GetTitle())
29 | fmt.Printf("its rating is : %s \n", myMov.GetRating())
30 | fmt.Printf("It made %f in the box office. \n", myMov.GetBoxOffice())
31 | myMov.SetTitle("New Top Gun")
32 | fmt.Printf("My fav movie is : %s \n", myMov.GetTitle())
33 | }
34 |
--------------------------------------------------------------------------------
/webservice/models/user.go:
--------------------------------------------------------------------------------
1 | package models
2 |
3 | import (
4 | "errors"
5 | "fmt"
6 | )
7 |
8 | type User struct {
9 | ID int
10 | FirstName string
11 | LastName string
12 | }
13 |
14 | var (
15 | users []*User
16 | nextID = 1
17 | )
18 |
19 | func GetUsers() []*User {
20 | return users
21 | }
22 |
23 | func AddUser(u User) (User, error) {
24 | if u.ID != 0 {
25 | return User{}, errors.New("New User must not include id or it must be set to zero")
26 | }
27 | u.ID = nextID
28 | nextID++
29 | users = append(users, &u)
30 | return u, nil
31 | }
32 |
33 | func GetUserById(id int) (User, error) {
34 | for _, u := range users {
35 | if u.ID == id {
36 | return *u, nil
37 | }
38 | }
39 | return User{}, fmt.Errorf("User Id with '%v' not found", id)
40 | }
41 |
42 | func UpdateUser(u User) (User, error) {
43 | for i, useritem := range users {
44 | if u.ID == useritem.ID {
45 | users[i] = &u
46 | return *users[i], nil
47 | }
48 | }
49 | return User{}, fmt.Errorf("User Id with '%v' not found", u.ID)
50 |
51 | }
52 |
53 | func RemoveUserById(id int) error {
54 | for i, u := range users {
55 | if u.ID == id {
56 | users = append(users[:i], users[i+1:]...)
57 | return nil
58 | }
59 | }
60 | return fmt.Errorf("User with ID '%v' not found", id)
61 | }
62 |
--------------------------------------------------------------------------------
/customdatatypes/datatypes4/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/erankitcs/golang_learning/customdatatypes/datatypes4/organisation"
7 | )
8 |
9 | type Name struct {
10 | First string
11 | Last string
12 | Middle []string
13 | }
14 |
15 | type OtherName struct {
16 | First string
17 | Last string
18 | }
19 |
20 | func (n Name) Equals(otherName Name) bool {
21 | return n.First == otherName.First && n.Last == otherName.Last && len(n.Middle) == len(otherName.Middle)
22 | }
23 |
24 | func main() {
25 | fmt.Println("Custom Type Demo 4")
26 | p := organisation.NewPerson("Ankit", "Singh", organisation.NewEuropeanUnionIdentifier("123-45-33", "UK"))
27 | err := p.SetTwitterHandler("@ankit63")
28 | fmt.Printf("%T\n", organisation.TwitterHandler("test"))
29 | if err != nil {
30 | fmt.Printf("An error occurred while setting handler %s", err.Error())
31 | }
32 |
33 | name1 := Name{
34 | First: "",
35 | Last: "",
36 | }
37 |
38 | if name1.Equals(Name{}) {
39 | println("We match")
40 | }
41 |
42 | p.First = "NewName"
43 | println(p.First)
44 | println(p.Name.First)
45 | fmt.Println(p.TwitterHandler())
46 | fmt.Println(p.TwitterHandler().RedirectURL())
47 | fmt.Println(p.FullName())
48 | fmt.Println(p.ID())
49 | println(p.Country())
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/customdatatypes/datatypes5/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/erankitcs/golang_learning/customdatatypes/datatypes5/organisation"
7 | )
8 |
9 | type Name struct {
10 | First string
11 | Last string
12 | Middle []string
13 | }
14 |
15 | type OtherName struct {
16 | First string
17 | Last string
18 | }
19 |
20 | func (n Name) Equals(otherName Name) bool {
21 | return n.First == otherName.First && n.Last == otherName.Last && len(n.Middle) == len(otherName.Middle)
22 | }
23 |
24 | func main() {
25 | fmt.Println("Custom Type Demo 4")
26 | p := organisation.NewPerson("Ankit", "Singh", organisation.NewEuropeanUnionIdentifier("123-445-3455", "UK"))
27 | err := p.SetTwitterHandler("@ankit63")
28 | fmt.Printf("%T\n", organisation.TwitterHandler("test"))
29 | if err != nil {
30 | fmt.Printf("An error occurred while setting handler %s", err.Error())
31 | }
32 |
33 | name1 := Name{
34 | First: "",
35 | Last: "",
36 | }
37 |
38 | if name1.Equals(Name{}) {
39 | println("We match")
40 | }
41 |
42 | p.First = "NewName"
43 | println(p.First)
44 | println(p.Name.First)
45 | fmt.Println(p.TwitterHandler())
46 | fmt.Println(p.TwitterHandler().RedirectURL())
47 | fmt.Println(p.FullName())
48 | fmt.Println(p.ID())
49 | println(p.Country())
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/distributedapp/cmd/gradingservice/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "context"
5 | "fmt"
6 | stlog "log"
7 |
8 | "github.com/erankitcs/golang_learning/distributedapp/grades"
9 | "github.com/erankitcs/golang_learning/distributedapp/log"
10 | "github.com/erankitcs/golang_learning/distributedapp/registry"
11 | "github.com/erankitcs/golang_learning/distributedapp/service"
12 | )
13 |
14 | func main() {
15 | var r registry.Registration
16 | hostname, port := "localhost", "6000"
17 | serviceURL := fmt.Sprintf("http://%v:%v", hostname, port)
18 | r.ServiceName = registry.GradingService
19 | r.ServiceURL = serviceURL
20 | r.RequiredServices = []registry.ServiceName{registry.LogService}
21 | r.ServiceUpdateURL = r.ServiceURL + "/services"
22 | r.HeartbeatURL = r.ServiceURL + "/heartbeat"
23 | fmt.Println(r)
24 | ctx, err := service.Start(
25 | context.Background(),
26 | r,
27 | hostname,
28 | port,
29 | grades.RegisterHandlers,
30 | )
31 |
32 | if err != nil {
33 | stlog.Fatal(err)
34 | }
35 | if logProvider, err := registry.GetProvider(registry.LogService); err == nil {
36 | fmt.Printf("Logging service found at: %v\n", logProvider)
37 | log.SetClientLogger(logProvider, r.ServiceName)
38 | }
39 | <-ctx.Done()
40 | fmt.Println("Shutting down Grading service.")
41 | }
42 |
--------------------------------------------------------------------------------
/distributedapp/service/service.go:
--------------------------------------------------------------------------------
1 | package service
2 |
3 | import (
4 | "context"
5 | "fmt"
6 | "log"
7 | "net/http"
8 |
9 | "github.com/erankitcs/golang_learning/distributedapp/registry"
10 | )
11 |
12 | func Start(ctx context.Context, reg registry.Registration, host, port string,
13 | registerHandlerFun func()) (context.Context, error) {
14 | registerHandlerFun()
15 | ctx = startService(ctx, reg.ServiceName, host, port)
16 | err := registry.RegisterService(reg)
17 | if err != nil {
18 | return ctx, err
19 | }
20 | return ctx, nil
21 | }
22 |
23 | func startService(ctx context.Context, serviceName registry.ServiceName, host, port string) context.Context {
24 | ctx, cancel := context.WithCancel(ctx)
25 |
26 | var srv http.Server
27 | srv.Addr = ":" + port
28 |
29 | go func() {
30 | log.Println(srv.ListenAndServe())
31 | cancel()
32 | }()
33 |
34 | go func() {
35 | fmt.Printf("%v started. Please press any key to stop.\n", serviceName)
36 | var s string
37 | fmt.Scanln(&s)
38 | fmt.Printf("De-registering the service- %v with URL http://%v:%v \n", serviceName, host, port)
39 | err := registry.ShutdownService(fmt.Sprintf("http://%v:%v", host, port))
40 | if err != nil {
41 | log.Println(err)
42 | }
43 | srv.Shutdown(ctx)
44 | cancel()
45 | }()
46 | return ctx
47 | }
48 |
--------------------------------------------------------------------------------
/grpcdemo/pb/messages.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 |
3 | option go_package = "pb/messages";
4 |
5 | package messages;
6 |
7 | message Employee {
8 | int32 id = 1 ;
9 | int32 badgeNumber = 2;
10 | string firstName = 3 ;
11 | string lastName = 4;
12 | float vacationAccrualRate = 5;
13 | float vacationAccrued = 6;
14 | repeated Vacation vacations = 7;
15 | }
16 |
17 | message Vacation {
18 | int32 id = 1 ;
19 | int64 startDate = 2 ;
20 | float duration = 3;
21 | bool isCancelled = 4;
22 | }
23 |
24 | message GetAllRequest {}
25 |
26 | message GetByBadgeNumberRequest {
27 | int32 badgeNumber = 1 ;
28 | }
29 |
30 | message EmployeeRequest {
31 | Employee employee = 1;
32 | }
33 |
34 | message EmployeeResponse {
35 | Employee employee = 1 ;
36 | }
37 |
38 | message AddPhotoRequest {
39 | bytes data = 1 ;
40 | }
41 |
42 | message AddPhotoResponse {
43 | bool isOK = 1 ;
44 | }
45 |
46 | service EmployeeService {
47 | rpc GetByBadgeNumber (GetByBadgeNumberRequest) returns (EmployeeResponse);
48 | rpc GetAll (GetAllRequest) returns (stream EmployeeResponse);
49 | rpc Save (EmployeeRequest) returns (EmployeeResponse);
50 | rpc SaveAll(stream EmployeeRequest) returns (stream EmployeeResponse);
51 | rpc AddPhoto (stream AddPhotoRequest) returns (AddPhotoResponse);
52 | }
--------------------------------------------------------------------------------
/distributedappdocker/service/service.go:
--------------------------------------------------------------------------------
1 | package service
2 |
3 | import (
4 | "context"
5 | "fmt"
6 | "log"
7 | "net/http"
8 |
9 | "github.com/erankitcs/golang_learning/distributedapp/registry"
10 | )
11 |
12 | func Start(ctx context.Context, reg registry.Registration, host, port string,
13 | registerHandlerFun func()) (context.Context, error) {
14 | registerHandlerFun()
15 | ctx = startService(ctx, reg.ServiceName, host, port)
16 | err := registry.RegisterService(reg)
17 | if err != nil {
18 | return ctx, err
19 | }
20 | return ctx, nil
21 | }
22 |
23 | func startService(ctx context.Context, serviceName registry.ServiceName, host, port string) context.Context {
24 | ctx, cancel := context.WithCancel(ctx)
25 |
26 | var srv http.Server
27 | srv.Addr = ":" + port
28 |
29 | go func() {
30 | log.Println(srv.ListenAndServe())
31 | cancel()
32 | }()
33 |
34 | go func() {
35 | fmt.Printf("%v started. Please press- s key to stop.\n", serviceName)
36 | var s string
37 | fmt.Scanln(&s)
38 | if s == "s" {
39 | fmt.Printf("De-registering the service- %v with URL http://%v:%v \n", serviceName, host, port)
40 | err := registry.ShutdownService(fmt.Sprintf("http://%v:%v", host, port))
41 | if err != nil {
42 | log.Println(err)
43 | }
44 | srv.Shutdown(ctx)
45 | cancel()
46 | }
47 |
48 | }()
49 | return ctx
50 | }
51 |
--------------------------------------------------------------------------------
/microservices/product-api-withswagger-client/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/erankitcs/golang_learning/microservices/productapiclient
2 |
3 | go 1.17
4 |
5 | require (
6 | github.com/go-openapi/errors v0.20.2
7 | github.com/go-openapi/runtime v0.24.1
8 | github.com/go-openapi/strfmt v0.21.3
9 | github.com/go-openapi/swag v0.21.1
10 | github.com/go-openapi/validate v0.22.0
11 | )
12 |
13 | require (
14 | github.com/PuerkitoBio/purell v1.1.1 // indirect
15 | github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
16 | github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect
17 | github.com/go-openapi/analysis v0.21.2 // indirect
18 | github.com/go-openapi/jsonpointer v0.19.5 // indirect
19 | github.com/go-openapi/jsonreference v0.19.6 // indirect
20 | github.com/go-openapi/loads v0.21.1 // indirect
21 | github.com/go-openapi/spec v0.20.4 // indirect
22 | github.com/josharian/intern v1.0.0 // indirect
23 | github.com/mailru/easyjson v0.7.7 // indirect
24 | github.com/mitchellh/mapstructure v1.4.3 // indirect
25 | github.com/oklog/ulid v1.3.1 // indirect
26 | github.com/opentracing/opentracing-go v1.2.0 // indirect
27 | go.mongodb.org/mongo-driver v1.10.0 // indirect
28 | golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd // indirect
29 | golang.org/x/text v0.3.7 // indirect
30 | gopkg.in/yaml.v2 v2.4.0 // indirect
31 | )
32 |
--------------------------------------------------------------------------------
/customdatatypes/datatypes2/organisation/person.go:
--------------------------------------------------------------------------------
1 | package organisation
2 |
3 | import (
4 | "errors"
5 | "fmt"
6 | "strings"
7 | )
8 |
9 | type Handler struct {
10 | handle string
11 | name string
12 | }
13 |
14 | type TwitterHandler string
15 |
16 | func (th TwitterHandler) RedirectURL() string {
17 | cleanHandler := strings.TrimPrefix(string(th), "@")
18 | return fmt.Sprintf("https://www.twitter.com/%s", cleanHandler)
19 | }
20 |
21 | type Identifiable interface {
22 | ID() string
23 | }
24 |
25 | type Person struct {
26 | firstName string
27 | lastName string
28 | twitterHandler TwitterHandler
29 | }
30 |
31 | func NewPerson(firstName, lastName string) Person {
32 | return Person{
33 | firstName: firstName,
34 | lastName: lastName,
35 | }
36 | }
37 |
38 | func (p *Person) SetTwitterHandler(handler TwitterHandler) error {
39 | if len(handler) == 0 {
40 | p.twitterHandler = handler
41 | } else if !strings.HasPrefix(string(handler), "@") {
42 | return errors.New("twitter handle must start with @ in text")
43 | }
44 | p.twitterHandler = handler
45 | return nil
46 | }
47 |
48 | func (p *Person) FullName() string {
49 | return fmt.Sprintf("%s %s", p.firstName, p.lastName)
50 | }
51 |
52 | func (p *Person) ID() string {
53 | return "123"
54 | }
55 |
56 | func (p *Person) TwitterHandler() TwitterHandler {
57 | return p.twitterHandler
58 | }
59 |
--------------------------------------------------------------------------------
/distributedappdocker/cmd/gradingservice/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "context"
5 | "fmt"
6 | stlog "log"
7 |
8 | "github.com/erankitcs/golang_learning/distributedapp/grades"
9 | "github.com/erankitcs/golang_learning/distributedapp/log"
10 | "github.com/erankitcs/golang_learning/distributedapp/registry"
11 | "github.com/erankitcs/golang_learning/distributedapp/service"
12 | )
13 |
14 | func main() {
15 | var r registry.Registration
16 | hostname, port := "gradingservice", "6000"
17 | serviceURL := fmt.Sprintf("http://%v:%v", hostname, port)
18 | globalServiceURL := fmt.Sprintf("http://gradingservice:%v", port)
19 | r.ServiceName = registry.GradingService
20 | r.ServiceURL = serviceURL
21 | r.RequiredServices = []registry.ServiceName{registry.LogService}
22 | r.ServiceUpdateURL = globalServiceURL + "/services"
23 | r.HeartbeatURL = globalServiceURL + "/heartbeat"
24 | fmt.Println(r)
25 | ctx, err := service.Start(
26 | context.Background(),
27 | r,
28 | hostname,
29 | port,
30 | grades.RegisterHandlers,
31 | )
32 |
33 | if err != nil {
34 | stlog.Fatal(err)
35 | }
36 | if logProvider, err := registry.GetProvider(registry.LogService); err == nil {
37 | fmt.Printf("Logging service found at: %v\n", logProvider)
38 | log.SetClientLogger(logProvider, r.ServiceName)
39 | }
40 | <-ctx.Done()
41 | fmt.Println("Shutting down Grading service.")
42 | }
43 |
--------------------------------------------------------------------------------
/microservices/product-api-withswagger/handlers/middleware.go:
--------------------------------------------------------------------------------
1 | package handlers
2 |
3 | import (
4 | "context"
5 | "net/http"
6 |
7 | "github.com/erankitcs/golang_learning/microservices/product-api-withswagger/data"
8 | )
9 |
10 | //Middleware Validate Product
11 | func (p *Products) MiddlewareProductsValidation(next http.Handler) http.Handler {
12 | return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
13 |
14 | prod := &data.Product{}
15 |
16 | err := data.FromJSON(prod, r.Body)
17 | if err != nil {
18 | p.l.Println("[ERROR] deserializing product", err)
19 |
20 | rw.WriteHeader(http.StatusBadRequest)
21 | data.ToJSON(&GenericError{Message: err.Error()}, rw)
22 | return
23 | }
24 | //validate the product
25 | errs := p.v.Validate(prod)
26 |
27 | if len(errs) != 0 {
28 | p.l.Println("[ERROR] Validating the product", errs)
29 | rw.WriteHeader(http.StatusUnprocessableEntity)
30 | data.ToJSON(&ValidationError{Messages: errs.Errors()}, rw)
31 | //http.Error(rw, fmt.Sprintf("Error validating the product: %s", err), http.StatusBadRequest)
32 | return
33 | }
34 | // add the product to the context
35 | ctx := context.WithValue(r.Context(), KeyProduct{}, prod)
36 | r = r.WithContext(ctx)
37 |
38 | // Call the next handler, which can be another middleware in the chain, or the final handler.
39 | next.ServeHTTP(rw, r)
40 | })
41 | }
42 |
--------------------------------------------------------------------------------
/microservices/product-api-withswagger/handlers/products.go:
--------------------------------------------------------------------------------
1 | package handlers
2 |
3 | import (
4 | "fmt"
5 | "log"
6 | "net/http"
7 | "strconv"
8 |
9 | "github.com/erankitcs/golang_learning/microservices/product-api-withswagger/data"
10 | "github.com/gorilla/mux"
11 | )
12 |
13 | type KeyProduct struct{}
14 |
15 | type Products struct {
16 | l *log.Logger
17 | v *data.Validation
18 | }
19 |
20 | func NewProduct(l *log.Logger, v *data.Validation) *Products {
21 | return &Products{l, v}
22 | }
23 |
24 | // ErrInvalidProductPath is an error message when the product path is not valid
25 | var ErrInvalidProductPath = fmt.Errorf("invalid Path, path should be /products/[id]")
26 |
27 | // GenericError is a generic error message returned by a server
28 | type GenericError struct {
29 | Message string `json:"message"`
30 | }
31 |
32 | // ValidationError is a collection of validation error messages
33 | type ValidationError struct {
34 | Messages []string `json:"messages"`
35 | }
36 |
37 | // getProductID returns the product ID from the URL
38 | // Panics if cannot convert the id into an integer
39 | // this should never happen as the router ensures that
40 | // this is a valid number
41 | func getProductID(r *http.Request) int {
42 | vars := mux.Vars(r)
43 | // convert the id into an integer and return
44 | id, err := strconv.Atoi(vars["id"])
45 | if err != nil {
46 | panic(err)
47 | }
48 | return id
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/distributedapp/cmd/teacherportalservice/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "context"
5 | "fmt"
6 | stlog "log"
7 |
8 | "github.com/erankitcs/golang_learning/distributedapp/log"
9 | "github.com/erankitcs/golang_learning/distributedapp/registry"
10 | "github.com/erankitcs/golang_learning/distributedapp/service"
11 | "github.com/erankitcs/golang_learning/distributedapp/teacherportal"
12 | )
13 |
14 | func main() {
15 | err := teacherportal.ImportTemplates()
16 |
17 | if err != nil {
18 | stlog.Fatal(err)
19 | }
20 |
21 | host, port := "localhost", "5000"
22 |
23 | serviceAddress := fmt.Sprintf("http://%v:%v", host, port)
24 |
25 | var r registry.Registration
26 | r.ServiceName = registry.TeacherPortalService
27 | r.ServiceURL = serviceAddress
28 | r.RequiredServices = []registry.ServiceName{
29 | registry.LogService,
30 | registry.GradingService,
31 | }
32 | r.ServiceUpdateURL = r.ServiceURL + "/services"
33 | r.HeartbeatURL = r.ServiceURL + "/heartbeat"
34 |
35 | ctx, err := service.Start(
36 | context.Background(),
37 | r,
38 | host,
39 | port,
40 | teacherportal.RegisterHandlers,
41 | )
42 |
43 | if err != nil {
44 | stlog.Fatal(err)
45 | }
46 |
47 | if logProvider, err := registry.GetProvider(registry.LogService); err == nil {
48 | log.SetClientLogger(logProvider, r.ServiceName)
49 | }
50 |
51 | <-ctx.Done()
52 | fmt.Println("Shutting down teacher portal.")
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/microservices/product-api-withswagger-client/models/generic_error.go:
--------------------------------------------------------------------------------
1 | // Code generated by go-swagger; DO NOT EDIT.
2 |
3 | package models
4 |
5 | // This file was generated by the swagger tool.
6 | // Editing this file might prove futile when you re-run the swagger generate command
7 |
8 | import (
9 | "context"
10 |
11 | "github.com/go-openapi/strfmt"
12 | "github.com/go-openapi/swag"
13 | )
14 |
15 | // GenericError GenericError is a generic error message returned by a server
16 | //
17 | // swagger:model GenericError
18 | type GenericError struct {
19 |
20 | // message
21 | Message string `json:"message,omitempty"`
22 | }
23 |
24 | // Validate validates this generic error
25 | func (m *GenericError) Validate(formats strfmt.Registry) error {
26 | return nil
27 | }
28 |
29 | // ContextValidate validates this generic error based on context it is used
30 | func (m *GenericError) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
31 | return nil
32 | }
33 |
34 | // MarshalBinary interface implementation
35 | func (m *GenericError) MarshalBinary() ([]byte, error) {
36 | if m == nil {
37 | return nil, nil
38 | }
39 | return swag.WriteJSON(m)
40 | }
41 |
42 | // UnmarshalBinary interface implementation
43 | func (m *GenericError) UnmarshalBinary(b []byte) error {
44 | var res GenericError
45 | if err := swag.ReadJSON(b, &res); err != nil {
46 | return err
47 | }
48 | *m = res
49 | return nil
50 | }
51 |
--------------------------------------------------------------------------------
/pluralsight_projects/golang-personal-budget-cli/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | m2 "personal-budget/module2"
6 | "time"
7 | )
8 |
9 | var months = []time.Month{
10 | time.January,
11 | time.February,
12 | time.March,
13 | time.April,
14 | time.May,
15 | time.June,
16 | time.July,
17 | time.August,
18 | time.September,
19 | time.October,
20 | time.November,
21 | time.December,
22 | time.January,
23 | }
24 |
25 | func main() {
26 | bu, _ := m2.CreateBudget(time.January, 1000)
27 | bu.AddItem("bananas", 10.0)
28 |
29 | fmt.Println("Items in January:", len(bu.Items))
30 | fmt.Printf("Current cost for January: $%.2f \n", bu.CurrentCost())
31 |
32 | m2.CreateBudget(time.February, 1000)
33 |
34 | bu2 := m2.GetBudget(time.February)
35 | bu2.AddItem("bananas", 10.0)
36 | bu2.AddItem("coffee", 3.99)
37 | bu2.AddItem("gym", 50.0)
38 | bu2.RemoveItem("coffee")
39 | fmt.Println("Items in February:", len(bu2.Items))
40 | fmt.Printf("Current cost for February: $%.2f \n", bu2.CurrentCost())
41 |
42 | fmt.Println("Resetting Budget Report...")
43 | m2.InitializeReport()
44 |
45 | for _, month := range months {
46 | _, err := m2.CreateBudget(month, 100.00)
47 | if err == nil {
48 | fmt.Println("Budget created for", month)
49 | } else {
50 | fmt.Println("Error creating budget:", err)
51 | }
52 | }
53 |
54 | _, err := m2.CreateBudget(time.December, 100.00)
55 | fmt.Println(err)
56 | }
57 |
--------------------------------------------------------------------------------
/microservices/product-api/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "context"
5 | "log"
6 | "net/http"
7 | "os"
8 | "os/signal"
9 | "syscall"
10 | "time"
11 |
12 | "github.com/erankitcs/golang_learning/microservices/product-api/handlers"
13 | )
14 |
15 | var bindAddress = ":9090"
16 |
17 | func main() {
18 | //Create a logger
19 | l := log.New(os.Stdout, "product-api ", log.LstdFlags)
20 | // New Product handler
21 | ph := handlers.NewProduct(l)
22 | // creating new Muxer and register handler
23 | sm := http.NewServeMux()
24 | sm.Handle("/", ph)
25 | //creating new server
26 | s := http.Server{
27 | Addr: bindAddress,
28 | Handler: sm,
29 | ErrorLog: l,
30 | ReadTimeout: 5 * time.Second,
31 | WriteTimeout: 10 * time.Second,
32 | IdleTimeout: 120 * time.Second,
33 | }
34 |
35 | //Starting the server
36 | go func() {
37 | l.Printf("Starting Server on Port %s\n", bindAddress)
38 | err := s.ListenAndServe()
39 | if err != nil {
40 | l.Printf("Error in starting the server: %s\n", err)
41 | os.Exit(1)
42 | }
43 | }()
44 |
45 | //Gracefull shutdown
46 | c := make(chan os.Signal, 1)
47 | signal.Notify(c, os.Interrupt)
48 | signal.Notify(c, syscall.SIGTERM)
49 |
50 | //block util a signal recieved
51 | sig := <-c
52 | log.Println("Got Signal: ", sig)
53 | ctx, cancelFun := context.WithTimeout(context.Background(), 30*time.Second)
54 | cancelFun()
55 | s.Shutdown(ctx)
56 |
57 | }
58 |
--------------------------------------------------------------------------------
/gostandard_libs/fmt_demo/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "os"
6 | )
7 |
8 | type messageType int
9 |
10 | const (
11 | INFO messageType = 0 + iota
12 | WARNING
13 | ERROR
14 | )
15 |
16 | const (
17 | InfoColor = "\033[1;34m%s\033[0m"
18 | WarningColor = "\033[1;33m%s\033[0m"
19 | ErrorColor = "\033[1;31m%s\033[0m"
20 | )
21 |
22 | func main() {
23 | var firstNumber int
24 | println("Whats you first number ?")
25 | fmt.Scanln("%d", &firstNumber)
26 |
27 | var secondNumber int
28 | println("Whats you second number ?")
29 | fmt.Scanln("%d", &secondNumber)
30 |
31 | fmt.Printf("Two number sum is %v", firstNumber+secondNumber)
32 |
33 | fmt.Println("\nMessage Formating program.")
34 |
35 | fileName := "test.txt"
36 |
37 | showMessage(INFO, fmt.Sprintf("About to open %s", fileName))
38 |
39 | file, err := os.Open("test.txt")
40 | if err != nil {
41 | showMessage(ERROR, err.Error())
42 | }
43 | defer file.Close()
44 |
45 | }
46 |
47 | func showMessage(messageType messageType, message string) {
48 | switch messageType {
49 | case INFO:
50 | printMessage := fmt.Sprintf("\nInformation: \n%s\n", message)
51 | fmt.Printf(InfoColor, printMessage)
52 | case WARNING:
53 | printMessage := fmt.Sprintf("\nWarning: \n%s\n", message)
54 | fmt.Printf(WarningColor, printMessage)
55 | case ERROR:
56 | printMessage := fmt.Sprintf("\nError: \n%s\n", message)
57 | fmt.Printf(ErrorColor, printMessage)
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/distributedappdocker/cmd/teacherportalservice/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "context"
5 | "fmt"
6 | stlog "log"
7 |
8 | "github.com/erankitcs/golang_learning/distributedapp/log"
9 | "github.com/erankitcs/golang_learning/distributedapp/registry"
10 | "github.com/erankitcs/golang_learning/distributedapp/service"
11 | "github.com/erankitcs/golang_learning/distributedapp/teacherportal"
12 | )
13 |
14 | func main() {
15 | err := teacherportal.ImportTemplates()
16 |
17 | if err != nil {
18 | stlog.Fatal(err)
19 | }
20 |
21 | host, port := "localhost", "5000"
22 |
23 | serviceAddress := fmt.Sprintf("http://%v:%v", host, port)
24 | globalServiceURL := fmt.Sprintf("http://teacherportalservice:%v", port)
25 | var r registry.Registration
26 | r.ServiceName = registry.TeacherPortalService
27 | r.ServiceURL = serviceAddress
28 | r.RequiredServices = []registry.ServiceName{
29 | registry.LogService,
30 | registry.GradingService,
31 | }
32 | r.ServiceUpdateURL = globalServiceURL + "/services"
33 | r.HeartbeatURL = globalServiceURL + "/heartbeat"
34 |
35 | ctx, err := service.Start(
36 | context.Background(),
37 | r,
38 | host,
39 | port,
40 | teacherportal.RegisterHandlers,
41 | )
42 |
43 | if err != nil {
44 | stlog.Fatal(err)
45 | }
46 |
47 | if logProvider, err := registry.GetProvider(registry.LogService); err == nil {
48 | log.SetClientLogger(logProvider, r.ServiceName)
49 | }
50 |
51 | <-ctx.Done()
52 | fmt.Println("Shutting down teacher portal.")
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/ginframeworkdemo/vacationtracker/templates/employee.tmpl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | PTO Events - {{.LastName}}, {{.FirstName}}
8 |
9 |
10 |
11 | PTO Information for {{.LastName}}, {{.FirstName}}
12 |
13 |
14 | | Date |
15 | Amount [h] |
16 | Type |
17 | Status |
18 |
19 | {{range .TimeOff}}
20 |
21 | | {{.StartDate.Format "02-Jan"}} |
22 | {{.Amount}} |
23 | {{.Type}} |
24 | {{.Status}} |
25 |
26 | {{end}}
27 |
28 |
29 |
30 |
51 |
52 |
--------------------------------------------------------------------------------
/gostandard_libs/custom_type/typesruntime.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "reflect"
6 | )
7 |
8 | func main() {
9 |
10 | type person struct {
11 | personId int
12 | firstName string
13 | lastName string
14 | }
15 |
16 | newPerson := person{0, "Ankit", "Singh"}
17 |
18 | fmt.Printf("My person is %s %s with Id %d\n", newPerson.firstName, newPerson.lastName, newPerson.personId)
19 | fmt.Printf("Type is %v \n", reflect.TypeOf(newPerson))
20 | fmt.Printf("Value is %v \n", reflect.ValueOf(newPerson))
21 | fmt.Printf("Kind of type is %v \n", reflect.ValueOf(newPerson).Kind())
22 | type employee struct {
23 | empId int
24 | firstName string
25 | lastName string
26 | }
27 |
28 | type customer struct {
29 | customerId int
30 | firstName string
31 | lastName string
32 | company string
33 | }
34 |
35 | newEmp := employee{0, "Ankit", "Singh"}
36 | newCus := customer{100, "Ankit", "Singh", "NAB"}
37 |
38 | addPerson(newEmp)
39 | addPerson(newCus)
40 |
41 | }
42 |
43 | func addPerson(p interface{}) bool {
44 | if reflect.ValueOf(p).Kind() == reflect.Struct {
45 | v := reflect.ValueOf(p)
46 |
47 | switch reflect.TypeOf(p).Name() {
48 | case "employee":
49 | empString := "insert into emp (?,?,?)"
50 | fmt.Printf("SQL String %s \n", empString)
51 | fmt.Printf("Added %v \n", v.Field(1))
52 | case "customer":
53 | custString := "insert into cust (?,?,?)"
54 | fmt.Printf("SQL String %s \n", custString)
55 | fmt.Printf("Added %v \n", v.Field(1))
56 | }
57 | return true
58 | } else {
59 | return false
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/microservices/product-api-withswagger/handlers/get.go:
--------------------------------------------------------------------------------
1 | package handlers
2 |
3 | import (
4 | "net/http"
5 |
6 | "github.com/erankitcs/golang_learning/microservices/product-api-withswagger/data"
7 | )
8 |
9 | // swagger:route GET /products products listProducts
10 | // Return a list of product.
11 | // responses:
12 | // 200: productsResponse
13 | func (p *Products) ListAll(rw http.ResponseWriter, r *http.Request) {
14 | p.l.Println("[DEBUG] get all records")
15 | prods := data.GetProducts()
16 | rw.Header().Add("Content-Type", "application/json")
17 | err := data.ToJSON(prods, rw)
18 | if err != nil {
19 | p.l.Println("[ERROR] serializing product", err)
20 | }
21 | }
22 |
23 | // swagger:route GET /products/{id} products listSingleProduct
24 | // Return a single product.
25 | // responses:
26 | // 200: productResponse
27 | func (p *Products) ListSingle(rw http.ResponseWriter, r *http.Request) {
28 | p.l.Println("[DEBUG] get single requested product")
29 | pid := getProductID(r)
30 | prod, err := data.GetProductByID(pid)
31 | switch err {
32 | case nil:
33 | case data.ErrorProductNotFound:
34 | p.l.Println("[ERROR] fetching product", err)
35 | rw.WriteHeader(http.StatusNotFound)
36 | data.ToJSON(&GenericError{Message: err.Error()}, rw)
37 | return
38 | default:
39 | p.l.Println("[ERROR] fetching product", err)
40 |
41 | rw.WriteHeader(http.StatusInternalServerError)
42 | data.ToJSON(&GenericError{Message: err.Error()}, rw)
43 | return
44 | }
45 | err = data.ToJSON(prod, rw)
46 | if err != nil {
47 | p.l.Println("[ERROR] serializing product", err)
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/ginframeworkdemo/requestdemo/public/employee.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | PTO Events - Jane, Allion
8 |
9 |
10 |
11 | PTO Information for Jane, Allison
12 |
13 |
14 | | Date |
15 | Amount [h] |
16 | Type |
17 | Status |
18 |
19 |
20 | | 1-Jan |
21 | 8 |
22 | Holiday |
23 | Taken |
24 |
25 |
26 | | 16-Aug |
27 | 16 |
28 | PTO |
29 | Scheduled |
30 |
31 |
32 | | 8-Dec |
33 | 16 |
34 | PTO |
35 | Requested |
36 |
37 |
38 |
39 |
60 |
61 |
--------------------------------------------------------------------------------
/ginframeworkdemo/vacationtracker/public/employee.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | PTO Events - Jane, Allion
8 |
9 |
10 |
11 | PTO Information for Jane, Allison
12 |
13 |
14 | | Date |
15 | Amount [h] |
16 | Type |
17 | Status |
18 |
19 |
20 | | 1-Jan |
21 | 8 |
22 | Holiday |
23 | Taken |
24 |
25 |
26 | | 16-Aug |
27 | 16 |
28 | PTO |
29 | Scheduled |
30 |
31 |
32 | | 8-Dec |
33 | 16 |
34 | PTO |
35 | Requested |
36 |
37 |
38 |
39 |
60 |
61 |
--------------------------------------------------------------------------------
/gostandard_libs/custom_type/functions.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "reflect"
6 | "runtime"
7 | "strings"
8 | "time"
9 | )
10 |
11 | func main() {
12 | ourTitle := "the go standard library"
13 | newTitle := properTitle(ourTitle)
14 | fmt.Printf("%s\n", newTitle)
15 | fmt.Printf("Double function : %d", doubleOurNumber(3))
16 |
17 | timed := MakeTimedFunction(properTitle).(func(string) string)
18 | newTitle1 := timed(ourTitle)
19 | fmt.Println(newTitle1)
20 | timedToo := MakeTimedFunction(doubleOurNumber).(func(int) int)
21 | fmt.Println(timedToo(2))
22 | }
23 |
24 | func MakeTimedFunction(f interface{}) interface{} {
25 | rf := reflect.TypeOf(f)
26 | if rf.Kind() != reflect.Func {
27 | panic("expects a function")
28 | }
29 | vf := reflect.ValueOf(f)
30 | wrapperF := reflect.MakeFunc(rf, func(in []reflect.Value) []reflect.Value {
31 | start := time.Now()
32 | out := vf.Call(in)
33 | end := time.Now()
34 | fmt.Printf("Calling %s took %v \n", runtime.FuncForPC(vf.Pointer()).Name(), end.Sub(start))
35 | return out
36 | })
37 | return wrapperF.Interface()
38 | }
39 |
40 | func properTitle(input string) string {
41 | // from: https://golangcookbook.com/chapters/strings/title/
42 | words := strings.Fields(input)
43 | smallwords := " a an on the to "
44 |
45 | for index, word := range words {
46 | if strings.Contains(smallwords, " "+word+" ") {
47 | words[index] = word
48 | } else {
49 | words[index] = strings.Title(word)
50 | }
51 | }
52 | return strings.Join(words, " ")
53 | }
54 |
55 | func doubleOurNumber(a int) int {
56 |
57 | time.Sleep(1 * time.Second)
58 | return a * 2
59 | }
60 |
--------------------------------------------------------------------------------
/pluralsight_projects/golang-fifa-world-cup-web-service/handlers/03_dispatch_handler_test.go:
--------------------------------------------------------------------------------
1 | package handlers
2 |
3 | import (
4 | "bytes"
5 | "golang-fifa-world-cup-web-service/data"
6 | "net/http"
7 | "net/http/httptest"
8 | "testing"
9 | )
10 |
11 | func TestCorrectHTTPGetMethodDispatch(t *testing.T) {
12 | setup()
13 |
14 | req, _ := http.NewRequest("GET", "/winners", nil)
15 |
16 | rr := httptest.NewRecorder()
17 | handler := http.HandlerFunc(WinnersHandler)
18 | handler.ServeHTTP(rr, req)
19 |
20 | if body := rr.Body.String(); body == "" {
21 | t.Error("Did not properly dispatch HTTP GET")
22 | }
23 | }
24 |
25 | func TestCorrectHTTPPostMethodDispatch(t *testing.T) {
26 | setup()
27 |
28 | var jsonStr = []byte(`{"country":"Croatia", "year": 2030}`)
29 | req, _ := http.NewRequest("POST", "/winners", bytes.NewBuffer(jsonStr))
30 | req.Header.Set("Content-Type", "application/json")
31 | req.Header.Set("X-ACCESS-TOKEN", data.AccessToken)
32 |
33 | rr := httptest.NewRecorder()
34 | handler := http.HandlerFunc(WinnersHandler)
35 | handler.ServeHTTP(rr, req)
36 |
37 | if status := rr.Code; status != http.StatusCreated {
38 | t.Error("Did not properly dispatch HTTP POST", status)
39 | }
40 | }
41 |
42 | func TestCorrectHTTPUnsupportedMethodDispatch(t *testing.T) {
43 | setup()
44 |
45 | req, _ := http.NewRequest("PUT", "/winners", nil)
46 |
47 | rr := httptest.NewRecorder()
48 | handler := http.HandlerFunc(WinnersHandler)
49 | handler.ServeHTTP(rr, req)
50 |
51 | if status := rr.Code; status != http.StatusMethodNotAllowed {
52 | t.Error("Did not properly catch unsupported HTTP methods", status)
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/ginframeworkdemo/vacationtracker/employee/data.go:
--------------------------------------------------------------------------------
1 | package employee
2 |
3 | import "time"
4 |
5 | var employees = []Employee{
6 | {
7 | ID: 962134,
8 | FirstName: "Jennifer",
9 | LastName: "Wat",
10 | Position: "CEO",
11 | StartDate: time.Now().Add(-13 * time.Hour * 24 * 365),
12 | Status: "Active",
13 | TotalPTO: 30,
14 | TimeOff: []TimeOff{
15 | {
16 | Type: TimeoffTypeHoliday,
17 | Amount: 8.,
18 | StartDate: time.Date(2023, 1, 1, 0, 0, 0, 0, time.UTC),
19 | Status: TimeoffStatusTaken,
20 | }, {
21 | Type: TimeoffTypePTO,
22 | Amount: 16.,
23 | StartDate: time.Date(2023, 8, 16, 0, 0, 0, 0, time.UTC),
24 | Status: TimeoffStatusScheduled,
25 | }, {
26 | Type: TimeoffTypePTO,
27 | Amount: 16.,
28 | StartDate: time.Date(2023, 12, 8, 0, 0, 0, 0, time.UTC),
29 | Status: TimeoffStatusRequested,
30 | },
31 | },
32 | },
33 | {
34 | ID: 176158,
35 | FirstName: "Allison",
36 | LastName: "Jane",
37 | Position: "COO",
38 | StartDate: time.Now().Add(-4 * time.Hour * 24 * 365),
39 | Status: "Active",
40 | TotalPTO: 20,
41 | TimeOff: nil,
42 | },
43 | {
44 | ID: 160898,
45 | FirstName: "Aakar",
46 | LastName: "Uppal",
47 | Position: "CTO",
48 | StartDate: time.Now().Add(-6 * time.Hour * 24 * 365),
49 | TotalPTO: 20,
50 | TimeOff: nil,
51 | },
52 | {
53 | ID: 297365,
54 | FirstName: "Jonathon",
55 | LastName: "Anderson",
56 | Position: "Worker Bee",
57 | StartDate: time.Now().Add(-12 * time.Hour * 24 * 365),
58 | TotalPTO: 30,
59 | TimeOff: nil,
60 | },
61 | }
62 |
--------------------------------------------------------------------------------
/grpcdemo/cert/generate_cert.sh:
--------------------------------------------------------------------------------
1 | #Removing old files.
2 | rm *.pem
3 | rm *.srl
4 |
5 | # 1. Generate CA's private key and self-signed certificate
6 | openssl req -x509 -newkey rsa:4096 -days 365 -nodes -keyout ca-key.pem -out ca-cert.pem -subj "/C=AU/ST=Vic/L=Melbourne/O=Go grpc/OU=Learning/CN=*.grpclearning.test/emailAddress=grpcgo.test@gmail.com"
7 |
8 | echo "CA's self-signed certificate"
9 | openssl x509 -in ca-cert.pem -noout -text
10 |
11 | # 2. Generate web server's private key and certificate signing request (CSR)
12 | openssl req -newkey rsa:4096 -nodes -keyout server-key.pem -out server-req.pem -subj "/C=AU/ST=Vic/L=Melbourne/O=Go grpc testing/OU=Learning/CN=*.gogrpcserver.com/emailAddress=grpcgoserver.test@gmail.com"
13 |
14 | # 3. Use CA's private key to sign web server's CSR and get back the signed certificate
15 | openssl x509 -req -in server-req.pem -days 60 -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem -extfile server-ext.cnf
16 |
17 | echo "Server's signed certificate"
18 | openssl x509 -in server-cert.pem -noout -text
19 |
20 | # 4. Generate client's private key and certificate signing request (CSR)
21 | openssl req -newkey rsa:4096 -nodes -keyout client-key.pem -out client-req.pem -subj "/C=AU/ST=Vic/L=Melbourne/O=Go grpc testing/OU=Learning/CN=*.gogrpcclient.com/emailAddress=grpcgoclient.test@gmail.com"
22 |
23 | # 5. Use CA's private key to sign client's CSR and get back the signed certificate
24 | openssl x509 -req -in client-req.pem -days 60 -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -out client-cert.pem -extfile client-ext.cnf
25 |
26 | echo "Client's signed certificate"
27 | openssl x509 -in client-cert.pem -noout -text
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/microservices/product-api-withswagger/data/validation.go:
--------------------------------------------------------------------------------
1 | package data
2 |
3 | import (
4 | "fmt"
5 | "regexp"
6 |
7 | "github.com/go-playground/validator/v10"
8 | )
9 |
10 | type ValidationError struct {
11 | validator.FieldError
12 | }
13 |
14 | func (v ValidationError) Error() string {
15 | return fmt.Sprintf(
16 | "Key: '%s' Error: Field validation for '%s' failed on the '%s' tag",
17 | v.Namespace(),
18 | v.Field(),
19 | v.Tag(),
20 | )
21 | }
22 |
23 | type ValidationErrors []ValidationError
24 |
25 | func (v ValidationErrors) Errors() []string {
26 | errs := []string{}
27 | for _, err := range v {
28 | errs = append(errs, err.Error())
29 | }
30 | return errs
31 | }
32 |
33 | type Validation struct {
34 | validate *validator.Validate
35 | }
36 |
37 | func NewValidation() *Validation {
38 | validate := validator.New()
39 | validate.RegisterValidation("sku", validateSKU)
40 | return &Validation{validate}
41 | }
42 |
43 | func (v *Validation) Validate(i interface{}) ValidationErrors {
44 | //fmt.Println(i)
45 | errs, ok := v.validate.Struct(i).(validator.ValidationErrors)
46 | //fmt.Println(errs)
47 | //fmt.Println(ok)
48 | if !ok || errs == nil || len(errs) == 0 {
49 | return nil
50 | }
51 |
52 | var returnErrs []ValidationError
53 |
54 | for _, err := range errs {
55 | ve := ValidationError{err}
56 | returnErrs = append(returnErrs, ve)
57 | }
58 | //fmt.Println(returnErrs)
59 | return returnErrs
60 | }
61 |
62 | func validateSKU(fl validator.FieldLevel) bool {
63 | // sku example abhb-sdd-sdscc
64 | re := regexp.MustCompile(`[a-z]+-[a-z]+-[a-z]+`)
65 | matches := re.FindAllString(fl.Field().String(), -1)
66 | return len(matches) == 1
67 |
68 | }
69 |
--------------------------------------------------------------------------------
/ginframeworkdemo/responsedemo/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "io"
5 | "log"
6 | "net/http"
7 | "os"
8 |
9 | "github.com/gin-gonic/gin"
10 | )
11 |
12 | func main() {
13 | router := gin.Default()
14 |
15 | router.StaticFile("/", "index.html")
16 |
17 | router.GET("/tale_of_two_cities", func(ctx *gin.Context) {
18 | // Simple File Serving
19 | //ctx.File("a_tale_of_two_cities.txt")
20 |
21 | // Data way of sharing
22 | f, err := os.Open("a_tale_of_two_cities.txt")
23 | if err != nil {
24 | ctx.AbortWithError(http.StatusInternalServerError, err)
25 | }
26 | defer f.Close()
27 | // IO Reader way
28 | /* data, err := io.ReadAll(f)
29 | if err != nil {
30 | ctx.AbortWithError(http.StatusInternalServerError, err)
31 | }
32 | ctx.Data(http.StatusOK, "test/plain", data) */
33 | ///Stream way of handling
34 | ctx.Stream(streamer(f))
35 | })
36 |
37 | router.GET("/great_expectations", func(ctx *gin.Context) {
38 | f, err := os.Open("great_expectations.txt")
39 | if err != nil {
40 | ctx.AbortWithError(http.StatusInternalServerError, err)
41 | }
42 | defer f.Close()
43 | fi, err := f.Stat()
44 | if err != nil {
45 | ctx.AbortWithError(http.StatusInternalServerError, err)
46 | }
47 | ctx.DataFromReader(http.StatusOK, fi.Size(), "text/plain", f, map[string]string{
48 | "Content-Disposition": "attachment;filename=great_expectations.txt",
49 | })
50 | })
51 |
52 | log.Fatal(router.Run(":3000"))
53 |
54 | }
55 |
56 | func streamer(r io.Reader) func(io.Writer) bool {
57 | return func(step io.Writer) bool {
58 | for {
59 | buf := make([]byte, 4*2^10)
60 | if _, err := r.Read(buf); err == nil {
61 | _, err := step.Write(buf)
62 | return err == nil
63 | } else {
64 | return false
65 | }
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/gostandard_libs/custom_type/media/media.go:
--------------------------------------------------------------------------------
1 | package media
2 |
3 | import "strings"
4 |
5 | /* This exportable.
6 | type Movie struct {
7 | Title string
8 | Rating Rating
9 | BoxOffice float32
10 | } */
11 |
12 | type Catalogable interface {
13 | NewMovie(title string, rating Rating, boxOffice float32)
14 | GetTitle() string
15 | GetRating() string
16 | GetBoxOffice() float32
17 | SetTitle(newTitle string)
18 | SetRating(newRating Rating)
19 | SetBoxOffice(newBoxOffice float32)
20 | }
21 |
22 | type Movie struct {
23 | title string
24 | rating Rating
25 | boxOffice float32
26 | }
27 |
28 | type Rating string
29 |
30 | const (
31 | R = "R (Restricted)"
32 | G = "G (General audiences)"
33 | PG = "PG (Parental Guidance)"
34 | PG13 = "PG-13 (Parental Caution)"
35 | NC17 = "NC-17 (No children under 17)"
36 | )
37 |
38 | /*
39 | func NewMovie(title string, rating Rating, boxOffice float32) Movie {
40 | return Movie{
41 | title: title,
42 | rating: rating,
43 | boxOffice: boxOffice,
44 | }
45 | } */
46 | // Dont want to return a copy of moview instead use same copy.
47 | func (m *Movie) NewMovie(title string, rating Rating, boxOffice float32) {
48 | m.title = title
49 | m.rating = rating
50 | m.boxOffice = boxOffice
51 | }
52 |
53 | func (m *Movie) GetTitle() string {
54 | return strings.ToTitle(m.title)
55 | }
56 |
57 | func (m *Movie) GetRating() string {
58 | return string(m.rating)
59 | }
60 |
61 | func (m *Movie) GetBoxOffice() float32 {
62 | return m.boxOffice
63 | }
64 |
65 | func (m *Movie) SetTitle(newTitle string) {
66 | m.title = newTitle
67 | }
68 |
69 | func (m *Movie) SetRating(newRating Rating) {
70 | m.rating = newRating
71 | }
72 |
73 | func (m *Movie) SetBoxOffice(newBoxOffice float32) {
74 | m.boxOffice = newBoxOffice
75 | }
76 |
--------------------------------------------------------------------------------
/pluralsight_projects/golang-fifa-world-cup-web-service/handlers/handlers.go:
--------------------------------------------------------------------------------
1 | package handlers
2 |
3 | import (
4 | "golang-fifa-world-cup-web-service/data"
5 | "net/http"
6 | )
7 |
8 | // RootHandler returns an empty body status code
9 | func RootHandler(res http.ResponseWriter, req *http.Request) {
10 | res.WriteHeader(http.StatusNoContent)
11 | }
12 |
13 | // ListWinners returns winners from the list
14 | func ListWinners(res http.ResponseWriter, req *http.Request) {
15 | res.Header().Set("Content-Type", "application/json")
16 | year := req.URL.Query().Get("year")
17 | if year == "" {
18 | winners, err := data.ListAllJSON()
19 | if err != nil {
20 | res.WriteHeader(http.StatusInternalServerError)
21 | return
22 | }
23 | res.Write(winners)
24 | } else {
25 | filteredWinners, err := data.ListAllByYear(year)
26 | if err != nil {
27 | res.WriteHeader(http.StatusBadRequest)
28 | return
29 | }
30 | res.Write(filteredWinners)
31 | }
32 |
33 | }
34 |
35 | // AddNewWinner adds new winner to the list
36 | func AddNewWinner(res http.ResponseWriter, req *http.Request) {
37 | accessToken := req.Header.Get("X-ACCESS-TOKEN")
38 | isTokenValid := data.IsAccessTokenValid(accessToken)
39 | if !isTokenValid {
40 | res.WriteHeader(http.StatusUnauthorized)
41 | } else {
42 | err := data.AddNewWinner(req.Body)
43 | if err != nil {
44 | res.WriteHeader(http.StatusUnprocessableEntity)
45 | return
46 | }
47 | res.WriteHeader(http.StatusCreated)
48 | }
49 | }
50 |
51 | // WinnersHandler is the dispatcher for all /winners URL
52 | func WinnersHandler(res http.ResponseWriter, req *http.Request) {
53 | switch req.Method {
54 | case http.MethodGet:
55 | ListWinners(res, req)
56 | case http.MethodPost:
57 | AddNewWinner(res, req)
58 | default:
59 | res.WriteHeader(http.StatusMethodNotAllowed)
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/microservices/product-api-gorilla/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "context"
5 | "log"
6 | "net/http"
7 | "os"
8 | "os/signal"
9 | "syscall"
10 | "time"
11 |
12 | "github.com/erankitcs/golang_learning/microservices/product-api-gorilla/handlers"
13 | "github.com/gorilla/mux"
14 | )
15 |
16 | var bindAddress = ":9090"
17 |
18 | func main() {
19 | //Create a logger
20 | l := log.New(os.Stdout, "product-api ", log.LstdFlags)
21 | // New Product handler
22 | ph := handlers.NewProduct(l)
23 |
24 | sm := mux.NewRouter()
25 |
26 | getRouter := sm.Methods(http.MethodGet).Subrouter()
27 | getRouter.HandleFunc("/", ph.GetProducts)
28 |
29 | putRouter := sm.Methods(http.MethodPut).Subrouter()
30 | putRouter.HandleFunc("/{id:[0-9]+}", ph.UpdateProduct)
31 | putRouter.Use(ph.MiddlewareProductsValidation)
32 |
33 | postRouter := sm.Methods(http.MethodPost).Subrouter()
34 | postRouter.HandleFunc("/", ph.AddProduct)
35 | postRouter.Use(ph.MiddlewareProductsValidation)
36 |
37 | //creating new server
38 | s := http.Server{
39 | Addr: bindAddress,
40 | Handler: sm,
41 | ErrorLog: l,
42 | ReadTimeout: 5 * time.Second,
43 | WriteTimeout: 10 * time.Second,
44 | IdleTimeout: 120 * time.Second,
45 | }
46 |
47 | //Starting the server
48 | go func() {
49 | l.Printf("Starting Server on Port %s\n", bindAddress)
50 | err := s.ListenAndServe()
51 | if err != nil {
52 | l.Printf("Error in starting the server: %s\n", err)
53 | os.Exit(1)
54 | }
55 | }()
56 |
57 | //Gracefull shutdown
58 | c := make(chan os.Signal, 1)
59 | signal.Notify(c, os.Interrupt)
60 | signal.Notify(c, syscall.SIGTERM)
61 |
62 | //block util a signal recieved
63 | sig := <-c
64 | log.Println("Got Signal: ", sig)
65 | ctx, cancelFun := context.WithTimeout(context.Background(), 30*time.Second)
66 | cancelFun()
67 | s.Shutdown(ctx)
68 |
69 | }
70 |
--------------------------------------------------------------------------------
/golang-async-logging-library/cmd/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "alog"
5 | "bufio"
6 | "flag"
7 | "fmt"
8 | "io"
9 | "log"
10 | "os"
11 | "strings"
12 | )
13 |
14 | func main() {
15 | out := flag.String("out", "stdout", "File name to use for log output. If stdout is provided, then output is written directly to the console.")
16 | async := flag.Bool("async", false, "This flag determines if the logger should write asynchronously.")
17 | flag.Parse()
18 |
19 | var w io.Writer
20 | var err error
21 | if strings.ToLower(*out) == "stdout" {
22 | w = os.Stdout
23 | } else {
24 | w, err = os.Create(*out)
25 | if err != nil {
26 | log.Fatal("Unable to open log file", err)
27 | }
28 | }
29 | l := alog.New(w)
30 | go l.Start()
31 |
32 | messageChan := l.MessageChannel()
33 | errChan := l.ErrorChannel()
34 |
35 | if errChan != nil {
36 | go func(errChan <-chan error) {
37 | err := <-errChan
38 | l.Stop()
39 | log.Fatalf("Error received from logger: %v\n", err)
40 | }(errChan)
41 | }
42 |
43 | for {
44 | reader := bufio.NewReader(os.Stdin)
45 |
46 | fmt.Println("Please enter message to write to log or 'q' to quit.")
47 | input, err := reader.ReadString('\n')
48 | if err != nil {
49 | fmt.Println("Unable to read input from command line, please try again.", err)
50 | continue
51 | }
52 |
53 | if strings.ToLower(input) == "q\n" || strings.ToLower(input) == "q\r\n" {
54 | if wc, ok := w.(io.Closer); ok {
55 | err := wc.Close()
56 | if err != nil {
57 | fmt.Println("Failed to close log file:", err)
58 | }
59 | }
60 | l.Stop()
61 | break
62 | }
63 | if *async {
64 | if messageChan != nil {
65 | messageChan <- input
66 | }
67 | } else {
68 | _, err = l.Write(input)
69 | if err != nil {
70 | fmt.Println("Unable to write message out to log")
71 | }
72 | }
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/microservices/product-api-withswagger-client/client/products/delete_product_responses.go:
--------------------------------------------------------------------------------
1 | // Code generated by go-swagger; DO NOT EDIT.
2 |
3 | package products
4 |
5 | // This file was generated by the swagger tool.
6 | // Editing this file might prove futile when you re-run the swagger generate command
7 |
8 | import (
9 | "fmt"
10 |
11 | "github.com/go-openapi/runtime"
12 | "github.com/go-openapi/strfmt"
13 | )
14 |
15 | // DeleteProductReader is a Reader for the DeleteProduct structure.
16 | type DeleteProductReader struct {
17 | formats strfmt.Registry
18 | }
19 |
20 | // ReadResponse reads a server response into the received o.
21 | func (o *DeleteProductReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
22 | switch response.Code() {
23 | case 201:
24 | result := NewDeleteProductCreated()
25 | if err := result.readResponse(response, consumer, o.formats); err != nil {
26 | return nil, err
27 | }
28 | return result, nil
29 | default:
30 | return nil, runtime.NewAPIError("response status code does not match any response statuses defined for this endpoint in the swagger spec", response, response.Code())
31 | }
32 | }
33 |
34 | // NewDeleteProductCreated creates a DeleteProductCreated with default headers values
35 | func NewDeleteProductCreated() *DeleteProductCreated {
36 | return &DeleteProductCreated{}
37 | }
38 |
39 | /* DeleteProductCreated describes a response with status code 201, with default header values.
40 |
41 | No content is returned by this API endpoint
42 | */
43 | type DeleteProductCreated struct {
44 | }
45 |
46 | func (o *DeleteProductCreated) Error() string {
47 | return fmt.Sprintf("[DELETE /products/{id}][%d] deleteProductCreated ", 201)
48 | }
49 |
50 | func (o *DeleteProductCreated) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
51 |
52 | return nil
53 | }
54 |
--------------------------------------------------------------------------------
/concurrentprogram/books/book.go:
--------------------------------------------------------------------------------
1 | package books
2 |
3 | import "fmt"
4 |
5 | type Book struct {
6 | ID int
7 | Title string
8 | Author string
9 | YearPublished int
10 | }
11 |
12 | func (b *Book) String() string {
13 | return fmt.Sprintf(
14 | "Title:\t\t%q\n"+
15 | "Author:\t\t%q\n"+
16 | "Published:\t%v\n", b.Title, b.Author, b.YearPublished)
17 | }
18 |
19 | var MyBook = []Book{
20 | Book{
21 | ID: 1,
22 | Title: "The Hitchhiker's Guide to the Galaxy",
23 | Author: "Douglas Adams",
24 | YearPublished: 1979,
25 | },
26 | Book{
27 | ID: 2,
28 | Title: "The Hobbit",
29 | Author: "J.R.R. Tolkien",
30 | YearPublished: 1937,
31 | },
32 | Book{
33 | ID: 3,
34 | Title: "A Tale of Two Cities",
35 | Author: "Charles Dickens",
36 | YearPublished: 1859,
37 | },
38 | Book{
39 | ID: 4,
40 | Title: "Les Misérables",
41 | Author: "Victor Hugo",
42 | YearPublished: 1862,
43 | },
44 | Book{
45 | ID: 5,
46 | Title: "Harry Potter and the Philosopher's Stone",
47 | Author: "J.K. Rowling",
48 | YearPublished: 1997,
49 | },
50 | Book{
51 | ID: 6,
52 | Title: "I, Robot",
53 | Author: "Isaac Asimov",
54 | YearPublished: 1950,
55 | },
56 | Book{
57 | ID: 7,
58 | Title: "The Gods Themselves",
59 | Author: "Isaac Asimov",
60 | YearPublished: 1973,
61 | },
62 | Book{
63 | ID: 8,
64 | Title: "The Moon is a Harsh Mistress",
65 | Author: "Robert A. Heinlein",
66 | YearPublished: 1966,
67 | },
68 | Book{
69 | ID: 9,
70 | Title: "On Basilisk Station",
71 | Author: "David Weber",
72 | YearPublished: 1993,
73 | },
74 | Book{
75 | ID: 10,
76 | Title: "The Android's Dream",
77 | Author: "John Scalzi",
78 | YearPublished: 2006,
79 | },
80 | }
81 |
--------------------------------------------------------------------------------
/testinggolang/messages/message_test.go:
--------------------------------------------------------------------------------
1 | package messages
2 |
3 | import (
4 | "crypto/sha1"
5 | "crypto/sha256"
6 | "crypto/sha512"
7 | "testing"
8 | )
9 |
10 | //Start with Test then next letter must be in Capital letter.
11 | // Immediate failure -t.FailNow , Fatal and Fatalf. Fatal will stop the execution of tests
12 | // Non immediate - t.Fail , Error and Errorf
13 | func TestGreet(t *testing.T) {
14 | got := Greet("Ankit")
15 | expect := "Hello, Ankit!"
16 | if got != expect {
17 | t.Errorf("Did not get expected result. Wanted %q got: %q", expect, got)
18 | }
19 |
20 | }
21 |
22 | func TestGreetTableDriven(t *testing.T) {
23 | scenarios := []struct {
24 | input string
25 | expect string
26 | }{
27 | {input: "Ankit", expect: "Hello, Ankit!"},
28 | {input: "", expect: "Hello, !"},
29 | }
30 |
31 | for _, s := range scenarios {
32 | got := Greet(s.input)
33 | if got != s.expect {
34 | t.Errorf("Did not got expected result for input: '%v'. Expected %q and got %q", s.input, got, s.expect)
35 | }
36 | }
37 |
38 | }
39 |
40 | func TestDapart(t *testing.T) {
41 | t.Log("Running Depart Test")
42 | got := depart("Ankit")
43 | expect := "Goodbye, Ankit"
44 | if got != expect {
45 | t.Errorf("Did not get expected result. Wanted %q got: %q", expect, got)
46 | }
47 | }
48 |
49 | func BenchmarkSHA1(b *testing.B) {
50 | data := []byte("My Benchmark testing..")
51 | b.StartTimer()
52 | for i := 0; i < b.N; i++ {
53 | sha1.Sum(data)
54 | }
55 | }
56 |
57 | func BenchmarkSHA256(b *testing.B) {
58 | data := []byte("My Benchmark testing..")
59 | b.StartTimer()
60 | for i := 0; i < b.N; i++ {
61 | sha256.Sum256(data)
62 | }
63 | }
64 |
65 | func BenchmarkSHA512(b *testing.B) {
66 | data := []byte("My Benchmark testing..")
67 | b.StartTimer()
68 | for i := 0; i < b.N; i++ {
69 | sha512.Sum512(data)
70 | }
71 | }
72 |
73 | func BenchmarkSHA512Alloc(b *testing.B) {
74 | data := []byte("My Benchmark testing..")
75 | b.StartTimer()
76 | for i := 0; i < b.N; i++ {
77 | h := sha512.New()
78 | h.Sum(data)
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/microservices/product-api-withswagger/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/erankitcs/golang_learning/microservices/product-api-withswagger
2 |
3 | go 1.17
4 |
5 | require (
6 | github.com/go-openapi/runtime v0.24.1
7 | github.com/go-playground/validator/v10 v10.11.0
8 | github.com/gorilla/handlers v1.5.1
9 | github.com/gorilla/mux v1.8.0
10 | github.com/stretchr/testify v1.8.0
11 | )
12 |
13 | require (
14 | github.com/PuerkitoBio/purell v1.1.1 // indirect
15 | github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
16 | github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect
17 | github.com/davecgh/go-spew v1.1.1 // indirect
18 | github.com/felixge/httpsnoop v1.0.1 // indirect
19 | github.com/go-openapi/analysis v0.21.2 // indirect
20 | github.com/go-openapi/errors v0.20.2 // indirect
21 | github.com/go-openapi/jsonpointer v0.19.5 // indirect
22 | github.com/go-openapi/jsonreference v0.19.6 // indirect
23 | github.com/go-openapi/loads v0.21.1 // indirect
24 | github.com/go-openapi/spec v0.20.4 // indirect
25 | github.com/go-openapi/strfmt v0.21.2 // indirect
26 | github.com/go-openapi/swag v0.21.1 // indirect
27 | github.com/go-openapi/validate v0.21.0 // indirect
28 | github.com/go-playground/locales v0.14.0 // indirect
29 | github.com/go-playground/universal-translator v0.18.0 // indirect
30 | github.com/go-stack/stack v1.8.1 // indirect
31 | github.com/josharian/intern v1.0.0 // indirect
32 | github.com/leodido/go-urn v1.2.1 // indirect
33 | github.com/mailru/easyjson v0.7.7 // indirect
34 | github.com/mitchellh/mapstructure v1.4.3 // indirect
35 | github.com/oklog/ulid v1.3.1 // indirect
36 | github.com/pmezard/go-difflib v1.0.0 // indirect
37 | go.mongodb.org/mongo-driver v1.8.3 // indirect
38 | golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 // indirect
39 | golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd // indirect
40 | golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e // indirect
41 | golang.org/x/text v0.3.7 // indirect
42 | gopkg.in/yaml.v2 v2.4.0 // indirect
43 | gopkg.in/yaml.v3 v3.0.1 // indirect
44 | )
45 |
--------------------------------------------------------------------------------
/microservices/product-api-withswagger/handlers/docs.go:
--------------------------------------------------------------------------------
1 | // Package Product API.
2 | //
3 | // The purpose of this API is to provide list of products, add new product and update the existing product.
4 | // Schemes: http
5 | // Host: localhost
6 | // BasePath: /
7 | // Version: 0.0.1
8 | // License: MIT http://opensource.org/licenses/MIT
9 | // Contact: er.ankit.cs@gmail.com
10 | // Consumes:
11 | // - application/json
12 | //
13 | // Produces:
14 | // - application/json
15 | // swagger:meta
16 | package handlers
17 |
18 | import "github.com/erankitcs/golang_learning/microservices/product-api-withswagger/data"
19 |
20 | // Generic error message returned as a string
21 | // swagger:response errorResponse
22 | type errorResponseWrapper struct {
23 | // Description of the error
24 | // in: body
25 | Body GenericError
26 | }
27 |
28 | // Validation error message returned as a string
29 | // swagger:response errorValidation
30 | type errorValidationWrapper struct {
31 | // Description of the error
32 | // in: body
33 | Body GenericError
34 | }
35 |
36 | // A list of product return into the response
37 | // swagger:response productsResponse
38 | type productsResponseWrapper struct {
39 | // All products in the system
40 | // in:body
41 | Body []data.Product
42 | }
43 |
44 | // Data structure representing a single product
45 | // swagger:response productResponse
46 | type productResponseWrapper struct {
47 | // Newly created product
48 | // in: body
49 | Body data.Product
50 | }
51 |
52 | // No content is returned by this API endpoint
53 | // swagger:response noContentResponse
54 | type noContentResponseWrapper struct {
55 | }
56 |
57 | // swagger:parameters deleteProduct listSingleProduct
58 | type productIDParamsWrapper struct {
59 | // The id of the product for which the operation relates
60 | // in: path
61 | // required: true
62 | ID int `json:"id"`
63 | }
64 |
65 | // swagger:parameters updateProduct createProduct
66 | type productParamsWrapper struct {
67 | // The product to be updated.
68 | // in: body
69 | // required: true
70 | Body data.Product
71 | }
72 |
--------------------------------------------------------------------------------
/distributedapp/teacherportal/student.gohtml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Student
7 |
8 |
9 |
10 | Grade Book
11 | - {{.LastName}}, {{.FirstName}}
12 |
13 | {{if gt (len .Grades) 0}}
14 |
15 |
16 | | Title |
17 | Type |
18 | Score |
19 |
20 | {{range .Grades}}
21 |
22 | | {{.Title}} |
23 | {{.Type}} |
24 | {{.Score}} |
25 |
26 | {{end}}
27 |
28 | {{else}}
29 | No grades available
30 | {{end}}
31 |
32 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/distributedappdocker/teacherportal/student.gohtml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Student
7 |
8 |
9 |
10 | Grade Book
11 | - {{.LastName}}, {{.FirstName}}
12 |
13 | {{if gt (len .Grades) 0}}
14 |
15 |
16 | | Title |
17 | Type |
18 | Score |
19 |
20 | {{range .Grades}}
21 |
22 | | {{.Title}} |
23 | {{.Type}} |
24 | {{.Score}} |
25 |
26 | {{end}}
27 |
28 | {{else}}
29 | No grades available
30 | {{end}}
31 |
32 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/microservices/product-api/data/products.go:
--------------------------------------------------------------------------------
1 | package data
2 |
3 | import (
4 | "encoding/json"
5 | "fmt"
6 | "io"
7 | "time"
8 | )
9 |
10 | type Product struct {
11 | ID int `json:"id"`
12 | Name string `json:"name"`
13 | Description string `json:"description"`
14 | Price float32 `json:"price"`
15 | SKU string `json:"sku"`
16 | CreatedOn string `json:"-"`
17 | UpdatedOn string `json:"-"`
18 | DeletedOn string `json:"-"`
19 | }
20 |
21 | //Collection of product
22 | type Products []*Product
23 |
24 | func (p *Products) ToJSON(w io.Writer) error {
25 | e := json.NewEncoder(w)
26 | return e.Encode(p)
27 | }
28 |
29 | func (p *Product) FromJSON(r io.Reader) error {
30 | e := json.NewDecoder(r)
31 | return e.Decode(p)
32 | }
33 |
34 | var productList = []*Product{
35 | {
36 | ID: 1,
37 | Name: "Latte",
38 | Description: "Frothy milky coffee",
39 | Price: 2.45,
40 | SKU: "abc323",
41 | CreatedOn: time.Now().UTC().String(),
42 | UpdatedOn: time.Now().UTC().String(),
43 | },
44 | {
45 | ID: 2,
46 | Name: "Espresso",
47 | Description: "Short and strong coffee without milk",
48 | Price: 1.99,
49 | SKU: "fjd34",
50 | CreatedOn: time.Now().UTC().String(),
51 | UpdatedOn: time.Now().UTC().String(),
52 | },
53 | }
54 |
55 | func GetProducts() Products {
56 | return productList
57 | }
58 |
59 | func getNextId() int {
60 | lp := productList[len(productList)-1]
61 | return lp.ID + 1
62 | }
63 |
64 | func AddProduct(p *Product) {
65 | p.ID = getNextId()
66 | productList = append(productList, p)
67 |
68 | }
69 |
70 | func UpdateProduct(id int, p *Product) error {
71 | _, ploc, err := findProduct(id)
72 | if err != nil {
73 | return err
74 | }
75 | p.ID = id
76 | productList[ploc] = p
77 | return nil
78 | }
79 |
80 | var ErrorProductNotFound = fmt.Errorf("Product not found")
81 |
82 | func findProduct(id int) (*Product, int, error) {
83 | for l, p := range productList {
84 | if p.ID == id {
85 | return p, l, nil
86 | }
87 | }
88 | return nil, -1, ErrorProductNotFound
89 | }
90 |
--------------------------------------------------------------------------------
/microservices/product-api-withswagger-client/client/products/list_products_responses.go:
--------------------------------------------------------------------------------
1 | // Code generated by go-swagger; DO NOT EDIT.
2 |
3 | package products
4 |
5 | // This file was generated by the swagger tool.
6 | // Editing this file might prove futile when you re-run the swagger generate command
7 |
8 | import (
9 | "fmt"
10 | "io"
11 |
12 | "github.com/go-openapi/runtime"
13 | "github.com/go-openapi/strfmt"
14 |
15 | "github.com/erankitcs/golang_learning/microservices/productapiclient/models"
16 | )
17 |
18 | // ListProductsReader is a Reader for the ListProducts structure.
19 | type ListProductsReader struct {
20 | formats strfmt.Registry
21 | }
22 |
23 | // ReadResponse reads a server response into the received o.
24 | func (o *ListProductsReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
25 | switch response.Code() {
26 | case 200:
27 | result := NewListProductsOK()
28 | if err := result.readResponse(response, consumer, o.formats); err != nil {
29 | return nil, err
30 | }
31 | return result, nil
32 | default:
33 | return nil, runtime.NewAPIError("response status code does not match any response statuses defined for this endpoint in the swagger spec", response, response.Code())
34 | }
35 | }
36 |
37 | // NewListProductsOK creates a ListProductsOK with default headers values
38 | func NewListProductsOK() *ListProductsOK {
39 | return &ListProductsOK{}
40 | }
41 |
42 | /* ListProductsOK describes a response with status code 200, with default header values.
43 |
44 | A list of product return into the response
45 | */
46 | type ListProductsOK struct {
47 | Payload []*models.Product
48 | }
49 |
50 | func (o *ListProductsOK) Error() string {
51 | return fmt.Sprintf("[GET /products][%d] listProductsOK %+v", 200, o.Payload)
52 | }
53 | func (o *ListProductsOK) GetPayload() []*models.Product {
54 | return o.Payload
55 | }
56 |
57 | func (o *ListProductsOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
58 |
59 | // response payload
60 | if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF {
61 | return err
62 | }
63 |
64 | return nil
65 | }
66 |
--------------------------------------------------------------------------------
/microservices/product-api-withswagger-client/client/products/list_single_product_responses.go:
--------------------------------------------------------------------------------
1 | // Code generated by go-swagger; DO NOT EDIT.
2 |
3 | package products
4 |
5 | // This file was generated by the swagger tool.
6 | // Editing this file might prove futile when you re-run the swagger generate command
7 |
8 | import (
9 | "fmt"
10 | "io"
11 |
12 | "github.com/go-openapi/runtime"
13 | "github.com/go-openapi/strfmt"
14 |
15 | "github.com/erankitcs/golang_learning/microservices/productapiclient/models"
16 | )
17 |
18 | // ListSingleProductReader is a Reader for the ListSingleProduct structure.
19 | type ListSingleProductReader struct {
20 | formats strfmt.Registry
21 | }
22 |
23 | // ReadResponse reads a server response into the received o.
24 | func (o *ListSingleProductReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
25 | switch response.Code() {
26 | case 200:
27 | result := NewListSingleProductOK()
28 | if err := result.readResponse(response, consumer, o.formats); err != nil {
29 | return nil, err
30 | }
31 | return result, nil
32 | default:
33 | return nil, runtime.NewAPIError("response status code does not match any response statuses defined for this endpoint in the swagger spec", response, response.Code())
34 | }
35 | }
36 |
37 | // NewListSingleProductOK creates a ListSingleProductOK with default headers values
38 | func NewListSingleProductOK() *ListSingleProductOK {
39 | return &ListSingleProductOK{}
40 | }
41 |
42 | /* ListSingleProductOK describes a response with status code 200, with default header values.
43 |
44 | Data structure representing a single product
45 | */
46 | type ListSingleProductOK struct {
47 | Payload *models.Product
48 | }
49 |
50 | func (o *ListSingleProductOK) Error() string {
51 | return fmt.Sprintf("[GET /products/{id}][%d] listSingleProductOK %+v", 200, o.Payload)
52 | }
53 | func (o *ListSingleProductOK) GetPayload() *models.Product {
54 | return o.Payload
55 | }
56 |
57 | func (o *ListSingleProductOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
58 |
59 | o.Payload = new(models.Product)
60 |
61 | // response payload
62 | if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF {
63 | return err
64 | }
65 |
66 | return nil
67 | }
68 |
--------------------------------------------------------------------------------
/microservices/product-api-gorilla/handlers/handlers.go:
--------------------------------------------------------------------------------
1 | package handlers
2 |
3 | import (
4 | "context"
5 | "fmt"
6 | "log"
7 | "net/http"
8 | "strconv"
9 |
10 | "github.com/erankitcs/golang_learning/microservices/product-api-gorilla/data"
11 | "github.com/gorilla/mux"
12 | )
13 |
14 | type Products struct {
15 | l *log.Logger
16 | }
17 |
18 | func NewProduct(l *log.Logger) *Products {
19 | return &Products{l}
20 | }
21 |
22 | func (p *Products) GetProducts(rw http.ResponseWriter, r *http.Request) {
23 | lp := data.GetProducts()
24 | err := lp.ToJSON(rw)
25 | if err != nil {
26 | http.Error(rw, "Unable to parse product data", http.StatusInternalServerError)
27 | }
28 | }
29 |
30 | func (p *Products) AddProduct(rw http.ResponseWriter, r *http.Request) {
31 | p.l.Printf("Handling PUT request")
32 | prod := r.Context().Value(KeyProduct{}).(data.Product)
33 | data.AddProduct(&prod)
34 | }
35 |
36 | func (p *Products) UpdateProduct(rw http.ResponseWriter, r *http.Request) {
37 | p.l.Println("Handle PUT product")
38 | vars := mux.Vars(r)
39 | id, err := strconv.Atoi(vars["id"])
40 | if err != nil {
41 | http.Error(rw, "Unxpected Id format", http.StatusBadRequest)
42 | }
43 | prod := r.Context().Value(KeyProduct{}).(data.Product)
44 |
45 | err = data.UpdateProduct(id, &prod)
46 | if err == data.ErrorProductNotFound {
47 | http.Error(rw, "Product not found", http.StatusNotFound)
48 | return
49 | }
50 |
51 | if err != nil {
52 | http.Error(rw, "Product update failed", http.StatusInternalServerError)
53 | return
54 | }
55 |
56 | }
57 |
58 | type KeyProduct struct{}
59 |
60 | func (p Products) MiddlewareProductsValidation(next http.Handler) http.Handler {
61 | return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
62 |
63 | prod := data.Product{}
64 |
65 | err := prod.FromJSON(r.Body)
66 | if err != nil {
67 | http.Error(rw, "Unable to parse product request", http.StatusBadRequest)
68 | return
69 | }
70 | //validate the product
71 | err = prod.Validate()
72 | if err != nil {
73 | p.l.Println("[ERROR] Validating the product", err)
74 | http.Error(rw, fmt.Sprintf("Error validating the product: %s", err), http.StatusBadRequest)
75 | return
76 | }
77 | ctx := context.WithValue(r.Context(), KeyProduct{}, prod)
78 | r = r.WithContext(ctx)
79 | next.ServeHTTP(rw, r)
80 | })
81 | }
82 |
--------------------------------------------------------------------------------
/customdatatypes/datatypes3/organisation/person.go:
--------------------------------------------------------------------------------
1 | package organisation
2 |
3 | import (
4 | "errors"
5 | "fmt"
6 | "strings"
7 | )
8 |
9 | type TwitterHandler string
10 |
11 | func (th TwitterHandler) RedirectURL() string {
12 | cleanHandler := strings.TrimPrefix(string(th), "@")
13 | return fmt.Sprintf("https://www.twitter.com/%s", cleanHandler)
14 | }
15 |
16 | type Identifiable interface {
17 | ID() string
18 | }
19 |
20 | type Citizen interface {
21 | Identifiable
22 | Country() string
23 | }
24 |
25 | type socialSecurityNumber string
26 |
27 | func NewSocialSecurityNumber(value string) Citizen {
28 | return socialSecurityNumber(value)
29 | }
30 |
31 | func (ssn socialSecurityNumber) ID() string {
32 | return string(ssn)
33 | }
34 |
35 | func (ssn socialSecurityNumber) Country() string {
36 | return "USA"
37 | }
38 |
39 | type europeanUnionIdentifier struct {
40 | id string
41 | country string
42 | }
43 |
44 | func NewEuropeanUnionIdentifier(id, country string) Citizen {
45 | return europeanUnionIdentifier{
46 | id: id,
47 | country: country,
48 | }
49 | }
50 |
51 | func (eui europeanUnionIdentifier) ID() string {
52 | return eui.id
53 | }
54 |
55 | func (eui europeanUnionIdentifier) Country() string {
56 | return eui.country
57 | }
58 |
59 | type Name struct {
60 | First string
61 | Last string
62 | }
63 |
64 | func (n *Name) FullName() string {
65 | return fmt.Sprintf("%s %s", n.First, n.Last)
66 | }
67 |
68 | type Employee struct {
69 | Name
70 | }
71 |
72 | type Person struct {
73 | Name
74 | First string
75 | Last string
76 | twitterHandler TwitterHandler
77 | Citizen
78 | }
79 |
80 | func NewPerson(firstName, lastName string, citizen Citizen) Person {
81 | return Person{
82 | Name: Name{
83 | First: firstName,
84 | Last: lastName,
85 | },
86 | Citizen: citizen,
87 | }
88 | }
89 |
90 | func (p *Person) SetTwitterHandler(handler TwitterHandler) error {
91 | if len(handler) == 0 {
92 | p.twitterHandler = handler
93 | } else if !strings.HasPrefix(string(handler), "@") {
94 | return errors.New("twitter handle must start with @ in text")
95 | }
96 | p.twitterHandler = handler
97 | return nil
98 | }
99 |
100 | func (p *Person) ID() string {
101 | return "123"
102 | }
103 |
104 | func (p *Person) TwitterHandler() TwitterHandler {
105 | return p.twitterHandler
106 | }
107 |
--------------------------------------------------------------------------------
/customdatatypes/datatypes4/organisation/person.go:
--------------------------------------------------------------------------------
1 | package organisation
2 |
3 | import (
4 | "errors"
5 | "fmt"
6 | "strings"
7 | )
8 |
9 | type TwitterHandler string
10 |
11 | func (th TwitterHandler) RedirectURL() string {
12 | cleanHandler := strings.TrimPrefix(string(th), "@")
13 | return fmt.Sprintf("https://www.twitter.com/%s", cleanHandler)
14 | }
15 |
16 | type Identifiable interface {
17 | ID() string
18 | }
19 |
20 | type Citizen interface {
21 | Identifiable
22 | Country() string
23 | }
24 |
25 | type socialSecurityNumber string
26 |
27 | func NewSocialSecurityNumber(value string) Citizen {
28 | return socialSecurityNumber(value)
29 | }
30 |
31 | func (ssn socialSecurityNumber) ID() string {
32 | return string(ssn)
33 | }
34 |
35 | func (ssn socialSecurityNumber) Country() string {
36 | return "USA"
37 | }
38 |
39 | type europeanUnionIdentifier struct {
40 | id string
41 | country []string
42 | }
43 |
44 | func NewEuropeanUnionIdentifier(id, country string) Citizen {
45 | return europeanUnionIdentifier{
46 | id: id,
47 | country: []string{country},
48 | }
49 | }
50 |
51 | func (eui europeanUnionIdentifier) ID() string {
52 | return eui.id
53 | }
54 |
55 | func (eui europeanUnionIdentifier) Country() string {
56 | return fmt.Sprintf("EU: %s", eui.country)
57 | }
58 |
59 | type Name struct {
60 | First string
61 | Last string
62 | }
63 |
64 | func (n *Name) FullName() string {
65 | return fmt.Sprintf("%s %s", n.First, n.Last)
66 | }
67 |
68 | type Employee struct {
69 | Name
70 | }
71 |
72 | type Person struct {
73 | Name
74 | First string
75 | Last string
76 | twitterHandler TwitterHandler
77 | Citizen
78 | }
79 |
80 | func NewPerson(firstName, lastName string, citizen Citizen) Person {
81 | return Person{
82 | Name: Name{
83 | First: firstName,
84 | Last: lastName,
85 | },
86 | Citizen: citizen,
87 | }
88 | }
89 |
90 | func (p *Person) SetTwitterHandler(handler TwitterHandler) error {
91 | if len(handler) == 0 {
92 | p.twitterHandler = handler
93 | } else if !strings.HasPrefix(string(handler), "@") {
94 | return errors.New("twitter handle must start with @ in text")
95 | }
96 | p.twitterHandler = handler
97 | return nil
98 | }
99 |
100 | func (p *Person) ID() string {
101 | return "123"
102 | }
103 |
104 | func (p *Person) TwitterHandler() TwitterHandler {
105 | return p.twitterHandler
106 | }
107 |
--------------------------------------------------------------------------------
/distributedapp/grades/mockdata.go:
--------------------------------------------------------------------------------
1 | package grades
2 |
3 | func init() {
4 | students = []Student{
5 | Student{
6 | ID: 1,
7 | FirstName: "Averill",
8 | LastName: "Simen",
9 | Grades: []Grade{
10 | Grade{
11 | Title: "Quiz 1",
12 | Type: GradeQuiz,
13 | Score: 85,
14 | },
15 | Grade{
16 | Title: "Week 1 Homework",
17 | Type: GradeHomework,
18 | Score: 94,
19 | },
20 | Grade{
21 | Title: "Quiz 2",
22 | Type: GradeQuiz,
23 | Score: 88,
24 | },
25 | },
26 | },
27 | Student{
28 | ID: 2,
29 | FirstName: "Marge",
30 | LastName: "Garrard",
31 | Grades: []Grade{
32 | Grade{
33 | Title: "Quiz 1",
34 | Type: GradeQuiz,
35 | Score: 100,
36 | },
37 | Grade{
38 | Title: "Week 1 Homework",
39 | Type: GradeHomework,
40 | Score: 100,
41 | },
42 | Grade{
43 | Title: "Quiz 2",
44 | Type: GradeQuiz,
45 | Score: 88,
46 | },
47 | },
48 | },
49 | Student{
50 | ID: 3,
51 | FirstName: "Sydnie",
52 | LastName: "Barber",
53 | Grades: []Grade{
54 | Grade{
55 | Title: "Quiz 1",
56 | Type: GradeQuiz,
57 | Score: 77,
58 | },
59 | Grade{
60 | Title: "Week 1 Homework",
61 | Type: GradeHomework,
62 | Score: 0,
63 | },
64 | Grade{
65 | Title: "Quiz 2",
66 | Type: GradeQuiz,
67 | Score: 65,
68 | },
69 | },
70 | },
71 | Student{
72 | ID: 4,
73 | FirstName: "Louie",
74 | LastName: "Easton",
75 | Grades: []Grade{
76 | Grade{
77 | Title: "Quiz 1",
78 | Type: GradeQuiz,
79 | Score: 88,
80 | },
81 | Grade{
82 | Title: "Week 1 Homework",
83 | Type: GradeHomework,
84 | Score: 93,
85 | },
86 | Grade{
87 | Title: "Quiz 2",
88 | Type: GradeQuiz,
89 | Score: 84,
90 | },
91 | },
92 | },
93 | Student{
94 | ID: 5,
95 | FirstName: "Kylee",
96 | LastName: "Attwood",
97 | Grades: []Grade{
98 | Grade{
99 | Title: "Quiz 1",
100 | Type: GradeQuiz,
101 | Score: 95,
102 | },
103 | Grade{
104 | Title: "Week 1 Homework",
105 | Type: GradeHomework,
106 | Score: 100,
107 | },
108 | Grade{
109 | Title: "Quiz 2",
110 | Type: GradeQuiz,
111 | Score: 97,
112 | },
113 | },
114 | },
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/distributedappdocker/grades/mockdata.go:
--------------------------------------------------------------------------------
1 | package grades
2 |
3 | func init() {
4 | students = []Student{
5 | Student{
6 | ID: 1,
7 | FirstName: "Averill",
8 | LastName: "Simen",
9 | Grades: []Grade{
10 | Grade{
11 | Title: "Quiz 1",
12 | Type: GradeQuiz,
13 | Score: 85,
14 | },
15 | Grade{
16 | Title: "Week 1 Homework",
17 | Type: GradeHomework,
18 | Score: 94,
19 | },
20 | Grade{
21 | Title: "Quiz 2",
22 | Type: GradeQuiz,
23 | Score: 88,
24 | },
25 | },
26 | },
27 | Student{
28 | ID: 2,
29 | FirstName: "Marge",
30 | LastName: "Garrard",
31 | Grades: []Grade{
32 | Grade{
33 | Title: "Quiz 1",
34 | Type: GradeQuiz,
35 | Score: 100,
36 | },
37 | Grade{
38 | Title: "Week 1 Homework",
39 | Type: GradeHomework,
40 | Score: 100,
41 | },
42 | Grade{
43 | Title: "Quiz 2",
44 | Type: GradeQuiz,
45 | Score: 88,
46 | },
47 | },
48 | },
49 | Student{
50 | ID: 3,
51 | FirstName: "Sydnie",
52 | LastName: "Barber",
53 | Grades: []Grade{
54 | Grade{
55 | Title: "Quiz 1",
56 | Type: GradeQuiz,
57 | Score: 77,
58 | },
59 | Grade{
60 | Title: "Week 1 Homework",
61 | Type: GradeHomework,
62 | Score: 0,
63 | },
64 | Grade{
65 | Title: "Quiz 2",
66 | Type: GradeQuiz,
67 | Score: 65,
68 | },
69 | },
70 | },
71 | Student{
72 | ID: 4,
73 | FirstName: "Louie",
74 | LastName: "Easton",
75 | Grades: []Grade{
76 | Grade{
77 | Title: "Quiz 1",
78 | Type: GradeQuiz,
79 | Score: 88,
80 | },
81 | Grade{
82 | Title: "Week 1 Homework",
83 | Type: GradeHomework,
84 | Score: 93,
85 | },
86 | Grade{
87 | Title: "Quiz 2",
88 | Type: GradeQuiz,
89 | Score: 84,
90 | },
91 | },
92 | },
93 | Student{
94 | ID: 5,
95 | FirstName: "Kylee",
96 | LastName: "Attwood",
97 | Grades: []Grade{
98 | Grade{
99 | Title: "Quiz 1",
100 | Type: GradeQuiz,
101 | Score: 95,
102 | },
103 | Grade{
104 | Title: "Week 1 Homework",
105 | Type: GradeHomework,
106 | Score: 100,
107 | },
108 | Grade{
109 | Title: "Quiz 2",
110 | Type: GradeQuiz,
111 | Score: 97,
112 | },
113 | },
114 | },
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/pluralsight_projects/golang-personal-budget-cli/module2/budget_2.go:
--------------------------------------------------------------------------------
1 | package module2
2 |
3 | import (
4 | "errors"
5 | "time"
6 | )
7 |
8 | // START Initial code
9 |
10 | // Budget stores Budget information
11 | type Budget struct {
12 | Max float32
13 | Items []Item
14 | }
15 |
16 | // Item stores Item information
17 | type Item struct {
18 | Description string
19 | Price float32
20 | }
21 |
22 | var report map[time.Month]*Budget
23 |
24 | // InitializeReport creates an empty map
25 | // to store each budget
26 | func InitializeReport() {
27 | report = make(map[time.Month]*Budget)
28 | }
29 |
30 | func init() {
31 | InitializeReport()
32 | }
33 |
34 | // CurrentCost returns how much we've added
35 | // to the current budget
36 | func (b Budget) CurrentCost() float32 {
37 | var sum float32
38 | for _, item := range b.Items {
39 | sum += item.Price
40 | }
41 | return sum
42 | }
43 |
44 | var errDoesNotFitBudget = errors.New("Item does not fit the budget")
45 |
46 | var errReportIsFull = errors.New("Report is full")
47 |
48 | var errDuplicateEntry = errors.New("Cannot add duplicate entry")
49 |
50 | // END Initial code
51 |
52 | // START Project code
53 |
54 | // AddItem adds an item to the current budget
55 | func (b *Budget) AddItem(description string, price float32) error {
56 | if b.CurrentCost()+price > b.Max {
57 | return errDoesNotFitBudget
58 | }
59 |
60 | newItem := Item{
61 | Description: description,
62 | Price: price,
63 | }
64 | b.Items = append(b.Items, newItem)
65 |
66 | return nil
67 | }
68 |
69 | // RemoveItem removes a given item from the current budget
70 | func (b *Budget) RemoveItem(description string) {
71 | for i := range b.Items {
72 | if b.Items[i].Description == description {
73 | b.Items = append(b.Items[:i], b.Items[i+1:]...)
74 | break
75 | }
76 | }
77 | }
78 |
79 | // CreateBudget creates a new budget with a specified max
80 | func CreateBudget(month time.Month, max float32) (*Budget, error) {
81 | var newBudget *Budget
82 | if len(report) >= 12 {
83 | return nil, errReportIsFull
84 | }
85 | if _, hasEntry := report[month]; hasEntry {
86 | return nil, errDuplicateEntry
87 | }
88 | newBudget = &Budget{
89 | Max: max,
90 | }
91 | report[month] = newBudget
92 |
93 | return newBudget, nil
94 | }
95 |
96 | // GetBudget returns budget for given month
97 | func GetBudget(month time.Month) *Budget {
98 | if budget, ok := report[month]; ok {
99 | return budget
100 | }
101 | return nil
102 | }
103 |
104 | // END Project code
105 |
--------------------------------------------------------------------------------
/microservices/product-api-withswagger/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "context"
5 | "log"
6 | "net/http"
7 | "os"
8 | "os/signal"
9 | "syscall"
10 | "time"
11 |
12 | "github.com/erankitcs/golang_learning/microservices/product-api-withswagger/data"
13 | "github.com/erankitcs/golang_learning/microservices/product-api-withswagger/handlers"
14 | "github.com/go-openapi/runtime/middleware"
15 | gohandlers "github.com/gorilla/handlers"
16 | "github.com/gorilla/mux"
17 | )
18 |
19 | var bindAddress = ":9090"
20 |
21 | func main() {
22 | //Create a logger
23 | l := log.New(os.Stdout, "product-api ", log.LstdFlags)
24 | v := data.NewValidation()
25 | // New Product handler
26 | ph := handlers.NewProduct(l, v)
27 |
28 | // create a new serve mux and register the handlers
29 | sm := mux.NewRouter()
30 |
31 | getRouter := sm.Methods(http.MethodGet).Subrouter()
32 | getRouter.HandleFunc("/products", ph.ListAll)
33 | getRouter.HandleFunc("/products/{id:[0-9]+}", ph.ListSingle)
34 |
35 | putRouter := sm.Methods(http.MethodPut).Subrouter()
36 | putRouter.HandleFunc("/products", ph.Update)
37 | putRouter.Use(ph.MiddlewareProductsValidation)
38 |
39 | postRouter := sm.Methods(http.MethodPost).Subrouter()
40 | postRouter.HandleFunc("/products", ph.Create)
41 | postRouter.Use(ph.MiddlewareProductsValidation)
42 |
43 | deleteRouter := sm.Methods(http.MethodDelete).Subrouter()
44 | deleteRouter.HandleFunc("/products/{id:[0-9]+}", ph.Delete)
45 |
46 | ops := middleware.RedocOpts{SpecURL: "/swagger.yaml"}
47 | sh := middleware.Redoc(ops, nil)
48 | getRouter.Handle("/docs", sh)
49 | getRouter.Handle("/swagger.yaml", http.FileServer(http.Dir("./")))
50 |
51 | ch := gohandlers.CORS(gohandlers.AllowedOrigins([]string{"http://localhost:3000"}))
52 | //creating new server
53 | s := http.Server{
54 | Addr: bindAddress,
55 | Handler: ch(sm),
56 | ErrorLog: l,
57 | ReadTimeout: 5 * time.Second,
58 | WriteTimeout: 10 * time.Second,
59 | IdleTimeout: 120 * time.Second,
60 | }
61 |
62 | //Starting the server
63 | go func() {
64 | l.Printf("Starting Server on Port %s\n", bindAddress)
65 | err := s.ListenAndServe()
66 | if err != nil {
67 | l.Printf("Error in starting the server: %s\n", err)
68 | os.Exit(1)
69 | }
70 | }()
71 |
72 | //Gracefull shutdown
73 | c := make(chan os.Signal, 1)
74 | signal.Notify(c, os.Interrupt)
75 | signal.Notify(c, syscall.SIGTERM)
76 |
77 | //block util a signal recieved
78 | sig := <-c
79 | log.Println("Got Signal: ", sig)
80 | ctx, cancelFun := context.WithTimeout(context.Background(), 30*time.Second)
81 | cancelFun()
82 | s.Shutdown(ctx)
83 |
84 | }
85 |
--------------------------------------------------------------------------------
/microservices/product-api-gorilla/data/products.go:
--------------------------------------------------------------------------------
1 | package data
2 |
3 | import (
4 | "encoding/json"
5 | "fmt"
6 | "io"
7 | "regexp"
8 | "time"
9 |
10 | "github.com/go-playground/validator/v10"
11 | )
12 |
13 | type Product struct {
14 | ID int `json:"id"`
15 | Name string `json:"name" validate:"required"`
16 | Description string `json:"description"`
17 | Price float32 `json:"price" validate:"gt=0"`
18 | SKU string `json:"sku" validate:"required,sku"`
19 | CreatedOn string `json:"-"`
20 | UpdatedOn string `json:"-"`
21 | DeletedOn string `json:"-"`
22 | }
23 |
24 | //Collection of product
25 | type Products []*Product
26 |
27 | func (p *Product) Validate() error {
28 | validate := validator.New()
29 | validate.RegisterValidation("sku", validateSKU)
30 | return validate.Struct(p)
31 | }
32 |
33 | func validateSKU(fl validator.FieldLevel) bool {
34 | // sku example abhb-sdd-sdscc
35 | re := regexp.MustCompile(`[a-z]+-[a-z]+-[a-z]+`)
36 | matches := re.FindAllString(fl.Field().String(), -1)
37 | return len(matches) == 1
38 |
39 | }
40 |
41 | func (p *Products) ToJSON(w io.Writer) error {
42 | e := json.NewEncoder(w)
43 | return e.Encode(p)
44 | }
45 |
46 | func (p *Product) FromJSON(r io.Reader) error {
47 | e := json.NewDecoder(r)
48 | return e.Decode(p)
49 | }
50 |
51 | var productList = []*Product{
52 | {
53 | ID: 1,
54 | Name: "Latte",
55 | Description: "Frothy milky coffee",
56 | Price: 2.45,
57 | SKU: "abc323",
58 | CreatedOn: time.Now().UTC().String(),
59 | UpdatedOn: time.Now().UTC().String(),
60 | },
61 | {
62 | ID: 2,
63 | Name: "Espresso",
64 | Description: "Short and strong coffee without milk",
65 | Price: 1.99,
66 | SKU: "fjd34",
67 | CreatedOn: time.Now().UTC().String(),
68 | UpdatedOn: time.Now().UTC().String(),
69 | },
70 | }
71 |
72 | func GetProducts() Products {
73 | return productList
74 | }
75 |
76 | func getNextId() int {
77 | lp := productList[len(productList)-1]
78 | return lp.ID + 1
79 | }
80 |
81 | func AddProduct(p *Product) {
82 | p.ID = getNextId()
83 | productList = append(productList, p)
84 |
85 | }
86 |
87 | func UpdateProduct(id int, p *Product) error {
88 | _, ploc, err := findProduct(id)
89 | if err != nil {
90 | return err
91 | }
92 | p.ID = id
93 | productList[ploc] = p
94 | return nil
95 | }
96 |
97 | var ErrorProductNotFound = fmt.Errorf("Product not found")
98 |
99 | func findProduct(id int) (*Product, int, error) {
100 | for l, p := range productList {
101 | if p.ID == id {
102 | return p, l, nil
103 | }
104 | }
105 | return nil, -1, ErrorProductNotFound
106 | }
107 |
--------------------------------------------------------------------------------
/microservices/product-api/handlers/handlers.go:
--------------------------------------------------------------------------------
1 | package handlers
2 |
3 | import (
4 | "log"
5 | "net/http"
6 | "regexp"
7 | "strconv"
8 |
9 | "github.com/erankitcs/golang_learning/microservices/product-api/data"
10 | )
11 |
12 | type Products struct {
13 | l *log.Logger
14 | }
15 |
16 | func NewProduct(l *log.Logger) *Products {
17 | return &Products{l}
18 | }
19 |
20 | func (p *Products) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
21 | if r.Method == http.MethodGet {
22 | p.getProducts(rw, r)
23 | return
24 | }
25 |
26 | if r.Method == http.MethodPost {
27 | p.addProduct(rw, r)
28 | return
29 | }
30 | if r.Method == http.MethodPut {
31 | regx := regexp.MustCompile(`/([0-9]+)`)
32 | g := regx.FindAllStringSubmatch(r.URL.Path, -1)
33 | if len(g) != 1 {
34 | p.l.Println("Invalid URI more than one id")
35 | http.Error(rw, "Invalid URI", http.StatusBadRequest)
36 | }
37 | if len(g[0]) != 2 {
38 | p.l.Println("Invalid URI more than one capture group")
39 | http.Error(rw, "Invalid URI", http.StatusBadRequest)
40 | return
41 | }
42 | idString := g[0][1]
43 | id, err := strconv.Atoi(idString)
44 | if err != nil {
45 | p.l.Println("Invalid URI unable to convert to numer", idString)
46 | http.Error(rw, "Invalid URI", http.StatusBadRequest)
47 | return
48 | }
49 | p.updateProduct(id, rw, r)
50 | return
51 | }
52 |
53 | rw.WriteHeader(http.StatusMethodNotAllowed)
54 |
55 | }
56 |
57 | func (p *Products) getProducts(rw http.ResponseWriter, r *http.Request) {
58 | lp := data.GetProducts()
59 | //d, err := json.Marshal(lp)
60 | // Encoder is much faster and memory efficient
61 | err := lp.ToJSON(rw)
62 | if err != nil {
63 | http.Error(rw, "Unable to parse product data", http.StatusInternalServerError)
64 | }
65 | //rw.Write(d)
66 | }
67 |
68 | func (p *Products) addProduct(rw http.ResponseWriter, r *http.Request) {
69 | p.l.Printf("Handling PUT request")
70 | newprod := &data.Product{}
71 | err := newprod.FromJSON(r.Body)
72 | if err != nil {
73 | http.Error(rw, "Unable to parse product request", http.StatusBadRequest)
74 | }
75 | //p.l.Printf("New Product %#v", newprod)
76 | data.AddProduct(newprod)
77 | }
78 |
79 | func (p *Products) updateProduct(id int, rw http.ResponseWriter, r *http.Request) {
80 | p.l.Println("Handle PUT product")
81 | prod := &data.Product{}
82 |
83 | err := prod.FromJSON(r.Body)
84 | if err != nil {
85 | http.Error(rw, "Unable to parse product request", http.StatusBadRequest)
86 | }
87 | err = data.UpdateProduct(id, prod)
88 | if err == data.ErrorProductNotFound {
89 | http.Error(rw, "Product not found", http.StatusNotFound)
90 | return
91 | }
92 |
93 | if err != nil {
94 | http.Error(rw, "Product update failed", http.StatusInternalServerError)
95 | return
96 | }
97 |
98 | }
99 |
--------------------------------------------------------------------------------
/customdatatypes/datatypes5/organisation/person.go:
--------------------------------------------------------------------------------
1 | package organisation
2 |
3 | import (
4 | "errors"
5 | "fmt"
6 | "strconv"
7 | "strings"
8 | )
9 |
10 | type TwitterHandler string
11 |
12 | func (th TwitterHandler) RedirectURL() string {
13 | cleanHandler := strings.TrimPrefix(string(th), "@")
14 | return fmt.Sprintf("https://www.twitter.com/%s", cleanHandler)
15 | }
16 |
17 | type Identifiable interface {
18 | ID() string
19 | }
20 |
21 | type Citizen interface {
22 | Identifiable
23 | Country() string
24 | }
25 |
26 | type socialSecurityNumber string
27 |
28 | func NewSocialSecurityNumber(value string) Citizen {
29 | return socialSecurityNumber(value)
30 | }
31 |
32 | func (ssn socialSecurityNumber) ID() string {
33 | return string(ssn)
34 | }
35 |
36 | func (ssn socialSecurityNumber) Country() string {
37 | return "USA"
38 | }
39 |
40 | type europeanUnionIdentifier struct {
41 | id string
42 | country []string
43 | }
44 |
45 | func NewEuropeanUnionIdentifier(id interface{}, country string) Citizen {
46 | switch v := id.(type) {
47 | case string:
48 | return europeanUnionIdentifier{
49 | id: v,
50 | country: []string{country},
51 | }
52 | case int:
53 | return europeanUnionIdentifier{
54 | id: strconv.Itoa(v),
55 | country: []string{country},
56 | }
57 | case europeanUnionIdentifier:
58 | return v
59 | case Person:
60 | euId, _ := v.Citizen.(europeanUnionIdentifier)
61 | return euId
62 | default:
63 | panic("Using invalid type initialize EU identifier")
64 | }
65 | }
66 |
67 | func (eui europeanUnionIdentifier) ID() string {
68 | return eui.id
69 | }
70 |
71 | func (eui europeanUnionIdentifier) Country() string {
72 | return fmt.Sprintf("EU: %s", eui.country)
73 | }
74 |
75 | type Name struct {
76 | First string
77 | Last string
78 | }
79 |
80 | func (n *Name) FullName() string {
81 | return fmt.Sprintf("%s %s", n.First, n.Last)
82 | }
83 |
84 | type Employee struct {
85 | Name
86 | }
87 |
88 | type Person struct {
89 | Name
90 | First string
91 | Last string
92 | twitterHandler TwitterHandler
93 | Citizen
94 | }
95 |
96 | func NewPerson(firstName, lastName string, citizen Citizen) Person {
97 | return Person{
98 | Name: Name{
99 | First: firstName,
100 | Last: lastName,
101 | },
102 | Citizen: citizen,
103 | }
104 | }
105 |
106 | func (p *Person) SetTwitterHandler(handler TwitterHandler) error {
107 | if len(handler) == 0 {
108 | p.twitterHandler = handler
109 | } else if !strings.HasPrefix(string(handler), "@") {
110 | return errors.New("twitter handle must start with @ in text")
111 | }
112 | p.twitterHandler = handler
113 | return nil
114 | }
115 |
116 | func (p *Person) TwitterHandler() TwitterHandler {
117 | return p.twitterHandler
118 | }
119 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # GoLang Programming Learning
2 | This repo is created for learning GO language. It consist of basics of golang and advanced use cases.
3 |
4 | ## Basics
5 |
6 | ### Go Standard Library
7 | 1. [Go Args ](gostandard_libs/args_demo)
8 | 2. [Input using Bufio](gostandard_libs/bufio_demo)
9 | 3. [Custom Data types](gostandard_libs/custom_type)
10 | 4. [File Handling](gostandard_libs/filemaker_demo)
11 | 5. [Flag Inputs](gostandard_libs/flag_demo)
12 | 6. [Formated Input/Output using fmt](gostandard_libs/fmt_demo)
13 | 7. [Logers in Golang](gostandard_libs/loger_demo)
14 | 8. [Primitives and Slices](gostandard_libs/others_demo)
15 | 9. [Print input/output](gostandard_libs/print_demo)
16 | 10. [Time handling](gostandard_libs/time_demo)
17 | 11. [Trace in Golang](gostandard_libs/trace_demo)
18 | 12. [Working with Functions](functions)
19 | 13. [Custom Datatypes](customdatatypes)
20 | 14. [Testing in Golang](testinggolang)
21 | 15. [A CLI in goland](pluralsight_projects/golang-personal-budget-cli)
22 | 16. [Advanced Branching into Golang](pluralsight_projects/golang-advanced-branching)
23 |
24 | ### Concurrent Programming
25 | 1. [Channel Basics with PingPong Game](pingpong)
26 | 2. [Channel and Sync Advance Usecases with DB Cache System](concurrentprogram)
27 | 3. [Asynchronous Go Logging](golang-async-logging-library)
28 |
29 | ### Web Services
30 | 1. [A Simple Web Service in Golang](webservice)
31 | 2. [A Pluralsight Fifa World Cup WebService](pluralsight_projects/golang-fifa-world-cup-web-service)
32 |
33 | ### Distributed Application Programming
34 | 1. A true distributed system in go along with in-built load balancing and auto discovery [Distributed App in Go](distributedapp)
35 |
36 | ### Web based Application in Golang
37 | 1. [A Teacher Portal Web App](distributedapp/teacherportal)
38 | 2. [A Employee Vacation Tracker Web App Using gin framework](ginframeworkdemo)
39 |
40 | ### Microservices with Golang
41 | 1. [Microservice in golang basics](microservices/product-api)
42 | 2. [Microservice in golang with Gorilla Framework](microservices/product-api-gorilla)
43 | 3. [Microservice in golang with Gorilla Framework and Swagger File](microservices/product-api-withswagger)
44 | 4. [Microservice in golang with Gorilla Framework, Swagger File and Client](microservices/product-api-withswagger-client)
45 |
46 |
47 |
48 | ### gRPC based Services
49 | 1. A gRPC based APIs (service and client) with TLS and mTLS setup and automated testing [gRPC with mTLS](grpcdemo)
50 |
51 | ### Docker with Golang
52 | 1. [gRPC Based Service with Docker](grpcdemo)
53 | 2. [Distributed Golang App with Docker](distributedappdocker)
54 |
55 | ### Learning References
56 | 1. Most of above projects and knowledge is coming from [Pluralsight Golang Path](https://app.pluralsight.com/paths/skills/go-core-language)
57 | 2. Microservices with Go By [Nic Jackson](https://youtu.be/VzBGi_n65iU)
58 |
59 | ### Few More Learning Links.
60 | 1. Go Testing - https://quii.gitbook.io/learn-go-with-tests/
61 | 2. Using Gin - https://github.com/PacktPublishing/Building-Distributed-Applications-in-Gin
62 | 3. Practical Go- https://www.practical-go-lessons.com/
63 | 4. Go Security - https://checkmarx.gitbooks.io/go-scp/content/
64 |
--------------------------------------------------------------------------------
/distributedapp/grades/server.go:
--------------------------------------------------------------------------------
1 | package grades
2 |
3 | import (
4 | "bytes"
5 | "encoding/json"
6 | "fmt"
7 | "log"
8 | "net/http"
9 | "strconv"
10 | "strings"
11 | )
12 |
13 | func RegisterHandlers() {
14 | handler := new(studentsHandler)
15 | http.Handle("/students", handler)
16 | http.Handle("/students/", handler)
17 |
18 | }
19 |
20 | type studentsHandler struct {
21 | }
22 |
23 | func (sh studentsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
24 | pathSegment := strings.Split(r.URL.Path, "/")
25 | switch len(pathSegment) {
26 | case 2:
27 | sh.getAll(w, r)
28 | case 3:
29 | id, err := strconv.Atoi(pathSegment[2])
30 | if err != nil {
31 | w.WriteHeader(http.StatusNotFound)
32 | return
33 | }
34 | sh.getOne(w, r, id)
35 | case 4:
36 | id, err := strconv.Atoi(pathSegment[2])
37 | if err != nil {
38 | w.WriteHeader(http.StatusNotFound)
39 | return
40 | }
41 | sh.addGrade(w, r, id)
42 | default:
43 | w.WriteHeader(http.StatusNotFound)
44 | return
45 | }
46 | }
47 |
48 | func (sh studentsHandler) getAll(w http.ResponseWriter, r *http.Request) {
49 | studentsMutex.Lock()
50 | defer studentsMutex.Unlock()
51 |
52 | data, err := sh.toJSON(students)
53 | if err != nil {
54 | w.WriteHeader(http.StatusInternalServerError)
55 | log.Println(err)
56 | }
57 | w.Header().Add("Content-Type", "application/json")
58 | w.Write(data)
59 | }
60 |
61 | func (sh studentsHandler) getOne(w http.ResponseWriter, r *http.Request, id int) {
62 | studentsMutex.Lock()
63 | defer studentsMutex.Unlock()
64 |
65 | student, err := students.GetByID(id)
66 | if err != nil {
67 | if err != nil {
68 | w.WriteHeader(http.StatusNotFound)
69 | log.Println(err)
70 | return
71 | }
72 | }
73 |
74 | data, err := sh.toJSON(student)
75 | if err != nil {
76 | w.WriteHeader(http.StatusInternalServerError)
77 | log.Println(fmt.Errorf("Failed to serialize students: %q", err))
78 | return
79 | }
80 | w.Header().Add("content-type", "application/json")
81 | w.Write(data)
82 | }
83 |
84 | func (sh studentsHandler) addGrade(w http.ResponseWriter, r *http.Request, id int) {
85 | studentsMutex.Lock()
86 | defer studentsMutex.Unlock()
87 |
88 | student, err := students.GetByID(id)
89 |
90 | if err != nil {
91 | w.WriteHeader(http.StatusNotFound)
92 | log.Println(err)
93 | return
94 | }
95 | var g Grade
96 | dec := json.NewDecoder(r.Body)
97 | err = dec.Decode(&g)
98 | if err != nil {
99 | w.WriteHeader(http.StatusBadRequest)
100 | fmt.Println(err)
101 | return
102 | }
103 | student.Grades = append(student.Grades, g)
104 | w.WriteHeader(http.StatusCreated)
105 | data, err := sh.toJSON(g)
106 | if err != nil {
107 | //w.WriteHeader(http.StatusInternalServerError)
108 | fmt.Println(err)
109 | return
110 | }
111 | w.Header().Add("content-type", "application/json")
112 | w.Write(data)
113 |
114 | }
115 |
116 | func (sh studentsHandler) toJSON(obj interface{}) ([]byte, error) {
117 | var b bytes.Buffer
118 | enc := json.NewEncoder(&b)
119 | err := enc.Encode(obj)
120 | if err != nil {
121 | return nil, fmt.Errorf("Failed to serialize stundents: %q", err)
122 | }
123 | return b.Bytes(), nil
124 | }
125 |
--------------------------------------------------------------------------------
/distributedappdocker/grades/server.go:
--------------------------------------------------------------------------------
1 | package grades
2 |
3 | import (
4 | "bytes"
5 | "encoding/json"
6 | "fmt"
7 | "log"
8 | "net/http"
9 | "strconv"
10 | "strings"
11 | )
12 |
13 | func RegisterHandlers() {
14 | handler := new(studentsHandler)
15 | http.Handle("/students", handler)
16 | http.Handle("/students/", handler)
17 |
18 | }
19 |
20 | type studentsHandler struct {
21 | }
22 |
23 | func (sh studentsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
24 | pathSegment := strings.Split(r.URL.Path, "/")
25 | switch len(pathSegment) {
26 | case 2:
27 | sh.getAll(w, r)
28 | case 3:
29 | id, err := strconv.Atoi(pathSegment[2])
30 | if err != nil {
31 | w.WriteHeader(http.StatusNotFound)
32 | return
33 | }
34 | sh.getOne(w, r, id)
35 | case 4:
36 | id, err := strconv.Atoi(pathSegment[2])
37 | if err != nil {
38 | w.WriteHeader(http.StatusNotFound)
39 | return
40 | }
41 | sh.addGrade(w, r, id)
42 | default:
43 | w.WriteHeader(http.StatusNotFound)
44 | return
45 | }
46 | }
47 |
48 | func (sh studentsHandler) getAll(w http.ResponseWriter, r *http.Request) {
49 | studentsMutex.Lock()
50 | defer studentsMutex.Unlock()
51 |
52 | data, err := sh.toJSON(students)
53 | if err != nil {
54 | w.WriteHeader(http.StatusInternalServerError)
55 | log.Println(err)
56 | }
57 | w.Header().Add("Content-Type", "application/json")
58 | w.Write(data)
59 | }
60 |
61 | func (sh studentsHandler) getOne(w http.ResponseWriter, r *http.Request, id int) {
62 | studentsMutex.Lock()
63 | defer studentsMutex.Unlock()
64 |
65 | student, err := students.GetByID(id)
66 | if err != nil {
67 | if err != nil {
68 | w.WriteHeader(http.StatusNotFound)
69 | log.Println(err)
70 | return
71 | }
72 | }
73 |
74 | data, err := sh.toJSON(student)
75 | if err != nil {
76 | w.WriteHeader(http.StatusInternalServerError)
77 | log.Println(fmt.Errorf("Failed to serialize students: %q", err))
78 | return
79 | }
80 | w.Header().Add("content-type", "application/json")
81 | w.Write(data)
82 | }
83 |
84 | func (sh studentsHandler) addGrade(w http.ResponseWriter, r *http.Request, id int) {
85 | studentsMutex.Lock()
86 | defer studentsMutex.Unlock()
87 |
88 | student, err := students.GetByID(id)
89 |
90 | if err != nil {
91 | w.WriteHeader(http.StatusNotFound)
92 | log.Println(err)
93 | return
94 | }
95 | var g Grade
96 | dec := json.NewDecoder(r.Body)
97 | err = dec.Decode(&g)
98 | if err != nil {
99 | w.WriteHeader(http.StatusBadRequest)
100 | fmt.Println(err)
101 | return
102 | }
103 | student.Grades = append(student.Grades, g)
104 | w.WriteHeader(http.StatusCreated)
105 | data, err := sh.toJSON(g)
106 | if err != nil {
107 | //w.WriteHeader(http.StatusInternalServerError)
108 | fmt.Println(err)
109 | return
110 | }
111 | w.Header().Add("content-type", "application/json")
112 | w.Write(data)
113 |
114 | }
115 |
116 | func (sh studentsHandler) toJSON(obj interface{}) ([]byte, error) {
117 | var b bytes.Buffer
118 | enc := json.NewEncoder(&b)
119 | err := enc.Encode(obj)
120 | if err != nil {
121 | return nil, fmt.Errorf("Failed to serialize stundents: %q", err)
122 | }
123 | return b.Bytes(), nil
124 | }
125 |
--------------------------------------------------------------------------------
/grpcdemo/README.md:
--------------------------------------------------------------------------------
1 | ### Vacation Tracker based on GRPC and GO Lang
2 |
3 |
4 | ### Tools to install
5 | ```
6 | go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28
7 | go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2
8 | go env GOPATH
9 | $env:PATH +="{GO PATH HERE}\bin"
10 | ```
11 | ### Commands
12 |
13 | 1. Generating Server Code from protoc message
14 | ```
15 | cd server
16 | go mod init github.com/erankitcs/golang_learning/grpcdemo/server
17 | protoc --proto_path=../pb ../pb/*.proto --go_out=. --go-grpc_out=.
18 | ```
19 |
20 | 2. Certificate Generate commands
21 | ```
22 | cd cert
23 | # 1. Generate CA's private key and self-signed certificate
24 | openssl req -x509 -newkey rsa:4096 -days 365 -nodes -keyout ca-key.pem -out ca-cert.pem -subj "/C=AU/ST=Vic/L=Melbourne/O=Go Grpc/OU=Testing/CN=*.gogrpc.test/emailAddress=gogrpctest@gmail.com"
25 | # View CA certificate
26 | openssl x509 -in ca-cert.pem -noout -text
27 |
28 | # 2. Generate web server's private key and certificate signing request (CSR)
29 | openssl req -newkey rsa:4096 -nodes -keyout server-key.pem -out server-req.pem -subj "/C=AU/ST=Vic/L=Melbourne/O=Go Grpc/OU=ServerTesting/CN=*.gogrpcserver.com/emailAddress=gogrpcserver@gmail.com"
30 |
31 | # 3. Use CA's private key to sign web server's CSR and get back the signed certificate
32 | openssl x509 -req -in server-req.pem -days 60 -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem -extfile server-ext.cnf
33 |
34 | echo "Server's signed certificate"
35 | openssl x509 -in server-cert.pem -noout -text
36 |
37 | # 4. Move certs starts with server into cert folder inside server.
38 | ```
39 |
40 | 3. Build and Run server, use -mtls=true for running into mTLS Mode.
41 | ```
42 | cd server
43 | go build .
44 | ./server.exe
45 | ```
46 |
47 | 4. Call server via grpccurl
48 |
49 | - You need to add below line for local DNS resolution.
50 |
51 | 127.0.0.1 test.gogrpcserver.com
52 |
53 | - Need to set Environment variable
54 | ```
55 | $env:GODEBUG="x509ignoreCN=0"
56 | ```
57 | - Run below command to call grpc server.
58 | ```
59 | grpcurl -cacert ca-cert.pem test.gogrpcserver.com:9000 messages.EmployeeService/GetAll
60 | ```
61 |
62 | *Postman support grpc now*
63 | https://blog.postman.com/postman-now-supports-grpc/
64 |
65 | 5. Call via Golang based client.
66 | - Run go mod init and get client for grpc
67 | ```
68 | cd client
69 | go mod init github.com/erankitcs/golang_learning/grpcdemo/client
70 | protoc --proto_path=../pb ../pb/*.proto --go_out=. --go-grpc_out=.
71 | go mod tidy
72 | go build .
73 | ```
74 | - Run Client, -tls true for TLS setup and -mtls true for mTLS setup.
75 | ```
76 | ./client.exe -tls true
77 | ```
78 |
79 | 6. Server Testing
80 | ```
81 | cd server
82 | go test -v
83 | ```
84 |
85 | 7. Docker setup for Server
86 | ```
87 | docker build -t employeegrpcserver -f server/Dockerfile .
88 | docker run -d -p 9000:9000 -e tls=mtls --network host --name employeegrpcserver employeegrpcserver
89 | ```
90 | 8. Docker setup for Client
91 | ```
92 | docker build -t employeegrpcclient -f client/Dockerfile .
93 | docker run -e tls=mtls -e opt=1 -e serverhost=localhost --network host --name grpcclient employeegrpcclient
94 | ```
95 | - Docker Links\
96 | https://www.docker.com/blog/tag/go-env-series/
97 | https://github.com/chris-crone/containerized-go-dev
98 |
--------------------------------------------------------------------------------
/pluralsight_projects/golang-fifa-world-cup-web-service/handlers/02_post_handler_test.go:
--------------------------------------------------------------------------------
1 | package handlers
2 |
3 | import (
4 | "bytes"
5 | "encoding/json"
6 | "golang-fifa-world-cup-web-service/data"
7 | "net/http"
8 | "net/http/httptest"
9 | "testing"
10 | )
11 |
12 | func TestAddNewWinnerHandlerReturnsUnauthorizedForInvalidAccessToken(t *testing.T) {
13 | setup()
14 |
15 | req, _ := http.NewRequest("POST", "/winners", nil)
16 | req.Header.Set("X-ACCESS-TOKEN", data.AccessToken+"bla")
17 | rr := httptest.NewRecorder()
18 | handler := http.HandlerFunc(AddNewWinner)
19 | handler.ServeHTTP(rr, req)
20 |
21 | if status := rr.Code; status != http.StatusUnauthorized {
22 | t.Error("Did not return status 401 - Unauthorized for invalid Access Token")
23 | }
24 | }
25 |
26 | func TestAddNewWinnerHandlerReturnsCreatedForValidAccessToken(t *testing.T) {
27 | var jsonStr = []byte(`{"country":"Croatia", "year": 2030}`)
28 | req, _ := http.NewRequest("POST", "/winners", bytes.NewBuffer(jsonStr))
29 | req.Header.Set("Content-Type", "application/json")
30 | req.Header.Set("X-ACCESS-TOKEN", data.AccessToken)
31 |
32 | rr := httptest.NewRecorder()
33 | handler := http.HandlerFunc(AddNewWinner)
34 | handler.ServeHTTP(rr, req)
35 |
36 | if status := rr.Code; status != http.StatusCreated {
37 | t.Error("Did not return status 201 - Created for valid Access Token")
38 | }
39 | }
40 |
41 | func TestAddNewWinnerHandlerAddsNewWinnerWithValidData(t *testing.T) {
42 | setup()
43 |
44 | var jsonStr = []byte(`{"country":"Croatia", "year": 2030}`)
45 | req, _ := http.NewRequest("POST", "/winners", bytes.NewBuffer(jsonStr))
46 | req.Header.Set("Content-Type", "application/json")
47 | req.Header.Set("X-ACCESS-TOKEN", data.AccessToken)
48 |
49 | rr := httptest.NewRecorder()
50 | handler := http.HandlerFunc(AddNewWinner)
51 | handler.ServeHTTP(rr, req)
52 |
53 | allWinners, _ := data.ListAllJSON()
54 | var winners data.Winners
55 | json.Unmarshal([]byte(allWinners), &winners)
56 |
57 | if len(winners.Winners) != 22 {
58 | t.Error("Did not properly add new winner to the list")
59 | }
60 | }
61 |
62 | func TestAddNewWinnerHandlerReturnsUnprocessableEntityForEmptyPayload(t *testing.T) {
63 | setup()
64 |
65 | // Invalid because empty
66 | var jsonStr = []byte(``)
67 | req, _ := http.NewRequest("POST", "/winners", bytes.NewBuffer(jsonStr))
68 | req.Header.Set("X-ACCESS-TOKEN", data.AccessToken)
69 | rr := httptest.NewRecorder()
70 | handler := http.HandlerFunc(AddNewWinner)
71 | handler.ServeHTTP(rr, req)
72 | if status := rr.Code; status != http.StatusUnprocessableEntity {
73 | t.Error("Did not properly validate winner payload")
74 | }
75 | }
76 |
77 | func TestAddNewWinnerHandlerDoesNotAddInvalidNewWinner(t *testing.T) {
78 | setup()
79 |
80 | // Invalid entry because year is in the past.
81 | var jsonStr = []byte(`{"country":"Croatia", "year": 1984}`)
82 | req, _ := http.NewRequest("POST", "/winners", bytes.NewBuffer(jsonStr))
83 | req.Header.Set("Content-Type", "application/json")
84 | req.Header.Set("X-ACCESS-TOKEN", data.AccessToken)
85 |
86 | rr := httptest.NewRecorder()
87 | handler := http.HandlerFunc(AddNewWinner)
88 | handler.ServeHTTP(rr, req)
89 |
90 | allWinners, _ := data.ListAllJSON()
91 | var winners data.Winners
92 | json.Unmarshal([]byte(allWinners), &winners)
93 |
94 | if rr.Code == http.StatusOK || len(winners.Winners) != 21 {
95 | t.Error("Added invalid winner to list")
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/golang-async-logging-library/module3_test.go:
--------------------------------------------------------------------------------
1 | package alog
2 |
3 | import (
4 | "bytes"
5 | "strings"
6 | "testing"
7 | "time"
8 | )
9 |
10 | // 01
11 | func TestNewInitializesShutdownChannelsModule3(t *testing.T) {
12 | alog := New(nil)
13 | if alog.shutdownCh == nil {
14 | t.Error("shutdownCh field not initialized")
15 | }
16 |
17 | if alog.shutdownCompleteCh == nil {
18 | t.Error("shutdownCompleteCh field not initialized")
19 | }
20 | }
21 |
22 | // 02
23 |
24 | func TestShutdownMethodModule3(t *testing.T) {
25 | alog := New(nil)
26 | alog.shutdownCompleteCh = make(chan struct{}, 1)
27 | alog.shutdown()
28 | time.Sleep(100 * time.Millisecond)
29 | select {
30 | case _, ok := <-alog.msgCh:
31 | if ok {
32 | t.Error("msgCh not closed by shutdown() method")
33 | }
34 | default:
35 | t.Error("msgCh not closed by shutdown() method")
36 | }
37 | select {
38 | case <-alog.shutdownCompleteCh:
39 | default:
40 | t.Error("shutdown() doesn't send message to shutdownCompleteCh")
41 | }
42 |
43 | }
44 |
45 | // 03
46 |
47 | func TestStartMethodCallsShutdownModule3(t *testing.T) {
48 | b := bytes.NewBuffer([]byte{})
49 | alog := New(b)
50 | alog.shutdownCh = make(chan struct{}, 1)
51 | alog.shutdownCompleteCh = make(chan struct{}, 1)
52 | go alog.Start()
53 | alog.shutdownCh <- struct{}{}
54 | time.Sleep(100 * time.Millisecond)
55 |
56 | select {
57 | case _, ok := <-alog.msgCh:
58 | if ok {
59 | t.Error("Passing message to shutdownCh doesn't call shutdown()")
60 | }
61 | default:
62 | t.Error("Passing message to shutdownCh doesn't call shutdown()")
63 | }
64 | select {
65 | case <-alog.shutdownCompleteCh:
66 | default:
67 | t.Error("Passing message to shutdownCh doesn't call shutdown()")
68 | }
69 | if b.Len() != 0 {
70 | t.Error("Passing message to shutdownCh doesn't break out of the Start method's for loop. " +
71 | "Note that 'break' statements can be used for select and for loops so a label might be " +
72 | "required to break out the loop.")
73 | }
74 | }
75 |
76 | // 04
77 |
78 | func TestStopMethodModule3(t *testing.T) {
79 | alog := New(nil)
80 | alog.shutdownCh = make(chan struct{}, 1)
81 | alog.shutdownCompleteCh = make(chan struct{}, 1)
82 | alog.shutdownCompleteCh <- struct{}{}
83 | alog.Stop()
84 | select {
85 | case <-alog.shutdownCh:
86 | default:
87 | t.Error("Stop() method doesn't send signal to shutdownCh channel")
88 | }
89 | select {
90 | case <-alog.shutdownCompleteCh:
91 | t.Error("Stop() method doesn't wait for signal from shutdownCompleteCh channel")
92 | default:
93 | }
94 | }
95 |
96 | // 05
97 |
98 | func TestWriteAllBeforeShutdownModule3(t *testing.T) {
99 | b := bytes.NewBuffer([]byte{})
100 | alog := New(sleepingWriter{b})
101 | alog.msgCh = make(chan string, 2)
102 | go alog.Start()
103 | alog.msgCh <- "first"
104 | alog.msgCh <- "second"
105 | time.Sleep(10 * time.Millisecond)
106 | doneCh := make(chan struct{})
107 | go func() {
108 | alog.Stop()
109 | written := b.String()
110 | if !strings.Contains(written, "first") || !strings.Contains(written, "second") {
111 | t.Error("Not all messages written before logger shutdown")
112 | }
113 | doneCh <- struct{}{}
114 | }()
115 | select {
116 | case <-time.Tick(1 * time.Second):
117 | t.Error("Test timed out, please check that the Done method on the wait group is being called in the write method")
118 | case <-doneCh:
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/microservices/product-api-withswagger/data/products.go:
--------------------------------------------------------------------------------
1 | package data
2 |
3 | import (
4 | "fmt"
5 | )
6 |
7 | // ErrProductNotFound is an error raised when a product can not be found in the database
8 | var ErrorProductNotFound = fmt.Errorf("Product not found")
9 |
10 | // Product defines the structure for an API product
11 | // swagger:model
12 | type Product struct {
13 | // the id for the product
14 | //
15 | // required: false
16 | // min:1
17 | ID int `json:"id"`
18 |
19 | // the name for this poduct
20 | //
21 | // required: true
22 | // max length: 255
23 | Name string `json:"name" validate:"required"`
24 |
25 | // the description for this poduct
26 | //
27 | // required: false
28 | // max length: 10000
29 | Description string `json:"description"`
30 |
31 | // the price for the product
32 | //
33 | // required: true
34 | // min: 0.01
35 | Price float32 `json:"price" validate:"gt=0"`
36 |
37 | // the SKU for the product
38 | //
39 | // required: true
40 | // pattern: [a-z]+-[a-z]+-[a-z]+
41 | SKU string `json:"sku" validate:"required,sku"`
42 | }
43 |
44 | //Collection of product
45 | type Products []*Product
46 |
47 | // func (p *Product) Validate() error {
48 | // validate := validator.New()
49 | // validate.RegisterValidation("sku", validateSKU)
50 | // return validate.Struct(p)
51 | // }
52 |
53 | var productList = []*Product{
54 | {
55 | ID: 1,
56 | Name: "Latte",
57 | Description: "Frothy milky coffee",
58 | Price: 2.45,
59 | SKU: "abc323",
60 | },
61 | {
62 | ID: 2,
63 | Name: "Espresso",
64 | Description: "Short and strong coffee without milk",
65 | Price: 1.99,
66 | SKU: "fjd34",
67 | },
68 | }
69 |
70 | // GetProducts returns all products from the database
71 | func GetProducts() Products {
72 | return productList
73 | }
74 |
75 | // GetProductByID returns a single product which matches the id from the
76 | // database.
77 | // If a product is not found this function returns a ProductNotFound error
78 | func GetProductByID(id int) (*Product, error) {
79 | i := findIndexByProductID(id)
80 | if i == -1 {
81 | return nil, ErrorProductNotFound
82 | }
83 | return productList[i], nil
84 | }
85 |
86 | // UpdateProduct replaces a product in the database with the given
87 | // item.
88 | // If a product with the given id does not exist in the database
89 | // this function returns a ProductNotFound erro
90 | func UpdateProduct(p *Product) error {
91 | i := findIndexByProductID(p.ID)
92 | if i == -1 {
93 | return ErrorProductNotFound
94 | }
95 | productList[i] = p
96 | return nil
97 | }
98 |
99 | // AddProduct adds a new product to the database
100 | func AddProduct(p *Product) {
101 | maxID := productList[len(productList)-1].ID
102 | p.ID = maxID + 1
103 | productList = append(productList, p)
104 |
105 | }
106 |
107 | // DeleteProduct deletes a product from the database
108 | func DeleteProduct(id int) error {
109 | i := findIndexByProductID(id)
110 | if i == -1 {
111 | return ErrorProductNotFound
112 | }
113 | productList = append(productList[:i], productList[i+1:]...)
114 | return nil
115 | }
116 |
117 | // findIndex finds the index of a product in the database
118 | // returns -1 when no product can be found
119 | func findIndexByProductID(id int) int {
120 | for i, p := range productList {
121 | if p.ID == id {
122 | return i
123 | }
124 | }
125 | return -1
126 | }
127 |
--------------------------------------------------------------------------------
/webservice/controllers/user.go:
--------------------------------------------------------------------------------
1 | package controllers
2 |
3 | import (
4 | "encoding/json"
5 | "net/http"
6 | "regexp"
7 | "strconv"
8 |
9 | "github.com/erankitcs/golang_learning/webservice/models"
10 | )
11 |
12 | type userController struct {
13 | userIDPattern *regexp.Regexp
14 | }
15 |
16 | func (uc userController) ServeHTTP(w http.ResponseWriter, r *http.Request) {
17 | // w.Write([]byte("Hello from User Controller."))
18 | if r.URL.Path == "/users" {
19 | switch r.Method {
20 | case http.MethodGet:
21 | uc.getAll(w, r)
22 | case http.MethodPost:
23 | uc.post(w, r)
24 | default:
25 | w.WriteHeader(http.StatusNotImplemented)
26 | }
27 | } else {
28 | matches := uc.userIDPattern.FindStringSubmatch(r.URL.Path)
29 | if len(matches) == 0 {
30 | w.WriteHeader(http.StatusNotFound)
31 | return
32 | }
33 | id, err := strconv.Atoi(matches[1])
34 | if err != nil {
35 | w.WriteHeader(http.StatusNotFound)
36 | return
37 | }
38 | switch r.Method {
39 | case http.MethodGet:
40 | uc.get(id, w)
41 | case http.MethodPut:
42 | uc.put(id, w, r)
43 | case http.MethodDelete:
44 | uc.delete(id, w)
45 | default:
46 | w.WriteHeader(http.StatusNotImplemented)
47 | }
48 |
49 | }
50 | }
51 |
52 | func (uc *userController) getAll(w http.ResponseWriter, r *http.Request) {
53 | encodeResponseAsJSON(models.GetUsers(), w)
54 | }
55 |
56 | func (uc *userController) get(id int, w http.ResponseWriter) {
57 | u, err := models.GetUserById(id)
58 | if err != nil {
59 | w.WriteHeader(http.StatusInternalServerError)
60 | return
61 | }
62 | encodeResponseAsJSON(u, w)
63 | }
64 |
65 | func (uc *userController) post(w http.ResponseWriter, r *http.Request) {
66 | u, err := uc.parseRequest(r)
67 | if err != nil {
68 | w.WriteHeader(http.StatusInternalServerError)
69 | w.Write([]byte("Could not parse User Object."))
70 | return
71 | }
72 | u, err = models.AddUser(u)
73 | if err != nil {
74 | w.WriteHeader(http.StatusInternalServerError)
75 | w.Write([]byte(err.Error()))
76 | return
77 | }
78 | encodeResponseAsJSON(u, w)
79 | }
80 |
81 | func (uc *userController) put(id int, w http.ResponseWriter, r *http.Request) {
82 | u, err := uc.parseRequest(r)
83 | if err != nil {
84 | w.WriteHeader(http.StatusInternalServerError)
85 | w.Write([]byte("Could not parse User object"))
86 | return
87 | }
88 | if id != u.ID {
89 | w.WriteHeader(http.StatusBadRequest)
90 | w.Write([]byte("ID of submitted user must match ID in URL"))
91 | return
92 | }
93 | u, err = models.UpdateUser(u)
94 | if err != nil {
95 | w.WriteHeader(http.StatusInternalServerError)
96 | w.Write([]byte(err.Error()))
97 | return
98 | }
99 | encodeResponseAsJSON(u, w)
100 | }
101 |
102 | func (uc *userController) delete(id int, w http.ResponseWriter) {
103 | err := models.RemoveUserById(id)
104 | if err != nil {
105 | w.WriteHeader(http.StatusInternalServerError)
106 | w.Write([]byte(err.Error()))
107 | return
108 | }
109 | w.WriteHeader(http.StatusOK)
110 | }
111 |
112 | func newUserController() *userController {
113 | return &userController{
114 | userIDPattern: regexp.MustCompile(`^/users/(\d+)/?`),
115 | }
116 | }
117 |
118 | func (uc *userController) parseRequest(r *http.Request) (models.User, error) {
119 | dec := json.NewDecoder(r.Body)
120 | var u models.User
121 | err := dec.Decode(&u)
122 | if err != nil {
123 | return models.User{}, nil
124 | }
125 | return u, nil
126 | }
127 |
--------------------------------------------------------------------------------