~nskaggs/+junk/xenial-test

« back to all changes in this revision

Viewing changes to src/github.com/juju/juju/api/uniter/leadership.go

  • Committer: Nicholas Skaggs
  • Date: 2016-10-24 20:56:05 UTC
  • Revision ID: nicholas.skaggs@canonical.com-20161024205605-z8lta0uvuhtxwzwl
Initi with beta15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2015 Canonical Ltd.
 
2
// Licensed under the AGPLv3, see LICENCE file for details.
 
3
 
 
4
package uniter
 
5
 
 
6
import (
 
7
        "github.com/juju/errors"
 
8
        "gopkg.in/juju/names.v2"
 
9
 
 
10
        "github.com/juju/juju/apiserver/params"
 
11
        "github.com/juju/juju/watcher"
 
12
)
 
13
 
 
14
// NewLeadershipSettingsAccessor returns a new LeadershipSettingsAccessor.
 
15
func NewLeadershipSettingsAccessor(
 
16
        caller FacadeCallFn,
 
17
        newWatcher NewNotifyWatcherFn,
 
18
        checkApiVersion CheckApiVersionFn,
 
19
) *LeadershipSettingsAccessor {
 
20
        return &LeadershipSettingsAccessor{caller, newWatcher, checkApiVersion}
 
21
}
 
22
 
 
23
type FacadeCallFn func(request string, params, response interface{}) error
 
24
type NewNotifyWatcherFn func(params.NotifyWatchResult) watcher.NotifyWatcher
 
25
type CheckApiVersionFn func(functionName string) error
 
26
 
 
27
// LeadershipSettingsAccessor provides a type that can make RPC calls
 
28
// to a service which can read, write, and watch leadership settings.
 
29
type LeadershipSettingsAccessor struct {
 
30
        facadeCaller     FacadeCallFn
 
31
        newNotifyWatcher NewNotifyWatcherFn
 
32
        checkApiVersion  CheckApiVersionFn
 
33
}
 
34
 
 
35
// Merge merges the provided settings into the leadership settings for
 
36
// the given service ID. Only leaders of a given service may perform
 
37
// this operation.
 
38
func (lsa *LeadershipSettingsAccessor) Merge(serviceId string, settings map[string]string) error {
 
39
 
 
40
        if err := lsa.checkApiVersion("Merge"); err != nil {
 
41
                return errors.Annotatef(err, "cannot access leadership api")
 
42
        }
 
43
 
 
44
        results, err := lsa.bulkMerge(lsa.prepareMerge(serviceId, settings))
 
45
        if err != nil {
 
46
                return errors.Annotatef(err, "failed to call leadership api")
 
47
        }
 
48
        if count := len(results.Results); count != 1 {
 
49
                return errors.Errorf("expected 1 result from leadership api, got %d", count)
 
50
        }
 
51
        if results.Results[0].Error != nil {
 
52
                return errors.Annotatef(results.Results[0].Error, "failed to merge leadership settings")
 
53
        }
 
54
        return nil
 
55
}
 
56
 
 
57
// Read retrieves the leadership settings for the given service
 
58
// ID. Anyone may perform this operation.
 
59
func (lsa *LeadershipSettingsAccessor) Read(serviceId string) (map[string]string, error) {
 
60
 
 
61
        if err := lsa.checkApiVersion("Read"); err != nil {
 
62
                return nil, errors.Annotatef(err, "cannot access leadership api")
 
63
        }
 
64
 
 
65
        results, err := lsa.bulkRead(lsa.prepareRead(serviceId))
 
66
        if err != nil {
 
67
                return nil, errors.Annotatef(err, "failed to call leadership api")
 
68
        }
 
69
        if count := len(results.Results); count != 1 {
 
70
                return nil, errors.Errorf("expected 1 result from leadership api, got %d", count)
 
71
        }
 
72
        if results.Results[0].Error != nil {
 
73
                return nil, errors.Annotatef(results.Results[0].Error, "failed to read leadership settings")
 
74
        }
 
75
        return results.Results[0].Settings, nil
 
76
}
 
77
 
 
78
// WatchLeadershipSettings returns a watcher which can be used to wait
 
79
// for leadership settings changes to be made for a given service ID.
 
80
func (lsa *LeadershipSettingsAccessor) WatchLeadershipSettings(serviceId string) (watcher.NotifyWatcher, error) {
 
81
 
 
82
        if err := lsa.checkApiVersion("WatchLeadershipSettings"); err != nil {
 
83
                return nil, errors.Annotatef(err, "cannot access leadership api")
 
84
        }
 
85
        var results params.NotifyWatchResults
 
86
        if err := lsa.facadeCaller(
 
87
                "WatchLeadershipSettings",
 
88
                params.Entities{[]params.Entity{{names.NewApplicationTag(serviceId).String()}}},
 
89
                &results,
 
90
        ); err != nil {
 
91
                return nil, errors.Annotate(err, "failed to call leadership api")
 
92
        }
 
93
        if count := len(results.Results); count != 1 {
 
94
                return nil, errors.Errorf("expected 1 result from leadership api, got %d", count)
 
95
        }
 
96
        if results.Results[0].Error != nil {
 
97
                return nil, errors.Annotatef(results.Results[0].Error, "failed to watch leadership settings")
 
98
        }
 
99
        return lsa.newNotifyWatcher(results.Results[0]), nil
 
100
}
 
101
 
 
102
//
 
103
// Prepare functions for building bulk-calls.
 
104
//
 
105
 
 
106
func (lsa *LeadershipSettingsAccessor) prepareMerge(serviceId string, settings map[string]string) params.MergeLeadershipSettingsParam {
 
107
        return params.MergeLeadershipSettingsParam{
 
108
                ApplicationTag: names.NewApplicationTag(serviceId).String(),
 
109
                Settings:       settings,
 
110
        }
 
111
}
 
112
 
 
113
func (lsa *LeadershipSettingsAccessor) prepareRead(serviceId string) params.Entity {
 
114
        return params.Entity{Tag: names.NewApplicationTag(serviceId).String()}
 
115
}
 
116
 
 
117
//
 
118
// Bulk calls.
 
119
//
 
120
 
 
121
func (lsa *LeadershipSettingsAccessor) bulkMerge(args ...params.MergeLeadershipSettingsParam) (*params.ErrorResults, error) {
 
122
        // Don't make the jump over the network if we don't have to.
 
123
        if len(args) <= 0 {
 
124
                return &params.ErrorResults{}, nil
 
125
        }
 
126
 
 
127
        bulkArgs := params.MergeLeadershipSettingsBulkParams{Params: args}
 
128
        var results params.ErrorResults
 
129
        return &results, lsa.facadeCaller("Merge", bulkArgs, &results)
 
130
}
 
131
 
 
132
func (lsa *LeadershipSettingsAccessor) bulkRead(args ...params.Entity) (*params.GetLeadershipSettingsBulkResults, error) {
 
133
 
 
134
        // Don't make the jump over the network if we don't have to.
 
135
        if len(args) <= 0 {
 
136
                return &params.GetLeadershipSettingsBulkResults{}, nil
 
137
        }
 
138
 
 
139
        bulkArgs := params.Entities{Entities: args}
 
140
        var results params.GetLeadershipSettingsBulkResults
 
141
        return &results, lsa.facadeCaller("Read", bulkArgs, &results)
 
142
}