github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/payload/api/private/client/unitfacade.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package client 5 6 import ( 7 "github.com/juju/errors" 8 9 "github.com/juju/juju/payload" 10 internal "github.com/juju/juju/payload/api/private" 11 ) 12 13 type facadeCaller interface { 14 FacadeCall(request string, params, response interface{}) error 15 } 16 17 // UnitFacadeClient provides methods for interacting with Juju's internal 18 // RPC API, relative to payloads. 19 type UnitFacadeClient struct { 20 facadeCaller 21 } 22 23 // NewUnitFacadeClient builds a new payload API client. 24 func NewUnitFacadeClient(caller facadeCaller) UnitFacadeClient { 25 return UnitFacadeClient{caller} 26 } 27 28 // Track calls the Track API server method. 29 func (c UnitFacadeClient) Track(payloads ...payload.Payload) ([]payload.Result, error) { 30 args := internal.Payloads2TrackArgs(payloads) 31 32 var rs internal.PayloadResults 33 if err := c.FacadeCall("Track", &args, &rs); err != nil { 34 return nil, errors.Trace(err) 35 } 36 37 return api2results(rs) 38 } 39 40 // List calls the List API server method. 41 func (c UnitFacadeClient) List(fullIDs ...string) ([]payload.Result, error) { 42 var ids []string 43 if len(fullIDs) > 0 { 44 actual, err := c.lookUp(fullIDs) 45 if err != nil { 46 return nil, errors.Trace(err) 47 } 48 ids = actual 49 } 50 args := internal.IDs2ListArgs(ids) 51 52 var rs internal.PayloadResults 53 if err := c.FacadeCall("List", &args, &rs); err != nil { 54 return nil, errors.Trace(err) 55 } 56 57 return api2results(rs) 58 } 59 60 // LookUp calls the LookUp API server method. 61 func (c UnitFacadeClient) LookUp(fullIDs ...string) ([]payload.Result, error) { 62 if len(fullIDs) == 0 { 63 // Unlike List(), LookUp doesn't fall back to looking up all IDs. 64 return nil, nil 65 } 66 args := internal.FullIDs2LookUpArgs(fullIDs) 67 68 var rs internal.PayloadResults 69 if err := c.FacadeCall("LookUp", &args, &rs); err != nil { 70 return nil, err 71 } 72 73 return api2results(rs) 74 } 75 76 // SetStatus calls the SetStatus API server method. 77 func (c UnitFacadeClient) SetStatus(status string, fullIDs ...string) ([]payload.Result, error) { 78 ids, err := c.lookUp(fullIDs) 79 if err != nil { 80 return nil, errors.Trace(err) 81 } 82 args := internal.IDs2SetStatusArgs(ids, status) 83 84 var rs internal.PayloadResults 85 if err := c.FacadeCall("SetStatus", &args, &rs); err != nil { 86 return nil, err 87 } 88 89 return api2results(rs) 90 } 91 92 // Untrack calls the Untrack API server method. 93 func (c UnitFacadeClient) Untrack(fullIDs ...string) ([]payload.Result, error) { 94 logger.Tracef("Calling untrack API: %q", fullIDs) 95 96 ids, err := c.lookUp(fullIDs) 97 if err != nil { 98 return nil, errors.Trace(err) 99 } 100 args := internal.IDs2UntrackArgs(ids) 101 102 var rs internal.PayloadResults 103 if err := c.FacadeCall("Untrack", &args, &rs); err != nil { 104 return nil, err 105 } 106 107 return api2results(rs) 108 } 109 110 func (c UnitFacadeClient) lookUp(fullIDs []string) ([]string, error) { 111 results, err := c.LookUp(fullIDs...) 112 if err != nil { 113 return nil, errors.Annotate(err, "while looking up IDs") 114 } 115 116 var ids []string 117 for _, result := range results { 118 if result.Error != nil { 119 // TODO(ericsnow) Do not short-circuit? 120 return nil, errors.Annotate(result.Error, "while looking up IDs") 121 } 122 ids = append(ids, result.ID) 123 } 124 return ids, nil 125 } 126 127 func api2results(rs internal.PayloadResults) ([]payload.Result, error) { 128 var results []payload.Result 129 for _, r := range rs.Results { 130 result, err := internal.API2Result(r) 131 if err != nil { 132 // This should not happen; we safely control the result. 133 return nil, errors.Trace(err) 134 } 135 results = append(results, result) 136 } 137 return results, nil 138 }