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