github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/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  }