You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
153 lines
5.3 KiB
153 lines
5.3 KiB
4 days ago
|
// Package main provides the main entry point for the Hyperledger Fabric Asset Transfer REST API
|
||
|
//
|
||
|
// @title Hyperledger Fabric Asset Transfer API
|
||
|
// @version 1.0
|
||
|
// @description RESTful API for managing assets on Hyperledger Fabric blockchain
|
||
|
// @termsOfService http://swagger.io/terms/
|
||
|
//
|
||
|
// @contact.name API Support
|
||
|
// @contact.url http://www.swagger.io/support
|
||
|
// @contact.email support@swagger.io
|
||
|
//
|
||
|
// @license.name Apache 2.0
|
||
|
// @license.url http://www.apache.org/licenses/LICENSE-2.0.html
|
||
|
//
|
||
|
// @host localhost:8888
|
||
|
// @BasePath /api/v1
|
||
|
//
|
||
|
// @schemes http https
|
||
|
package main
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"log"
|
||
|
"net/http"
|
||
|
|
||
|
"spiderman/docs" // Import generated docs
|
||
|
|
||
|
"spiderman/internal/api"
|
||
|
"spiderman/internal/fabric"
|
||
|
"spiderman/internal/logger"
|
||
|
"spiderman/internal/middleware"
|
||
|
"spiderman/pkg/config"
|
||
|
|
||
|
"github.com/gorilla/mux"
|
||
|
"github.com/sirupsen/logrus"
|
||
|
httpSwagger "github.com/swaggo/http-swagger"
|
||
|
)
|
||
|
|
||
|
func main() {
|
||
|
// Load configuration from environment variables and .env files
|
||
|
cfg := config.LoadConfig()
|
||
|
|
||
|
// Update Swagger configuration with values from config.env
|
||
|
docs.SwaggerInfo.Host = fmt.Sprintf("%s:%s", cfg.Server.Host, cfg.Server.Port)
|
||
|
|
||
|
// Initialize logger
|
||
|
logger.Init(&cfg.Log)
|
||
|
|
||
|
// Log startup information
|
||
|
logger.Logger.WithFields(logrus.Fields{
|
||
|
"environment": cfg.Environment.Environment,
|
||
|
"host": cfg.Server.Host,
|
||
|
"port": cfg.Server.Port,
|
||
|
"swagger_host": docs.SwaggerInfo.Host,
|
||
|
"log_level": cfg.Log.Level,
|
||
|
"log_format": cfg.Log.Format,
|
||
|
}).Info("Starting Hyperledger Fabric Asset Transfer REST API")
|
||
|
|
||
|
// Initialize Fabric client
|
||
|
logger.Logger.Info("Initializing Fabric client...")
|
||
|
fabricClient, err := fabric.NewClient(&cfg.Fabric)
|
||
|
if err != nil {
|
||
|
logger.Logger.WithError(err).Fatal("Failed to initialize Fabric client")
|
||
|
}
|
||
|
defer fabricClient.Close()
|
||
|
|
||
|
// Create API handler
|
||
|
apiHandler := api.NewHandler(fabricClient)
|
||
|
|
||
|
// Setup router with middleware
|
||
|
router := setupRouter(apiHandler, cfg)
|
||
|
|
||
|
// Start server
|
||
|
startServer(router, cfg)
|
||
|
}
|
||
|
|
||
|
func setupRouter(apiHandler *api.Handler, cfg *config.Config) *mux.Router {
|
||
|
router := mux.NewRouter()
|
||
|
|
||
|
// Add middleware in order
|
||
|
router.Use(middleware.Recovery)
|
||
|
router.Use(middleware.CORS)
|
||
|
router.Use(middleware.Logging)
|
||
|
|
||
|
// Swagger documentation route (only in development)
|
||
|
if cfg.IsDevelopment() {
|
||
|
router.PathPrefix("/swagger/").Handler(httpSwagger.WrapHandler)
|
||
|
logger.Logger.Info("Swagger documentation enabled at /swagger/")
|
||
|
}
|
||
|
|
||
|
// API routes
|
||
|
api := router.PathPrefix("/api/v1").Subrouter()
|
||
|
|
||
|
// Health check
|
||
|
router.HandleFunc("/health", apiHandler.HealthCheck).Methods("GET").Name("HealthCheck")
|
||
|
|
||
|
// Ledger operations
|
||
|
api.HandleFunc("/ledger/init", apiHandler.InitLedger).Methods("POST").Name("InitLedger")
|
||
|
|
||
|
// Asset operations with OPTIONS support
|
||
|
api.HandleFunc("/assets", apiHandler.GetAllAssets).Methods("GET").Name("GetAllAssets")
|
||
|
api.HandleFunc("/assets", apiHandler.CreateAsset).Methods("POST").Name("CreateAsset")
|
||
|
api.HandleFunc("/assets", func(w http.ResponseWriter, r *http.Request) {}).Methods("OPTIONS").Name("AssetsOptions")
|
||
|
|
||
|
api.HandleFunc("/assets/{id}", apiHandler.GetAssetByID).Methods("GET").Name("GetAssetByID")
|
||
|
api.HandleFunc("/assets/{id}/transfer", apiHandler.TransferAsset).Methods("PUT").Name("TransferAsset")
|
||
|
api.HandleFunc("/assets/{id}", apiHandler.UpdateAsset).Methods("PUT").Name("UpdateAsset")
|
||
|
api.HandleFunc("/assets/{id}", func(w http.ResponseWriter, r *http.Request) {}).Methods("OPTIONS").Name("AssetByIdOptions")
|
||
|
api.HandleFunc("/assets/{id}/transfer", func(w http.ResponseWriter, r *http.Request) {}).Methods("OPTIONS").Name("TransferAssetOptions")
|
||
|
|
||
|
// Blockchain operations
|
||
|
api.HandleFunc("/blockchain/height", apiHandler.GetBlockHeight).Methods("GET").Name("GetBlockHeight")
|
||
|
api.HandleFunc("/blockchain/info", apiHandler.GetChainInfo).Methods("GET").Name("GetChainInfo")
|
||
|
api.HandleFunc("/blockchain/height", func(w http.ResponseWriter, r *http.Request) {}).Methods("OPTIONS").Name("BlockHeightOptions")
|
||
|
api.HandleFunc("/blockchain/info", func(w http.ResponseWriter, r *http.Request) {}).Methods("OPTIONS").Name("ChainInfoOptions")
|
||
|
|
||
|
// Transaction operations
|
||
|
api.HandleFunc("/transactions/{txid}", apiHandler.GetTransactionByID).Methods("GET").Name("GetTransactionByID")
|
||
|
api.HandleFunc("/transactions/{txid}", func(w http.ResponseWriter, r *http.Request) {}).Methods("OPTIONS").Name("TransactionByIdOptions")
|
||
|
|
||
|
return router
|
||
|
}
|
||
|
|
||
|
func startServer(router *mux.Router, cfg *config.Config) {
|
||
|
host := cfg.Server.Host
|
||
|
port := cfg.Server.Port
|
||
|
|
||
|
logger.Logger.WithFields(logrus.Fields{
|
||
|
"host": host,
|
||
|
"port": port,
|
||
|
"environment": cfg.Environment.Environment,
|
||
|
"swagger_url": fmt.Sprintf("http://%s:%s/swagger/index.html", host, port),
|
||
|
"health_url": fmt.Sprintf("http://%s:%s/health", host, port),
|
||
|
"api_base_url": fmt.Sprintf("http://%s:%s/api/v1", host, port),
|
||
|
}).Info("Server configuration")
|
||
|
|
||
|
fmt.Printf("Starting REST API server on %s:%s\n", host, port)
|
||
|
fmt.Printf("Environment: %s\n", cfg.Environment.Environment)
|
||
|
fmt.Printf("Health check: http://%s:%s/health\n", host, port)
|
||
|
|
||
|
if cfg.IsDevelopment() {
|
||
|
fmt.Printf("Swagger documentation: http://%s:%s/swagger/index.html\n", host, port)
|
||
|
}
|
||
|
|
||
|
logger.Logger.WithFields(logrus.Fields{
|
||
|
"address": ":" + port,
|
||
|
}).Info("Starting HTTP server")
|
||
|
|
||
|
if err := http.ListenAndServe(":"+port, router); err != nil {
|
||
|
log.Fatal("Failed to start server: ", err)
|
||
|
}
|
||
|
}
|