diff options
author | Ola Aunrønning <ola.aunroe@gmail.com> | 2018-10-09 10:54:15 +0200 |
---|---|---|
committer | Ola Aunrønning <ola.aunroe@gmail.com> | 2018-10-09 10:54:15 +0200 |
commit | fba3e14103fcd769c6f87e7c35fd5556ebc738d8 (patch) | |
tree | 33b5a766305dfc81778a686ea7704014eb34bef6 /controller-server | |
parent | e4adda540be339c150e12012e069c8dc44bbdb9c (diff) |
Only use persistent contact info. Moved slime serialization. Several other fixes as well
Diffstat (limited to 'controller-server')
7 files changed, 62 insertions, 209 deletions
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ContactInformationMaintainer.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ContactInformationMaintainer.java index 650d3d6a812..0e7b84a8d13 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ContactInformationMaintainer.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ContactInformationMaintainer.java @@ -12,7 +12,7 @@ import com.yahoo.vespa.hosted.controller.tenant.Tenant; import com.yahoo.yolean.Exceptions; import java.time.Duration; -import java.util.Arrays; +import java.util.EnumSet; import java.util.List; import java.util.Objects; import java.util.Optional; @@ -31,7 +31,7 @@ public class ContactInformationMaintainer extends Maintainer { private final Organization organization; public ContactInformationMaintainer(Controller controller, Duration interval, JobControl jobControl, Organization organization) { - super(Arrays.asList(SystemName.main, SystemName.cd), controller, interval, jobControl); + super(controller, interval, jobControl, EnumSet.of(SystemName.cd, SystemName.main)); this.organization = Objects.requireNonNull(organization, "organization must be non-null"); } diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/Maintainer.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/Maintainer.java index 54e9dddd649..0869f28f977 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/Maintainer.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/Maintainer.java @@ -7,8 +7,8 @@ import com.yahoo.vespa.curator.Lock; import com.yahoo.vespa.hosted.controller.Controller; import java.time.Duration; -import java.util.ArrayList; -import java.util.List; +import java.util.EnumSet; +import java.util.Set; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; @@ -30,23 +30,26 @@ public abstract class Maintainer extends AbstractComponent implements Runnable { private final JobControl jobControl; private final ScheduledExecutorService service; private final String name; - private List<SystemName> systemNames; + private final Set<SystemName> systemNames; public Maintainer(Controller controller, Duration interval, JobControl jobControl) { - this(controller, interval, jobControl, null); + this(controller, interval, jobControl, null, EnumSet.allOf(SystemName.class)); } - public Maintainer(List<SystemName> systemNames, Controller controller, Duration interval, JobControl jobControl) { - this(controller, interval, jobControl, null); - this.systemNames = systemNames; + public Maintainer(Controller controller, Duration interval, JobControl jobControl, String name) { + this(controller, interval, jobControl, name, EnumSet.allOf(SystemName.class)); } - public Maintainer(Controller controller, Duration interval, JobControl jobControl, String name) { + public Maintainer(Controller controller, Duration interval, JobControl jobControl, Set<SystemName> systemNames) { + this(controller, interval, jobControl, null, systemNames); + } + + public Maintainer(Controller controller, Duration interval, JobControl jobControl, String name, Set<SystemName> systemNames) { this.controller = controller; this.maintenanceInterval = interval; this.jobControl = jobControl; this.name = name; - this.systemNames = new ArrayList<>(); + this.systemNames = systemNames; service = new ScheduledThreadPoolExecutor(1); service.scheduleAtFixedRate(this, interval.toMillis(), interval.toMillis(), TimeUnit.MILLISECONDS); @@ -58,8 +61,7 @@ public abstract class Maintainer extends AbstractComponent implements Runnable { @Override public void run() { try { - boolean correctSystem = systemNames.isEmpty() || systemNames.contains(controller.system()); - if (jobControl.isActive(name()) && correctSystem) { + if (jobControl.isActive(name()) && systemNames.contains(controller.system())) { try (Lock lock = jobControl.curator().lockMaintenanceJob(name())) { maintain(); } diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/contactinfo/ContactInfoHandler.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/contactinfo/ContactInfoHandler.java index 5ea926afff6..5c4573e1ce7 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/contactinfo/ContactInfoHandler.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/contactinfo/ContactInfoHandler.java @@ -36,17 +36,18 @@ import java.util.logging.Level; import java.util.stream.Collectors; /** + * This implements the contactinfo/v1 API which allows getting and feeding + * contact information for a given tenant. + * * @author olaa */ public class ContactInfoHandler extends LoggingRequestHandler { private final Controller controller; - private final Organization organization; - public ContactInfoHandler(Context ctx, Controller controller, Organization organization) { + public ContactInfoHandler(Context ctx, Controller controller) { super(ctx); this.controller = controller; - this.organization = organization; } @Override @@ -72,7 +73,7 @@ public class ContactInfoHandler extends LoggingRequestHandler { private HttpResponse get(HttpRequest request) { Path path = new Path(request.getUri().getPath()); - if (path.matches("/contactinfo/v1/tenant/{tenant}")) return getContactInfo(path.get("tenant"), request); + if (path.matches("/contactinfo/v1/tenant/{tenant}")) return getContactInfo(path.get("tenant")); return ErrorResponse.notFoundError("Nothing at " + path); } @@ -82,20 +83,14 @@ public class ContactInfoHandler extends LoggingRequestHandler { return ErrorResponse.notFoundError("Nothing at " + path); } - private HttpResponse getContactInfo(String tenantName, HttpRequest request) { + private HttpResponse getContactInfo(String tenantName) { Optional<AthenzTenant> tenant = controller.tenants().athenzTenant(TenantName.from(tenantName)); - if (! tenant.isPresent()) { + if (!tenant.isPresent()) { return ErrorResponse.notFoundError("Invalid tenant " + tenantName); } - boolean useOpsDb = getUseOpsDbFromRequest(request); - Optional<Contact> contact = Optional.empty(); - if (useOpsDb) { - contact = findContactFromOpsDb(tenant.get()); - } else { - contact = tenant.get().contact(); - } + Optional<Contact> contact = tenant.get().contact(); if (contact.isPresent()) { - return new SlimeJsonResponse(contact.get().toSlime()); + return new SlimeJsonResponse(contactToSlime(contact.get())); } return ErrorResponse.notFoundError("Could not find contact info for " + tenantName); } @@ -107,51 +102,47 @@ public class ContactInfoHandler extends LoggingRequestHandler { lockedTenant -> controller.tenants().store(lockedTenant.with(contact))); return new StringResponse("Added contact info for " + tenantName + " - " + contact.toString()); } - catch (URISyntaxException | IOException e) { + catch (IOException e) { return ErrorResponse.notFoundError("Unable to create Contact object from request data"); } } - private boolean getUseOpsDbFromRequest(HttpRequest request) { - String query = request.getUri().getQuery(); - if (query == null) { - return false; - } - - HashMap<String, String> keyValPair = new HashMap<>(); - Arrays.stream(query.split("&")).forEach(pair -> { - String[] splitPair = pair.split("="); - keyValPair.put(splitPair[0], splitPair[1]); - }); - - if (keyValPair.containsKey("useOpsDb")) { - return Boolean.valueOf(keyValPair.get("useOpsDb")); - } - return false; - } - private PropertyId getPropertyIdFromRequest(HttpRequest request) { - return new PropertyId(request.getProperty("propertyId")); - } - - private Contact getContactFromRequest(HttpRequest request) throws IOException, URISyntaxException { + private Contact getContactFromRequest(HttpRequest request) throws IOException { Slime slime = SlimeUtils.jsonToSlime(IOUtils.readBytes(request.getData(), 1000 * 1000)); - return Contact.fromSlime(slime); + return contactFromSlime(slime); } - private Optional<Contact> findContactFromOpsDb(AthenzTenant tenant) { - if (!tenant.propertyId().isPresent()) { - return Optional.empty(); + protected static Slime contactToSlime(Contact contact) { + Slime slime = new Slime(); + Cursor cursor = slime.setObject(); + cursor.setString("url", contact.url().toString()); + cursor.setString("issueTrackerUrl", contact.issueTrackerUrl().toString()); + cursor.setString("propertyUrl", contact.propertyUrl().toString()); + Cursor personsCursor = cursor.setArray("persons"); + for (List<String> personList : contact.persons()) { + Cursor sublist = personsCursor.addArray(); + for(String person : personList) { + sublist.addString(person); + } } - List<List<String>> persons = organization.contactsFor(tenant.propertyId().get()) - .stream() - .map(personList -> personList.stream() - .map(User::displayName) - .collect(Collectors.toList())) - .collect(Collectors.toList()); - return Optional.of(new Contact(organization.contactsUri(tenant.propertyId().get()), - organization.propertyUri(tenant.propertyId().get()), - organization.issueCreationUri(tenant.propertyId().get()), - persons)); + return slime; + } + + protected static Contact contactFromSlime(Slime slime) { + Inspector inspector = slime.get(); + URI propertyUrl = URI.create(inspector.field("propertyUrl").asString()); + URI url = URI.create(inspector.field("url").asString()); + URI issueTrackerUrl = URI.create(inspector.field("issueTrackerUrl").asString()); + Inspector personInspector = inspector.field("persons"); + List<List<String>> personList = new ArrayList<>(); + personInspector.traverse((ArrayTraverser) (index, entry) -> { + List<String> subList = new ArrayList<>(); + entry.traverse((ArrayTraverser) (idx, subEntry) -> { + subList.add(subEntry.asString()); + }); + personList.add(subList); + }); + return new Contact(url, propertyUrl, issueTrackerUrl, personList); } } diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/tenant/Contact.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/tenant/Contact.java index cd77a42c7c0..230c3a34794 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/tenant/Contact.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/tenant/Contact.java @@ -51,39 +51,6 @@ public class Contact { return persons; } - public Slime toSlime() { - Slime slime = new Slime(); - Cursor cursor = slime.setObject(); - cursor.setString("url", url.toString()); - cursor.setString("issueTrackerUrl", issueTrackerUrl.toString()); - cursor.setString("propertyUrl", propertyUrl.toString()); - Cursor personsCursor = cursor.setArray("persons"); - for (List<String> personList : persons) { - Cursor sublist = personsCursor.addArray(); - for(String person : personList) { - sublist.addString(person); - } - } - return slime; - } - - public static Contact fromSlime(Slime slime) { - Inspector inspector = slime.get(); - URI propertyUrl = URI.create(inspector.field("propertyUrl").asString()); - URI url = URI.create(inspector.field("url").asString()); - URI issueTrackerUrl = URI.create(inspector.field("issueTrackerUrl").asString()); - Inspector personInspector = inspector.field("persons"); - List<List<String>> personList = new ArrayList<>(); - personInspector.traverse((ArrayTraverser) (index, entry) -> { - List<String> subList = new ArrayList<>(); - entry.traverse((ArrayTraverser) (idx, subEntry) -> { - subList.add(subEntry.asString()); - }); - personList.add(subList); - }); - return new Contact(url, propertyUrl, issueTrackerUrl, personList); - } - @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ControllerContainerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ControllerContainerTest.java index 992e3cfcd36..e46af8dc64a 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ControllerContainerTest.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ControllerContainerTest.java @@ -89,6 +89,9 @@ public class ControllerContainerTest { " <handler id='com.yahoo.vespa.hosted.controller.restapi.application.ApplicationApiHandler'>\n" + " <binding>http://*/application/v4/*</binding>\n" + " </handler>\n" + + " <handler id='com.yahoo.vespa.hosted.controller.restapi.contactinfo.ContactInfoHandler'>\n" + + " <binding>https://*/contactinfo/v1/*</binding>\n" + + " </handler>\n" + " <handler id='com.yahoo.vespa.hosted.controller.restapi.deployment.DeploymentApiHandler'>\n" + " <binding>http://*/deployment/v1/*</binding>\n" + " </handler>\n" + diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/contactinfo/ContactInfoHandlerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/contactinfo/ContactInfoHandlerTest.java index f98a4467f0b..aa4e0f93260 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/contactinfo/ContactInfoHandlerTest.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/contactinfo/ContactInfoHandlerTest.java @@ -1,14 +1,9 @@ package com.yahoo.vespa.hosted.controller.restapi.contactinfo; -import com.yahoo.application.Networking; -import com.yahoo.application.container.JDisc; import com.yahoo.application.container.handler.Request; import com.yahoo.application.container.handler.Response; import com.yahoo.slime.Slime; import com.yahoo.vespa.config.SlimeUtils; -import com.yahoo.vespa.hosted.controller.ControllerTester; -import com.yahoo.vespa.hosted.controller.api.identifiers.PropertyId; -import com.yahoo.vespa.hosted.controller.api.integration.organization.User; import com.yahoo.vespa.hosted.controller.restapi.ContainerControllerTester; import com.yahoo.vespa.hosted.controller.restapi.ControllerContainerTest; import com.yahoo.vespa.hosted.controller.tenant.Contact; @@ -17,8 +12,6 @@ import org.junit.Test; import java.net.URI; import java.util.Arrays; -import java.util.List; -import java.util.stream.Collectors; import static org.junit.Assert.*; @@ -26,9 +19,6 @@ public class ContactInfoHandlerTest extends ControllerContainerTest { private ContainerControllerTester tester; - @Override - public void startContainer() { container = JDisc.fromServicesXml(controllerServicesXml, Networking.disable); } - @Before public void before() { tester = new ContainerControllerTester(container, null); @@ -44,97 +34,15 @@ public class ContactInfoHandlerTest extends ControllerContainerTest { // Feed contact information for tenant1 Contact contact = new Contact(URI.create("https://localhost:4444/"), URI.create("https://localhost:4444/"), URI.create("https://localhost:4444/"), Arrays.asList(Arrays.asList("foo", "bar"))); - Slime contactSlime = contact.toSlime(); + Slime contactSlime = ContactInfoHandler.contactToSlime(contact); byte[] body = SlimeUtils.toJsonBytes(contactSlime); String expectedResponseMessage = "Added contact info for tenant1 - Contact{url=https://localhost:4444/, propertyUrl=https://localhost:4444/, issueTrackerUrl=https://localhost:4444/, persons=[[foo, bar]]}"; assertResponse(new Request("https://localhost:8080/contactinfo/v1/tenant/tenant1", body, Request.Method.POST), 200, expectedResponseMessage); // Get contact information for tenant1 Response response = container.handleRequest(new Request("https://localhost:8080/contactinfo/v1/tenant/tenant1")); - Contact actualContact = Contact.fromSlime(SlimeUtils.jsonToSlime(response.getBody())); + Contact actualContact = ContactInfoHandler.contactFromSlime(SlimeUtils.jsonToSlime(response.getBody())); assertEquals(contact, actualContact); } - private final String controllerServicesXml = - "<jdisc version='1.0'>\n" + - " <config name=\"container.handler.threadpool\">\n" + - " <maxthreads>10</maxthreads>\n" + - " </config> \n" + - " <config name='vespa.hosted.zone.config.zone'>\n" + - " <system>main</system>\n" + - " </config>\n" + - " <config name=\"vespa.hosted.rotation.config.rotations\">\n" + - " <rotations>\n" + - " <item key=\"rotation-id-1\">rotation-fqdn-1</item>\n" + - " <item key=\"rotation-id-2\">rotation-fqdn-2</item>\n" + - " <item key=\"rotation-id-3\">rotation-fqdn-3</item>\n" + - " <item key=\"rotation-id-4\">rotation-fqdn-4</item>\n" + - " <item key=\"rotation-id-5\">rotation-fqdn-5</item>\n" + - " </rotations>\n" + - " </config>\n" + - " <config name=\"jdisc.http.filter.security.cors.cors-filter\">\n" + - " <allowedUrls>\n" + - " <item>http://localhost</item>\n" + - " </allowedUrls>\n" + - " </config>\n" + - " <component id='com.yahoo.vespa.hosted.controller.persistence.MockCuratorDb'/>\n" + - " <component id='com.yahoo.vespa.hosted.controller.athenz.mock.AthenzClientFactoryMock'/>\n" + - " <component id='com.yahoo.vespa.hosted.controller.api.integration.chef.ChefMock'/>\n" + - " <component id='com.yahoo.vespa.hosted.controller.api.integration.dns.MemoryNameService'/>\n" + - " <component id='com.yahoo.vespa.hosted.controller.api.integration.entity.MemoryEntityService'/>\n" + - " <component id='com.yahoo.vespa.hosted.controller.api.integration.github.GitHubMock'/>\n" + - " <component id='com.yahoo.vespa.hosted.controller.api.integration.stubs.LoggingDeploymentIssues'/>\n" + - " <component id='com.yahoo.vespa.hosted.controller.api.integration.stubs.DummyOwnershipIssues'/>\n" + - " <component id='com.yahoo.vespa.hosted.controller.api.integration.stubs.MockRunDataStore'/>\n" + - " <component id='com.yahoo.vespa.hosted.controller.api.integration.organization.MockOrganization'/>\n" + - " <component id='com.yahoo.vespa.hosted.controller.integration.ConfigServerMock'/>\n" + - " <component id='com.yahoo.vespa.hosted.controller.integration.NodeRepositoryClientMock'/>\n" + - " <component id='com.yahoo.vespa.hosted.controller.integration.ZoneRegistryMock'/>\n" + - " <component id='com.yahoo.vespa.hosted.controller.Controller'/>\n" + - " <component id='com.yahoo.vespa.hosted.controller.api.integration.stubs.MockBuildService'/>\n" + - " <component id='com.yahoo.vespa.hosted.controller.integration.ConfigServerProxyMock'/>\n" + - " <component id='com.yahoo.vespa.hosted.controller.integration.MetricsServiceMock'/>\n" + - " <component id='com.yahoo.vespa.hosted.controller.maintenance.ControllerMaintenance'/>\n" + - " <component id='com.yahoo.vespa.hosted.controller.maintenance.JobControl'/>\n" + - " <component id='com.yahoo.vespa.hosted.controller.integration.RoutingGeneratorMock'/>\n" + - " <component id='com.yahoo.vespa.hosted.controller.integration.ArtifactRepositoryMock'/>\n" + - " <component id='com.yahoo.vespa.hosted.controller.integration.ApplicationStoreMock'/>\n" + - " <component id='com.yahoo.vespa.hosted.controller.api.integration.stubs.MockTesterCloud'/>\n" + - " <handler id='com.yahoo.vespa.hosted.controller.restapi.application.ApplicationApiHandler'>\n" + - " <binding>http://*/application/v4/*</binding>\n" + - " </handler>\n" + - " <handler id='com.yahoo.vespa.hosted.controller.restapi.contactinfo.ContactInfoHandler'>\n" + - " <binding>https://*/contactinfo/v1/*</binding>\n" + - " </handler>\n" + - " <handler id='com.yahoo.vespa.hosted.controller.restapi.deployment.DeploymentApiHandler'>\n" + - " <binding>http://*/deployment/v1/*</binding>\n" + - " </handler>\n" + - " <handler id='com.yahoo.vespa.hosted.controller.restapi.controller.ControllerApiHandler'>\n" + - " <binding>http://*/controller/v1/*</binding>\n" + - " </handler>\n" + - " <handler id='com.yahoo.vespa.hosted.controller.restapi.os.OsApiHandler'>\n" + - " <binding>http://*/os/v1/*</binding>\n" + - " </handler>\n" + - " <handler id='com.yahoo.vespa.hosted.controller.restapi.screwdriver.ScrewdriverApiHandler'>\n" + - " <binding>http://*/screwdriver/v1/*</binding>\n" + - " </handler>\n" + - " <handler id='com.yahoo.vespa.hosted.controller.restapi.zone.v1.ZoneApiHandler'>\n" + - " <binding>http://*/zone/v1</binding>\n" + - " <binding>http://*/zone/v1/*</binding>\n" + - " </handler>\n" + - " <handler id='com.yahoo.vespa.hosted.controller.restapi.zone.v2.ZoneApiHandler'>\n" + - " <binding>http://*/zone/v2</binding>\n" + - " <binding>http://*/zone/v2/*</binding>\n" + - " </handler>\n" + - " <http>\n" + - " <server id='default' port='8080' />\n" + - " <filtering>\n" + - " <request-chain id='default'>\n" + - " <filter id='com.yahoo.vespa.hosted.controller.integration.AthenzFilterMock'/>\n" + - " <filter id='com.yahoo.vespa.hosted.controller.restapi.filter.ControllerAuthorizationFilter'/>\n" + - " <binding>http://*/*</binding>\n" + - " </request-chain>\n" + - " </filtering>\n" + - " </http>\n" + - "</jdisc>"; }
\ No newline at end of file diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/tenant/ContactTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/tenant/ContactTest.java deleted file mode 100644 index f25facfc84c..00000000000 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/tenant/ContactTest.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.yahoo.vespa.hosted.controller.tenant; - -import org.junit.Test; - -import java.net.URI; -import java.util.Arrays; - -import static org.junit.Assert.*; - -public class ContactTest { - - @Test - public void testSlimeSerialization() { - Contact contact = new Contact(URI.create("https://localhost:4444/"), URI.create("https://localhost:4444/"), URI.create("https://localhost:4444/"), Arrays.asList(Arrays.asList("foo", "bar"))); - assertEquals(contact, Contact.fromSlime(contact.toSlime())); - } - -}
\ No newline at end of file |