diff options
Diffstat (limited to 'orchestrator')
12 files changed, 69 insertions, 21 deletions
diff --git a/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/model/ApplicationApi.java b/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/model/ApplicationApi.java index 7e044379137..0ca509d13f1 100644 --- a/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/model/ApplicationApi.java +++ b/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/model/ApplicationApi.java @@ -1,6 +1,7 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.orchestrator.model; +import com.yahoo.config.provision.ApplicationId; import com.yahoo.vespa.applicationmodel.HostName; import com.yahoo.vespa.orchestrator.status.ApplicationInstanceStatus; import com.yahoo.vespa.orchestrator.status.HostStatus; @@ -11,7 +12,10 @@ import java.util.List; * The API a Policy has access to */ public interface ApplicationApi { - String applicationInfo(); + /** + * @return The 3-part application ID of the form tenant:name:instance. + */ + ApplicationId applicationId(); /** * The policy acts on some subset of nodes in the application. diff --git a/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/model/ApplicationApiImpl.java b/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/model/ApplicationApiImpl.java index e280341d02c..c5bcaf4de82 100644 --- a/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/model/ApplicationApiImpl.java +++ b/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/model/ApplicationApiImpl.java @@ -1,10 +1,12 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.orchestrator.model; +import com.yahoo.config.provision.ApplicationId; import com.yahoo.vespa.applicationmodel.ApplicationInstance; import com.yahoo.vespa.applicationmodel.HostName; import com.yahoo.vespa.applicationmodel.ServiceCluster; import com.yahoo.vespa.applicationmodel.ServiceInstance; +import com.yahoo.vespa.orchestrator.OrchestratorUtil; import com.yahoo.vespa.orchestrator.controller.ClusterControllerClientFactory; import com.yahoo.vespa.orchestrator.status.ApplicationInstanceStatus; import com.yahoo.vespa.orchestrator.status.HostStatus; @@ -44,8 +46,8 @@ public class ApplicationApiImpl implements ApplicationApi { } @Override - public String applicationInfo() { - return applicationInstance.reference().toString(); + public ApplicationId applicationId() { + return OrchestratorUtil.toApplicationId(applicationInstance.reference()); } private static Map<HostName, HostStatus> createHostStatusMap(Collection<HostName> hosts, @@ -113,13 +115,14 @@ public class ApplicationApiImpl implements ApplicationApi { .collect(Collectors.toList()); } - private static List<ClusterApi> makeClustersInOrder + private List<ClusterApi> makeClustersInOrder (NodeGroup nodeGroup, Map<HostName, HostStatus> hostStatusMap, ClusterControllerClientFactory clusterControllerClientFactory) { Set<ServiceCluster> clustersInGroup = getServiceClustersInGroup(nodeGroup); return clustersInGroup.stream() .map(serviceCluster -> new ClusterApiImpl( + this, serviceCluster, nodeGroup, hostStatusMap, diff --git a/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/model/ClusterApi.java b/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/model/ClusterApi.java index 1b536cce3b5..025d21316ef 100644 --- a/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/model/ClusterApi.java +++ b/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/model/ClusterApi.java @@ -7,6 +7,8 @@ import com.yahoo.vespa.applicationmodel.ServiceType; import java.util.Optional; public interface ClusterApi { + ApplicationApi getApplication(); + NodeGroup getNodeGroup(); String clusterInfo(); diff --git a/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/model/ClusterApiImpl.java b/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/model/ClusterApiImpl.java index dfa2610a130..d0217710bdb 100644 --- a/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/model/ClusterApiImpl.java +++ b/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/model/ClusterApiImpl.java @@ -5,10 +5,10 @@ import com.yahoo.vespa.applicationmodel.ClusterId; import com.yahoo.vespa.applicationmodel.HostName; import com.yahoo.vespa.applicationmodel.ServiceCluster; import com.yahoo.vespa.applicationmodel.ServiceInstance; +import com.yahoo.vespa.applicationmodel.ServiceStatus; import com.yahoo.vespa.applicationmodel.ServiceType; import com.yahoo.vespa.orchestrator.controller.ClusterControllerClientFactory; import com.yahoo.vespa.orchestrator.status.HostStatus; -import com.yahoo.vespa.applicationmodel.ServiceStatus; import java.util.Collections; import java.util.HashSet; @@ -19,6 +19,7 @@ import java.util.function.Predicate; import java.util.stream.Collectors; class ClusterApiImpl implements ClusterApi { + private final ApplicationApi applicationApi; private final ServiceCluster serviceCluster; private final NodeGroup nodeGroup; private final Map<HostName, HostStatus> hostStatusMap; @@ -28,10 +29,12 @@ class ClusterApiImpl implements ClusterApi { private final Set<ServiceInstance> servicesNotInGroup; private final Set<ServiceInstance> servicesDownAndNotInGroup; - public ClusterApiImpl(ServiceCluster serviceCluster, + 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; @@ -71,6 +74,11 @@ class ClusterApiImpl implements ClusterApi { } @Override + public ApplicationApi getApplication() { + return applicationApi; + } + + @Override public boolean noServicesInGroupIsUp() { return servicesDownInGroup.size() == servicesInGroup.size(); } diff --git a/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/model/VespaModelUtil.java b/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/model/VespaModelUtil.java index 40556eb2f40..4dd8133d2e9 100644 --- a/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/model/VespaModelUtil.java +++ b/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/model/VespaModelUtil.java @@ -1,6 +1,7 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.orchestrator.model; +import com.yahoo.config.provision.ApplicationId; import com.yahoo.vespa.applicationmodel.ApplicationInstance; import com.yahoo.vespa.applicationmodel.ClusterId; import com.yahoo.vespa.applicationmodel.ConfigId; @@ -29,10 +30,13 @@ import static com.yahoo.collections.CollectionUtil.first; * @author hakonhall */ public class VespaModelUtil { - private static final Logger log = Logger.getLogger(VespaModelUtil.class.getName()); + public static final ApplicationId ZONE_APPLICATION_ID = + ApplicationId.from("hosted-vespa", "routing", "default"); + public static final ClusterId ADMIN_CLUSTER_ID = new ClusterId("admin"); + public static final ClusterId NODE_ADMIN_CLUSTER_ID = new ClusterId("node-admin"); public static final ServiceType SLOBROK_SERVICE_TYPE = new ServiceType("slobrok"); public static final ServiceType CLUSTER_CONTROLLER_SERVICE_TYPE = new ServiceType("container-clustercontroller"); diff --git a/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/policy/ConcurrentSuspensionLimitForCluster.java b/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/policy/ConcurrentSuspensionLimitForCluster.java index 85750a9e9c8..215d9ed1b2d 100644 --- a/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/policy/ConcurrentSuspensionLimitForCluster.java +++ b/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/policy/ConcurrentSuspensionLimitForCluster.java @@ -7,6 +7,7 @@ package com.yahoo.vespa.orchestrator.policy; public enum ConcurrentSuspensionLimitForCluster { ONE_NODE(0), TEN_PERCENT(10), + TWENTY_PERCENT(20), ALL_NODES(100); int percentage; diff --git a/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/policy/HostedVespaClusterPolicy.java b/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/policy/HostedVespaClusterPolicy.java index 4f718af27b1..f45aa8c02ac 100644 --- a/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/policy/HostedVespaClusterPolicy.java +++ b/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/policy/HostedVespaClusterPolicy.java @@ -1,8 +1,8 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.orchestrator.policy; -import com.yahoo.vespa.orchestrator.model.VespaModelUtil; import com.yahoo.vespa.orchestrator.model.ClusterApi; +import com.yahoo.vespa.orchestrator.model.VespaModelUtil; import static com.yahoo.vespa.orchestrator.policy.HostedVespaPolicy.ENOUGH_SERVICES_UP_CONSTRAINT; @@ -64,6 +64,10 @@ public class HostedVespaClusterPolicy implements ClusterPolicy { // Non-private for testing purposes ConcurrentSuspensionLimitForCluster getConcurrentSuspensionLimit(ClusterApi clusterApi) { + if (clusterApi.isStorageCluster()) { + return ConcurrentSuspensionLimitForCluster.ONE_NODE; + } + if (VespaModelUtil.ADMIN_CLUSTER_ID.equals(clusterApi.clusterId())) { if (VespaModelUtil.SLOBROK_SERVICE_TYPE.equals(clusterApi.serviceType())) { return ConcurrentSuspensionLimitForCluster.ONE_NODE; @@ -72,8 +76,9 @@ public class HostedVespaClusterPolicy implements ClusterPolicy { return ConcurrentSuspensionLimitForCluster.ALL_NODES; } - if (clusterApi.isStorageCluster()) { - return ConcurrentSuspensionLimitForCluster.ONE_NODE; + if (clusterApi.getApplication().applicationId().equals(VespaModelUtil.ZONE_APPLICATION_ID) && + clusterApi.clusterId().equals(VespaModelUtil.NODE_ADMIN_CLUSTER_ID)) { + return ConcurrentSuspensionLimitForCluster.TWENTY_PERCENT; } return ConcurrentSuspensionLimitForCluster.TEN_PERCENT; diff --git a/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/policy/HostedVespaPolicy.java b/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/policy/HostedVespaPolicy.java index 49a7739c839..1e9efa2e700 100644 --- a/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/policy/HostedVespaPolicy.java +++ b/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/policy/HostedVespaPolicy.java @@ -1,6 +1,7 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.orchestrator.policy; +import com.yahoo.config.provision.ApplicationId; import com.yahoo.log.LogLevel; import com.yahoo.vespa.applicationmodel.ApplicationInstance; import com.yahoo.vespa.applicationmodel.HostName; @@ -22,7 +23,6 @@ import java.util.logging.Logger; */ public class HostedVespaPolicy implements Policy { - public static final String APPLICATION_SUSPENDED_CONSTRAINT = "application-suspended"; public static final String ENOUGH_SERVICES_UP_CONSTRAINT = "enough-services-up"; public static final String SET_NODE_STATE_CONSTRAINT = "controller-set-node-state"; @@ -81,8 +81,8 @@ public class HostedVespaPolicy implements Policy { throw new HostStateChangeDeniedException( applicationApi.getNodeGroup(), HostedVespaPolicy.APPLICATION_SUSPENDED_CONSTRAINT, - "Unable to test availability constraints as the application " + applicationApi.applicationInfo() - + " is allowed to be down"); + "Unable to test availability constraints as the application " + + applicationApi.applicationId() + " is allowed to be down"); } // Apply per-cluster policy diff --git a/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/model/ApplicationApiImplTest.java b/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/model/ApplicationApiImplTest.java index 3abffac3a9c..a712c1db3e8 100644 --- a/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/model/ApplicationApiImplTest.java +++ b/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/model/ApplicationApiImplTest.java @@ -19,10 +19,10 @@ public class ApplicationApiImplTest { final ModelTestUtils modelUtils = new ModelTestUtils(); @Test - public void testApplicationInfo() { + public void testApplicationId() { ApplicationApiImpl applicationApi = modelUtils.createApplicationApiImpl(modelUtils.createApplicationInstance(new ArrayList<>())); - assertEquals("tenant:application-name:foo:bar:default", applicationApi.applicationInfo()); + assertEquals("tenant:application-name:default", applicationApi.applicationId().serializedForm()); } @Test diff --git a/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/model/ClusterApiImplTest.java b/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/model/ClusterApiImplTest.java index d17ffd4452d..ad1ce647a7c 100644 --- a/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/model/ClusterApiImplTest.java +++ b/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/model/ClusterApiImplTest.java @@ -16,8 +16,10 @@ import java.util.Optional; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; public class ClusterApiImplTest { + final ApplicationApi applicationApi = mock(ApplicationApi.class); final ModelTestUtils modelUtils = new ModelTestUtils(); @Test @@ -42,6 +44,7 @@ public class ClusterApiImplTest { ); ClusterApiImpl clusterApi = new ClusterApiImpl( + applicationApi, serviceCluster, new NodeGroup(modelUtils.createApplicationInstance(new ArrayList<>()), hostName5), modelUtils.getHostStatusMap(), @@ -97,6 +100,7 @@ public class ClusterApiImplTest { boolean expectedNoServicesOutsideGroupIsDown, HostName... groupNodes) { ClusterApiImpl clusterApi = new ClusterApiImpl( + applicationApi, serviceCluster, new NodeGroup(modelUtils.createApplicationInstance(new ArrayList<>()), groupNodes), modelUtils.getHostStatusMap(), @@ -122,6 +126,7 @@ public class ClusterApiImplTest { ); ClusterApiImpl clusterApi = new ClusterApiImpl( + applicationApi, serviceCluster, new NodeGroup(modelUtils.createApplicationInstance(new ArrayList<>()), hostName1, hostName3), new HashMap<>(), diff --git a/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/policy/HostedVespaClusterPolicyTest.java b/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/policy/HostedVespaClusterPolicyTest.java index 0f56a620f1c..c316f79c3d2 100644 --- a/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/policy/HostedVespaClusterPolicyTest.java +++ b/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/policy/HostedVespaClusterPolicyTest.java @@ -1,15 +1,14 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.orchestrator.policy; -import com.yahoo.vespa.applicationmodel.ApplicationInstanceId; +import com.yahoo.config.provision.ApplicationId; import com.yahoo.vespa.applicationmodel.ClusterId; -import com.yahoo.vespa.applicationmodel.HostName; import com.yahoo.vespa.applicationmodel.ServiceType; -import com.yahoo.vespa.applicationmodel.TenantId; +import com.yahoo.vespa.orchestrator.model.ApplicationApi; import com.yahoo.vespa.orchestrator.model.ClusterApi; import com.yahoo.vespa.orchestrator.model.NodeGroup; import com.yahoo.vespa.orchestrator.model.VespaModelUtil; -import com.yahoo.vespa.orchestrator.status.MutableStatusRegistry; +import org.junit.Before; import org.junit.Test; import static org.junit.Assert.assertEquals; @@ -20,9 +19,15 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; public class HostedVespaClusterPolicyTest { + private ApplicationApi applicationApi = mock(ApplicationApi.class); private ClusterApi clusterApi = mock(ClusterApi.class); private HostedVespaClusterPolicy policy = spy(new HostedVespaClusterPolicy()); + @Before + public void setUp() { + when(clusterApi.getApplication()).thenReturn(applicationApi); + } + @Test public void testSlobrokSuspensionLimit() { when(clusterApi.clusterId()).thenReturn(VespaModelUtil.ADMIN_CLUSTER_ID); @@ -48,7 +53,17 @@ public class HostedVespaClusterPolicyTest { } @Test + public void testNodeAdminSuspensionLimit() { + when(applicationApi.applicationId()).thenReturn(VespaModelUtil.ZONE_APPLICATION_ID); + when(clusterApi.clusterId()).thenReturn(VespaModelUtil.NODE_ADMIN_CLUSTER_ID); + when(clusterApi.isStorageCluster()).thenReturn(false); + assertEquals(ConcurrentSuspensionLimitForCluster.TWENTY_PERCENT, + policy.getConcurrentSuspensionLimit(clusterApi)); + } + + @Test public void testDefaultSuspensionLimit() { + when(applicationApi.applicationId()).thenReturn(ApplicationId.fromSerializedForm("a:b:c")); when(clusterApi.clusterId()).thenReturn(new ClusterId("some-cluster-id")); when(clusterApi.isStorageCluster()).thenReturn(false); assertEquals(ConcurrentSuspensionLimitForCluster.TEN_PERCENT, diff --git a/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/policy/HostedVespaPolicyTest.java b/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/policy/HostedVespaPolicyTest.java index ec11ed47ba5..220371c4a17 100644 --- a/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/policy/HostedVespaPolicyTest.java +++ b/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/policy/HostedVespaPolicyTest.java @@ -2,6 +2,7 @@ package com.yahoo.vespa.orchestrator.policy; +import com.yahoo.config.provision.ApplicationId; import com.yahoo.vespa.applicationmodel.HostName; import com.yahoo.vespa.orchestrator.OrchestrationException; import com.yahoo.vespa.orchestrator.controller.ClusterControllerClient; @@ -42,7 +43,7 @@ public class HostedVespaPolicyTest { final HostedVespaClusterPolicy clusterPolicy = mock(HostedVespaClusterPolicy.class); final HostedVespaPolicy policy = new HostedVespaPolicy(clusterPolicy, clientFactory); final ApplicationApi applicationApi = mock(ApplicationApi.class); - when(applicationApi.applicationInfo()).thenReturn("tenant:app"); + when(applicationApi.applicationId()).thenReturn(ApplicationId.fromSerializedForm("tenant:app:default")); ClusterApi clusterApi1 = mock(ClusterApi.class); ClusterApi clusterApi2 = mock(ClusterApi.class); @@ -93,7 +94,7 @@ public class HostedVespaPolicyTest { final HostedVespaClusterPolicy clusterPolicy = mock(HostedVespaClusterPolicy.class); final HostedVespaPolicy policy = new HostedVespaPolicy(clusterPolicy, clientFactory); final ApplicationApi applicationApi = mock(ApplicationApi.class); - when(applicationApi.applicationInfo()).thenReturn("tenant:app"); + when(applicationApi.applicationId()).thenReturn(ApplicationId.fromSerializedForm("tenant:app:default")); ClusterApi clusterApi1 = mock(ClusterApi.class); ClusterApi clusterApi2 = mock(ClusterApi.class); |