github.com/mook-as/cf-cli@v7.0.0-beta.28.0.20200120190804-b91c115fae48+incompatible/actor/v2action/application_instance_with_stats.go (about)

     1  package v2action
     2  
     3  import (
     4  	"fmt"
     5  	"sort"
     6  	"strings"
     7  	"time"
     8  
     9  	"code.cloudfoundry.org/cli/actor/actionerror"
    10  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccerror"
    11  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccv2"
    12  )
    13  
    14  type ApplicationInstanceWithStats struct {
    15  	// CPU is the instance's CPU utilization percentage.
    16  	CPU float64
    17  
    18  	// Details are arbitrary information about the instance.
    19  	Details string
    20  
    21  	// Disk is the instance's disk usage in bytes.
    22  	Disk int64
    23  
    24  	// DiskQuota is the instance's allowed disk usage in bytes.
    25  	DiskQuota int64
    26  
    27  	// ID is the instance ID.
    28  	ID int
    29  
    30  	// IsolationSegment that the app instance is currently running on.
    31  	IsolationSegment string
    32  
    33  	// Memory is the instance's memory usage in bytes.
    34  	Memory int64
    35  
    36  	// MemoryQuota is the instance's allowed memory usage in bytes.
    37  	MemoryQuota int64
    38  
    39  	// Since is the Unix time stamp that represents the time the instance was
    40  	// created.
    41  	Since float64
    42  
    43  	// State is the instance's state.
    44  	State ApplicationInstanceState
    45  }
    46  
    47  // newApplicationInstanceWithStats returns a pointer to a new
    48  // ApplicationInstance.
    49  func newApplicationInstanceWithStats(id int) ApplicationInstanceWithStats {
    50  	return ApplicationInstanceWithStats{ID: id}
    51  }
    52  
    53  func (instance ApplicationInstanceWithStats) TimeSinceCreation() time.Time {
    54  	return time.Unix(int64(instance.Since), 0)
    55  }
    56  
    57  func (instance *ApplicationInstanceWithStats) setInstance(ccAppInstance ApplicationInstance) {
    58  	instance.Details = ccAppInstance.Details
    59  	instance.Since = ccAppInstance.Since
    60  	instance.State = ApplicationInstanceState(ccAppInstance.State)
    61  }
    62  
    63  func (instance *ApplicationInstanceWithStats) setStats(ccAppStats ccv2.ApplicationInstanceStatus) {
    64  	instance.CPU = ccAppStats.CPU
    65  	instance.Disk = ccAppStats.Disk
    66  	instance.DiskQuota = ccAppStats.DiskQuota
    67  	instance.Memory = ccAppStats.Memory
    68  	instance.MemoryQuota = ccAppStats.MemoryQuota
    69  	instance.IsolationSegment = ccAppStats.IsolationSegment
    70  }
    71  
    72  func (instance *ApplicationInstanceWithStats) incomplete() {
    73  	instance.Details = strings.TrimSpace(fmt.Sprintf("%s (%s)", instance.Details, "Unable to retrieve information"))
    74  }
    75  
    76  func (actor Actor) GetApplicationInstancesWithStatsByApplication(guid string) ([]ApplicationInstanceWithStats, Warnings, error) {
    77  	var allWarnings Warnings
    78  
    79  	appInstanceStats, apiWarnings, err := actor.CloudControllerClient.GetApplicationApplicationInstanceStatuses(guid)
    80  	allWarnings = append(allWarnings, apiWarnings...)
    81  
    82  	switch err.(type) {
    83  	case ccerror.ResourceNotFoundError, ccerror.ApplicationStoppedStatsError:
    84  		return nil, allWarnings, actionerror.ApplicationInstancesNotFoundError{ApplicationGUID: guid}
    85  	case nil:
    86  		// continue
    87  	default:
    88  		return nil, allWarnings, err
    89  	}
    90  
    91  	appInstances, warnings, err := actor.GetApplicationInstancesByApplication(guid)
    92  	allWarnings = append(allWarnings, warnings...)
    93  	if err != nil {
    94  		return nil, allWarnings, err
    95  	}
    96  
    97  	returnedInstances := combineStatsAndInstances(appInstanceStats, appInstances)
    98  
    99  	sort.Slice(returnedInstances, func(i int, j int) bool { return returnedInstances[i].ID < returnedInstances[j].ID })
   100  
   101  	return returnedInstances, allWarnings, err
   102  }
   103  
   104  func combineStatsAndInstances(appInstanceStats map[int]ccv2.ApplicationInstanceStatus, appInstances map[int]ApplicationInstance) []ApplicationInstanceWithStats {
   105  	returnedInstances := []ApplicationInstanceWithStats{}
   106  	seenStatuses := make(map[int]bool, len(appInstanceStats))
   107  
   108  	for id, appInstanceStat := range appInstanceStats {
   109  		seenStatuses[id] = true
   110  
   111  		returnedInstance := newApplicationInstanceWithStats(id)
   112  		returnedInstance.setStats(appInstanceStat)
   113  
   114  		if appInstance, found := appInstances[id]; found {
   115  			returnedInstance.setInstance(appInstance)
   116  		} else {
   117  			returnedInstance.incomplete()
   118  		}
   119  
   120  		returnedInstances = append(returnedInstances, returnedInstance)
   121  	}
   122  
   123  	// add instances that are missing stats
   124  	for index, appInstance := range appInstances {
   125  		if _, found := seenStatuses[index]; !found {
   126  			returnedInstance := newApplicationInstanceWithStats(index)
   127  			returnedInstance.setInstance(appInstance)
   128  			returnedInstance.incomplete()
   129  
   130  			returnedInstances = append(returnedInstances, returnedInstance)
   131  		}
   132  	}
   133  
   134  	return returnedInstances
   135  }