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