2024-02-10 15:17:34 +00:00
|
|
|
package api
|
|
|
|
|
|
|
|
import (
|
2024-02-27 19:58:57 +00:00
|
|
|
"fmt"
|
|
|
|
"net/http"
|
|
|
|
|
2024-02-10 15:17:34 +00:00
|
|
|
"github.com/gin-gonic/gin"
|
2024-02-27 19:58:57 +00:00
|
|
|
"github.com/pikami/cosmium/api/config"
|
2024-02-10 15:17:34 +00:00
|
|
|
"github.com/pikami/cosmium/api/handlers"
|
2024-02-12 19:38:03 +00:00
|
|
|
"github.com/pikami/cosmium/api/handlers/middleware"
|
2024-02-27 20:38:59 +00:00
|
|
|
"github.com/pikami/cosmium/internal/logger"
|
|
|
|
tlsprovider "github.com/pikami/cosmium/internal/tls_provider"
|
2024-02-10 15:17:34 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func CreateRouter() *gin.Engine {
|
2024-10-28 12:29:26 +00:00
|
|
|
|
|
|
|
router := gin.Default(func(e *gin.Engine) {
|
|
|
|
e.RemoveExtraSlash = true
|
|
|
|
})
|
2024-02-10 15:17:34 +00:00
|
|
|
|
2024-02-27 20:38:59 +00:00
|
|
|
if config.Config.Debug {
|
|
|
|
router.Use(middleware.RequestLogger())
|
|
|
|
}
|
|
|
|
|
2024-02-21 21:40:54 +00:00
|
|
|
router.Use(middleware.Authentication())
|
2024-02-12 19:38:03 +00:00
|
|
|
|
2024-02-10 23:44:20 +00:00
|
|
|
router.GET("/dbs/:databaseId/colls/:collId/pkranges", handlers.GetPartitionKeyRanges)
|
|
|
|
router.POST("/dbs/:databaseId/colls/:collId/docs", handlers.DocumentsPost)
|
|
|
|
router.GET("/dbs/:databaseId/colls/:collId/docs", handlers.GetAllDocuments)
|
|
|
|
router.GET("/dbs/:databaseId/colls/:collId/docs/:docId", handlers.GetDocument)
|
2024-02-14 18:36:57 +00:00
|
|
|
router.PUT("/dbs/:databaseId/colls/:collId/docs/:docId", handlers.ReplaceDocument)
|
2024-06-01 17:52:07 +01:00
|
|
|
router.PATCH("/dbs/:databaseId/colls/:collId/docs/:docId", handlers.PatchDocument)
|
2024-02-10 23:44:20 +00:00
|
|
|
router.DELETE("/dbs/:databaseId/colls/:collId/docs/:docId", handlers.DeleteDocument)
|
2024-02-10 16:52:41 +00:00
|
|
|
router.POST("/dbs/:databaseId/colls", handlers.CreateCollection)
|
|
|
|
router.GET("/dbs/:databaseId/colls", handlers.GetAllCollections)
|
|
|
|
router.GET("/dbs/:databaseId/colls/:collId", handlers.GetCollection)
|
|
|
|
router.DELETE("/dbs/:databaseId/colls/:collId", handlers.DeleteCollection)
|
2024-02-10 15:17:34 +00:00
|
|
|
router.POST("/dbs", handlers.CreateDatabase)
|
2024-02-10 16:52:41 +00:00
|
|
|
router.GET("/dbs", handlers.GetAllDatabases)
|
|
|
|
router.GET("/dbs/:databaseId", handlers.GetDatabase)
|
|
|
|
router.DELETE("/dbs/:databaseId", handlers.DeleteDatabase)
|
2024-02-10 19:05:08 +00:00
|
|
|
router.GET("/dbs/:databaseId/colls/:collId/udfs", handlers.GetAllUserDefinedFunctions)
|
|
|
|
router.GET("/dbs/:databaseId/colls/:collId/sprocs", handlers.GetAllStoredProcedures)
|
|
|
|
router.GET("/dbs/:databaseId/colls/:collId/triggers", handlers.GetAllTriggers)
|
|
|
|
router.GET("/offers", handlers.GetOffers)
|
2024-02-10 15:17:34 +00:00
|
|
|
router.GET("/", handlers.GetServerInfo)
|
2024-02-22 22:27:12 +00:00
|
|
|
router.GET("/cosmium/export", handlers.CosmiumExport)
|
|
|
|
|
2024-10-28 12:29:26 +00:00
|
|
|
addRoutesForTrailingSlashes(router)
|
|
|
|
|
2024-02-13 23:47:51 +00:00
|
|
|
handlers.RegisterExplorerHandlers(router)
|
|
|
|
|
2024-02-10 15:17:34 +00:00
|
|
|
return router
|
|
|
|
}
|
2024-02-27 19:58:57 +00:00
|
|
|
|
2024-10-28 12:29:26 +00:00
|
|
|
func addRoutesForTrailingSlashes(router *gin.Engine) {
|
|
|
|
trailingSlashGroup := router.Group("/")
|
|
|
|
//prepend, so slash is stripped before authentication middleware reads path
|
|
|
|
trailingSlashGroup.Handlers = prepend(trailingSlashGroup.Handlers, middleware.TrailingSlashStripper())
|
|
|
|
|
|
|
|
for _, route := range router.Routes() {
|
|
|
|
if route.Path != "/" { //don't append slash to root path, already handled by RemoveExtraSlash
|
|
|
|
trailingSlashGroup.Handle(route.Method, route.Path+"/", route.HandlerFunc)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func prepend[T any](a []T, e T) []T {
|
|
|
|
a = append([]T{e}, a...)
|
|
|
|
return a
|
|
|
|
}
|
|
|
|
|
2024-02-27 19:58:57 +00:00
|
|
|
func StartAPI() {
|
2024-02-27 20:38:59 +00:00
|
|
|
if !config.Config.Debug {
|
|
|
|
gin.SetMode(gin.ReleaseMode)
|
|
|
|
}
|
|
|
|
|
2024-02-27 19:58:57 +00:00
|
|
|
router := CreateRouter()
|
|
|
|
listenAddress := fmt.Sprintf(":%d", config.Config.Port)
|
|
|
|
|
|
|
|
if config.Config.TLS_CertificatePath != "" && config.Config.TLS_CertificateKey != "" {
|
|
|
|
err := router.RunTLS(
|
|
|
|
listenAddress,
|
|
|
|
config.Config.TLS_CertificatePath,
|
|
|
|
config.Config.TLS_CertificateKey)
|
|
|
|
if err != nil {
|
2024-02-27 20:38:59 +00:00
|
|
|
logger.Error("Failed to start HTTPS server:", err)
|
2024-02-27 19:58:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if config.Config.DisableTls {
|
|
|
|
router.Run(listenAddress)
|
|
|
|
}
|
|
|
|
|
2024-02-27 20:38:59 +00:00
|
|
|
tlsConfig := tlsprovider.GetDefaultTlsConfig()
|
2024-02-27 19:58:57 +00:00
|
|
|
server := &http.Server{
|
|
|
|
Addr: listenAddress,
|
|
|
|
Handler: router.Handler(),
|
|
|
|
TLSConfig: tlsConfig,
|
|
|
|
}
|
|
|
|
|
2024-02-27 20:38:59 +00:00
|
|
|
logger.Infof("Listening and serving HTTPS on %s\n", server.Addr)
|
2024-02-27 19:58:57 +00:00
|
|
|
err := server.ListenAndServeTLS("", "")
|
|
|
|
if err != nil {
|
2024-02-27 20:38:59 +00:00
|
|
|
logger.Error("Failed to start HTTPS server:", err)
|
2024-02-27 19:58:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
router.Run()
|
|
|
|
}
|