예제 #1
0
// Rcvf receives the message and the context.
func Rcvf(msg beehive.Msg, ctx beehive.RcvContext) error {
	// msg is an envelope around the Hello message.
	// You can retrieve the Hello, using msg.Data() and then
	// you need to assert that its a Hello.
	hello := msg.Data().(Hello)
	// Using ctx.Dict you can get (or create) a dictionary.
	dict := ctx.Dict("hello_dict")
	// Using Get(), you can get the value associated with
	// a key in the dictionary. Keys are always string
	// and values are generic interface{}'s.
	v, err := dict.Get(hello.Name)
	// If there is an error, the entry is not in the
	// dictionary. Otherwise, we set cnt based on
	// the value we already have in the dictionary
	// for that name.
	cnt := 0
	if err == nil {
		cnt = v.(int)
	}
	// Now we increment the count.
	cnt++
	// And then we print the hello message.
	ctx.Printf("hello %s (%d)!\n", hello.Name, cnt)
	// Finally we update the count stored in the dictionary.
	return dict.Put(hello.Name, cnt)
}
예제 #2
0
파일: calc.go 프로젝트: jyzhe/beehive
func (c *Calculator) Rcv(msg bh.Msg, ctx bh.RcvContext) error {
	op := msg.Data().(Op)
	res := c.calc(op)
	fmt.Printf("%d %s %d = %d\n", op.Lhs, op.OpT, op.Rhs, res)
	ctx.Reply(msg, res)
	return nil
}
예제 #3
0
파일: flow.go 프로젝트: 1995parham/FlyNest
func confirmFlowEntryForPath(flow nom.FlowEntry, ctx bh.RcvContext) error {
	d := ctx.Dict(dictPath)

	v, err := d.Get(flow.ID)
	if err != nil {
		return fmt.Errorf("path: flow not found: %v", err)
	}

	pf := v.(pathAndFlows)

	for i := range pf.Flows {
		if pf.Flows[i].Flow.Equals(flow) {
			if pf.Flows[i].Installed {
				return fmt.Errorf("%v is already installed", flow)
			}
			pf.Flows[i].Installed = true
			pf.Installed++
			break
		}
	}

	if pf.Installed == len(pf.Flows) {
		ctx.SendToCell(nom.PathAdded{Path: pf.Path}, pf.Subscriber.App,
			pf.Subscriber.Cell())
	}
	return d.Put(flow.ID, pf)
}
// The bee hander
func BeeHandler(
	beehiveMessage beehive.Msg,
	beeContext beehive.RcvContext) error {
	// beehiveMessage is an envelope around the Hello message.
	// You can retrieve the Hello, using msg.Data() and then
	// you need to assert that its a MessageToBee.
	message := beehiveMessage.Data().(MessageToBee)
	// Using ctx.Dict you can get (or create) a dictionary.
	dict := beeContext.Dict("beehive-app-dict")
	value, err := dict.Get(message.DestinationBee)

	logger.Trace.Printf("[BeeHandler] Message sent to bee with id (%s) \n",
		message.DestinationBee)

	count := 0
	if err == nil {
		// No error mean there is already an item with given key
		count = value.(int)
	}
	count++
	logger.Trace.Printf("[BeeHandler] Count = %d\n",
		count)

	logger.Trace.Printf("[BeeHandler] Calculate fib number %d\n",
		message.FibNumber)
	Fib(message.FibNumber)

	beeContext.Reply(beehiveMessage, count)
	return dict.Put(message.DestinationBee, count)
}
예제 #5
0
파일: server.go 프로젝트: jyzhe/beehive
func (h EnQHandler) Rcv(msg beehive.Msg, ctx beehive.RcvContext) error {
	enq := msg.Data().(Enque)
	dict := ctx.Dict(active)

	next := TaskID(1)
	if v, err := dict.Get("_next_"); err == nil {
		next = v.(TaskID)
	}

	key := next.String()
	task := Task{
		Queue: enq.Queue,
		ID:    next,
		Body:  enq.Body,
	}
	if err := dict.Put(key, task); err != nil {
		return err
	}

	if err := dict.Put("_next_", next+1); err != nil {
		return err
	}

	enqued := Enqued{
		ID:     enq.ID,
		Queue:  enq.Queue,
		TaskID: next,
	}
	return ctx.Reply(msg, enqued)
}
예제 #6
0
func (h portStatusHandler) Rcv(msg bh.Msg, ctx bh.RcvContext) error {
	// FIXME(soheil): This implementation is very naive and cannot tolerate
	// faults. We need to first check if the driver is the mater, and then apply
	// the change. Otherwise, we need to enque this message for that driver and
	// make sure we apply the log to the port status
	data := msg.Data().(nom.PortStatusChanged)
	dict := ctx.Dict(driversDict)
	k := string(data.Port.Node)
	v, err := dict.Get(k)
	if err != nil {
		return fmt.Errorf("NOMController: node %v not found", data.Port.Node)
	}
	n := v.(nodeDrivers)

	if !n.isMaster(data.Driver) {
		glog.Warningf("NOMController: %v ignored, %v is not master, master is %v",
			data.Port, data.Driver, n.master())
		return nil
	}

	if p, ok := n.Ports.GetPort(data.Port.UID()); ok {
		if p == data.Port {
			return fmt.Errorf("NOMController: duplicate port status change for %v",
				data.Port)
		}

		n.Ports.DelPort(p)
	}

	n.Ports.AddPort(data.Port)
	ctx.Emit(nom.PortUpdated(data.Port))
	return nil
}
예제 #7
0
// NodesCentralized returns the nodes with outgoing links so far.
//
// Note that this methods should be used only when the GraphBuilderCentralized
// is in use.
func NodesCentralized(ctx bh.RcvContext) (nodes []nom.UID) {
	ctx.Dict(GraphDict).ForEach(func(k string, v interface{}) bool {
		nodes = append(nodes, nom.UID(k))
		return true
	})
	return nodes
}
예제 #8
0
func (h HealthChecker) Rcv(msg bh.Msg, ctx bh.RcvContext) error {
	db := msg.From()
	dict := ctx.Dict(driversDict)

	dict.ForEach(func(k string, v interface{}) {
		nd := v.(nodeDrivers)
		updated := false
		for i := range nd.Drivers {
			if nd.Drivers[i].BeeID == db {
				nd.Drivers[i].LastSeen = time.Now()
				// TODO(soheil): Maybe if outpings was more than MaxPings we
				// should emit a connected message.
				nd.Drivers[i].OutPings--
				updated = true
			}
		}

		if !updated {
			return
		}

		if err := dict.Put(k, nd); err != nil {
			glog.Warningf("error in encoding drivers: %v", err)
		}
	})

	return nil
}
예제 #9
0
// Rcv method of the composed handler.
func (c *ComposedHandler) Rcv(msg bh.Msg, ctx bh.RcvContext) error {
	var err error
	for i := range c.Handlers {
		if c.Isolate {
			rctx := composedRcvContext{RcvContext: ctx, prefix: strconv.Itoa(i)}
			err = c.callRcv(c.Handlers[i], msg, rctx)
		} else {
			err = c.callRcv(c.Handlers[i], msg, ctx)
		}

		switch c.Composer(msg, ctx, err) {
		case Abort:
			ctx.AbortTx()
			return nil
		case Commit:
			ctx.CommitTx()
			return nil
		case Continue:
			if i == len(c.Handlers)-1 {
				if err == nil {
					ctx.CommitTx()
				} else {
					ctx.AbortTx()
				}
				return nil
			}
		case ContinueOrAbort:
			if i == len(c.Handlers)-1 {
				ctx.AbortTx()
				return nil
			}
		}
	}
	return nil
}
예제 #10
0
func (b GraphBuilderCentralized) Rcv(msg bh.Msg, ctx bh.RcvContext) error {
	dict := ctx.Dict(GraphDict)
	var link nom.Link
	switch dm := msg.Data().(type) {
	case nom.LinkAdded:
		link = nom.Link(dm)
	case nom.LinkDeleted:
		link = nom.Link(dm)
	default:
		return fmt.Errorf("GraphBuilderCentralized: unsupported message type %v",
			msg.Type())
	}

	nf, _ := nom.ParsePortUID(link.From)
	nt, _ := nom.ParsePortUID(link.To)

	if nf == nt {
		return fmt.Errorf("%v is a loop", link)
	}

	k := string(nf)
	links := make(map[nom.UID][]nom.Link)
	if v, err := dict.Get(k); err == nil {
		links = v.(map[nom.UID][]nom.Link)
	}
	links[nt.UID()] = append(links[nt.UID()], link)
	return dict.Put(k, links)
}
예제 #11
0
파일: host.go 프로젝트: 1995parham/FlyNest
func (h *httpHostListHandler) Rcv(msg bh.Msg, ctx bh.RcvContext) error {
	hrq := msg.Data().(http.HTTPRequest)
	if hrq.AppName == "host" && hrq.Verb == "list" {
		dict := ctx.Dict(hostDict)

		v, err := dict.Get("hsts")
		hsts := []nom.Host{}
		if err == nil {
			hsts = v.([]nom.Host)
		}

		data, err := json.Marshal(hsts)
		if err != nil {
			glog.Errorf("Host list JSON marshaling: %v", err)
			return err
		}

		fmt.Println(hsts)

		hrs := http.HTTPResponse{
			AppName: "host",
			Data:    data,
		}

		err = ctx.Reply(msg, hrs)
		if err != nil {
			glog.Errorf("Replay error: %v", err)
			return err
		}
	}
	return nil
}
예제 #12
0
파일: host.go 프로젝트: 1995parham/FlyNest
func (h *arpPktInHandler) Rcv(msg bh.Msg, ctx bh.RcvContext) error {
	pin := msg.Data().(nom.PacketIn)
	p := gopacket.NewPacket([]byte(pin.Packet), layers.LayerTypeEthernet, gopacket.Default)
	etherlayer := p.Layer(layers.LayerTypeEthernet)

	if etherlayer == nil {
		return nil
	}

	e, _ := etherlayer.(*layers.Ethernet)

	if e.EthernetType != layers.EthernetTypeARP {
		return nil
	}

	host, _, err := decodeARP([]byte(pin.Packet))
	host.Node = pin.Node

	if err != nil {
		glog.Errorf("ARP decoding error: %v", err)
		return err
	}
	glog.V(2).Infof("Host detected: %v", host)

	ctx.Emit(nom.HostConnected(host))

	return nil
}
예제 #13
0
파일: host.go 프로젝트: 1995parham/FlyNest
func (h *hostConnectedHandler) Rcv(msg bh.Msg, ctx bh.RcvContext) error {
	host := msg.Data().(nom.HostConnected)
	dict := ctx.Dict(hostDict)

	_, err := dict.Get(host.MACAddr.String())
	if err == nil {
		return nil
	}

	v, err := dict.Get("hsts")
	hsts := []nom.Host{}
	if err == nil {
		hsts = v.([]nom.Host)

	}
	hsts = append(hsts, nom.Host(host))

	err = dict.Put(host.MACAddr.String(), host)
	if err != nil {
		glog.Errorf("Put %v in %s: %v", host, host.MACAddr.String(), err)
		return err
	}

	err = dict.Put("hsts", hsts)
	if err != nil {
		glog.Errorf("Put %v in hsts: %v", hsts, err)
		return err
	}

	ctx.Emit(nom.HostJoined(host))

	return nil
}
예제 #14
0
파일: driver.go 프로젝트: jyzhe/beehive
func (d *Driver) Rcv(m beehive.Msg, ctx beehive.RcvContext) error {
	if m.NoReply() {
		return nil
	}

	q, ok := m.Data().(StatQuery)
	if !ok {
		return nil
	}

	s, ok := d.switches[q.Switch]
	if !ok {
		return fmt.Errorf("No switch stored in the driver: %+v", s)
	}

	for i, f := range s.Flows {
		f.Bytes += uint64(rand.Intn(maxSpike))
		s.Flows[i] = f
		glog.V(2).Infof("Emitting stat result for %+v", f)
		ctx.Emit(StatResult{q, f.Flow, f.Bytes})
	}

	d.switches[q.Switch] = s
	return nil
}
예제 #15
0
파일: server.go 프로젝트: jyzhe/beehive
func (h *ConnHandler) handleAck(req ReqID, ctx beehive.RcvContext,
	r *bufio.Reader) error {

	q, err := r.ReadString(' ')
	if err != nil {
		return err
	}
	q = q[:len(q)-1]

	s, err := r.ReadString('\n')
	if err != nil {
		return err
	}
	s = dropNewLine(s)

	tid, err := strconv.ParseUint(s, 10, 64)
	if err != nil {
		return err
	}

	ctx.Emit(Ack{
		ID:     req,
		Queue:  Queue(q),
		TaskID: TaskID(tid),
	})
	return nil
}
예제 #16
0
func (h *intentHandler) Rcv(msg bh.Msg, ctx bh.RcvContext) error {
	hrq := msg.Data().(http.HTTPRequest)
	if hrq.AppName == "intent" && hrq.Verb == "build" {
		spd := shortestPathData{}
		err := json.Unmarshal(hrq.Data, &spd)
		if err != nil {
			glog.Errorf("Host list JSON unmarshaling: %v", err)
			return err
		}
		fmt.Println(spd)
		fmt.Println(discovery.ShortestPathCentralized(spd.From, spd.To, ctx))

		hrs := http.HTTPResponse{
			AppName: "host",
			Data:    []byte{'A'},
		}

		err = ctx.Reply(msg, hrs)
		if err != nil {
			glog.Errorf("Replay error: %v", err)
			return err
		}
	}
	return nil

}
예제 #17
0
func (l *ofListener) startOFConn(conn net.Conn, ctx bh.RcvContext) {
	ofc := &ofConn{
		HeaderConn: of.NewHeaderConn(conn),
		readBufLen: l.readBufLen,
	}

	ctx.StartDetached(ofc)
}
예제 #18
0
파일: routing.go 프로젝트: jyzhe/beehive
func (r Router) neighbors(node Node, ctx bh.RcvContext) Edges {
	dict := ctx.Dict(neighDict)
	var neighs Edges
	if v, err := dict.Get(node.Key()); err == nil {
		neighs = v.(Edges)
	}
	return neighs
}
예제 #19
0
func (p Poller) Rcv(msg bh.Msg, ctx bh.RcvContext) error {
	ctx.Dict("Switches").ForEach(func(k string, v interface{}) {
		fmt.Printf("poller: polling switch %v\n", k)
		ctx.Emit(nom.FlowStatsQuery{
			Node: nom.UID(k),
		})
	})
	return nil
}
예제 #20
0
파일: routing.go 프로젝트: jyzhe/beehive
func (r Router) appendNieghbor(edge Edge, ctx bh.RcvContext) error {
	neighs := r.neighbors(edge.To, ctx)
	if neighs.Contains(edge) {
		return fmt.Errorf("%v is already a neighbor", edge)
	}
	neighs = append(neighs, edge)
	ctx.Dict(neighDict).Put(edge.To.Key(), neighs)
	return nil
}
예제 #21
0
func (h *nodeLeftHandler) Rcv(msg bh.Msg, ctx bh.RcvContext) error {
	n := nom.Node(msg.Data().(nom.NodeLeft))
	d := ctx.Dict(nodeDict)
	k := string(n.UID())
	if _, err := d.Get(k); err != nil {
		return fmt.Errorf("%v is not joined", n)
	}
	d.Del(k)
	return nil
}
예제 #22
0
파일: id.go 프로젝트: 1995parham/FlyNest
func reservePathID(ctx bh.RcvContext) uint64 {
	d := ctx.Dict(dictID)
	var id uint64
	if v, err := d.Get("path"); err == nil {
		id = v.(uint64)
	}
	id++
	d.Put("path", id)
	return id - 1
}
예제 #23
0
파일: id.go 프로젝트: 1995parham/FlyNest
func reserveFlowID(ctx bh.RcvContext, cnt int) uint64 {
	d := ctx.Dict(dictID)
	var id uint64
	if v, err := d.Get("flow"); err == nil {
		id = v.(uint64)
	}
	id += uint64(cnt)
	d.Put("flow", id)
	return id - uint64(cnt)
}
예제 #24
0
func (h *timeoutHandler) Rcv(msg bh.Msg, ctx bh.RcvContext) error {
	d := ctx.Dict(nodeDict)
	d.ForEach(func(k string, v interface{}) {
		np := v.(nodePortsAndLinks)
		for _, p := range np.P {
			sendLLDPPacket(np.N, p, ctx)
		}
	})
	return nil
}
예제 #25
0
func (h addTriggerHandler) Rcv(msg bh.Msg, ctx bh.RcvContext) error {
	add := msg.Data().(nom.AddTrigger)
	dict := ctx.Dict(triggersDict)
	var nt nodeTriggers
	if v, err := dict.Get(string(add.Node)); err == nil {
		nt = v.(nodeTriggers)
	}
	nt.maybeAddTrigger(nom.Trigger(add))
	return dict.Put(string(add.Node), nt)
}
예제 #26
0
파일: route.go 프로젝트: jyzhe/beehive
func (h *UpdateHandler) Rcv(m beehive.Msg, ctx beehive.RcvContext) error {
	if m.NoReply() {
		return nil
	}

	u := m.Data().(MatrixUpdate)
	glog.Infof("Received matrix update: %+v", u)
	ctx.Emit(FlowMod{Switch: u.Switch})
	return nil
}
예제 #27
0
파일: routing.go 프로젝트: jyzhe/beehive
func (r Router) routingTable(from Node, ctx bh.RcvContext) RoutingTable {
	dict := ctx.Dict(routeDict)
	var tbl RoutingTable
	if v, err := dict.Get(from.Key()); err == nil {
		tbl = v.(RoutingTable)
	} else {
		tbl = make(RoutingTable)
	}
	return tbl
}
예제 #28
0
func (h delTriggerHandler) Rcv(msg bh.Msg, ctx bh.RcvContext) error {
	del := msg.Data().(nom.DelTrigger)
	var nt nodeTriggers
	dict := ctx.Dict(triggersDict)
	if v, err := dict.Get(string(del.Node)); err == nil {
		nt = v.(nodeTriggers)
	}
	nt.delTrigger(nom.Trigger(del))
	return dict.Put(string(del.Node), nt)
}
예제 #29
0
func (h Hub) Rcv(msg bh.Msg, ctx bh.RcvContext) error {
	in := msg.Data().(nom.PacketIn)
	out := nom.PacketOut{
		Node:     in.Node,
		InPort:   in.InPort,
		BufferID: in.BufferID,
		Packet:   in.Packet,
		Actions:  []nom.Action{nom.ActionFlood{}},
	}
	ctx.ReplyTo(msg, out)
	return nil
}
예제 #30
0
// ShortestPathCentralized calculates the shortest path from node "from" to node
// "to" according to the state stored in GraphDict by the
// GraphBuilderCentralized.
//
// This method is not go-routine safe and must be called within a handler of the
// application that uses the GraphBuilderCentralized as a handler. Otherwise,
// the user needs to synchronize the two.
func ShortestPathCentralized(from, to nom.UID, ctx bh.RcvContext) (
	paths [][]nom.Link, length int) {

	if from == to {
		return nil, 0
	}

	visited := make(map[nom.UID]distAndLinks)
	visited[from] = distAndLinks{Dist: 0}

	pq := nodeAndDistSlice{{Dist: 0, Node: from}}
	heap.Init(&pq)

	dict := ctx.Dict(GraphDict)
	for len(pq) != 0 {
		nd := heap.Pop(&pq).(nodeAndDist)
		if nd.Node == to {
			continue
		}
		nodeLinks := make(map[nom.UID][]nom.Link)
		if v, err := dict.Get(string(nd.Node)); err == nil {
			nodeLinks = v.(map[nom.UID][]nom.Link)
		}
		nd.Dist = visited[nd.Node].Dist
		for _, links := range nodeLinks {
			for _, l := range links {
				nid, _ := nom.ParsePortUID(l.To)
				ton := nom.UID(nid)
				if dl, ok := visited[ton]; ok {
					switch {
					case nd.Dist+1 < dl.Dist:
						glog.Fatalf("invalid distance in BFS")
					case nd.Dist+1 == dl.Dist:
						dl.BackLinks = append(dl.BackLinks, l)
						visited[ton] = dl
					}
					continue
				}

				visited[ton] = distAndLinks{
					Dist:      nd.Dist + 1,
					BackLinks: []nom.Link{l},
				}
				ndto := nodeAndDist{
					Dist: nd.Dist + 1,
					Node: ton,
				}
				heap.Push(&pq, ndto)
			}
		}
	}
	return allPaths(from, to, visited)
}