/**
* Copyright 2011 LiveRamp
*
* 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.
*/
package com.liveramp.hank.coordinator;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.TreeSet;
import com.google.common.collect.Sets;
import com.liveramp.hank.partition_server.FilesystemStatisticsAggregator;
import com.liveramp.hank.partition_server.RuntimeStatisticsAggregator;
public final class RingGroups {
private RingGroups() {
}
public static boolean isUpToDate(RingGroup ringGroup) throws IOException {
return isUpToDate(ringGroup, ringGroup.getDomainGroup());
}
public static boolean isUpToDate(RingGroup ringGroup, DomainGroup domainGroup) throws IOException {
for (Ring ring : ringGroup.getRings()) {
if (!Rings.isUpToDate(ring, domainGroup)) {
return false;
}
}
return true;
}
// Return true iff each host is either up to date or not serving any data
public static boolean isServingOnlyUpToDate(RingGroup ringGroup) throws IOException {
DomainGroup domainGroup = ringGroup.getDomainGroup();
for (Ring ring : ringGroup.getRings()) {
for (Host host : ring.getHosts()) {
if (host.getState() == HostState.SERVING && !Hosts.isUpToDate(host, domainGroup)) {
return false;
}
}
}
return true;
}
// Return true iff each host is either up to date or serving more recent versions, or not serving any data
public static boolean isServingOnlyUpToDateOrMoreRecent(RingGroup ringGroup, List<DomainAndVersion> domainVersions) throws IOException {
for (Ring ring : ringGroup.getRings()) {
for (Host host : ring.getHosts()) {
if (host.getState() == HostState.SERVING && !Hosts.isUpToDateOrMoreRecent(host, domainVersions)) {
return false;
}
}
}
return true;
}
public static UpdateProgressAggregator computeUpdateProgress(RingGroup ringGroup,
DomainGroup domainGroup) throws IOException {
UpdateProgressAggregator result = new UpdateProgressAggregator();
for (Ring ring : ringGroup.getRings()) {
result.aggregate(Rings.computeUpdateProgress(ring, domainGroup));
}
return result;
}
public static int getNumHosts(RingGroup ringGroup) {
int result = 0;
for (Ring ring : ringGroup.getRings()) {
result += ring.getHosts().size();
}
return result;
}
public static Set<Host> getHosts(RingGroup ringGroup) {
TreeSet<Host> result = new TreeSet<Host>();
for (Ring ring : ringGroup.getRings()) {
result.addAll(ring.getHosts());
}
return result;
}
public static Set<Host> getHostsInState(RingGroup ringGroup, HostState state) throws IOException {
Set<Host> result = new TreeSet<Host>();
for (Ring ring : ringGroup.getRings()) {
result.addAll(Rings.getHostsInState(ring, state));
}
return result;
}
public static ServingStatusAggregator
computeServingStatusAggregator(RingGroup ringGroup, DomainGroup domainGroup) throws IOException {
ServingStatusAggregator servingStatusAggregator = new ServingStatusAggregator();
for (Ring ring : ringGroup.getRings()) {
servingStatusAggregator.aggregate(Rings.computeServingStatusAggregator(ring, domainGroup));
}
return servingStatusAggregator;
}
public static Map<Ring, Map<Host, Map<Domain, RuntimeStatisticsAggregator>>>
computeRuntimeStatistics(Coordinator coordinator, RingGroup ringGroup) throws IOException {
Map<Ring, Map<Host, Map<Domain, RuntimeStatisticsAggregator>>> result =
new HashMap<Ring, Map<Host, Map<Domain, RuntimeStatisticsAggregator>>>();
for (Ring ring : ringGroup.getRings()) {
result.put(ring, Rings.computeRuntimeStatistics(coordinator, ring));
}
return result;
}
public static RuntimeStatisticsAggregator
computeRuntimeStatisticsForRingGroup(
Map<Ring, Map<Host, Map<Domain, RuntimeStatisticsAggregator>>> runtimeStatistics) {
List<RuntimeStatisticsAggregator> runtimeStatisticsAggregators = new ArrayList<RuntimeStatisticsAggregator>();
for (Map.Entry<Ring, Map<Host, Map<Domain, RuntimeStatisticsAggregator>>> entry1 : runtimeStatistics.entrySet()) {
for (Map.Entry<Host, Map<Domain, RuntimeStatisticsAggregator>> entry2 : entry1.getValue().entrySet()) {
for (Map.Entry<Domain, RuntimeStatisticsAggregator> entry3 : entry2.getValue().entrySet()) {
runtimeStatisticsAggregators.add(entry3.getValue());
}
}
}
return RuntimeStatisticsAggregator.combine(runtimeStatisticsAggregators);
}
public static RuntimeStatisticsAggregator
computeRuntimeStatisticsForRing(
Map<Ring, Map<Host, Map<Domain, RuntimeStatisticsAggregator>>> runtimeStatistics, Ring ring) {
if (runtimeStatistics.containsKey(ring)) {
return Rings.computeRuntimeStatisticsForRing(runtimeStatistics.get(ring));
} else {
return new RuntimeStatisticsAggregator();
}
}
public static SortedMap<Domain, RuntimeStatisticsAggregator>
computeRuntimeStatisticsForDomains(
Map<Ring, Map<Host, Map<Domain, RuntimeStatisticsAggregator>>> runtimeStatistics) {
// Build lists of aggregators
Map<Domain, List<RuntimeStatisticsAggregator>> runtimeStatisticsAggregators = new HashMap<Domain, List<RuntimeStatisticsAggregator>>();
for (Map.Entry<Ring, Map<Host, Map<Domain, RuntimeStatisticsAggregator>>> entry1 : runtimeStatistics.entrySet()) {
for (Map.Entry<Host, Map<Domain, RuntimeStatisticsAggregator>> entry2 : entry1.getValue().entrySet()) {
for (Map.Entry<Domain, RuntimeStatisticsAggregator> entry3 : entry2.getValue().entrySet()) {
List<RuntimeStatisticsAggregator> aggregators = runtimeStatisticsAggregators.get(entry3.getKey());
if (aggregators == null) {
aggregators = new ArrayList<RuntimeStatisticsAggregator>();
runtimeStatisticsAggregators.put(entry3.getKey(), aggregators);
}
aggregators.add(entry3.getValue());
}
}
}
// Build result
SortedMap<Domain, RuntimeStatisticsAggregator> result = new TreeMap<Domain, RuntimeStatisticsAggregator>();
for (Map.Entry<Domain, List<RuntimeStatisticsAggregator>> entry : runtimeStatisticsAggregators.entrySet()) {
result.put(entry.getKey(), RuntimeStatisticsAggregator.combine(entry.getValue()));
}
return result;
}
public static Map<Ring, Map<Host, Map<String, FilesystemStatisticsAggregator>>>
computeFilesystemStatistics(RingGroup ringGroup) throws IOException {
Map<Ring, Map<Host, Map<String, FilesystemStatisticsAggregator>>> result =
new HashMap<Ring, Map<Host, Map<String, FilesystemStatisticsAggregator>>>();
for (Ring ring : ringGroup.getRings()) {
result.put(ring, Rings.computeFilesystemStatistics(ring));
}
return result;
}
public static FilesystemStatisticsAggregator
computeFilesystemStatisticsForRingGroup(
Map<Ring, Map<Host, Map<String, FilesystemStatisticsAggregator>>> filesystemStatistics) {
FilesystemStatisticsAggregator result = new FilesystemStatisticsAggregator();
for (Map.Entry<Ring, Map<Host, Map<String, FilesystemStatisticsAggregator>>> entry1 : filesystemStatistics.entrySet()) {
for (Map.Entry<Host, Map<String, FilesystemStatisticsAggregator>> entry2 : entry1.getValue().entrySet()) {
Set<String> hostAndFilesystemRootsAdded = new HashSet<String>();
for (Map.Entry<String, FilesystemStatisticsAggregator> entry3 : entry2.getValue().entrySet()) {
String hostAndFilesystemRoot = entry2.getKey().getAddress().getHostName() + entry3.getKey();
if (!hostAndFilesystemRootsAdded.contains(hostAndFilesystemRoot)) {
hostAndFilesystemRootsAdded.add(hostAndFilesystemRoot);
result.add(entry3.getValue());
}
}
}
}
return result;
}
public static FilesystemStatisticsAggregator
computeFilesystemStatisticsForRing(
Map<Ring, Map<Host, Map<String, FilesystemStatisticsAggregator>>> filesystemStatistics, Ring ring) {
if (filesystemStatistics.containsKey(ring)) {
return Rings.computeFilesystemStatisticsForRing(filesystemStatistics.get(ring));
} else {
return new FilesystemStatisticsAggregator();
}
}
public static Set<Host> getHostsNotUpToDate(RingGroup ringGroup, Collection<DomainAndVersion> versions) throws IOException {
Set<Host> outOfDateHosts = Sets.newHashSet();
for (Ring ring : ringGroup.getRings()) {
for (Host host : ring.getHosts()) {
if (!Hosts.isUpToDateOrMoreRecent(host, versions)) {
outOfDateHosts.add(host);
}
}
}
return outOfDateHosts;
}
}