Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(316)

Delta Between Two Patch Sets: state/topology.go

Issue 6198055: Added methods for relation endpoints to topology. (Closed)
Left Patch Set: Added methods for relation endpoints to topology. Created 12 years, 10 months ago
Right Patch Set: Added methods for relation endpoints to topology. Created 12 years, 10 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « state/relation.go ('k') | no next file » | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 package state 1 package state
2 2
3 import ( 3 import (
4 "errors" 4 "errors"
5 "fmt" 5 "fmt"
6 "launchpad.net/goyaml" 6 "launchpad.net/goyaml"
7 "launchpad.net/gozk/zookeeper" 7 "launchpad.net/gozk/zookeeper"
8 "sort" 8 "sort"
9 ) 9 )
10 10
11 // The protocol version, which is stored in the /topology node under 11 // The protocol version, which is stored in the /topology node under
12 // the "version" key. The protocol version should *only* be updated 12 // the "version" key. The protocol version should *only* be updated
13 // when we know that a version is in fact actually incompatible. 13 // when we know that a version is in fact actually incompatible.
14 const topologyVersion = 1 14 const topologyVersion = 1
15 15
16 // NoRelationError represents a relation not found for one or more endpoints. 16 // NoRelationError represents a relation not found for one or more endpoints.
17 type NoRelationError struct { 17 type NoRelationError struct {
18 Endpoints []RelationEndpoint 18 Endpoints []RelationEndpoint
19 } 19 }
20 20
21 // Error returns the string representation of the error. 21 // Error returns the string representation of the error.
22 func (e NoRelationError) Error() string { 22 func (e NoRelationError) Error() string {
23 switch len(e.Endpoints) { 23 switch len(e.Endpoints) {
24 case 1: 24 case 1:
25 » » return fmt.Sprintf("state: no peer relation for %q", e.Endpoints [0].Id()) 25 » » return fmt.Sprintf("state: no peer relation for %q", e.Endpoints [0])
26 case 2: 26 case 2:
27 » » return fmt.Sprintf("state: no relation between %q and %q", e.End points[0].Id(), e.Endpoints[1].Id()) 27 » » return fmt.Sprintf("state: no relation between %q and %q", e.End points[0], e.Endpoints[1])
28 » } 28 » }
29 » panic("state: illegal relation error") 29 » panic("state: illegal relation")
30 } 30 }
31 31
32 // zkTopology is used to marshal and unmarshal the content 32 // zkTopology is used to marshal and unmarshal the content
33 // of the /topology node in ZooKeeper. 33 // of the /topology node in ZooKeeper.
34 type zkTopology struct { 34 type zkTopology struct {
35 Version int 35 Version int
36 Machines map[string]*zkMachine 36 Machines map[string]*zkMachine
37 Services map[string]*zkService 37 Services map[string]*zkService
38 UnitSequence map[string]int "unit-sequence" 38 UnitSequence map[string]int "unit-sequence"
39 Relations map[string]*zkRelation 39 Relations map[string]*zkRelation
(...skipping 16 matching lines...) Expand all
56 type zkUnit struct { 56 type zkUnit struct {
57 Sequence int 57 Sequence int
58 Machine string 58 Machine string
59 } 59 }
60 60
61 // zkRelation represents the relation data within the· 61 // zkRelation represents the relation data within the·
62 // /topology node in ZooKeeper. 62 // /topology node in ZooKeeper.
63 type zkRelation struct { 63 type zkRelation struct {
64 Interface string 64 Interface string
65 Scope RelationScope 65 Scope RelationScope
66 » Services map[RelationRole]string 66 » Services map[RelationRole]*zkRelationService
67 }
68
69 // zkRelationService represents the data of one
70 // service of a relation within the /topology
71 // node in ZooKeeper.
72 type zkRelationService struct {
73 » Service string
74 » RelationName string "relation-name"
67 } 75 }
68 76
69 // check verifies that r is a proper relation. 77 // check verifies that r is a proper relation.
70 func (r *zkRelation) check() error { 78 func (r *zkRelation) check() error {
71 if len(r.Interface) == 0 { 79 if len(r.Interface) == 0 {
72 return fmt.Errorf("relation interface is empty") 80 return fmt.Errorf("relation interface is empty")
73 } 81 }
74 if len(r.Services) == 0 { 82 if len(r.Services) == 0 {
75 return fmt.Errorf("relation has no services") 83 return fmt.Errorf("relation has no services")
76 } 84 }
77 counterpart := map[RelationRole]RelationRole{ 85 counterpart := map[RelationRole]RelationRole{
78 RoleRequirer: RoleProvider, 86 RoleRequirer: RoleProvider,
79 RoleProvider: RoleRequirer, 87 RoleProvider: RoleRequirer,
80 RolePeer: RolePeer, 88 RolePeer: RolePeer,
81 } 89 }
82 » for serviceRole, serviceKey := range r.Services { 90 » for serviceRole, service := range r.Services {
83 » » if serviceKey == "" { 91 » » if service.Service == "" {
84 » » » return fmt.Errorf("relation has %s service with empty ke y", serviceRole) 92 » » » return fmt.Errorf("relation has %s service with empty se rvice key", serviceRole)
93 » » }
94 » » if service.RelationName == "" {
95 » » » return fmt.Errorf("relation has %s service with empty re lation name", serviceRole)
85 } 96 }
86 counterRole, ok := counterpart[serviceRole] 97 counterRole, ok := counterpart[serviceRole]
87 if !ok { 98 if !ok {
88 return fmt.Errorf("relation has unknown service role: %q ", serviceRole) 99 return fmt.Errorf("relation has unknown service role: %q ", serviceRole)
89 } 100 }
90 if _, ok := r.Services[counterRole]; !ok { 101 if _, ok := r.Services[counterRole]; !ok {
91 return fmt.Errorf("relation has %s but no %s", serviceRo le, counterRole) 102 return fmt.Errorf("relation has %s but no %s", serviceRo le, counterRole)
92 } 103 }
93 } 104 }
94 if len(r.Services) > 2 { 105 if len(r.Services) > 2 {
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after
400 t.topology.Relations = make(map[string]*zkRelation) 411 t.topology.Relations = make(map[string]*zkRelation)
401 } 412 }
402 _, ok := t.topology.Relations[relationKey] 413 _, ok := t.topology.Relations[relationKey]
403 if ok { 414 if ok {
404 return fmt.Errorf("relation key %q already in use", relationKey) 415 return fmt.Errorf("relation key %q already in use", relationKey)
405 } 416 }
406 // Check if the relation definition and the service keys are valid. 417 // Check if the relation definition and the service keys are valid.
407 if err := relation.check(); err != nil { 418 if err := relation.check(); err != nil {
408 return err 419 return err
409 } 420 }
410 » for _, serviceKey := range relation.Services { 421 » for _, service := range relation.Services {
411 » » if err := t.assertService(serviceKey); err != nil { 422 » » if err := t.assertService(service.Service); err != nil {
412 return err 423 return err
413 } 424 }
414 } 425 }
415 » if relation.Services[RolePeer] == "" { 426 » if relation.Services[RolePeer] == nil {
416 » » providerKey := relation.Services[RoleProvider] 427 » » providerKey := relation.Services[RoleProvider].Service
417 » » requirerKey := relation.Services[RoleRequirer] 428 » » requirerKey := relation.Services[RoleRequirer].Service
418 if providerKey == requirerKey { 429 if providerKey == requirerKey {
419 » » » return fmt.Errorf("provider and consumer keys must not b e the same") 430 » » » return fmt.Errorf("provider and requirer keys must not b e the same")
420 } 431 }
421 } 432 }
422 t.topology.Relations[relationKey] = relation 433 t.topology.Relations[relationKey] = relation
423 return nil 434 return nil
424 } 435 }
425 436
426 // RelationKeys returns the keys for all relations in the topology. 437 // RelationKeys returns the keys for all relations in the topology.
427 func (t *topology) RelationKeys() []string { 438 func (t *topology) RelationKeys() []string {
428 keys := []string{} 439 keys := []string{}
429 for key, _ := range t.topology.Relations { 440 for key, _ := range t.topology.Relations {
430 keys = append(keys, key) 441 keys = append(keys, key)
431 } 442 }
432 sort.Strings(keys) 443 sort.Strings(keys)
433 return keys 444 return keys
434 } 445 }
435 446
436 // RemoveRelation removes the relation with key from the topology. 447 // RemoveRelation removes the relation with key from the topology.
437 func (t *topology) RemoveRelation(key string) { 448 func (t *topology) RemoveRelation(key string) {
438 delete(t.topology.Relations, key) 449 delete(t.topology.Relations, key)
439 } 450 }
440 451
441 // RelationsForService returns all relations that the service 452 // RelationsForService returns all relations that the service
442 // with serviceKey is part of. 453 // with serviceKey is part of.
443 func (t *topology) RelationsForService(serviceKey string) (map[string]*zkRelatio n, error) { 454 func (t *topology) RelationsForService(serviceKey string) (map[string]*zkRelatio n, error) {
444 if err := t.assertService(serviceKey); err != nil { 455 if err := t.assertService(serviceKey); err != nil {
445 return nil, err 456 return nil, err
446 } 457 }
447 relations := make(map[string]*zkRelation) 458 relations := make(map[string]*zkRelation)
448 for relationKey, relation := range t.topology.Relations { 459 for relationKey, relation := range t.topology.Relations {
449 » » for _, roleServiceKey := range relation.Services { 460 » » for _, service := range relation.Services {
450 » » » if roleServiceKey == serviceKey { 461 » » » if service.Service == serviceKey {
451 relations[relationKey] = relation 462 relations[relationKey] = relation
452 break 463 break
453 } 464 }
454 } 465 }
455 } 466 }
456 return relations, nil 467 return relations, nil
457 } 468 }
458 469
459 // RelationKey returns the key for the relation established between the 470 // RelationKey returns the key for the relation established between the
460 // provided endpoints. If no matching relation is found, error will be 471 // provided endpoints. If no matching relation is found, error will be
461 // of type *NoRelationError. 472 // of type *NoRelationError.
462 func (t *topology) RelationKey(endpoints ...RelationEndpoint) (string, error) { 473 func (t *topology) RelationKey(endpoints ...RelationEndpoint) (string, error) {
463 if t.topology.Relations == nil {
464 return "", &NoRelationError{endpoints}
465 }
466 switch len(endpoints) { 474 switch len(endpoints) {
467 case 1: 475 case 1:
468 // Just pass. 476 // Just pass.
469 case 2: 477 case 2:
470 if endpoints[0].Interface != endpoints[1].Interface { 478 if endpoints[0].Interface != endpoints[1].Interface {
471 » » » return "", fmt.Errorf("state: differing interfaces %q an d %q", endpoints[0].Interface, endpoints[1].Interface) 479 » » » return "", &NoRelationError{endpoints}
472 } 480 }
473 default: 481 default:
474 » » return "", fmt.Errorf("state: illegal number of endpoints passed ") 482 » » return "", fmt.Errorf("state: illegal number of relation endpoin ts provided")
475 } 483 }
476 for relationKey, relation := range t.topology.Relations { 484 for relationKey, relation := range t.topology.Relations {
477 if relation.Interface != endpoints[0].Interface { 485 if relation.Interface != endpoints[0].Interface {
478 continue 486 continue
479 } 487 }
480 found := true 488 found := true
481 for _, endpoint := range endpoints { 489 for _, endpoint := range endpoints {
482 » » » serviceKey, ok := relation.Services[endpoint.RelationRol e] 490 » » » service, ok := relation.Services[endpoint.RelationRole]
483 » » » if !ok { 491 » » » if !ok || service.RelationName != endpoint.RelationName {
484 » » » » found = false
485 » » » » break
486 » » » }
487 » » » serviceName, err := t.ServiceName(serviceKey)
488 » » » if err != nil {
489 » » » » return "", err
490 » » » }
491 » » » if serviceName != endpoint.RelationName {
492 found = false 492 found = false
493 break 493 break
494 } 494 }
495 } 495 }
496 if found { 496 if found {
497 // All endpoints tested positive. 497 // All endpoints tested positive.
498 return relationKey, nil 498 return relationKey, nil
499 } 499 }
500 } 500 }
501 return "", &NoRelationError{endpoints} 501 return "", &NoRelationError{endpoints}
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
566 } 566 }
567 } 567 }
568 // Apply the passed function. 568 // Apply the passed function.
569 if err = f(it); err != nil { 569 if err = f(it); err != nil {
570 return "", err 570 return "", err
571 } 571 }
572 return it.dump() 572 return it.dump()
573 } 573 }
574 return zk.RetryChange(zkTopologyPath, 0, zkPermAll, change) 574 return zk.RetryChange(zkTopologyPath, 0, zkPermAll, change)
575 } 575 }
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b