@Override public ClusterId clusterId() { return serviceCluster.clusterId(); }
@Override public int percentageOfServicesDown() { int numberOfServicesDown = servicesDownAndNotInGroup.size() + servicesDownInGroup.size(); return numberOfServicesDown * 100 / serviceCluster.serviceInstances().size(); }
@Override public ServiceType serviceType() { return serviceCluster.serviceType(); }
public static int getSuspendPercentageAllowed(ServiceCluster serviceCluster) { if (VespaModelUtil.ADMIN_CLUSTER_ID.equals(serviceCluster.clusterId())) { if (VespaModelUtil.SLOBROK_SERVICE_TYPE.equals(serviceCluster.serviceType())) { return SUSPENSION_ALLOW_MINIMAL; } return SUSPENSION_ALLOW_ALL; } if (VespaModelUtil.isStorage(serviceCluster)) { return SUSPENSION_ALLOW_MINIMAL; } return SUSPENSION_ALLOW_TEN_PERCENT; }
/** * @return The set of all Cluster Controller service instances for the application. */ public static List<HostName> getClusterControllerInstancesInOrder(ApplicationInstance application, ClusterId contentClusterId) { Set<ServiceCluster> controllerClusters = getClusterControllerServiceClusters(application); Collection<ServiceCluster> controllerClustersForContentCluster = filter(controllerClusters, contentClusterId); Set<ServiceInstance> clusterControllerInstances; if (controllerClustersForContentCluster.size() == 1) { clusterControllerInstances = first(controllerClustersForContentCluster).serviceInstances(); } else if (controllerClusters.size() == 1) { ServiceCluster cluster = first(controllerClusters); log.warning("No cluster controller cluster for content cluster " + contentClusterId + ", using the only cluster controller cluster available: " + cluster.clusterId()); clusterControllerInstances = cluster.serviceInstances(); } else { throw new RuntimeException("Failed getting cluster controller for content cluster " + contentClusterId + ". Available clusters = " + controllerClusters + ", matching clusters = " + controllerClustersForContentCluster); } return clusterControllerInstances.stream() .sorted(CLUSTER_CONTROLLER_INDEX_COMPARATOR) .map(serviceInstance -> serviceInstance.hostName()) .collect(Collectors.toList()); }
@Override public Map<ApplicationInstanceReference, ApplicationInstance> getAllApplicationInstances() { // Convert apps information to the response payload to return Map<ApplicationInstanceReference, ApplicationInstance> status = new HashMap<>(); for (Map.Entry<ApplicationId, MockDeployer.ApplicationContext> app : apps.entrySet()) { Set<ServiceInstance> serviceInstances = new HashSet<>(); for (Node node : nodeRepository.getNodes(app.getValue().id(), Node.State.active)) { serviceInstances.add(new ServiceInstance(new ConfigId("configid"), new HostName(node.hostname()), getHostStatus(node.hostname()))); } Set<ServiceCluster> serviceClusters = new HashSet<>(); serviceClusters.add(new ServiceCluster(new ClusterId(app.getValue().clusterContexts().get(0).cluster().id().value()), new ServiceType("serviceType"), serviceInstances)); TenantId tenantId = new TenantId(app.getKey().tenant().value()); ApplicationInstanceId applicationInstanceId = new ApplicationInstanceId(app.getKey().application().value()); status.put(new ApplicationInstanceReference(tenantId, applicationInstanceId), new ApplicationInstance(tenantId, applicationInstanceId, serviceClusters)); } return status; }
@Override public GetHostResponse getHost(String hostNameString) { HostName hostName = new HostName(hostNameString); try { Host host = orchestrator.getHost(hostName); URI applicationUri = uriInfo.getBaseUriBuilder() .path(InstanceResource.class) .path(host.getApplicationInstanceReference().asString()) .build(); List<HostService> hostServices = host.getServiceInstances().stream() .map(serviceInstance -> new HostService( serviceInstance.getServiceCluster().clusterId().s(), serviceInstance.getServiceCluster().serviceType().s(), serviceInstance.configId().s(), serviceInstance.serviceStatus().name())) .collect(Collectors.toList()); return new GetHostResponse( host.getHostName().s(), host.getHostStatus().name(), applicationUri.toString(), hostServices); } catch (UncheckedTimeoutException e) { log.log(LogLevel.INFO, "Failed to get host " + hostName + ": " + e.getMessage()); throw webExceptionFromTimeout("getHost", hostName, e); } catch (HostNameNotFoundException e) { log.log(LogLevel.INFO, "Host not found: " + hostName); throw new NotFoundException(e); } }
@Override public int percentageOfServicesDownIfGroupIsAllowedToBeDown() { int numberOfServicesDown = servicesDownAndNotInGroup.size() + servicesInGroup.size(); return numberOfServicesDown * 100 / serviceCluster.serviceInstances().size(); }
/** * @return true iff the service cluster is a content service cluster. */ public static boolean isContent(ServiceCluster cluster) { return DISTRIBUTOR_SERVICE_TYPE.equals(cluster.serviceType()) || SEARCHNODE_SERVICE_TYPE.equals(cluster.serviceType()) || STORAGENODE_SERVICE_TYPE.equals(cluster.serviceType()); }
private static Collection<ServiceCluster> filter(Set<ServiceCluster> controllerClusters, ClusterId contentClusterId) { ClusterId clusterControllerClusterId = new ClusterId(contentClusterId.s() + "-controllers"); return controllerClusters.stream(). filter(cluster -> cluster.clusterId().equals(clusterControllerClusterId)). collect(Collectors.toList()); }
public static Set<HostName> getHostsUsedByServiceCluster(ServiceCluster serviceCluster) { return serviceCluster.serviceInstances().stream() .map(ServiceInstance::hostName) .collect(toSet()); }
/** * Note that a search node service cluster (service type searchnode aka proton) is * always accompanied by a storage node service cluster, but not vice versa. * * @return true iff the service cluster consists of storage nodes (proton or vds). */ public static boolean isStorage(ServiceCluster cluster) { return STORAGENODE_SERVICE_TYPE.equals(cluster.serviceType()); }
private static boolean clusterHasInstanceOnHost(ServiceCluster cluster, HostName hostName) { return cluster.serviceInstances().stream().anyMatch(service -> Objects.equals(hostName, service.hostName())); }
public static boolean isClusterController(ServiceCluster cluster) { return CLUSTER_CONTROLLER_SERVICE_TYPE.equals(cluster.serviceType()); }
private static boolean applicationInstanceUsesHost(ApplicationInstance applicationInstance, HostName hostName) { return applicationInstance.serviceClusters().stream() .anyMatch(serviceCluster -> serviceCluster.serviceInstances().stream() .anyMatch(serviceInstance -> serviceInstance.hostName().equals(hostName))); }
public static Stream<ServiceInstance> serviceInstancesOnHost(ServiceCluster serviceCluster, HostName hostName) { return serviceCluster.serviceInstances().stream() .filter(instance -> instance.hostName().equals(hostName)); }
public ClusterApiImpl(ApplicationApi applicationApi, ServiceCluster serviceCluster, NodeGroup nodeGroup, Map<HostName, HostStatus> hostStatusMap, ClusterControllerClientFactory clusterControllerClientFactory) { this.applicationApi = applicationApi; this.serviceCluster = serviceCluster; this.nodeGroup = nodeGroup; this.hostStatusMap = hostStatusMap; this.clusterControllerClientFactory = clusterControllerClientFactory; Map<Boolean, Set<ServiceInstance>> serviceInstancesByLocality = serviceCluster.serviceInstances().stream() .collect( Collectors.groupingBy( instance -> nodeGroup.contains(instance.hostName()), Collectors.toSet())); servicesInGroup = serviceInstancesByLocality.getOrDefault(true, Collections.emptySet()); servicesNotInGroup = serviceInstancesByLocality.getOrDefault(false, Collections.emptySet()); servicesDownInGroup = servicesInGroup.stream().filter(this::serviceEffectivelyDown).collect(Collectors.toSet()); servicesDownAndNotInGroup = servicesNotInGroup.stream().filter(this::serviceEffectivelyDown).collect(Collectors.toSet()); }
public static Optional<ServiceInstance> getStorageNodeAtHost(ApplicationInstance application, HostName hostName) { Set<ServiceInstance> storageNodesOnHost = application.serviceClusters().stream() .filter(VespaModelUtil::isStorage) .flatMap(cluster -> cluster.serviceInstances().stream()) .filter(service -> service.hostName().equals(hostName)) .collect(Collectors.toSet()); if (storageNodesOnHost.isEmpty()) { return Optional.empty(); } if (storageNodesOnHost.size() > 1) { throw new RuntimeException("Expected application " + application.applicationInstanceId() + " to have exactly one storage node service on host " + hostName + " but got " + storageNodesOnHost.size() + ": " + storageNodesOnHost); } return storageNodesOnHost.stream().findAny(); }
private static Set<ServiceCluster> getServiceClustersInGroup(NodeGroup nodeGroup) { ApplicationInstance applicationInstance = nodeGroup.getApplication(); Set<ServiceCluster> serviceClustersInGroup = new HashSet<>(); for (ServiceCluster cluster : applicationInstance.serviceClusters()) { for (ServiceInstance instance : cluster.serviceInstances()) { if (nodeGroup.contains(instance.hostName())) { serviceClustersInGroup.add(cluster); break; } } } return serviceClustersInGroup; }
@Override public Host getHost(HostName hostName) throws HostNameNotFoundException { ApplicationInstance applicationInstance = getApplicationInstance(hostName); List<ServiceInstance> serviceInstances = applicationInstance .serviceClusters().stream() .flatMap(cluster -> cluster.serviceInstances().stream()) .filter(serviceInstance -> hostName.equals(serviceInstance.hostName())) .collect(Collectors.toList()); HostStatus hostStatus = getNodeStatus(applicationInstance.reference(), hostName); return new Host(hostName, hostStatus, applicationInstance.reference(), serviceInstances); }