use of com.yahoo.vespa.applicationmodel.HostName in project vespa by vespa-engine.
the class HttpPatchTest method clientPatchRequestUsingProxyClass.
@Test
public void clientPatchRequestUsingProxyClass() throws Exception {
final URI targetUri = target(TestResourceApi.PATH).getUri();
final HostName apiHost = new HostName(targetUri.getHost());
final int apiPort = targetUri.getPort();
final String apiPath = targetUri.getPath();
final JaxRsClientFactory jaxRsClientFactory = new JerseyJaxRsClientFactory();
final JaxRsStrategyFactory factory = new JaxRsStrategyFactory(Collections.singleton(apiHost), apiPort, jaxRsClientFactory, "http");
final JaxRsStrategy<TestResourceApi> client = factory.apiNoRetries(TestResourceApi.class, apiPath);
final String responseBody;
responseBody = client.apply(api -> api.doPatch(REQUEST_BODY));
assertThat(testResourceSingleton.invocation.get(60, TimeUnit.SECONDS), is(REQUEST_BODY));
assertThat(responseBody, is(REQUEST_BODY));
}
use of com.yahoo.vespa.applicationmodel.HostName in project vespa by vespa-engine.
the class JaxRsStrategyFactory method apiNoRetries.
public <T> JaxRsStrategy<T> apiNoRetries(final Class<T> apiClass, final String pathPrefix) {
Objects.requireNonNull(apiClass, "apiClass argument may not be null");
Objects.requireNonNull(pathPrefix, "pathPrefix argument may not be null");
final HostName hostName = getRandom(hostNames);
return new NoRetryJaxRsStrategy<T>(hostName, port, jaxRsClientFactory, apiClass, pathPrefix, scheme);
}
use of com.yahoo.vespa.applicationmodel.HostName in project vespa by vespa-engine.
the class MetricsReporter method updateNodeMetrics.
private void updateNodeMetrics(Node node, Map<HostName, List<ServiceInstance>> servicesByHost) {
Metric.Context context;
Optional<Allocation> allocation = node.allocation();
if (allocation.isPresent()) {
ApplicationId applicationId = allocation.get().owner();
context = getContextAt("state", node.state().name(), "host", node.hostname(), "tenantName", applicationId.tenant().value(), "applicationId", applicationId.serializedForm().replace(':', '.'), "app", toApp(applicationId), "clustertype", allocation.get().membership().cluster().type().name(), "clusterid", allocation.get().membership().cluster().id().value());
long wantedRestartGeneration = allocation.get().restartGeneration().wanted();
metric.set("wantedRestartGeneration", wantedRestartGeneration, context);
long currentRestartGeneration = allocation.get().restartGeneration().current();
metric.set("currentRestartGeneration", currentRestartGeneration, context);
boolean wantToRestart = currentRestartGeneration < wantedRestartGeneration;
metric.set("wantToRestart", wantToRestart ? 1 : 0, context);
Version wantedVersion = allocation.get().membership().cluster().vespaVersion();
double wantedVersionNumber = getVersionAsNumber(wantedVersion);
metric.set("wantedVespaVersion", wantedVersionNumber, context);
Optional<Version> currentVersion = node.status().vespaVersion();
boolean converged = currentVersion.isPresent() && currentVersion.get().equals(wantedVersion);
metric.set("wantToChangeVespaVersion", converged ? 0 : 1, context);
} else {
context = getContextAt("state", node.state().name(), "host", node.hostname());
}
Optional<Version> currentVersion = node.status().vespaVersion();
// Node repo checks for !isEmpty(), so let's do that here too.
if (currentVersion.isPresent() && !currentVersion.get().isEmpty()) {
double currentVersionNumber = getVersionAsNumber(currentVersion.get());
metric.set("currentVespaVersion", currentVersionNumber, context);
}
long wantedRebootGeneration = node.status().reboot().wanted();
metric.set("wantedRebootGeneration", wantedRebootGeneration, context);
long currentRebootGeneration = node.status().reboot().current();
metric.set("currentRebootGeneration", currentRebootGeneration, context);
boolean wantToReboot = currentRebootGeneration < wantedRebootGeneration;
metric.set("wantToReboot", wantToReboot ? 1 : 0, context);
metric.set("wantToRetire", node.status().wantToRetire() ? 1 : 0, context);
metric.set("wantToDeprovision", node.status().wantToDeprovision() ? 1 : 0, context);
metric.set("hardwareFailure", node.status().hardwareFailureDescription().isPresent() ? 1 : 0, context);
metric.set("hardwareDivergence", node.status().hardwareDivergence().isPresent() ? 1 : 0, context);
try {
HostStatus status = orchestrator.getNodeStatus(new HostName(node.hostname()));
boolean allowedToBeDown = status == HostStatus.ALLOWED_TO_BE_DOWN;
metric.set("allowedToBeDown", allowedToBeDown ? 1 : 0, context);
} catch (HostNameNotFoundException e) {
// Ignore
}
long numberOfServices;
HostName hostName = new HostName(node.hostname());
List<ServiceInstance> services = servicesByHost.get(hostName);
if (services == null) {
numberOfServices = 0;
} else {
Map<ServiceStatus, Long> servicesCount = services.stream().collect(Collectors.groupingBy(ServiceInstance::serviceStatus, Collectors.counting()));
numberOfServices = servicesCount.values().stream().mapToLong(Long::longValue).sum();
metric.set("numberOfServicesUp", servicesCount.getOrDefault(ServiceStatus.UP, 0L), context);
metric.set("numberOfServicesNotChecked", servicesCount.getOrDefault(ServiceStatus.NOT_CHECKED, 0L), context);
long numberOfServicesDown = servicesCount.getOrDefault(ServiceStatus.DOWN, 0L);
metric.set("numberOfServicesDown", numberOfServicesDown, context);
metric.set("someServicesDown", (numberOfServicesDown > 0 ? 1 : 0), context);
boolean badNode = NodeFailer.badNode(services);
metric.set("nodeFailerBadNode", (badNode ? 1 : 0), context);
boolean nodeDownInNodeRepo = node.history().event(History.Event.Type.down).isPresent();
metric.set("downInNodeRepo", (nodeDownInNodeRepo ? 1 : 0), context);
}
metric.set("numberOfServices", numberOfServices, context);
}
use of com.yahoo.vespa.applicationmodel.HostName in project vespa by vespa-engine.
the class RetiredExpirer method maintain.
@Override
protected void maintain() {
List<Node> activeNodes = nodeRepository().getNodes(Node.State.active);
Map<ApplicationId, List<Node>> retiredNodesByApplication = activeNodes.stream().filter(node -> node.allocation().isPresent()).filter(node -> node.allocation().get().membership().retired()).collect(Collectors.groupingBy(node -> node.allocation().get().owner()));
for (Map.Entry<ApplicationId, List<Node>> entry : retiredNodesByApplication.entrySet()) {
ApplicationId application = entry.getKey();
List<Node> retiredNodes = entry.getValue();
try {
Optional<Deployment> deployment = deployer.deployFromLocalActive(application);
// this will be done at another config server
if (!deployment.isPresent())
continue;
List<Node> nodesToRemove = retiredNodes.stream().filter(this::canRemove).collect(Collectors.toList());
if (nodesToRemove.isEmpty()) {
continue;
}
nodeRepository().setRemovable(application, nodesToRemove);
deployment.get().activate();
String nodeList = nodesToRemove.stream().map(Node::hostname).collect(Collectors.joining(", "));
log.info("Redeployed " + application + " to deactivate retired nodes: " + nodeList);
} catch (RuntimeException e) {
String nodeList = retiredNodes.stream().map(Node::hostname).collect(Collectors.joining(", "));
log.log(Level.WARNING, "Exception trying to deactivate retired nodes from " + application + ": " + nodeList, e);
}
}
}
use of com.yahoo.vespa.applicationmodel.HostName in project vespa by vespa-engine.
the class RetiredExpirer method canRemove.
/**
* Checks if the node can be removed:
* if the node is a docker host, it will only be removed if it has no children,
* or all its children are parked or failed
* Otherwise, a removal is allowed if either of these are true:
* - The node has been in state {@link History.Event.Type#retired} for longer than {@link #retiredExpiry}
* - Orchestrator allows it
*/
private boolean canRemove(Node node) {
if (node.type().isDockerHost()) {
return nodeRepository().getChildNodes(node.hostname()).stream().allMatch(child -> child.state() == Node.State.parked || child.state() == Node.State.failed);
}
Optional<Instant> timeOfRetiredEvent = node.history().event(History.Event.Type.retired).map(History.Event::at);
Optional<Instant> retireAfter = timeOfRetiredEvent.map(retiredEvent -> retiredEvent.plus(retiredExpiry));
boolean shouldRetireNowBecauseExpried = retireAfter.map(time -> time.isBefore(clock.instant())).orElse(false);
if (shouldRetireNowBecauseExpried) {
return true;
}
try {
orchestrator.acquirePermissionToRemove(new HostName(node.hostname()));
return true;
} catch (OrchestrationException e) {
log.info("Did not get permission to remove retired " + node + ": " + e.getMessage());
return false;
}
}
Aggregations