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

Delta Between Two Patch Sets: state/topology.go

Issue 6200044: Added relations to topology. (Closed)
Left Patch Set: Added relations to topology. Created 12 years, 9 months ago
Right Patch Set: Added relations to topology. Created 12 years, 9 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
15 const topologyVersion = 1 14 const topologyVersion = 1
16 15
17 // zkTopology is used to marshal and unmarshal the content 16 // zkTopology is used to marshal and unmarshal the content
18 // of the /topology node in ZooKeeper. 17 // of the /topology node in ZooKeeper.
19 type zkTopology struct { 18 type zkTopology struct {
20 Version int 19 Version int
21 Machines map[string]*zkMachine 20 Machines map[string]*zkMachine
22 Services map[string]*zkService 21 Services map[string]*zkService
23 UnitSequence map[string]int "unit-sequence" 22 UnitSequence map[string]int "unit-sequence"
24 Relations map[string]*zkRelation 23 Relations map[string]*zkRelation
(...skipping 12 matching lines...) Expand all
37 } 36 }
38 37
39 // zkUnit represents the unit data within the /topology 38 // zkUnit represents the unit data within the /topology
40 // node in ZooKeeper. 39 // node in ZooKeeper.
41 type zkUnit struct { 40 type zkUnit struct {
42 Sequence int 41 Sequence int
43 Machine string 42 Machine string
44 } 43 }
45 44
46 // zkRelation represents the relation data within the· 45 // zkRelation represents the relation data within the·
47 // /topology node in ZooKeeper. "Services" references to 46 // /topology node in ZooKeeper.
48 // the service keys of provider, consumer or peer.
49 type zkRelation struct { 47 type zkRelation struct {
50 Key string "omitempty"
51 Interface string 48 Interface string
52 Scope RelationScope 49 Scope RelationScope
53 Services map[RelationRole]string 50 Services map[RelationRole]string
54 } 51 }
55 52
56 // check validates if interface isn't empty and the· 53 // check verifies that r is a proper relation.
57 // services are provider and consumer or peer.
58 func (r *zkRelation) check() error { 54 func (r *zkRelation) check() error {
59 if len(r.Interface) == 0 { 55 if len(r.Interface) == 0 {
60 return fmt.Errorf("relation interface is empty") 56 return fmt.Errorf("relation interface is empty")
61 } 57 }
62 » switch len(r.Services) { 58 » if len(r.Services) == 0 {
63 » case 0: 59 » » return fmt.Errorf("relation has no services")
64 » » return fmt.Errorf("no service defined") 60 » }
65 » case 1: 61 » counterpart := map[RelationRole]RelationRole{
66 » » if r.Services[RolePeer] == "" { 62 » » RoleRequirer: RoleProvider,
67 » » » return fmt.Errorf("provider or consumer service missing" ) 63 » » RoleProvider: RoleRequirer,
68 » » } 64 » » RolePeer: RolePeer,
69 » case 2: 65 » }
70 » » if r.Services[RoleProvider] == "" || r.Services[RoleConsumer] == "" { 66 » for serviceRole, serviceKey := range r.Services {
71 » » » return fmt.Errorf("mixed peer with provider or consumer service") 67 » » if serviceKey == "" {
72 » » } 68 » » » return fmt.Errorf("relation has %s service with empty ke y", serviceRole)
73 » default: 69 » » }
74 » » return fmt.Errorf("too much services defined") 70 » » counterRole, ok := counterpart[serviceRole]
fwereade 2012/05/23 10:28:02 s/much/many/
TheMue 2012/05/23 10:43:04 Done.
71 » » if !ok {
72 » » » return fmt.Errorf("relation has unknown service role: %q ", serviceRole)
73 » » }
74 » » if _, ok := r.Services[counterRole]; !ok {
75 » » » return fmt.Errorf("relation has %s but no %s", serviceRo le, counterRole)
76 » » }
77 » }
78 » if len(r.Services) > 2 {
79 » » return fmt.Errorf("relation with mixed peer, provider, and requi rer roles")
75 } 80 }
76 return nil 81 return nil
77 } 82 }
78 83
79 // topology is an internal helper that handles the content 84 // topology is an internal helper that handles the content
80 // of the /topology node in ZooKeeper. 85 // of the /topology node in ZooKeeper.
81 type topology struct { 86 type topology struct {
82 topology *zkTopology 87 topology *zkTopology
83 } 88 }
84 89
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
358 return err 363 return err
359 } 364 }
360 unit := t.topology.Services[serviceKey].Units[unitKey] 365 unit := t.topology.Services[serviceKey].Units[unitKey]
361 if unit.Machine == "" { 366 if unit.Machine == "" {
362 return fmt.Errorf("unit %q in service %q not assigned to a machi ne", unitKey, serviceKey) 367 return fmt.Errorf("unit %q in service %q not assigned to a machi ne", unitKey, serviceKey)
363 } 368 }
364 unit.Machine = "" 369 unit.Machine = ""
365 return nil 370 return nil
366 } 371 }
367 372
368 // Relation returns a relation with the given key or an error if it doesn't exis t. 373 // Relation returns the relation with key from the topology.
369 func (t *topology) Relation(relationKey string) (*zkRelation, error) { 374 func (t *topology) Relation(key string) (*zkRelation, error) {
370 » if t.topology.Relations == nil || t.topology.Relations[relationKey] == n il { 375 » if t.topology.Relations == nil || t.topology.Relations[key] == nil {
371 » » return nil, fmt.Errorf("relation %q does not exist", relationKey ) 376 » » return nil, fmt.Errorf("relation %q does not exist", key)
372 » } 377 » }
373 » return t.topology.Relations[relationKey], nil 378 » return t.topology.Relations[key], nil
374 } 379 }
375 380
376 // AddRelation adds a new relation with the given key and relation data. 381 // AddRelation adds a new relation with the given key and relation data.
377 func (t *topology) AddRelation(relationKey string, relation *zkRelation) error { 382 func (t *topology) AddRelation(relationKey string, relation *zkRelation) error {
378 if t.topology.Relations == nil { 383 if t.topology.Relations == nil {
379 t.topology.Relations = make(map[string]*zkRelation) 384 t.topology.Relations = make(map[string]*zkRelation)
380 } 385 }
381 » _, err := t.Relation(relationKey) 386 » _, ok := t.topology.Relations[relationKey]
382 » if err == nil { 387 » if ok {
383 » » // No error means relation with key already exists.
384 return fmt.Errorf("relation key %q already in use", relationKey) 388 return fmt.Errorf("relation key %q already in use", relationKey)
385 } 389 }
386 // Check if the relation definition and the service keys are valid. 390 // Check if the relation definition and the service keys are valid.
387 » err = relation.check() 391 » if err := relation.check(); err != nil {
388 » if err != nil {
389 return err 392 return err
390 } 393 }
391 for _, serviceKey := range relation.Services { 394 for _, serviceKey := range relation.Services {
392 » » if err = t.assertService(serviceKey); err != nil { 395 » » if err := t.assertService(serviceKey); err != nil {
393 return err 396 return err
394 } 397 }
395 } 398 }
396 if relation.Services[RolePeer] == "" { 399 if relation.Services[RolePeer] == "" {
397 providerKey := relation.Services[RoleProvider] 400 providerKey := relation.Services[RoleProvider]
398 » » consumerKey := relation.Services[RoleConsumer] 401 » » consumerKey := relation.Services[RoleRequirer]
399 if providerKey == consumerKey { 402 if providerKey == consumerKey {
400 return fmt.Errorf("provider and consumer keys must not b e the same") 403 return fmt.Errorf("provider and consumer keys must not b e the same")
401 } 404 }
402 } 405 }
403 relation.Key = relationKey
404 t.topology.Relations[relationKey] = relation 406 t.topology.Relations[relationKey] = relation
405 return nil 407 return nil
406 } 408 }
407 409
408 // RelationKeys returns all relation keys. 410 // RelationKeys returns the keys for all relations in the topology.
409 func (t *topology) RelationKeys() []string { 411 func (t *topology) RelationKeys() []string {
410 keys := []string{} 412 keys := []string{}
411 for key, _ := range t.topology.Relations { 413 for key, _ := range t.topology.Relations {
412 keys = append(keys, key) 414 keys = append(keys, key)
413 } 415 }
414 sort.Strings(keys) 416 sort.Strings(keys)
415 return keys 417 return keys
416 } 418 }
417 419
418 // RemoveRelation removes a relation. 420 // RemoveRelation removes the relation with key from the topology.
419 func (t *topology) RemoveRelation(key string) { 421 func (t *topology) RemoveRelation(key string) {
420 delete(t.topology.Relations, key) 422 delete(t.topology.Relations, key)
421 } 423 }
422 424
423 // RelationWithService returns the relation data for a given 425 // RelationsForService returns all relations that the service
424 // relation key if the service with the given key is assigned 426 // with serviceKey is part of.
425 // to the relation. 427 func (t *topology) RelationsForService(serviceKey string) (map[string]*zkRelatio n, error) {
426 func (t *topology) RelationWithService(relationKey, serviceKey string) (*zkRelat ion, error) {
427 if err := t.assertService(serviceKey); err != nil { 428 if err := t.assertService(serviceKey); err != nil {
428 return nil, err 429 return nil, err
429 } 430 }
430 » if err := t.assertRelation(relationKey); err != nil { 431 » relations := make(map[string]*zkRelation)
431 » » return nil, err 432 » for relationKey, relation := range t.topology.Relations {
432 » } 433 » » for _, roleServiceKey := range relation.Services {
433 » relation := t.topology.Relations[relationKey] 434 » » » if roleServiceKey == serviceKey {
434 » for _, key := range relation.Services { 435 » » » » relations[relationKey] = relation
435 » » if key == serviceKey { 436 » » » » break
436 » » » return relation, nil
437 » » }
438 » }
439 » return nil, fmt.Errorf("service %q is not assigned to relation %q", serv iceKey, relationKey)
440 }
441
442 // RelationsForService returns all relations for a
443 // given service key.
444 func (t *topology) RelationsForService(serviceKey string) ([]*zkRelation, error) {
445 » if err := t.assertService(serviceKey); err != nil {
446 » » return nil, err
447 » }
448 » relations := []*zkRelation{}
449 » for _, relation := range t.topology.Relations {
450 » » for _, key := range relation.Services {
451 » » » if key == serviceKey {
452 » » » » relations = append(relations, relation)
453 } 437 }
454 } 438 }
455 } 439 }
456 return relations, nil 440 return relations, nil
457 } 441 }
458 442
459 // assertMachine checks if a machine exists. 443 // assertMachine checks if a machine exists.
460 func (t *topology) assertMachine(machineKey string) error { 444 func (t *topology) assertMachine(machineKey string) error {
461 if _, ok := t.topology.Machines[machineKey]; !ok { 445 if _, ok := t.topology.Machines[machineKey]; !ok {
462 return fmt.Errorf("machine with key %q not found", machineKey) 446 return fmt.Errorf("machine with key %q not found", machineKey)
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
521 } 505 }
522 } 506 }
523 // Apply the passed function. 507 // Apply the passed function.
524 if err = f(it); err != nil { 508 if err = f(it); err != nil {
525 return "", err 509 return "", err
526 } 510 }
527 return it.dump() 511 return it.dump()
528 } 512 }
529 return zk.RetryChange(zkTopologyPath, 0, zkPermAll, change) 513 return zk.RetryChange(zkTopologyPath, 0, zkPermAll, change)
530 } 514 }
LEFTRIGHT

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