github.com/arunkumar7540/cli@v6.45.0+incompatible/actor/v3action/application.go (about)

     1  package v3action
     2  
     3  import (
     4  	"time"
     5  
     6  	"code.cloudfoundry.org/cli/actor/actionerror"
     7  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccerror"
     8  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccv3"
     9  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccv3/constant"
    10  )
    11  
    12  // Application represents a V3 actor application.
    13  type Application struct {
    14  	Name                string
    15  	GUID                string
    16  	StackName           string
    17  	State               constant.ApplicationState
    18  	LifecycleType       constant.AppLifecycleType
    19  	LifecycleBuildpacks []string
    20  	SpaceGUID           string
    21  }
    22  
    23  func (app Application) Started() bool {
    24  	return app.State == constant.ApplicationStarted
    25  }
    26  
    27  func (app Application) Stopped() bool {
    28  	return app.State == constant.ApplicationStopped
    29  }
    30  
    31  func (actor Actor) DeleteApplicationByNameAndSpace(name string, spaceGUID string) (Warnings, error) {
    32  	var allWarnings Warnings
    33  
    34  	app, getAppWarnings, err := actor.GetApplicationByNameAndSpace(name, spaceGUID)
    35  	allWarnings = append(allWarnings, getAppWarnings...)
    36  	if err != nil {
    37  		return allWarnings, err
    38  	}
    39  
    40  	jobURL, deleteAppWarnings, err := actor.CloudControllerClient.DeleteApplication(app.GUID)
    41  	allWarnings = append(allWarnings, deleteAppWarnings...)
    42  	if err != nil {
    43  		return allWarnings, err
    44  	}
    45  
    46  	pollWarnings, err := actor.CloudControllerClient.PollJob(jobURL)
    47  	allWarnings = append(allWarnings, pollWarnings...)
    48  	return allWarnings, err
    49  }
    50  
    51  // GetApplicationByNameAndSpace returns the application with the given
    52  // name in the given space.
    53  func (actor Actor) GetApplicationByNameAndSpace(appName string, spaceGUID string) (Application, Warnings, error) {
    54  	apps, warnings, err := actor.CloudControllerClient.GetApplications(
    55  		ccv3.Query{Key: ccv3.NameFilter, Values: []string{appName}},
    56  		ccv3.Query{Key: ccv3.SpaceGUIDFilter, Values: []string{spaceGUID}},
    57  	)
    58  	if err != nil {
    59  		return Application{}, Warnings(warnings), err
    60  	}
    61  
    62  	if len(apps) == 0 {
    63  		return Application{}, Warnings(warnings), actionerror.ApplicationNotFoundError{Name: appName}
    64  	}
    65  
    66  	return actor.convertCCToActorApplication(apps[0]), Warnings(warnings), nil
    67  }
    68  
    69  // GetApplicationsBySpace returns all applications in a space.
    70  func (actor Actor) GetApplicationsBySpace(spaceGUID string) ([]Application, Warnings, error) {
    71  	ccApps, warnings, err := actor.CloudControllerClient.GetApplications(
    72  		ccv3.Query{Key: ccv3.SpaceGUIDFilter, Values: []string{spaceGUID}},
    73  	)
    74  
    75  	if err != nil {
    76  		return []Application{}, Warnings(warnings), err
    77  	}
    78  
    79  	var apps []Application
    80  	for _, ccApp := range ccApps {
    81  		apps = append(apps, actor.convertCCToActorApplication(ccApp))
    82  	}
    83  	return apps, Warnings(warnings), nil
    84  }
    85  
    86  // GetApplicationsByGUIDs returns all applications with the provided GUIDs.
    87  func (actor Actor) GetApplicationsByGUIDs(appGUIDs ...string) ([]Application, Warnings, error) {
    88  	ccApps, warnings, err := actor.CloudControllerClient.GetApplications(
    89  		ccv3.Query{Key: ccv3.GUIDFilter, Values: appGUIDs},
    90  	)
    91  
    92  	if err != nil {
    93  		return []Application{}, Warnings(warnings), err
    94  	}
    95  
    96  	var apps []Application
    97  	for _, ccApp := range ccApps {
    98  		apps = append(apps, actor.convertCCToActorApplication(ccApp))
    99  	}
   100  	return apps, Warnings(warnings), nil
   101  }
   102  
   103  // CreateApplicationInSpace creates and returns the application with the given
   104  // name in the given space.
   105  func (actor Actor) CreateApplicationInSpace(app Application, spaceGUID string) (Application, Warnings, error) {
   106  	createdApp, warnings, err := actor.CloudControllerClient.CreateApplication(
   107  		ccv3.Application{
   108  			LifecycleType:       app.LifecycleType,
   109  			LifecycleBuildpacks: app.LifecycleBuildpacks,
   110  			StackName:           app.StackName,
   111  			Name:                app.Name,
   112  			Relationships: ccv3.Relationships{
   113  				constant.RelationshipTypeSpace: ccv3.Relationship{GUID: spaceGUID},
   114  			},
   115  		})
   116  
   117  	if err != nil {
   118  		if _, ok := err.(ccerror.NameNotUniqueInSpaceError); ok {
   119  			return Application{}, Warnings(warnings), actionerror.ApplicationAlreadyExistsError{Name: app.Name}
   120  		}
   121  		return Application{}, Warnings(warnings), err
   122  	}
   123  
   124  	return actor.convertCCToActorApplication(createdApp), Warnings(warnings), nil
   125  }
   126  
   127  // StopApplication stops an application.
   128  func (actor Actor) StopApplication(appGUID string) (Warnings, error) {
   129  	_, warnings, err := actor.CloudControllerClient.UpdateApplicationStop(appGUID)
   130  
   131  	return Warnings(warnings), err
   132  }
   133  
   134  // StartApplication starts an application.
   135  func (actor Actor) StartApplication(appGUID string) (Application, Warnings, error) {
   136  	updatedApp, warnings, err := actor.CloudControllerClient.UpdateApplicationStart(appGUID)
   137  	if err != nil {
   138  		return Application{}, Warnings(warnings), err
   139  	}
   140  
   141  	return actor.convertCCToActorApplication(updatedApp), Warnings(warnings), nil
   142  }
   143  
   144  // RestartApplication restarts an application.
   145  func (actor Actor) RestartApplication(appGUID string) (Warnings, error) {
   146  	_, warnings, err := actor.CloudControllerClient.UpdateApplicationRestart(appGUID)
   147  
   148  	return Warnings(warnings), err
   149  }
   150  
   151  func (actor Actor) PollStart(appGUID string, warningsChannel chan<- Warnings) error {
   152  	processes, warnings, err := actor.CloudControllerClient.GetApplicationProcesses(appGUID)
   153  	warningsChannel <- Warnings(warnings)
   154  	if err != nil {
   155  		return err
   156  	}
   157  
   158  	timeout := time.Now().Add(actor.Config.StartupTimeout())
   159  	for time.Now().Before(timeout) {
   160  		readyProcs := 0
   161  		for _, process := range processes {
   162  			ready, err := actor.processStatus(process, warningsChannel)
   163  			if err != nil {
   164  				return err
   165  			}
   166  
   167  			if ready {
   168  				readyProcs++
   169  			}
   170  		}
   171  
   172  		if readyProcs == len(processes) {
   173  			return nil
   174  		}
   175  		time.Sleep(actor.Config.PollingInterval())
   176  	}
   177  
   178  	return actionerror.StartupTimeoutError{}
   179  }
   180  
   181  // UpdateApplication updates the buildpacks on an application
   182  func (actor Actor) UpdateApplication(app Application) (Application, Warnings, error) {
   183  	ccApp := ccv3.Application{
   184  		GUID:                app.GUID,
   185  		StackName:           app.StackName,
   186  		LifecycleType:       app.LifecycleType,
   187  		LifecycleBuildpacks: app.LifecycleBuildpacks,
   188  	}
   189  
   190  	updatedApp, warnings, err := actor.CloudControllerClient.UpdateApplication(ccApp)
   191  	if err != nil {
   192  		return Application{}, Warnings(warnings), err
   193  	}
   194  
   195  	return actor.convertCCToActorApplication(updatedApp), Warnings(warnings), nil
   196  }
   197  
   198  func (Actor) convertCCToActorApplication(app ccv3.Application) Application {
   199  	return Application{
   200  		GUID:                app.GUID,
   201  		StackName:           app.StackName,
   202  		LifecycleType:       app.LifecycleType,
   203  		LifecycleBuildpacks: app.LifecycleBuildpacks,
   204  		Name:                app.Name,
   205  		State:               app.State,
   206  		SpaceGUID:           app.Relationships[constant.RelationshipTypeSpace].GUID,
   207  	}
   208  }
   209  
   210  func (actor Actor) processStatus(process ccv3.Process, warningsChannel chan<- Warnings) (bool, error) {
   211  	instances, warnings, err := actor.CloudControllerClient.GetProcessInstances(process.GUID)
   212  	warningsChannel <- Warnings(warnings)
   213  	if err != nil {
   214  		return false, err
   215  	}
   216  	if len(instances) == 0 {
   217  		return true, nil
   218  	}
   219  
   220  	for _, instance := range instances {
   221  		if instance.State == constant.ProcessInstanceRunning {
   222  			return true, nil
   223  		}
   224  	}
   225  
   226  	for _, instance := range instances {
   227  		if instance.State != constant.ProcessInstanceCrashed {
   228  			return false, nil
   229  		}
   230  	}
   231  
   232  	// all of the instances are crashed at this point
   233  	return true, nil
   234  }