github.com/swisscom/cloudfoundry-cli@v7.1.0+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 }