@@ -407,214 +407,6 @@ In this tutorial, you use a variant feature flag to manage experiences for diffe
407
407
// The rest of existing code
408
408
// ... ...
409
409
```
410
- 1. After completing the previous steps, your `main.go` file should now contain the complete implementation as shown below:
411
-
412
- ```golang
413
- package main
414
-
415
- import (
416
- "context"
417
- "fmt"
418
- "log"
419
- "net/http"
420
- "strings"
421
-
422
- "github.com/Azure/AppConfiguration-GoProvider/azureappconfiguration"
423
- "github.com/gin-contrib/sessions"
424
- "github.com/gin-contrib/sessions/cookie"
425
- "github.com/gin-gonic/gin"
426
- "github.com/microsoft/Featuremanagement-Go/featuremanagement"
427
- "github.com/microsoft/Featuremanagement-Go/featuremanagement/providers/azappconfig"
428
- )
429
-
430
- type Quote struct {
431
- Message string `json:"message"`
432
- Author string `json:"author"`
433
- }
434
-
435
- type WebApp struct {
436
- featureManager *featuremanagement.FeatureManager
437
- appConfig *azureappconfiguration.AzureAppConfiguration
438
- quotes []Quote
439
- }
440
-
441
- func main() {
442
- // Load Azure App Configuration
443
- appConfig, err := loadAzureAppConfiguration(context.Background())
444
- if err != nil {
445
- log.Fatalf("Error loading Azure App Configuration: %v", err)
446
- }
447
-
448
- // Create feature flag provider
449
- featureFlagProvider, err := azappconfig.NewFeatureFlagProvider(appConfig)
450
- if err != nil {
451
- log.Fatalf("Error creating feature flag provider: %v", err)
452
- }
453
-
454
- // Create feature manager
455
- featureManager, err := featuremanagement.NewFeatureManager(featureFlagProvider, nil)
456
- if err != nil {
457
- log.Fatalf("Error creating feature manager: %v", err)
458
- }
459
-
460
- // Initialize quotes
461
- quotes := []Quote{
462
- {
463
- Message: "You cannot change what you are, only what you do.",
464
- Author: "Philip Pullman",
465
- },
466
- }
467
-
468
- // Create web app
469
- app := &WebApp{
470
- featureManager: featureManager,
471
- appConfig: appConfig,
472
- quotes: quotes,
473
- }
474
-
475
- // Setup Gin with default middleware (Logger and Recovery)
476
- r := gin.Default()
477
-
478
- // Setup routes
479
- app.setupRoutes(r)
480
-
481
- // Start server
482
- if err := r.Run(":8080"); err != nil {
483
- log.Fatalf("Failed to start server: %v", err)
484
- }
485
-
486
- fmt.Println("Starting Quote of the Day server on http://localhost:8080")
487
- fmt.Println("Open http://localhost:8080 in your browser")
488
- fmt.Println()
489
-
490
- }
491
-
492
- func (app *WebApp) refreshMiddleware() gin.HandlerFunc {
493
- return func(c *gin.Context) {
494
- go func() {
495
- if err := app.appConfig.Refresh(context.Background()); err != nil {
496
- log.Printf("Error refreshing configuration: %v", err)
497
- }
498
- }()
499
- c.Next()
500
- }
501
- }
502
-
503
- func (app *WebApp) setupRoutes(r *gin.Engine) {
504
- // Setup sessions
505
- store := cookie.NewStore([]byte("secret-key-change-in-production"))
506
- store.Options(sessions.Options{
507
- MaxAge: 3600, // 1 hour
508
- HttpOnly: true,
509
- Secure: false, // Set to true in production with HTTPS
510
- })
511
- r.Use(sessions.Sessions("session", store))
512
-
513
- r.Use(app.refreshMiddleware())
514
-
515
- // Load HTML templates
516
- r.LoadHTMLGlob("templates/*.html")
517
- // Routes
518
- r.GET("/", app.homeHandler)
519
- r.GET("/login", app.loginPageHandler)
520
- r.POST("/login", app.loginHandler)
521
- r.GET("/logout", app.logoutHandler)
522
- }
523
-
524
- // Home page handler
525
- func (app *WebApp) homeHandler(c *gin.Context) {
526
- session := sessions.Default(c)
527
- username := session.Get("username")
528
- quote := app.quotes[0]
529
-
530
- var greetingMessage string
531
- var targetingContext featuremanagement.TargetingContext
532
- if username != nil {
533
- // Create targeting context for the user
534
- targetingContext = createTargetingContext(username.(string))
535
-
536
- // Get the Greeting variant for the current user
537
- if variant, err := app.featureManager.GetVariant("Greeting", targetingContext); err != nil {
538
- log.Printf("Error getting Greeting variant: %v", err)
539
- } else if variant != nil && variant.ConfigurationValue != nil {
540
- // Extract the greeting message from the variant configuration
541
- if configValue, ok := variant.ConfigurationValue.(string); ok {
542
- greetingMessage = configValue
543
- }
544
- }
545
- }
546
-
547
- c.HTML(http.StatusOK, "index.html", gin.H{
548
- "title": "Quote of the Day",
549
- "user": username,
550
- "greetingMessage": greetingMessage,
551
- "quote": quote,
552
- })
553
- }
554
-
555
- func (app *WebApp) loginPageHandler(c *gin.Context) {
556
- c.HTML(http.StatusOK, "login.html", gin.H{
557
- "title": "Login - Quote of the Day",
558
- })
559
- }
560
-
561
- func (app *WebApp) loginHandler(c *gin.Context) {
562
- email := strings.TrimSpace(c.PostForm("email"))
563
-
564
- // Basic validation
565
- if email == "" {
566
- c.HTML(http.StatusOK, "login.html", gin.H{
567
- "title": "Login - Quote of the Day",
568
- "error": "Email cannot be empty",
569
- })
570
- return
571
- }
572
-
573
- if !strings.Contains(email, "@") {
574
- c.HTML(http.StatusOK, "login.html", gin.H{
575
- "title": "Login - Quote of the Day",
576
- "error": "Please enter a valid email address",
577
- })
578
- return
579
- }
580
-
581
- // Store email in session
582
- session := sessions.Default(c)
583
- session.Set("username", email)
584
- if err := session.Save(); err != nil {
585
- log.Printf("Error saving session: %v", err)
586
- }
587
-
588
- c.Redirect(http.StatusFound, "/")
589
- }
590
-
591
- func (app *WebApp) logoutHandler(c *gin.Context) {
592
- session := sessions.Default(c)
593
- session.Clear()
594
- if err := session.Save(); err != nil {
595
- log.Printf("Error saving session: %v", err)
596
- }
597
- c.Redirect(http.StatusFound, "/")
598
- }
599
-
600
- // Helper function to create TargetingContext
601
- func createTargetingContext(userID string) featuremanagement.TargetingContext {
602
- targetingContext := featuremanagement.TargetingContext{
603
- UserID: userID,
604
- Groups: []string{},
605
- }
606
-
607
- if strings.Contains(userID, "@") {
608
- parts := strings.Split(userID, "@")
609
- if len(parts) == 2 {
610
- domain := parts[1]
611
- targetingContext.Groups = append(targetingContext.Groups, domain) // Add domain as group
612
- }
613
- }
614
-
615
- return targetingContext
616
- }
617
- ```
618
410
619
411
## Build and run the app
620
412
0 commit comments