github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/state/endpoint.go (about)

     1  // Copyright 2012, 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package state
     5  
     6  import (
     7  	"fmt"
     8  
     9  	"gopkg.in/juju/charm.v6-unstable"
    10  )
    11  
    12  // counterpartRole returns the RelationRole that this RelationRole
    13  // can relate to.
    14  // This should remain an internal method because the relation
    15  // model does not guarantee that for every role there will
    16  // necessarily exist a single counterpart role that is sensible
    17  // for basing algorithms upon.
    18  func counterpartRole(r charm.RelationRole) charm.RelationRole {
    19  	switch r {
    20  	case charm.RoleProvider:
    21  		return charm.RoleRequirer
    22  	case charm.RoleRequirer:
    23  		return charm.RoleProvider
    24  	case charm.RolePeer:
    25  		return charm.RolePeer
    26  	}
    27  	panic(fmt.Errorf("unknown relation role %q", r))
    28  }
    29  
    30  // Endpoint represents one endpoint of a relation.
    31  type Endpoint struct {
    32  	ApplicationName string
    33  	// TODO: thumper 2016-06-27
    34  	// This is pure evil and we should not be storing structures from
    35  	// external packages directly in mongo.
    36  	charm.Relation
    37  }
    38  
    39  // String returns the unique identifier of the relation endpoint.
    40  func (ep Endpoint) String() string {
    41  	return ep.ApplicationName + ":" + ep.Name
    42  }
    43  
    44  // CanRelateTo returns whether a relation may be established between e and other.
    45  func (ep Endpoint) CanRelateTo(other Endpoint) bool {
    46  	return ep.ApplicationName != other.ApplicationName &&
    47  		ep.Interface == other.Interface &&
    48  		ep.Role != charm.RolePeer &&
    49  		counterpartRole(ep.Role) == other.Role
    50  }
    51  
    52  type epSlice []Endpoint
    53  
    54  var roleOrder = map[charm.RelationRole]int{
    55  	charm.RoleRequirer: 0,
    56  	charm.RoleProvider: 1,
    57  	charm.RolePeer:     2,
    58  }
    59  
    60  func (eps epSlice) Len() int      { return len(eps) }
    61  func (eps epSlice) Swap(i, j int) { eps[i], eps[j] = eps[j], eps[i] }
    62  func (eps epSlice) Less(i, j int) bool {
    63  	ep1 := eps[i]
    64  	ep2 := eps[j]
    65  	if ep1.Role != ep2.Role {
    66  		return roleOrder[ep1.Role] < roleOrder[ep2.Role]
    67  	}
    68  	return ep1.String() < ep2.String()
    69  }