From 1c64e96b11ace03fa9feca0d5d570d7d09cc5001 Mon Sep 17 00:00:00 2001 From: Ola Aunrønning Date: Thu, 7 Mar 2019 15:09:55 +0100 Subject: Stream logs --- .../api/integration/configserver/ConfigServer.java | 6 ++++-- .../restapi/application/ApplicationApiHandler.java | 17 ++++++++++++++--- .../hosted/controller/integration/ConfigServerMock.java | 10 +++++++++- .../restapi/application/ApplicationApiTest.java | 7 ++++++- 4 files changed, 33 insertions(+), 7 deletions(-) diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/ConfigServer.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/ConfigServer.java index 07eaf046eeb..b43cb176607 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/ConfigServer.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/ConfigServer.java @@ -9,7 +9,7 @@ import com.yahoo.vespa.hosted.controller.api.integration.zone.ZoneId; import com.yahoo.vespa.serviceview.bindings.ApplicationView; import java.io.IOException; -import java.util.HashMap; +import java.io.InputStream; import java.util.List; import java.util.Map; import java.util.Optional; @@ -41,7 +41,9 @@ public interface ConfigServer { Map getServiceApiResponse(String tenantName, String applicationName, String instanceName, String environment, String region, String serviceName, String restPath); - Optional getLogs(DeploymentId deployment, HashMap queryParameters); + Optional getLogs(DeploymentId deployment, Map queryParameters); + + InputStream getLogStream(DeploymentId deployment, Map queryParameters); List getContentClusters(DeploymentId deployment); diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java index 0d5130b8aeb..66ee65a036e 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java @@ -89,6 +89,7 @@ import javax.ws.rs.InternalServerErrorException; import javax.ws.rs.NotAuthorizedException; import java.io.IOException; import java.io.InputStream; +import java.io.OutputStream; import java.net.URI; import java.net.URISyntaxException; import java.security.Principal; @@ -180,7 +181,7 @@ public class ApplicationApiHandler extends LoggingRequestHandler { if (path.matches("/application/v4/tenant/{tenant}/application/{application}")) return application(path.get("tenant"), path.get("application"), request); if (path.matches("/application/v4/tenant/{tenant}/application/{application}/deploying")) return deploying(path.get("tenant"), path.get("application"), request); if (path.matches("/application/v4/tenant/{tenant}/application/{application}/deploying/pin")) return deploying(path.get("tenant"), path.get("application"), request); - if (path.matches("/application/v4/tenant/{tenant}/application/{application}/environment/{environment}/region/{region}/instance/{instance}/logs")) return logs(path.get("tenant"), path.get("application"), path.get("instance"), path.get("environment"), path.get("region"), request.getUri().getQuery()); + if (path.matches("/application/v4/tenant/{tenant}/application/{application}/environment/{environment}/region/{region}/instance/{instance}/logs")) return logs(path.get("tenant"), path.get("application"), path.get("instance"), path.get("environment"), path.get("region"), request.propertyMap()); if (path.matches("/application/v4/tenant/{tenant}/application/{application}/instance/{instance}/job")) return JobControllerApiHandlerHelper.jobTypeResponse(controller, appIdFromPath(path), request.getUri()); if (path.matches("/application/v4/tenant/{tenant}/application/{application}/instance/{instance}/job/{jobtype}")) return JobControllerApiHandlerHelper.runResponse(controller.jobController().runs(appIdFromPath(path), jobTypeFromPath(path)), request.getUri()); if (path.matches("/application/v4/tenant/{tenant}/application/{application}/instance/{instance}/job/{jobtype}/run/{number}")) return JobControllerApiHandlerHelper.runDetailsResponse(controller.jobController(), runIdFromPath(path), request.getProperty("after")); @@ -377,11 +378,21 @@ public class ApplicationApiHandler extends LoggingRequestHandler { .orElseThrow(() -> new NotExistsException(applicationId + " not found")); } - private HttpResponse logs(String tenantName, String applicationName, String instanceName, String environment, String region, String query) { + private HttpResponse logs(String tenantName, String applicationName, String instanceName, String environment, String region, Map queryParameters) { ApplicationId application = ApplicationId.from(tenantName, applicationName, instanceName); ZoneId zone = ZoneId.from(environment, region); DeploymentId deployment = new DeploymentId(application, zone); - HashMap queryParameters = getParameters(query); + + if (queryParameters.containsKey("streaming")) { + InputStream logStream = controller.configServer().getLogStream(deployment, queryParameters); + return new HttpResponse(200) { + @Override + public void render(OutputStream outputStream) throws IOException { + logStream.transferTo(outputStream); + } + }; + } + Optional response = controller.configServer().getLogs(deployment, queryParameters); Slime slime = new Slime(); Cursor object = slime.setObject(); diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ConfigServerMock.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ConfigServerMock.java index bb8228db679..eaccb5fa12d 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ConfigServerMock.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ConfigServerMock.java @@ -28,7 +28,10 @@ import com.yahoo.vespa.hosted.controller.application.SystemApplication; import com.yahoo.vespa.serviceview.bindings.ApplicationView; import com.yahoo.vespa.serviceview.bindings.ClusterView; import com.yahoo.vespa.serviceview.bindings.ServiceView; +import org.apache.commons.io.IOUtils; +import org.apache.http.impl.io.EmptyInputStream; +import java.io.InputStream; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -334,13 +337,18 @@ public class ConfigServerMock extends AbstractComponent implements ConfigServer } @Override - public Optional getLogs(DeploymentId deployment, HashMap queryParameters) { + public Optional getLogs(DeploymentId deployment, Map queryParameters) { HashMap logs = new HashMap<>(); logs.put("subfolder-log2.log", "VGhpcyBpcyBhbm90aGVyIGxvZyBmaWxl"); logs.put("log1.log", "VGhpcyBpcyBvbmUgbG9nIGZpbGU="); return Optional.of(new Logs(logs)); } + @Override + public InputStream getLogStream(DeploymentId deployment, Map queryParameters) { + return IOUtils.toInputStream("INFO - All good"); + } + @Override public List getContentClusters(DeploymentId deployment) { return Collections.singletonList("music"); diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java index e0657400a4b..2cdc124a88c 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java @@ -377,7 +377,12 @@ public class ApplicationApiTest extends ControllerContainerTest { new File("application1-recursive.json")); // GET logs - tester.assertResponse(request("/application/v4/tenant/tenant2/application//application1/environment/prod/region/us-central-1/instance/default/logs?from=1233&to=3214", GET).userIdentity(USER_ID), new File("logs.json")); + tester.assertResponse(request("/application/v4/tenant/tenant2/application//application1/environment/prod/region/us-central-1/instance/default/logs?from=1233&to=3214", GET) + .userIdentity(USER_ID), + new File("logs.json")); + tester.assertResponse(request("/application/v4/tenant/tenant2/application//application1/environment/prod/region/us-central-1/instance/default/logs?from=1233&to=3214&streaming", GET) + .userIdentity(USER_ID), + "INFO - All good"); // DELETE (cancel) ongoing change tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/deploying", DELETE) -- cgit v1.2.3 From 4fa8c17165a313e5a5b25505f57178a966574804 Mon Sep 17 00:00:00 2001 From: Ola Aunrønning Date: Thu, 7 Mar 2019 16:17:51 +0100 Subject: Removed unused function --- .../controller/restapi/application/ApplicationApiHandler.java | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java index 66ee65a036e..6b5ffc23f0a 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java @@ -96,8 +96,6 @@ import java.security.Principal; import java.time.DayOfWeek; import java.time.Duration; import java.time.Instant; -import java.util.Arrays; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; @@ -416,15 +414,6 @@ public class ApplicationApiHandler extends LoggingRequestHandler { return new MessageResponse(type.jobName() + " for " + id + " paused for " + DeploymentTrigger.maxPause); } - private HashMap getParameters(String query) { - HashMap keyValPair = new HashMap<>(); - Arrays.stream(query.split("&")).forEach(pair -> { - String[] splitPair = pair.split("="); - keyValPair.put(splitPair[0], splitPair[1]); - }); - return keyValPair; - } - private void toSlime(Cursor object, Application application, HttpRequest request) { object.setString("application", application.id().application().value()); object.setString("instance", application.id().instance().value()); -- cgit v1.2.3