blob: 9a54fc8dfdc7ffcfe0d814d0413c9c3c272698d1 [file] [log] [blame]
/*******************************************************************************
* Copyright 2017 General Electric Company
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*******************************************************************************/
package com.ge.predix.acs.monitoring;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthAggregator;
import org.springframework.boot.actuate.health.Status;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
@Component
// Modified version of org.springframework.boot.actuate.health.OrderedHealthAggregator
public class AcsHealthAggregator implements HealthAggregator {
static final Status DEGRADED_STATUS = new Status(AcsMonitoringUtilities.HealthCode.DEGRADED.toString());
private List<String> statusOrder;
AcsHealthAggregator() {
this.setStatusOrder(Status.DOWN, Status.OUT_OF_SERVICE, DEGRADED_STATUS, Status.UP, Status.UNKNOWN);
}
void setStatusOrder(final Status... statusOrder) {
String[] order = new String[statusOrder.length];
for (int i = 0; i < statusOrder.length; ++i) {
order[i] = statusOrder[i].getCode();
}
this.setStatusOrder(Arrays.asList(order));
}
void setStatusOrder(final List<String> statusOrder) {
Assert.notNull(statusOrder, "StatusOrder must not be null");
this.statusOrder = statusOrder;
}
@Override
public final Health aggregate(final Map<String, Health> healths) {
List<Status> statusCandidates = new ArrayList<>();
for (Map.Entry<String, Health> entry : healths.entrySet()) {
Status status = entry.getValue().getStatus();
if (entry.getKey().toLowerCase().contains("cache")) {
if (status.equals(Status.DOWN)) {
statusCandidates.add(DEGRADED_STATUS);
} else if (status.equals(Status.UNKNOWN)) {
statusCandidates.add(Status.UP);
}
} else {
statusCandidates.add(entry.getValue().getStatus());
}
}
Status status = this.aggregateStatus(statusCandidates);
Map<String, Object> details = aggregateDetails(healths);
return new Health.Builder(status, details).build();
}
private Status aggregateStatus(final List<Status> candidates) {
// Only sort those status instances that we know about
List<Status> filteredCandidates = new ArrayList<>();
for (Status candidate : candidates) {
if (this.statusOrder.contains(candidate.getCode())) {
filteredCandidates.add(candidate);
}
}
// If no status is given return UNKNOWN
if (filteredCandidates.isEmpty()) {
return Status.UNKNOWN;
}
// Sort given Status instances by configured order
filteredCandidates.sort(new StatusComparator(this.statusOrder));
return filteredCandidates.get(0);
}
private static Map<String, Object> aggregateDetails(final Map<String, Health> healths) {
return new LinkedHashMap<>(healths);
}
private class StatusComparator implements Comparator<Status> {
private final List<String> statusOrder;
StatusComparator(final List<String> statusOrder) {
this.statusOrder = statusOrder;
}
@Override
public int compare(final Status s1, final Status s2) {
int i1 = this.statusOrder.indexOf(s1.getCode());
int i2 = this.statusOrder.indexOf(s2.getCode());
if (i1 < i2) {
return -1;
} else if (i1 == i2) {
return s1.getCode().compareTo(s2.getCode());
} else {
return 1;
}
}
}
}