-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.go
194 lines (156 loc) · 7.21 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
// Ortelius v11 Domain Microservice that handles creating and retrieving Domains
package main
import (
"context"
"encoding/json"
_ "github.com/ortelius/scec-domain/docs"
driver "github.com/arangodb/go-driver/v2/arangodb"
"github.com/arangodb/go-driver/v2/arangodb/shared"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/cors"
"github.com/gofiber/swagger"
"github.com/ortelius/scec-commons/database"
"github.com/ortelius/scec-commons/model"
)
var logger = database.InitLogger()
var dbconn = database.InitializeDatabase()
// GetDomains godoc
// @Summary Get a List of Domains
// @Description Get a list of domains for the user.
// @Tags domain
// @Accept */*
// @Produce json
// @Success 200
// @Router /msapi/domain [get]
func GetDomains(c *fiber.Ctx) error {
var cursor driver.Cursor // db cursor for rows
var err error // for error handling
var ctx = context.Background() // use default database context
// query all the domains in the collection
aql := `FOR domain in evidence
FILTER (domain.objtype == 'DomainDetails')
RETURN domain`
// execute the query with no parameters
if cursor, err = dbconn.Database.Query(ctx, aql, nil); err != nil {
logger.Sugar().Errorf("Failed to run query: %v", err) // log error
}
defer cursor.Close() // close the cursor when returning from this function
var domains []*model.Domain // define a list of domains to be returned
for cursor.HasMore() { // loop thru all of the documents
domain := model.NewDomain() // fetched domain
var meta driver.DocumentMeta // data about the fetch
// fetch a document from the cursor
if meta, err = cursor.ReadDocument(ctx, domain); err != nil {
logger.Sugar().Errorf("Failed to read document: %v", err)
}
domains = append(domains, domain) // add the domain to the list
logger.Sugar().Infof("Got doc with key '%s' from query\n", meta.Key) // log the key
}
return c.JSON(domains) // return the list of domains in JSON format
}
// GetDomain godoc
// @Summary Get a Domain
// @Description Get a domain based on the _key or name.
// @Tags domain
// @Accept */*
// @Produce json
// @Success 200
// @Router /msapi/domain/:key [get]
func GetDomain(c *fiber.Ctx) error {
var cursor driver.Cursor // db cursor for rows
var err error // for error handling
var ctx = context.Background() // use default database context
key := c.Params("key") // key from URL
parameters := map[string]interface{}{ // parameters
"key": key,
}
// query the domains that match the key or name
aql := `FOR domain in evidence
FILTER (domain.name == @key or domain._key == @key)
RETURN domain`
// run the query with patameters
if cursor, err = dbconn.Database.Query(ctx, aql, &driver.QueryOptions{BindVars: parameters}); err != nil {
logger.Sugar().Errorf("Failed to run query: %v", err)
}
defer cursor.Close() // close the cursor when returning from this function
domain := model.NewDomain() // define a domain to be returned
if cursor.HasMore() { // domain found
var meta driver.DocumentMeta // data about the fetch
if meta, err = cursor.ReadDocument(ctx, domain); err != nil { // fetch the document into the object
logger.Sugar().Errorf("Failed to read document: %v", err)
}
logger.Sugar().Infof("Got doc with key '%s' from query\n", meta.Key)
} else { // not found so get from NFT Storage
if jsonStr, exists := database.MakeJSON(key); exists {
if err := json.Unmarshal([]byte(jsonStr), domain); err != nil { // convert the JSON string from LTF into the object
logger.Sugar().Errorf("Failed to unmarshal from LTS: %v", err)
}
}
}
return c.JSON(domain) // return the domain in JSON format
}
// NewDomain godoc
// @Summary Create a Domain
// @Description Create a new Domain and persist it
// @Tags domain
// @Accept application/json
// @Produce json
// @Success 200
// @Router /msapi/domain [post]
func NewDomain(c *fiber.Ctx) error {
var err error // for error handling
var meta driver.DocumentMeta // data about the document
var ctx = context.Background() // use default database context
domain := new(model.Domain) // define a domain to be returned
if err = c.BodyParser(domain); err != nil { // parse the JSON into the domain object
return c.Status(503).Send([]byte(err.Error()))
}
cid, dbStr := database.MakeNFT(domain) // normalize the object into NFTs and JSON string for db persistence
logger.Sugar().Infof("%s=%s\n", cid, dbStr) // log the new nft
var resp driver.CollectionDocumentCreateResponse
// add the domain to the database. Ignore if it already exists since it will be identical
if resp, err = dbconn.Collections["domains"].CreateDocument(ctx, domain); err != nil && !shared.IsConflict(err) {
logger.Sugar().Errorf("Failed to create document: %v", err)
}
meta = resp.DocumentMeta
logger.Sugar().Infof("Created document in collection '%s' in db '%s' key='%s'\n", dbconn.Collections["domains"].Name(), dbconn.Database.Name(), meta.Key)
return c.JSON(domain) // return the domain object in JSON format. This includes the new _key
}
// setupRoutes defines maps the routes to the functions
func setupRoutes(app *fiber.App) {
app.Get("/swagger/*", swagger.HandlerDefault) // handle displaying the swagger
app.Get("/msapi/domain", GetDomains) // list of domains
app.Get("/msapi/domain/:key", GetDomain) // single domain based on name or key
app.Post("/msapi/domain", NewDomain) // save a single domain
}
// @title Ortelius v11 Domain Microservice
// @version 11.0.0
// @description RestAPI for the Domain Object
// @description ![Release](https://img.shields.io/github/v/release/ortelius/scec-domain?sort=semver)
// @description ![license](https://img.shields.io/github/license/ortelius/.github)
// @description
// @description ![Build](https://img.shields.io/github/actions/workflow/status/ortelius/scec-domain/build-push-chart.yml)
// @description [![MegaLinter](https://github.com/ortelius/scec-domain/workflows/MegaLinter/badge.svg?branch=main)](https://github.com/ortelius/scec-domain/actions?query=workflow%3AMegaLinter+branch%3Amain)
// @description ![CodeQL](https://github.com/ortelius/scec-domain/workflows/CodeQL/badge.svg)
// @description [![OpenSSF-Scorecard](https://api.securityscorecards.dev/projects/github.com/ortelius/scec-domain/badge)](https://api.securityscorecards.dev/projects/github.com/ortelius/scec-domain)
// @description
// @description ![Discord](https://img.shields.io/discord/722468819091849316)
// @termsOfService http://swagger.io/terms/
// @contact.name Ortelius Google Group
// @contact.email [email protected]
// @license.name Apache 2.0
// @license.url http://www.apache.org/licenses/LICENSE-2.0.html
// @host localhost:3000
// @BasePath /msapi/domain
func main() {
port := ":" + database.GetEnvDefault("MS_PORT", "8080") // database port
app := fiber.New() // create a new fiber application
app.Use(cors.New(cors.Config{
AllowHeaders: "Origin, Content-Type, Accept",
AllowOrigins: "*",
}))
setupRoutes(app) // define the routes for this microservice
if err := app.Listen(port); err != nil { // start listening for incoming connections
logger.Sugar().Fatalf("Failed get the microservice running: %v", err)
}
}