go.ligato.io/vpp-agent/v3@v3.5.0/examples/tutorials/05_kv-scheduler/main.go (about)

     1  //  Copyright (c) 2019 Cisco and/or its affiliates.
     2  //
     3  //  Licensed under the Apache License, Version 2.0 (the "License");
     4  //  you may not use this file except in compliance with the License.
     5  //  You may obtain a copy of the License at:
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  //  Unless required by applicable law or agreed to in writing, software
    10  //  distributed under the License is distributed on an "AS IS" BASIS,
    11  //  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  //  See the License for the specific language governing permissions and
    13  //  limitations under the License.
    14  
    15  package main
    16  
    17  import (
    18  	"context"
    19  	"time"
    20  
    21  	"go.ligato.io/cn-infra/v2/agent"
    22  	"go.ligato.io/cn-infra/v2/infra"
    23  	"go.ligato.io/cn-infra/v2/logging"
    24  
    25  	"go.ligato.io/vpp-agent/v3/examples/tutorials/05_kv-scheduler/model"
    26  	"go.ligato.io/vpp-agent/v3/plugins/kvscheduler"
    27  	"go.ligato.io/vpp-agent/v3/plugins/kvscheduler/api"
    28  )
    29  
    30  //go:generate protoc --proto_path=. --go_out=paths=source_relative:. model/model.proto
    31  
    32  //go:generate descriptor-adapter --descriptor-name Interface --value-type *model.Interface --import "go.ligato.io/vpp-agent/v3/examples/tutorials/05_kv-scheduler/model"
    33  //go:generate descriptor-adapter --descriptor-name Route --value-type *model.Route --import "go.ligato.io/vpp-agent/v3/examples/tutorials/05_kv-scheduler/model"
    34  
    35  func main() {
    36  	// Create an instance of our plugin using its constructor.
    37  	p := NewHelloWorld()
    38  
    39  	// Create new agent with our plugin instance.
    40  	a := agent.NewAgent(agent.AllPlugins(p))
    41  
    42  	// Run starts the agent with plugins, wait until shutdown
    43  	// and then stops the agent and its plugins.
    44  	if err := a.Run(); err != nil {
    45  		logging.DefaultLogger.Error(err)
    46  	}
    47  }
    48  
    49  // HelloWorld represents our plugin.
    50  type HelloWorld struct {
    51  	// This embeds essential plugin deps into our plugin.
    52  	infra.PluginDeps
    53  	// This embeds KV scheduler as a dependency for our plugin
    54  	KVScheduler api.KVScheduler
    55  }
    56  
    57  // NewHelloWorld is a constructor for our HelloWorld plugin.
    58  func NewHelloWorld() *HelloWorld {
    59  	// Create new instance.
    60  	p := new(HelloWorld)
    61  	// Set the plugin name.
    62  	p.SetName("helloworld")
    63  	// Initialize essential plugin deps: logger and config.
    64  	p.Setup()
    65  	// Initialize the KV scheduler
    66  	p.KVScheduler = &kvscheduler.DefaultPlugin
    67  	return p
    68  }
    69  
    70  // Init is executed on agent initialization.
    71  func (p *HelloWorld) Init() error {
    72  	p.Log.Println("Hello World!")
    73  
    74  	err := p.KVScheduler.RegisterKVDescriptor(NewIfDescriptor(p.Log))
    75  	if err != nil {
    76  		// handle error
    77  	}
    78  
    79  	err = p.KVScheduler.RegisterKVDescriptor(NewRouteDescriptor(p.Log))
    80  	if err != nil {
    81  		// handle error
    82  	}
    83  
    84  	return nil
    85  }
    86  
    87  // AfterInit is called after the Init() for all other plugins. In the example, the AfterInit
    88  // is used for testing teh hello world plugin.
    89  func (p *HelloWorld) AfterInit() error {
    90  	p.Log.Println("Testing the KV scheduler ... ")
    91  
    92  	go func() {
    93  		p.Log.Info("CASE 1: the interface created before the route")
    94  
    95  		// Case 1: the interface created before the route
    96  		txn := p.KVScheduler.StartNBTransaction()
    97  		txn.SetValue("/interface/if1", &model.Interface{Name: "if1"})
    98  		txn.SetValue("/route/route1", &model.Route{Name: "route1", InterfaceName: "if1"})
    99  		_, err := txn.Commit(context.Background())
   100  		if err != nil {
   101  			panic(err)
   102  		}
   103  
   104  		time.Sleep(1 * time.Second)
   105  		p.Log.Info("CASE 2: the route created before the interface")
   106  
   107  		// Case 2: the route is created before the interface
   108  		txn = p.KVScheduler.StartNBTransaction()
   109  		txn.SetValue("/route/route2", &model.Route{Name: "route2", InterfaceName: "if2"})
   110  		txn.SetValue("/interface/if2", &model.Interface{Name: "if2"})
   111  		_, err = txn.Commit(context.Background())
   112  		if err != nil {
   113  			panic(err)
   114  		}
   115  
   116  		time.Sleep(1 * time.Second)
   117  		p.Log.Info("CASE 3: the route created before the interface in separate transaction")
   118  
   119  		// Case 3: the route is created before the interface in separate transaction
   120  		txn = p.KVScheduler.StartNBTransaction()
   121  		txn.SetValue("/route/route3", &model.Route{Name: "route3", InterfaceName: "if3"})
   122  		_, err = txn.Commit(context.Background())
   123  		if err != nil {
   124  			panic(err)
   125  		}
   126  		txn = p.KVScheduler.StartNBTransaction()
   127  		txn.SetValue("/interface/if3", &model.Interface{Name: "if3"})
   128  		_, err = txn.Commit(context.Background())
   129  		if err != nil {
   130  			panic(err)
   131  		}
   132  	}()
   133  
   134  	return nil
   135  }
   136  
   137  // Close is executed on agent shutdown.
   138  func (p *HelloWorld) Close() error {
   139  	p.Log.Info("Goodbye World!")
   140  	return nil
   141  }