<T> T createClient(Class<T> apiClass, HostName hostName, int port, String pathPrefix, String scheme); }
public HostStateChangeDeniedException(HostName hostName, String constraintName, String message, Exception e) { this(hostName.s(), constraintName, Optional.empty(), message, e); }
@Override public int compareTo(StorageNode otherStorageNode) { if (!(otherStorageNode instanceof StorageNodeImpl)) { throw new IllegalArgumentException("Unable to compare our class to any StorageNode object"); } StorageNodeImpl that = (StorageNodeImpl) otherStorageNode; // We're guaranteed there's only one storage service per node. return this.storageService.hostName().compareTo(that.storageService.hostName()); } }
@Override public UpdateHostResponse suspend(String hostNameString) { HostName hostName = new HostName(hostNameString); try { orchestrator.suspend(hostName); } catch (HostNameNotFoundException e) { log.log(LogLevel.INFO, "Host not found: " + hostName); throw new NotFoundException(e); } catch (UncheckedTimeoutException e) { log.log(LogLevel.INFO, "Failed to suspend " + hostName + ": " + e.getMessage()); throw webExceptionFromTimeout("suspend", hostName, e); } catch (HostStateChangeDeniedException e) { log.log(LogLevel.INFO, "Failed to suspend " + hostName + ": " + e.getMessage()); throw webExceptionWithDenialReason("suspend", hostName, e); } return new UpdateHostResponse(hostName.s(), null); }
public static Stream<ServiceInstance> serviceInstancesOnHost(ServiceCluster serviceCluster, HostName hostName) { return serviceCluster.serviceInstances().stream() .filter(instance -> instance.hostName().equals(hostName)); }
@Override public UpdateHostResponse resume(final String hostNameString) { HostName hostName = new HostName(hostNameString); try { orchestrator.resume(hostName); } catch (HostNameNotFoundException e) { log.log(LogLevel.INFO, "Host not found: " + hostName); throw new NotFoundException(e); } catch (UncheckedTimeoutException e) { log.log(LogLevel.INFO, "Failed to resume " + hostName + ": " + e.getMessage()); throw webExceptionFromTimeout("resume", hostName, e); } catch (HostStateChangeDeniedException e) { log.log(LogLevel.INFO, "Failed to resume " + hostName + ": " + e.getMessage()); throw webExceptionWithDenialReason("resume", hostName, e); } return new UpdateHostResponse(hostName.s(), null); }
private static boolean applicationInstanceUsesHost(ApplicationInstance applicationInstance, HostName hostName) { return applicationInstance.serviceClusters().stream() .anyMatch(serviceCluster -> serviceCluster.serviceInstances().stream() .anyMatch(serviceInstance -> serviceInstance.hostName().equals(hostName))); }
@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); } }
private boolean nodeSuspended(Node node) { try { return orchestrator.getNodeStatus(new HostName(node.hostname())) == HostStatus.ALLOWED_TO_BE_DOWN; } catch (HostNameNotFoundException e) { // Treat it as not suspended return false; } }
private static String hostAllowedDownPath(ApplicationInstanceReference applicationInstanceReference, HostName hostname) { return hostsAllowedDownPath(applicationInstanceReference) + '/' + hostname.s(); }
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(); }
@Override public BatchOperationResult suspendAll(String parentHostnameString, List<String> hostnamesAsStrings) { HostName parentHostname = new HostName(parentHostnameString); List<HostName> hostnames = hostnamesAsStrings.stream().map(HostName::new).collect(Collectors.toList()); try { orchestrator.suspendAll(parentHostname, hostnames); } catch (BatchHostStateChangeDeniedException | UncheckedTimeoutException e) { log.log(LogLevel.DEBUG, "Failed to suspend nodes " + hostnames + " with parent host " + parentHostname, e); throw createWebApplicationException(e.getMessage(), Response.Status.CONFLICT); } catch (BatchHostNameNotFoundException e) { log.log(LogLevel.DEBUG, "Failed to suspend nodes " + hostnames + " with parent host " + parentHostname, e); // Note that we're returning BAD_REQUEST instead of NOT_FOUND because the resource identified // by the URL path was found. It's one of the hostnames in the request it failed to find. throw createWebApplicationException(e.getMessage(), Response.Status.BAD_REQUEST); } catch (BatchInternalErrorException e) { log.log(LogLevel.DEBUG, "Failed to suspend nodes " + hostnames + " with parent host " + parentHostname, e); throw createWebApplicationException(e.getMessage(), Response.Status.INTERNAL_SERVER_ERROR); } log.log(LogLevel.DEBUG, "Suspended " + hostnames + " with parent " + parentHostname); return BatchOperationResult.successResult(); }
@Override public Optional<ApplicationInstance> findInstanceByHost(HostName hostName) { Map<ApplicationInstanceReference, ApplicationInstance> instanceMap = serviceMonitor.getAllApplicationInstances(); List<ApplicationInstance> applicationInstancesUsingHost = instanceMap.entrySet().stream() .filter(entry -> applicationInstanceUsesHost(entry.getValue(), hostName)) .map(Map.Entry::getValue) .collect(Collectors.toList()); if (applicationInstancesUsingHost.isEmpty()) { return Optional.empty(); } if (applicationInstancesUsingHost.size() > 1) { throw new IllegalStateException( "Major assumption broken: Multiple application instances contain host " + hostName.s() + ": " + applicationInstancesUsingHost); } return Optional.of(applicationInstancesUsingHost.get(0)); }
@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); }
@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; }
private static WebApplicationException createWebException(String operationDescription, HostName hostname, Exception e, String constraint, String message) { HostStateChangeDenialReason hostStateChangeDenialReason = new HostStateChangeDenialReason( constraint, operationDescription + " failed: " + message); UpdateHostResponse response = new UpdateHostResponse(hostname.s(), hostStateChangeDenialReason); return new WebApplicationException( hostStateChangeDenialReason.toString(), e, Response.status(Response.Status.CONFLICT) .entity(response) .type(MediaType.APPLICATION_JSON_TYPE) .build()); } }
@Override public PatchHostResponse patch(String hostNameString, PatchHostRequest request) { HostName hostName = new HostName(hostNameString); if (request.state != null) { HostStatus state; try { state = HostStatus.valueOf(request.state); } catch (IllegalArgumentException dummy) { throw new BadRequestException("Bad state in request: '" + request.state + "'"); } try { orchestrator.setNodeStatus(hostName, state); } catch (HostNameNotFoundException e) { log.log(LogLevel.INFO, "Host not found: " + hostName); throw new NotFoundException(e); } catch (UncheckedTimeoutException e) { log.log(LogLevel.INFO, "Failed to patch " + hostName + ": " + e.getMessage()); throw webExceptionFromTimeout("patch", hostName, e); } catch (OrchestrationException e) { String message = "Failed to set " + hostName + " to " + state + ": " + e.getMessage(); log.log(LogLevel.INFO, message, e); throw new InternalServerErrorException(message); } } PatchHostResponse response = new PatchHostResponse(); response.description = "ok"; return response; }
/** * If the node is down (see {@link #badNode}), and there is no "down" history record, we add it. * Otherwise we remove any "down" history record. */ private void updateNodeDownState() { Map<String, Node> activeNodesByHostname = nodeRepository().getNodes(Node.State.active).stream() .collect(Collectors.toMap(Node::hostname, node -> node)); serviceMonitor.getServiceModelSnapshot().getServiceInstancesByHostName() .forEach((hostName, serviceInstances) -> { Node node = activeNodesByHostname.get(hostName.s()); if (node == null) return; if (badNode(serviceInstances)) { recordAsDown(node); } else { clearDownRecord(node); } }); }
orchestrator.acquirePermissionToRemove(new HostName(node.hostname())); log.info("Node " + node + " has been granted permission to be removed"); return true;
@Override public <T> T createClient(Class<T> apiClass, HostName hostName, int port, String pathPrefix, String scheme) { UriBuilder uriBuilder = UriBuilder.fromPath(pathPrefix).host(hostName.s()).port(port).scheme(scheme); return createClient(new Params<>(apiClass, uriBuilder.build())); } }