github.com/mattyw/juju@v0.0.0-20140610034352-732aecd63861/state/api/uniter/service.go (about)

     1  // Copyright 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package uniter
     5  
     6  import (
     7  	"fmt"
     8  
     9  	"github.com/juju/names"
    10  
    11  	"github.com/juju/juju/charm"
    12  	"github.com/juju/juju/state/api/params"
    13  	"github.com/juju/juju/state/api/watcher"
    14  )
    15  
    16  // This module implements a subset of the interface provided by
    17  // state.Service, as needed by the uniter API.
    18  
    19  // Service represents the state of a service.
    20  type Service struct {
    21  	st   *State
    22  	tag  string
    23  	life params.Life
    24  }
    25  
    26  // Name returns the service name.
    27  func (s *Service) Name() string {
    28  	_, serviceName, err := names.ParseTag(s.tag, names.ServiceTagKind)
    29  	if err != nil {
    30  		panic(fmt.Sprintf("%q is not a valid service tag", s.tag))
    31  	}
    32  	return serviceName
    33  }
    34  
    35  // String returns the service as a string.
    36  func (s *Service) String() string {
    37  	return s.Name()
    38  }
    39  
    40  // Watch returns a watcher for observing changes to a service.
    41  func (s *Service) Watch() (watcher.NotifyWatcher, error) {
    42  	var results params.NotifyWatchResults
    43  	args := params.Entities{
    44  		Entities: []params.Entity{{Tag: s.tag}},
    45  	}
    46  	err := s.st.call("Watch", args, &results)
    47  	if err != nil {
    48  		return nil, err
    49  	}
    50  	if len(results.Results) != 1 {
    51  		return nil, fmt.Errorf("expected 1 result, got %d", len(results.Results))
    52  	}
    53  	result := results.Results[0]
    54  	if result.Error != nil {
    55  		return nil, result.Error
    56  	}
    57  	w := watcher.NewNotifyWatcher(s.st.caller, result)
    58  	return w, nil
    59  }
    60  
    61  // WatchRelations returns a StringsWatcher that notifies of changes to
    62  // the lifecycles of relations involving s.
    63  func (s *Service) WatchRelations() (watcher.StringsWatcher, error) {
    64  	var results params.StringsWatchResults
    65  	args := params.Entities{
    66  		Entities: []params.Entity{{Tag: s.tag}},
    67  	}
    68  	err := s.st.call("WatchServiceRelations", args, &results)
    69  	if err != nil {
    70  		return nil, err
    71  	}
    72  	if len(results.Results) != 1 {
    73  		return nil, fmt.Errorf("expected 1 result, got %d", len(results.Results))
    74  	}
    75  	result := results.Results[0]
    76  	if result.Error != nil {
    77  		return nil, result.Error
    78  	}
    79  	w := watcher.NewStringsWatcher(s.st.caller, result)
    80  	return w, nil
    81  }
    82  
    83  // Life returns the service's current life state.
    84  func (s *Service) Life() params.Life {
    85  	return s.life
    86  }
    87  
    88  // Refresh refreshes the contents of the Service from the underlying
    89  // state.
    90  func (s *Service) Refresh() error {
    91  	life, err := s.st.life(s.tag)
    92  	if err != nil {
    93  		return err
    94  	}
    95  	s.life = life
    96  	return nil
    97  }
    98  
    99  // CharmURL returns the service's charm URL, and whether units should
   100  // upgrade to the charm with that URL even if they are in an error
   101  // state (force flag).
   102  //
   103  // NOTE: This differs from state.Service.CharmURL() by returning
   104  // an error instead as well, because it needs to make an API call.
   105  func (s *Service) CharmURL() (*charm.URL, bool, error) {
   106  	var results params.StringBoolResults
   107  	args := params.Entities{
   108  		Entities: []params.Entity{{Tag: s.tag}},
   109  	}
   110  	err := s.st.call("CharmURL", args, &results)
   111  	if err != nil {
   112  		return nil, false, err
   113  	}
   114  	if len(results.Results) != 1 {
   115  		return nil, false, fmt.Errorf("expected 1 result, got %d", len(results.Results))
   116  	}
   117  	result := results.Results[0]
   118  	if result.Error != nil {
   119  		return nil, false, result.Error
   120  	}
   121  	if result.Result != "" {
   122  		curl, err := charm.ParseURL(result.Result)
   123  		if err != nil {
   124  			return nil, false, err
   125  		}
   126  		return curl, result.Ok, nil
   127  	}
   128  	return nil, false, fmt.Errorf("%q has no charm url set", s.tag)
   129  }
   130  
   131  // TODO(dimitern) bug #1270795 2014-01-20
   132  // Add a doc comment here.
   133  func (s *Service) GetOwnerTag() (string, error) {
   134  	var result params.StringResult
   135  	args := params.Entities{
   136  		Entities: []params.Entity{{Tag: s.tag}},
   137  	}
   138  	err := s.st.call("GetOwnerTag", args, &result)
   139  	if err != nil {
   140  		return "", err
   141  	}
   142  	if result.Error != nil {
   143  		return "", result.Error
   144  	}
   145  	return result.Result, nil
   146  }