From ac8b475cb275db5e85af24589688c104014fed8b Mon Sep 17 00:00:00 2001 From: epankou Date: Thu, 20 Dec 2018 12:26:37 +0300 Subject: [PATCH 01/11] Bug(fix) microservice removal: networking microsrevice isn't removed (EWC-424) --- .../eclipse/iofog/field_agent/FieldAgent.java | 11 +- .../iofog/process_manager/DockerUtil.java | 38 +++- .../iofog/process_manager/ProcessManager.java | 97 ++++----- .../process_manager/ProcessManagerStatus.java | 184 +++++++++--------- .../org/eclipse/iofog/utils/Constants.java | 2 +- 5 files changed, 187 insertions(+), 145 deletions(-) diff --git a/daemon/src/org/eclipse/iofog/field_agent/FieldAgent.java b/daemon/src/org/eclipse/iofog/field_agent/FieldAgent.java index bb6a6dd1..0195d849 100644 --- a/daemon/src/org/eclipse/iofog/field_agent/FieldAgent.java +++ b/daemon/src/org/eclipse/iofog/field_agent/FieldAgent.java @@ -139,6 +139,13 @@ private JsonObject getFogStatus() { return json; } + /** + * executes actions after successful status post request + */ + private void onPostStatusSuccess() { + StatusReporter.getProcessManagerStatus().removeNotRunningMicroserviceStatus(); + } + /** * checks if IOFog is not provisioned * @@ -173,7 +180,7 @@ private boolean notProvisioned() { logInfo("sending IOFog status..."); orchestrator.request("status", RequestType.PUT, null, status); - + onPostStatusSuccess(); } catch (CertificateException | SSLHandshakeException e) { verificationFailed(); } catch (ForbiddenException e) { @@ -926,7 +933,7 @@ public String deProvision() { if (notProvisioned()) { return "\nFailure - not provisioned"; } - + //// TODO: 20.12.18 make deprovision request to controller in order to mark related microservices as not running StatusReporter.setFieldAgentStatus().setControllerStatus(NOT_PROVISIONED); try { Configuration.setIofogUuid(""); diff --git a/daemon/src/org/eclipse/iofog/process_manager/DockerUtil.java b/daemon/src/org/eclipse/iofog/process_manager/DockerUtil.java index a20dd31d..f537bdc2 100755 --- a/daemon/src/org/eclipse/iofog/process_manager/DockerUtil.java +++ b/daemon/src/org/eclipse/iofog/process_manager/DockerUtil.java @@ -27,6 +27,7 @@ import org.apache.commons.lang.SystemUtils; import org.eclipse.iofog.microservice.*; import org.eclipse.iofog.status_reporter.StatusReporter; +import org.eclipse.iofog.utils.Constants; import org.eclipse.iofog.utils.configuration.Configuration; import org.eclipse.iofog.utils.logging.LoggingService; @@ -199,6 +200,10 @@ public String getContainerName(Container container) { return container.getNames()[0].substring(1); } + public String getContainerMicroserviceUuid(Container container) { + return getContainerName(container).substring(Constants.IOFOG_DOCKER_CONTAINER_NAME_PREFIX.length()); + } + /** * returns a {@link Container} if exists * @@ -208,7 +213,7 @@ public String getContainerName(Container container) { public Optional getContainer(String microserviceUuid) { List containers = getContainers(); return containers.stream() - .filter(c -> getContainerName(c).equals(microserviceUuid)) + .filter(c -> getContainerMicroserviceUuid(c).equals(microserviceUuid)) .findAny(); } @@ -257,6 +262,33 @@ public MicroserviceStatus getMicroserviceStatus(String containerId) { return result; } + public List getRunningContainers() { + return getContainers().stream() + .filter(container -> { + InspectContainerResponse inspectInfo = dockerClient.inspectContainerCmd(container.getId()).exec(); + ContainerState containerState = inspectInfo.getState(); + if (containerState != null) { + if (containerState.getStatus() != null) { + return MicroserviceState.fromText(containerState.getStatus()) == MicroserviceState.RUNNING; + } + } + return false; + }) + .collect(Collectors.toList()); + } + + public List getRunningIofogContainers() { + return getRunningContainers().stream() + .filter(container -> getContainerName(container).startsWith(Constants.IOFOG_DOCKER_CONTAINER_NAME_PREFIX)) + .collect(Collectors.toList()); + } + + public List getRunningNonIofogContainers() { + return getRunningContainers().stream() + .filter(container -> !getContainerName(container).startsWith(Constants.IOFOG_DOCKER_CONTAINER_NAME_PREFIX)) + .collect(Collectors.toList()); + } + public Optional getContainerStats(String containerId) { StatsCmd statsCmd = dockerClient.statsCmd(containerId); CountDownLatch countDownLatch = new CountDownLatch(1); @@ -434,7 +466,7 @@ public String createContainer(Microservice microservice, String host) throws Not volumeBindings.add(new Bind(volumeMapping.getHostDestination(), volume, accessMode)); }); } - String[] extraHosts = {"iofabric:" + host, "iofog:" + host}; + String[] extraHosts = {"iofabric:" + host, "iofog:" + host, "connector.iofog.org:192.168.2.105"}; Map containerLogConfig = new HashMap<>(); int logFiles = 1; @@ -451,7 +483,7 @@ public String createContainer(Microservice microservice, String host) throws Not .withExposedPorts(exposedPorts.toArray(new ExposedPort[0])) .withPortBindings(portBindings) .withEnv("SELFNAME=" + microservice.getMicroserviceUuid()) - .withName(microservice.getMicroserviceUuid()) + .withName(Constants.IOFOG_DOCKER_CONTAINER_NAME_PREFIX + microservice.getMicroserviceUuid()) .withRestartPolicy(restartPolicy); if (microservice.getVolumeMappings() != null) { cmd = cmd diff --git a/daemon/src/org/eclipse/iofog/process_manager/ProcessManager.java b/daemon/src/org/eclipse/iofog/process_manager/ProcessManager.java index 486c9c46..9c5d72b1 100644 --- a/daemon/src/org/eclipse/iofog/process_manager/ProcessManager.java +++ b/daemon/src/org/eclipse/iofog/process_manager/ProcessManager.java @@ -30,7 +30,7 @@ import static java.lang.String.format; import static org.eclipse.iofog.process_manager.ContainerTask.Tasks.*; import static org.eclipse.iofog.utils.Constants.ControllerStatus.OK; -import static org.eclipse.iofog.utils.Constants.IOFOG_DOCKER_REPOSITORY; +import static org.eclipse.iofog.utils.Constants.IOFOG_DOCKER_CONTAINER_NAME_PREFIX; import static org.eclipse.iofog.utils.Constants.PROCESS_MANAGER; /** @@ -103,40 +103,13 @@ public void update() { logInfo("monitoring containers"); try { - for (Microservice microservice : microserviceManager.getLatestMicroservices()) { - - if (!microservice.isUpdating()) { - Optional containerOptional = docker.getContainer(microservice.getMicroserviceUuid()); - - MicroserviceStatus status = containerOptional.isPresent() - ? docker.getMicroserviceStatus(containerOptional.get().getId()) - : new MicroserviceStatus(MicroserviceState.NOT_RUNNING); - StatusReporter.setProcessManagerStatus().setMicroservicesStatus(microservice.getMicroserviceUuid(), status); - - if (microservice.isDelete()) { - if (containerOptional.isPresent()) { - deleteMicroservice(microservice); - } - } else if (!containerOptional.isPresent()) { - addMicroservice(microservice); - } else { - Container container = containerOptional.get(); - updateMicroservice(container, microservice); - } - } - } - + handleLatestMicroservices(); deleteRemainingMicroservices(); - StatusReporter.setProcessManagerStatus().setRunningMicroservicesCount(docker.getContainers().size()); - + updateRunningMicroservicesCount(); } catch (Exception ex) { logWarning(ex.getMessage()); } - - List currentMicroservices = microserviceManager.getLatestMicroservices().stream() - .filter(microservice -> !microservice.isDelete()) - .collect(Collectors.toList()); - microserviceManager.setCurrentMicroservices(currentMicroservices); + updateCurrentMicroservices(); } }; @@ -174,17 +147,46 @@ private void updateMicroservice(Container container, Microservice microservice) } } + private void handleLatestMicroservices() { + microserviceManager.getLatestMicroservices().stream() + .filter(microservice -> !microservice.isUpdating()) + .forEach(microservice -> { + Optional containerOptional = docker.getContainer(microservice.getMicroserviceUuid()); + MicroserviceStatus status = containerOptional.isPresent() + ? docker.getMicroserviceStatus(containerOptional.get().getId()) + : new MicroserviceStatus(MicroserviceState.NOT_RUNNING); + StatusReporter.setProcessManagerStatus().setMicroservicesStatus(microservice.getMicroserviceUuid(), status); + + if (!containerOptional.isPresent() && !microservice.isDelete()) { + addMicroservice(microservice); + } else if (containerOptional.isPresent() && microservice.isDelete()) { + deleteMicroservice(microservice); + } else if (containerOptional.isPresent() && !microservice.isDelete()) { + updateMicroservice(containerOptional.get(), microservice); + } + }); + } + private void deleteRemainingMicroservices() { + Set allAgentMicroservices = Stream.concat( + microserviceManager.getLatestMicroservices().stream(), + microserviceManager.getCurrentMicroservices().stream() + ) + .collect(Collectors.toSet()); deleteOldAgentMicroservices(); + deleteObsoleteAgentMicroservices(allAgentMicroservices); + deleteNonAgentMicroservices(allAgentMicroservices); + } - List allDockerContainers = docker.getContainers(); - Set allAgentMicroservices = Stream.concat( - microserviceManager.getLatestMicroservices().stream(), microserviceManager.getCurrentMicroservices().stream()) - .collect(Collectors.toSet() - ); + private void updateRunningMicroservicesCount() { + StatusReporter.setProcessManagerStatus().setRunningMicroservicesCount(docker.getRunningIofogContainers().size()); + } - deleteObsoleteAgentMicroservices(allAgentMicroservices, allDockerContainers); - deleteNonAgentMicroservices(allAgentMicroservices, allDockerContainers); + private void updateCurrentMicroservices() { + List currentMicroservices = microserviceManager.getLatestMicroservices().stream() + .filter(microservice -> !microservice.isDelete()) + .collect(Collectors.toList()); + microserviceManager.setCurrentMicroservices(currentMicroservices); } /** @@ -194,6 +196,8 @@ private void deleteOldAgentMicroservices() { microserviceManager.getCurrentMicroservices().stream() .filter(microservice -> !microserviceManager.getLatestMicroservices().contains(microservice)) .forEach(microservice -> { + MicroserviceStatus status = new MicroserviceStatus(MicroserviceState.NOT_RUNNING); + StatusReporter.setProcessManagerStatus().setMicroservicesStatus(microservice.getMicroserviceUuid(), status); disableMicroserviceFeaturesBeforeRemoval(microservice.getMicroserviceUuid()); addTask(new ContainerTask(REMOVE, microservice.getMicroserviceUuid())); }); @@ -202,12 +206,11 @@ private void deleteOldAgentMicroservices() { /** * Deletes obsolete agent microservices that aren't present in current or latest microservices list * @param allAgentMicroservices all microservices run by iofog agent - * @param allDockerContainers all running docker containers */ - private void deleteObsoleteAgentMicroservices(Set allAgentMicroservices, List allDockerContainers) { - allDockerContainers.stream() - .filter(container -> container.getImage().startsWith(IOFOG_DOCKER_REPOSITORY)) - .map(container -> docker.getContainerName(container)) + private void deleteObsoleteAgentMicroservices(Set allAgentMicroservices) { + docker.getRunningIofogContainers().stream() + .filter(container -> docker.getContainerName(container).startsWith(IOFOG_DOCKER_CONTAINER_NAME_PREFIX)) + .map(container -> docker.getContainerMicroserviceUuid(container)) .filter(microserviceUuid -> allAgentMicroservices.stream() .noneMatch(microservice -> microservice.getMicroserviceUuid().equals(microserviceUuid))) .forEach(microserviceUuid -> addTask(new ContainerTask(REMOVE, microserviceUuid))); @@ -216,13 +219,11 @@ private void deleteObsoleteAgentMicroservices(Set allAgentMicroser /** * Deletes any microservices which don't belong to iofog agent * @param allAgentMicroservices all microservices run by iofog agent - * @param allDockerContainers all running docker containers */ - private void deleteNonAgentMicroservices(Set allAgentMicroservices, List allDockerContainers) { + private void deleteNonAgentMicroservices(Set allAgentMicroservices) { if (Configuration.isWatchdogEnabled()) { - allDockerContainers.stream() - .filter(container -> !container.getImage().startsWith(IOFOG_DOCKER_REPOSITORY)) - .map(container -> docker.getContainerName(container)) + docker.getRunningNonIofogContainers().stream() + .map(container -> docker.getContainerMicroserviceUuid(container)) .filter(microserviceUuid -> allAgentMicroservices.stream() .noneMatch(microservice -> microservice.getMicroserviceUuid().equals(microserviceUuid))) .forEach(microserviceUuid -> addTask(new ContainerTask(REMOVE, microserviceUuid))); diff --git a/daemon/src/org/eclipse/iofog/process_manager/ProcessManagerStatus.java b/daemon/src/org/eclipse/iofog/process_manager/ProcessManagerStatus.java index 02f18949..d00ac132 100644 --- a/daemon/src/org/eclipse/iofog/process_manager/ProcessManagerStatus.java +++ b/daemon/src/org/eclipse/iofog/process_manager/ProcessManagerStatus.java @@ -12,10 +12,7 @@ *******************************************************************************/ package org.eclipse.iofog.process_manager; -import org.eclipse.iofog.microservice.Microservice; -import org.eclipse.iofog.microservice.MicroserviceManager; -import org.eclipse.iofog.microservice.MicroserviceStatus; -import org.eclipse.iofog.microservice.Registry; +import org.eclipse.iofog.microservice.*; import org.eclipse.iofog.utils.Constants.LinkStatus; import javax.json.Json; @@ -28,95 +25,100 @@ /** * represents Process Manager status - * - * @author saeid * + * @author saeid */ public class ProcessManagerStatus { - private int runningMicroservicesCount; - private final Map microservicesStatus; - private final Map registriesStatus; - - public ProcessManagerStatus() { - microservicesStatus = new HashMap<>(); - registriesStatus = new HashMap<>(); - runningMicroservicesCount = 0; - } - - /** - * returns {@link Microservice} status in json format - * - * @return string in json format - */ - public String getJsonMicroservicesStatus() { - JsonArrayBuilder arrayBuilder = Json.createArrayBuilder(); - - NumberFormat nf = NumberFormat.getInstance(Locale.US); - nf.setMaximumFractionDigits(2); - - microservicesStatus.forEach((key, status) -> { - if (status.getContainerId() != null) { - JsonObjectBuilder objectBuilder = Json.createObjectBuilder() - .add("id", key) - .add("containerId", status.getContainerId()) - .add("status", status.getStatus().toString()) - .add("startTime", status.getStartTime()) - .add("operatingDuration", status.getOperatingDuration()) - .add("cpuUsage", nf.format(status.getCpuUsage())) - .add("memoryUsage", String.format("%d", status.getMemoryUsage())); - arrayBuilder.add(objectBuilder); - } - }); - return arrayBuilder.build().toString(); - } - - /** - * returns {@link Registry} status in json format - * - * @return string in json format - */ - public String getJsonRegistriesStatus() { - JsonArrayBuilder arrayBuilder = Json.createArrayBuilder(); - registriesStatus.forEach((key, value) -> { - JsonObjectBuilder objectBuilder = Json.createObjectBuilder() - .add("url", key) - .add("linkStatus", value.toString()); - arrayBuilder.add(objectBuilder); - - }); - return arrayBuilder.build().toString(); - } - - public int getRunningMicroservicesCount() { - return runningMicroservicesCount; - } - - public ProcessManagerStatus setRunningMicroservicesCount(int count) { - this.runningMicroservicesCount = count; - return this; - } - - public ProcessManagerStatus setMicroservicesStatus(String microserviceUuid, MicroserviceStatus status) { - synchronized (microservicesStatus) { - this.microservicesStatus.put(microserviceUuid, status); - } - return this; - } - - public MicroserviceStatus getMicroserviceStatus(String microserviceUuid) { - synchronized (microservicesStatus) { - if (!this.microservicesStatus.containsKey(microserviceUuid)) - this.microservicesStatus.put(microserviceUuid, new MicroserviceStatus()); - } - return microservicesStatus.get(microserviceUuid); - } - - public int getRegistriesCount() { - return MicroserviceManager.getInstance().getRegistries().size(); - } - - public Map getRegistriesStatus() { - return registriesStatus; - } + private int runningMicroservicesCount; + private final Map microservicesStatus; + private final Map registriesStatus; + + public ProcessManagerStatus() { + microservicesStatus = new HashMap<>(); + registriesStatus = new HashMap<>(); + runningMicroservicesCount = 0; + } + + /** + * returns {@link Microservice} status in json format + * + * @return string in json format + */ + public String getJsonMicroservicesStatus() { + JsonArrayBuilder arrayBuilder = Json.createArrayBuilder(); + + NumberFormat nf = NumberFormat.getInstance(Locale.US); + nf.setMaximumFractionDigits(2); + + microservicesStatus.forEach((key, status) -> { + if (status.getContainerId() != null) { + JsonObjectBuilder objectBuilder = Json.createObjectBuilder() + .add("id", key) + .add("containerId", status.getContainerId()) + .add("status", status.getStatus().toString()) + .add("startTime", status.getStartTime()) + .add("operatingDuration", status.getOperatingDuration()) + .add("cpuUsage", nf.format(status.getCpuUsage())) + .add("memoryUsage", String.format("%d", status.getMemoryUsage())); + arrayBuilder.add(objectBuilder); + } + }); + return arrayBuilder.build().toString(); + } + + /** + * returns {@link Registry} status in json format + * + * @return string in json format + */ + public String getJsonRegistriesStatus() { + JsonArrayBuilder arrayBuilder = Json.createArrayBuilder(); + registriesStatus.forEach((key, value) -> { + JsonObjectBuilder objectBuilder = Json.createObjectBuilder() + .add("url", key) + .add("linkStatus", value.toString()); + arrayBuilder.add(objectBuilder); + + }); + return arrayBuilder.build().toString(); + } + + public int getRunningMicroservicesCount() { + return runningMicroservicesCount; + } + + public ProcessManagerStatus setRunningMicroservicesCount(int count) { + this.runningMicroservicesCount = count; + return this; + } + + public ProcessManagerStatus setMicroservicesStatus(String microserviceUuid, MicroserviceStatus status) { + synchronized (microservicesStatus) { + this.microservicesStatus.put(microserviceUuid, status); + } + return this; + } + + public MicroserviceStatus getMicroserviceStatus(String microserviceUuid) { + synchronized (microservicesStatus) { + if (!this.microservicesStatus.containsKey(microserviceUuid)) + this.microservicesStatus.put(microserviceUuid, new MicroserviceStatus()); + } + return microservicesStatus.get(microserviceUuid); + } + + public void removeNotRunningMicroserviceStatus() { + synchronized (microservicesStatus) { + microservicesStatus.entrySet().removeIf(entry -> entry.getValue().getStatus() == MicroserviceState.NOT_RUNNING); + } + } + + public int getRegistriesCount() { + return MicroserviceManager.getInstance().getRegistries().size(); + } + + public Map getRegistriesStatus() { + return registriesStatus; + } } diff --git a/daemon/src/org/eclipse/iofog/utils/Constants.java b/daemon/src/org/eclipse/iofog/utils/Constants.java index 12be73c7..a5deb850 100755 --- a/daemon/src/org/eclipse/iofog/utils/Constants.java +++ b/daemon/src/org/eclipse/iofog/utils/Constants.java @@ -104,5 +104,5 @@ public String fullValue() { public static final String SWITCHER_ELEMENT = "switcher"; public static final String SWITCHER_NODE = "current_config"; public static final String OS_GROUP = "iofog-agent"; - public static final String IOFOG_DOCKER_REPOSITORY = "iofog/"; + public static final String IOFOG_DOCKER_CONTAINER_NAME_PREFIX = "iofog_"; } \ No newline at end of file From f3b3276c2836b6433ceed46fb2e0178b4d8510e5 Mon Sep 17 00:00:00 2001 From: epankou Date: Thu, 20 Dec 2018 12:30:29 +0300 Subject: [PATCH 02/11] Bug(fix) microservice removal: removed extra host mapping (EWC-424) --- daemon/src/org/eclipse/iofog/process_manager/DockerUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daemon/src/org/eclipse/iofog/process_manager/DockerUtil.java b/daemon/src/org/eclipse/iofog/process_manager/DockerUtil.java index f537bdc2..c8968f1a 100755 --- a/daemon/src/org/eclipse/iofog/process_manager/DockerUtil.java +++ b/daemon/src/org/eclipse/iofog/process_manager/DockerUtil.java @@ -466,7 +466,7 @@ public String createContainer(Microservice microservice, String host) throws Not volumeBindings.add(new Bind(volumeMapping.getHostDestination(), volume, accessMode)); }); } - String[] extraHosts = {"iofabric:" + host, "iofog:" + host, "connector.iofog.org:192.168.2.105"}; + String[] extraHosts = {"iofabric:" + host, "iofog:" + host}; Map containerLogConfig = new HashMap<>(); int logFiles = 1; From 1c2ee60efa13195634d45faf3cc16143377fa77c Mon Sep 17 00:00:00 2001 From: epankou Date: Thu, 20 Dec 2018 12:39:02 +0300 Subject: [PATCH 03/11] Bug(fix) microservice removal: simplified getRunningContainers method (EWC-424) --- .../eclipse/iofog/process_manager/DockerUtil.java | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/daemon/src/org/eclipse/iofog/process_manager/DockerUtil.java b/daemon/src/org/eclipse/iofog/process_manager/DockerUtil.java index c8968f1a..df9ef9a1 100755 --- a/daemon/src/org/eclipse/iofog/process_manager/DockerUtil.java +++ b/daemon/src/org/eclipse/iofog/process_manager/DockerUtil.java @@ -265,15 +265,12 @@ public MicroserviceStatus getMicroserviceStatus(String containerId) { public List getRunningContainers() { return getContainers().stream() .filter(container -> { - InspectContainerResponse inspectInfo = dockerClient.inspectContainerCmd(container.getId()).exec(); - ContainerState containerState = inspectInfo.getState(); - if (containerState != null) { - if (containerState.getStatus() != null) { - return MicroserviceState.fromText(containerState.getStatus()) == MicroserviceState.RUNNING; - } - } - return false; - }) + InspectContainerResponse inspectInfo = dockerClient.inspectContainerCmd(container.getId()).exec(); + ContainerState containerState = inspectInfo.getState(); + return containerState != null + && containerState.getStatus() != null + && MicroserviceState.fromText(containerState.getStatus()) == MicroserviceState.RUNNING; + }) .collect(Collectors.toList()); } From 3903b39bbb2a4f0975dff813f761d173eb1b627b Mon Sep 17 00:00:00 2001 From: epankou Date: Thu, 27 Dec 2018 12:57:10 +0300 Subject: [PATCH 04/11] Bug(fix) route update: added missing method for route update (EWC-374) --- daemon/src/org/eclipse/iofog/field_agent/FieldAgent.java | 4 ++-- .../org/eclipse/iofog/local_api/ControlWebsocketHandler.java | 1 - daemon/src/org/eclipse/iofog/local_api/HalApiHandler.java | 0 .../src/org/eclipse/iofog/process_manager/ProcessManager.java | 2 -- 4 files changed, 2 insertions(+), 5 deletions(-) delete mode 100644 daemon/src/org/eclipse/iofog/local_api/HalApiHandler.java diff --git a/daemon/src/org/eclipse/iofog/field_agent/FieldAgent.java b/daemon/src/org/eclipse/iofog/field_agent/FieldAgent.java index 0195d849..9019afcc 100644 --- a/daemon/src/org/eclipse/iofog/field_agent/FieldAgent.java +++ b/daemon/src/org/eclipse/iofog/field_agent/FieldAgent.java @@ -294,13 +294,13 @@ private void verificationFailed() { if (microserviceConfig) { processMicroserviceConfig(microservices); + LocalApi.getInstance().update(); } if (routing) { processRoutes(microservices); + MessageBus.getInstance().update(); } - - LocalApi.getInstance().update(); } if (changes.getBoolean("tunnel") && !initialization) { sshProxyManager.update(getProxyConfig()); diff --git a/daemon/src/org/eclipse/iofog/local_api/ControlWebsocketHandler.java b/daemon/src/org/eclipse/iofog/local_api/ControlWebsocketHandler.java index 6eeb6f1a..a87e2ff4 100644 --- a/daemon/src/org/eclipse/iofog/local_api/ControlWebsocketHandler.java +++ b/daemon/src/org/eclipse/iofog/local_api/ControlWebsocketHandler.java @@ -75,7 +75,6 @@ public void handle(ChannelHandlerContext ctx, HttpRequest req) { WebSocketMap.addWebsocket('C', id, ctx); StatusReporter.setLocalApiStatus().setOpenConfigSocketsCount(WebSocketMap.controlWebsocketMap.size()); - } /** diff --git a/daemon/src/org/eclipse/iofog/local_api/HalApiHandler.java b/daemon/src/org/eclipse/iofog/local_api/HalApiHandler.java deleted file mode 100644 index e69de29b..00000000 diff --git a/daemon/src/org/eclipse/iofog/process_manager/ProcessManager.java b/daemon/src/org/eclipse/iofog/process_manager/ProcessManager.java index 9c5d72b1..2b13e754 100644 --- a/daemon/src/org/eclipse/iofog/process_manager/ProcessManager.java +++ b/daemon/src/org/eclipse/iofog/process_manager/ProcessManager.java @@ -30,7 +30,6 @@ import static java.lang.String.format; import static org.eclipse.iofog.process_manager.ContainerTask.Tasks.*; import static org.eclipse.iofog.utils.Constants.ControllerStatus.OK; -import static org.eclipse.iofog.utils.Constants.IOFOG_DOCKER_CONTAINER_NAME_PREFIX; import static org.eclipse.iofog.utils.Constants.PROCESS_MANAGER; /** @@ -209,7 +208,6 @@ private void deleteOldAgentMicroservices() { */ private void deleteObsoleteAgentMicroservices(Set allAgentMicroservices) { docker.getRunningIofogContainers().stream() - .filter(container -> docker.getContainerName(container).startsWith(IOFOG_DOCKER_CONTAINER_NAME_PREFIX)) .map(container -> docker.getContainerMicroserviceUuid(container)) .filter(microserviceUuid -> allAgentMicroservices.stream() .noneMatch(microservice -> microservice.getMicroserviceUuid().equals(microserviceUuid))) From 344e069a7e70df0d9bdf2e8e8e2218dceb0dda4e Mon Sep 17 00:00:00 2001 From: epankou Date: Fri, 28 Dec 2018 16:53:25 +0300 Subject: [PATCH 05/11] Bug(fix) mic removal update: added synchronization (EWC-374) --- .../iofog/microservice/Microservice.java | 6 +- .../process_manager/ContainerManager.java | 14 ++- .../iofog/process_manager/ProcessManager.java | 110 ++++++++++-------- 3 files changed, 78 insertions(+), 52 deletions(-) diff --git a/daemon/src/org/eclipse/iofog/microservice/Microservice.java b/daemon/src/org/eclipse/iofog/microservice/Microservice.java index 2d6c2fd4..f4360f9a 100644 --- a/daemon/src/org/eclipse/iofog/microservice/Microservice.java +++ b/daemon/src/org/eclipse/iofog/microservice/Microservice.java @@ -21,6 +21,7 @@ */ public class Microservice { + public static final Object deleteLock = new Object(); private final String microserviceUuid; //container name private final String imageName; private List portMappings; @@ -34,6 +35,7 @@ public class Microservice { private long logSize; private List volumeMappings; private boolean isUpdating; + private boolean delete; private boolean deleteWithCleanup; @@ -123,11 +125,11 @@ public void setVolumeMappings(List volumeMappings) { this.volumeMappings = volumeMappings; } - public boolean isUpdating() { + public synchronized boolean isUpdating() { return isUpdating; } - public void setUpdating(boolean updating) { + public synchronized void setUpdating(boolean updating) { isUpdating = updating; } diff --git a/daemon/src/org/eclipse/iofog/process_manager/ContainerManager.java b/daemon/src/org/eclipse/iofog/process_manager/ContainerManager.java index 58b8b422..39cd9b34 100644 --- a/daemon/src/org/eclipse/iofog/process_manager/ContainerManager.java +++ b/daemon/src/org/eclipse/iofog/process_manager/ContainerManager.java @@ -12,6 +12,7 @@ *******************************************************************************/ package org.eclipse.iofog.process_manager; +import com.github.dockerjava.api.exception.ConflictException; import com.github.dockerjava.api.model.Container; import com.github.dockerjava.api.model.Image; import org.eclipse.iofog.microservice.Microservice; @@ -22,6 +23,8 @@ import java.util.Optional; +import static org.eclipse.iofog.microservice.Microservice.deleteLock; + /** * provides methods to manage Docker containers * @@ -68,7 +71,9 @@ private Registry getRegistry(Microservice microservice) throws Exception { */ private void updateContainer(Microservice microservice, boolean withCleanUp) throws Exception { microservice.setUpdating(true); - removeContainerByMicroserviceUuid(microservice.getMicroserviceUuid(), withCleanUp); + synchronized (deleteLock) { + removeContainerByMicroserviceUuid(microservice.getMicroserviceUuid(), withCleanUp); + } createContainer(microservice); microservice.setUpdating(false); } @@ -147,7 +152,12 @@ private void removeContainer(String containerId, String imageId, boolean withCle docker.stopContainer(containerId); docker.removeContainer(containerId, withCleanUp); if (withCleanUp) { - docker.removeImageById(imageId); + try { + docker.removeImageById(imageId); + } catch (ConflictException ex) { + LoggingService.logInfo(MODULE_NAME, String.format("image for contaner \"%s\" hasn't been removed", containerId)); + LoggingService.logInfo(MODULE_NAME, ex.getMessage().replace("\n", "")); + } } LoggingService.logInfo(MODULE_NAME, String.format("container \"%s\" removed", containerId)); diff --git a/daemon/src/org/eclipse/iofog/process_manager/ProcessManager.java b/daemon/src/org/eclipse/iofog/process_manager/ProcessManager.java index 2b13e754..9d6435d6 100644 --- a/daemon/src/org/eclipse/iofog/process_manager/ProcessManager.java +++ b/daemon/src/org/eclipse/iofog/process_manager/ProcessManager.java @@ -20,6 +20,7 @@ import org.eclipse.iofog.microservice.MicroserviceState; import org.eclipse.iofog.microservice.MicroserviceStatus; import org.eclipse.iofog.status_reporter.StatusReporter; +import org.eclipse.iofog.utils.Constants; import org.eclipse.iofog.utils.Constants.ModulesStatus; import org.eclipse.iofog.utils.configuration.Configuration; @@ -28,6 +29,7 @@ import java.util.stream.Stream; import static java.lang.String.format; +import static org.eclipse.iofog.microservice.Microservice.deleteLock; import static org.eclipse.iofog.process_manager.ContainerTask.Tasks.*; import static org.eclipse.iofog.utils.Constants.ControllerStatus.OK; import static org.eclipse.iofog.utils.Constants.PROCESS_MANAGER; @@ -167,18 +169,69 @@ private void handleLatestMicroservices() { } private void deleteRemainingMicroservices() { - Set allAgentMicroservices = Stream.concat( - microserviceManager.getLatestMicroservices().stream(), - microserviceManager.getCurrentMicroservices().stream() + Set latestMicroserviceUuids = microserviceManager.getLatestMicroservices().stream() + .map(Microservice::getMicroserviceUuid).collect(Collectors.toSet()); + Set currentMicroserviceUuids = microserviceManager.getCurrentMicroservices().stream() + .map(Microservice::getMicroserviceUuid).collect(Collectors.toSet()); + List runningContainers; + synchronized (deleteLock) { + runningContainers = docker.getRunningContainers(); + } + Set runningContainerNames = runningContainers.stream() + .map(docker::getContainerName) + .collect(Collectors.toSet()); + + Set allMicroserviceUuids = Stream.concat( + Stream.concat( + latestMicroserviceUuids.stream(), + currentMicroserviceUuids.stream() + ), + runningContainers.stream() + .map(docker::getContainerMicroserviceUuid) ) .collect(Collectors.toSet()); - deleteOldAgentMicroservices(); - deleteObsoleteAgentMicroservices(allAgentMicroservices); - deleteNonAgentMicroservices(allAgentMicroservices); + + Set oldAgentMicroserviceUuids = new HashSet<>(); + Set unknownMicroserviceUuids = new HashSet<>(); + + for (String uuid : allMicroserviceUuids) { + boolean isCurrentMicroserviceUuid = currentMicroserviceUuids.contains(uuid); + boolean isLatestMicroserviceUuid = latestMicroserviceUuids.contains(uuid); + + if (isCurrentMicroserviceUuid && !isLatestMicroserviceUuid) { + oldAgentMicroserviceUuids.add(uuid); + } else if (!isCurrentMicroserviceUuid + && !isLatestMicroserviceUuid + && runningContainerNames.contains(Constants.IOFOG_DOCKER_CONTAINER_NAME_PREFIX + uuid)) { + unknownMicroserviceUuids.add(uuid); + } else if (!isCurrentMicroserviceUuid + && !isLatestMicroserviceUuid + && Configuration.isWatchdogEnabled()) { + unknownMicroserviceUuids.add(uuid); + } + } + + deleteOldAgentContainers(oldAgentMicroserviceUuids); + deleteUnknownContainers(unknownMicroserviceUuids); + } + + private void deleteOldAgentContainers(Set oldAgentContainerNames) { + oldAgentContainerNames.forEach(name -> { + MicroserviceStatus status = new MicroserviceStatus(MicroserviceState.NOT_RUNNING); + StatusReporter.setProcessManagerStatus().setMicroservicesStatus(name, status); + disableMicroserviceFeaturesBeforeRemoval(name); + addTask(new ContainerTask(REMOVE, name)); + }); + } + + private void deleteUnknownContainers(Set unknownContainerNames) { + unknownContainerNames.forEach(name -> addTask(new ContainerTask(REMOVE, name))); } private void updateRunningMicroservicesCount() { - StatusReporter.setProcessManagerStatus().setRunningMicroservicesCount(docker.getRunningIofogContainers().size()); + synchronized (deleteLock) { + StatusReporter.setProcessManagerStatus().setRunningMicroservicesCount(docker.getRunningIofogContainers().size()); + } } private void updateCurrentMicroservices() { @@ -188,50 +241,11 @@ private void updateCurrentMicroservices() { microserviceManager.setCurrentMicroservices(currentMicroservices); } - /** - * Deletes microservices which don't present in latest microservices list but do present in current microservices list - */ - private void deleteOldAgentMicroservices() { - microserviceManager.getCurrentMicroservices().stream() - .filter(microservice -> !microserviceManager.getLatestMicroservices().contains(microservice)) - .forEach(microservice -> { - MicroserviceStatus status = new MicroserviceStatus(MicroserviceState.NOT_RUNNING); - StatusReporter.setProcessManagerStatus().setMicroservicesStatus(microservice.getMicroserviceUuid(), status); - disableMicroserviceFeaturesBeforeRemoval(microservice.getMicroserviceUuid()); - addTask(new ContainerTask(REMOVE, microservice.getMicroserviceUuid())); - }); - } - - /** - * Deletes obsolete agent microservices that aren't present in current or latest microservices list - * @param allAgentMicroservices all microservices run by iofog agent - */ - private void deleteObsoleteAgentMicroservices(Set allAgentMicroservices) { - docker.getRunningIofogContainers().stream() - .map(container -> docker.getContainerMicroserviceUuid(container)) - .filter(microserviceUuid -> allAgentMicroservices.stream() - .noneMatch(microservice -> microservice.getMicroserviceUuid().equals(microserviceUuid))) - .forEach(microserviceUuid -> addTask(new ContainerTask(REMOVE, microserviceUuid))); - } - - /** - * Deletes any microservices which don't belong to iofog agent - * @param allAgentMicroservices all microservices run by iofog agent - */ - private void deleteNonAgentMicroservices(Set allAgentMicroservices) { - if (Configuration.isWatchdogEnabled()) { - docker.getRunningNonIofogContainers().stream() - .map(container -> docker.getContainerMicroserviceUuid(container)) - .filter(microserviceUuid -> allAgentMicroservices.stream() - .noneMatch(microservice -> microservice.getMicroserviceUuid().equals(microserviceUuid))) - .forEach(microserviceUuid -> addTask(new ContainerTask(REMOVE, microserviceUuid))); - } - } - private boolean shouldContainerBeUpdated(Microservice microservice, Container container, MicroserviceStatus status) { boolean isNotRunning = !MicroserviceState.RUNNING.equals(status.getStatus()); boolean areNotEqual = !docker.areMicroserviceAndContainerEqual(container.getId(), microservice); - return isNotRunning || areNotEqual; + boolean isRebuild = microservice.isRebuild(); + return isNotRunning || areNotEqual || isRebuild; } /** From 8268143c62c9ac48fb6937c5c147f21d8c9a08db Mon Sep 17 00:00:00 2001 From: epankou Date: Fri, 28 Dec 2018 16:59:12 +0300 Subject: [PATCH 06/11] Bug(fix) mic removal update: added synchronization (EWC-374) --- .../src/org/eclipse/iofog/process_manager/ContainerManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daemon/src/org/eclipse/iofog/process_manager/ContainerManager.java b/daemon/src/org/eclipse/iofog/process_manager/ContainerManager.java index 39cd9b34..9d5db990 100644 --- a/daemon/src/org/eclipse/iofog/process_manager/ContainerManager.java +++ b/daemon/src/org/eclipse/iofog/process_manager/ContainerManager.java @@ -155,7 +155,7 @@ private void removeContainer(String containerId, String imageId, boolean withCle try { docker.removeImageById(imageId); } catch (ConflictException ex) { - LoggingService.logInfo(MODULE_NAME, String.format("image for contaner \"%s\" hasn't been removed", containerId)); + LoggingService.logInfo(MODULE_NAME, String.format("Image for container \"%s\" hasn't been removed", containerId)); LoggingService.logInfo(MODULE_NAME, ex.getMessage().replace("\n", "")); } } From 7390c449ba87bad1b6d8cd96495d9bf7badd5ad1 Mon Sep 17 00:00:00 2001 From: epankou Date: Sat, 29 Dec 2018 13:43:41 +0300 Subject: [PATCH 07/11] Bug(fix) mic removal update: added synchronization (EWC-374) --- .../iofog/process_manager/ContainerManager.java | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/daemon/src/org/eclipse/iofog/process_manager/ContainerManager.java b/daemon/src/org/eclipse/iofog/process_manager/ContainerManager.java index 9d5db990..e9d708a1 100644 --- a/daemon/src/org/eclipse/iofog/process_manager/ContainerManager.java +++ b/daemon/src/org/eclipse/iofog/process_manager/ContainerManager.java @@ -71,9 +71,7 @@ private Registry getRegistry(Microservice microservice) throws Exception { */ private void updateContainer(Microservice microservice, boolean withCleanUp) throws Exception { microservice.setUpdating(true); - synchronized (deleteLock) { - removeContainerByMicroserviceUuid(microservice.getMicroserviceUuid(), withCleanUp); - } + removeContainerByMicroserviceUuid(microservice.getMicroserviceUuid(), withCleanUp); createContainer(microservice); microservice.setUpdating(false); } @@ -137,12 +135,12 @@ private void stopContainer(String microserviceUuid) { * removes a {@link Container} by Microservice uuid */ private void removeContainerByMicroserviceUuid(String microserviceUuid, boolean withCleanUp) { - - Optional containerOptional = docker.getContainer(microserviceUuid); - - if (containerOptional.isPresent()) { - Container container = containerOptional.get(); - removeContainer(container.getId(), container.getImageId(), withCleanUp); + synchronized (deleteLock) { + Optional containerOptional = docker.getContainer(microserviceUuid); + if (containerOptional.isPresent()) { + Container container = containerOptional.get(); + removeContainer(container.getId(), container.getImageId(), withCleanUp); + } } } From 4dce9c6f87f343fb30045ab700fc3f8b26a85bda Mon Sep 17 00:00:00 2001 From: epankou Date: Sat, 29 Dec 2018 16:32:47 +0300 Subject: [PATCH 08/11] Bug(fix) strace: fixed method getpid (EWC-421) --- .../iofog/diagnostics/strace/StraceDiagnosticManger.java | 3 ++- .../src/org/eclipse/iofog/process_manager/DockerUtil.java | 6 ------ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/daemon/src/org/eclipse/iofog/diagnostics/strace/StraceDiagnosticManger.java b/daemon/src/org/eclipse/iofog/diagnostics/strace/StraceDiagnosticManger.java index 5693e312..5995327a 100644 --- a/daemon/src/org/eclipse/iofog/diagnostics/strace/StraceDiagnosticManger.java +++ b/daemon/src/org/eclipse/iofog/diagnostics/strace/StraceDiagnosticManger.java @@ -15,6 +15,7 @@ import org.eclipse.iofog.command_line.util.CommandShellExecutor; import org.eclipse.iofog.command_line.util.CommandShellResultSet; +import org.eclipse.iofog.utils.Constants; import org.eclipse.iofog.utils.logging.LoggingService; import javax.json.*; @@ -81,7 +82,7 @@ private Optional getStraceDataByMicroserviceUuid(String public void enableMicroserviceStraceDiagnostics(String microserviceUuid) { try { - int pid = getPidByMicroserviceUuid(microserviceUuid); + int pid = getPidByMicroserviceUuid(Constants.IOFOG_DOCKER_CONTAINER_NAME_PREFIX + microserviceUuid); MicroserviceStraceData newMicroserviceStraceData = new MicroserviceStraceData(microserviceUuid, pid, true); this.monitoringMicroservices.removeIf( oldMicroserviceStraceData -> oldMicroserviceStraceData.getMicroserviceUuid().equals(microserviceUuid) diff --git a/daemon/src/org/eclipse/iofog/process_manager/DockerUtil.java b/daemon/src/org/eclipse/iofog/process_manager/DockerUtil.java index df9ef9a1..c5733128 100755 --- a/daemon/src/org/eclipse/iofog/process_manager/DockerUtil.java +++ b/daemon/src/org/eclipse/iofog/process_manager/DockerUtil.java @@ -280,12 +280,6 @@ public List getRunningIofogContainers() { .collect(Collectors.toList()); } - public List getRunningNonIofogContainers() { - return getRunningContainers().stream() - .filter(container -> !getContainerName(container).startsWith(Constants.IOFOG_DOCKER_CONTAINER_NAME_PREFIX)) - .collect(Collectors.toList()); - } - public Optional getContainerStats(String containerId) { StatsCmd statsCmd = dockerClient.statsCmd(containerId); CountDownLatch countDownLatch = new CountDownLatch(1); From 35338da26a3a52c8ac1ed07074d63e70ab446a19 Mon Sep 17 00:00:00 2001 From: epankou Date: Sat, 29 Dec 2018 16:39:06 +0300 Subject: [PATCH 09/11] Bug(fix) strace: fixed method getpid (EWC-421) --- .../diagnostics/strace/StraceDiagnosticManger.java | 8 +++++--- .../eclipse/iofog/process_manager/DockerUtil.java | 14 ++++++++++++++ .../iofog/process_manager/ProcessManager.java | 3 +-- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/daemon/src/org/eclipse/iofog/diagnostics/strace/StraceDiagnosticManger.java b/daemon/src/org/eclipse/iofog/diagnostics/strace/StraceDiagnosticManger.java index 5995327a..c8fdf28e 100644 --- a/daemon/src/org/eclipse/iofog/diagnostics/strace/StraceDiagnosticManger.java +++ b/daemon/src/org/eclipse/iofog/diagnostics/strace/StraceDiagnosticManger.java @@ -15,10 +15,12 @@ import org.eclipse.iofog.command_line.util.CommandShellExecutor; import org.eclipse.iofog.command_line.util.CommandShellResultSet; -import org.eclipse.iofog.utils.Constants; +import org.eclipse.iofog.process_manager.DockerUtil; import org.eclipse.iofog.utils.logging.LoggingService; -import javax.json.*; +import javax.json.JsonArray; +import javax.json.JsonObject; +import javax.json.JsonValue; import java.util.List; import java.util.Optional; import java.util.concurrent.CopyOnWriteArrayList; @@ -82,7 +84,7 @@ private Optional getStraceDataByMicroserviceUuid(String public void enableMicroserviceStraceDiagnostics(String microserviceUuid) { try { - int pid = getPidByMicroserviceUuid(Constants.IOFOG_DOCKER_CONTAINER_NAME_PREFIX + microserviceUuid); + int pid = getPidByMicroserviceUuid(DockerUtil.getContainerName(microserviceUuid)); MicroserviceStraceData newMicroserviceStraceData = new MicroserviceStraceData(microserviceUuid, pid, true); this.monitoringMicroservices.removeIf( oldMicroserviceStraceData -> oldMicroserviceStraceData.getMicroserviceUuid().equals(microserviceUuid) diff --git a/daemon/src/org/eclipse/iofog/process_manager/DockerUtil.java b/daemon/src/org/eclipse/iofog/process_manager/DockerUtil.java index c5733128..2891907a 100755 --- a/daemon/src/org/eclipse/iofog/process_manager/DockerUtil.java +++ b/daemon/src/org/eclipse/iofog/process_manager/DockerUtil.java @@ -200,10 +200,24 @@ public String getContainerName(Container container) { return container.getNames()[0].substring(1); } + /** + * gets microsreviceUuid (basically just gets substring of container name) + * @param container Container object + * @return microsreviceUuid + */ public String getContainerMicroserviceUuid(Container container) { return getContainerName(container).substring(Constants.IOFOG_DOCKER_CONTAINER_NAME_PREFIX.length()); } + /** + * gets container name by microserviceUuid + * @param microserviceUuid + * @return container name + */ + public static String getContainerName(String microserviceUuid) { + return Constants.IOFOG_DOCKER_CONTAINER_NAME_PREFIX + microserviceUuid; + } + /** * returns a {@link Container} if exists * diff --git a/daemon/src/org/eclipse/iofog/process_manager/ProcessManager.java b/daemon/src/org/eclipse/iofog/process_manager/ProcessManager.java index 9d6435d6..46a9a4a6 100644 --- a/daemon/src/org/eclipse/iofog/process_manager/ProcessManager.java +++ b/daemon/src/org/eclipse/iofog/process_manager/ProcessManager.java @@ -20,7 +20,6 @@ import org.eclipse.iofog.microservice.MicroserviceState; import org.eclipse.iofog.microservice.MicroserviceStatus; import org.eclipse.iofog.status_reporter.StatusReporter; -import org.eclipse.iofog.utils.Constants; import org.eclipse.iofog.utils.Constants.ModulesStatus; import org.eclipse.iofog.utils.configuration.Configuration; @@ -202,7 +201,7 @@ private void deleteRemainingMicroservices() { oldAgentMicroserviceUuids.add(uuid); } else if (!isCurrentMicroserviceUuid && !isLatestMicroserviceUuid - && runningContainerNames.contains(Constants.IOFOG_DOCKER_CONTAINER_NAME_PREFIX + uuid)) { + && runningContainerNames.contains(DockerUtil.getContainerName(uuid))) { unknownMicroserviceUuids.add(uuid); } else if (!isCurrentMicroserviceUuid && !isLatestMicroserviceUuid From 641123b5978ab8713f7287c2070512ef0c741239 Mon Sep 17 00:00:00 2001 From: epankou Date: Wed, 2 Jan 2019 19:11:38 +0300 Subject: [PATCH 10/11] Bug(fix) strace: added method to kill orphaned processes (EWC-421) --- .../util/CommandShellExecutor.java | 241 ++++++++++-------- .../strace/StraceDiagnosticManger.java | 16 +- 2 files changed, 144 insertions(+), 113 deletions(-) diff --git a/daemon/src/org/eclipse/iofog/command_line/util/CommandShellExecutor.java b/daemon/src/org/eclipse/iofog/command_line/util/CommandShellExecutor.java index 34e240fa..63499462 100755 --- a/daemon/src/org/eclipse/iofog/command_line/util/CommandShellExecutor.java +++ b/daemon/src/org/eclipse/iofog/command_line/util/CommandShellExecutor.java @@ -34,116 +34,133 @@ * on 2/7/18. */ public class CommandShellExecutor { - private static final String MODULE_NAME = "CommandShellExecutor"; - private static final String CMD = "/bin/sh"; - private static final String CMD_WIN = "powershell"; - - - public static CommandShellResultSet, List> executeCommand(String command) { - String[] fullCommand = computeCommand(command); - return execute(fullCommand); - } - - public static CommandShellResultSet, List> executeScript(String script, String... args) { - String[] fullCommand = computeScript(script, args); - return execute(fullCommand); - } - - public static void executeDynamicCommand(String command, CommandShellResultSet, List> resultSet, AtomicBoolean isRun) { - String[] fullCommand = computeCommand(command); - executeDynamic(fullCommand, resultSet, isRun); - } - - private static CommandShellResultSet, List> execute( String[] fullCommand) { - CommandShellResultSet, List> resultSet = null; - try { - Process process = Runtime.getRuntime().exec(fullCommand); - List value = readOutput(process, Process::getInputStream); - List errors = readOutput(process, Process::getErrorStream); - resultSet = new CommandShellResultSet<>(value, errors); - } catch (IOException e) { - LoggingService.logWarning(MODULE_NAME, e.getMessage()); - } - return resultSet; - } - - private static void executeDynamic( String[] fullCommand, CommandShellResultSet, List> resultSet, AtomicBoolean isRun) { - try { - Process process = Runtime.getRuntime().exec(fullCommand); - - Runnable readVal = () -> { - readOutputDynamic(process, Process::getInputStream, resultSet.getValue(), isRun); - }; - new Thread(readVal).start(); - - Runnable readErr = () -> { - readOutputDynamic(process, Process::getErrorStream, resultSet.getError(), isRun); - }; - new Thread(readErr).start(); - - } catch (IOException e) { - LoggingService.logWarning(MODULE_NAME, e.getMessage()); - } - } - - - public static CommandShellResultSet executeCommand(String command, Function, List>, CommandShellResultSet> mapper) { - return executeCommand(command).map(mapper); - } - - private static String[] computeCommand(String command) { - return new String[]{ - SystemUtils.IS_OS_WINDOWS ? CMD_WIN : CMD, - "-c", - command - }; - } - - private static String[] computeScript(String script, String... args) { - String[] command = { - SystemUtils.IS_OS_WINDOWS ? CMD_WIN : CMD, - script - }; - - Stream s1 = Arrays.stream(command); - Stream s2 = Arrays.stream(args); - return Stream.concat(s1, s2).toArray(String[]::new); - } - - private static List readOutput(Process process, Function streamExtractor) throws IOException { - List result = new ArrayList<>(); - String line; - try (BufferedReader stdInput = new BufferedReader(new - InputStreamReader(streamExtractor.apply(process), UTF_8))) { - while ((line = stdInput.readLine()) != null) { - result.add(line); - } - } - return result; - } - - private static void readOutputDynamic(Process process, Function streamExtractor, List result, - AtomicBoolean isRun) { - String line; - if (result == null) { - return; - } - try (BufferedReader stdInput = new BufferedReader(new - InputStreamReader(streamExtractor.apply(process)))) { - - while (isRun != null && isRun.get()) { - line = stdInput.readLine(); - if (line != null) { - result.add(line); - } else { - Thread.sleep(3000); - } - } - } catch (InterruptedException | IOException e) { - LoggingService.logWarning(MODULE_NAME, e.getMessage()); - } finally { - process.destroy(); - } - } + private static final String MODULE_NAME = "CommandShellExecutor"; + private static final String CMD = "/bin/sh"; + private static final String CMD_WIN = "powershell"; + + + public static CommandShellResultSet, List> executeCommand(String command) { + String[] fullCommand = computeCommand(command); + return execute(fullCommand); + } + + public static CommandShellResultSet, List> executeScript(String script, String... args) { + String[] fullCommand = computeScript(script, args); + return execute(fullCommand); + } + + public static void executeDynamicCommand(String command, + CommandShellResultSet, List> resultSet, + AtomicBoolean isRun, + Runnable killOrphanedProcessesRunnable) { + String[] fullCommand = computeCommand(command); + executeDynamic(fullCommand, resultSet, isRun, killOrphanedProcessesRunnable); + } + + private static CommandShellResultSet, List> execute(String[] fullCommand) { + CommandShellResultSet, List> resultSet = null; + try { + Process process = Runtime.getRuntime().exec(fullCommand); + List value = readOutput(process, Process::getInputStream); + List errors = readOutput(process, Process::getErrorStream); + resultSet = new CommandShellResultSet<>(value, errors); + } catch (IOException e) { + LoggingService.logWarning(MODULE_NAME, e.getMessage()); + } + return resultSet; + } + + private static void executeDynamic(String[] fullCommand, + CommandShellResultSet, List> resultSet, + AtomicBoolean isRun, + Runnable killOrphanedProcessesRunnable) { + try { + Process process = Runtime.getRuntime().exec(fullCommand); + + Runnable readVal = () -> { + readOutputDynamic(process, Process::getInputStream, resultSet.getValue(), isRun, killOrphanedProcessesRunnable); + }; + new Thread(readVal).start(); + + Runnable readErr = () -> { + readOutputDynamic(process, Process::getErrorStream, resultSet.getError(), isRun, killOrphanedProcessesRunnable); + }; + new Thread(readErr).start(); + + } catch (IOException e) { + LoggingService.logWarning(MODULE_NAME, e.getMessage()); + } + } + + + public static CommandShellResultSet executeCommand(String command, Function, List>, CommandShellResultSet> mapper) { + return executeCommand(command).map(mapper); + } + + private static String[] computeCommand(String command) { + return new String[]{ + SystemUtils.IS_OS_WINDOWS ? CMD_WIN : CMD, + "-c", + command + }; + } + + private static String[] computeScript(String script, String... args) { + String[] command = { + SystemUtils.IS_OS_WINDOWS ? CMD_WIN : CMD, + script + }; + + Stream s1 = Arrays.stream(command); + Stream s2 = Arrays.stream(args); + return Stream.concat(s1, s2).toArray(String[]::new); + } + + private static List readOutput(Process process, Function streamExtractor) throws IOException { + List result = new ArrayList<>(); + String line; + try (BufferedReader stdInput = new BufferedReader(new + InputStreamReader(streamExtractor.apply(process), UTF_8))) { + while ((line = stdInput.readLine()) != null) { + result.add(line); + } + } + return result; + } + + private static void readOutputDynamic(Process process, + Function streamExtractor, + List result, + AtomicBoolean isRun, + Runnable killOrphanedProcessesRunnable) { + StringBuilder line = new StringBuilder(); + if (result == null) { + return; + } + try (BufferedReader reader = new BufferedReader(new + InputStreamReader(streamExtractor.apply(process)))) { + + while (isRun != null && isRun.get()) { + if (reader.ready()) { + int c = reader.read(); + if (c == -1) { + break; + } + if (System.lineSeparator().contains(Character.toString((char)c)) && line.length() != 0) { + result.add(line.toString()); + line.setLength(0); + } else { + line.append((char)c); + } + } else { + Thread.sleep(3000); + } + } + } catch (InterruptedException | IOException e) { + LoggingService.logWarning(MODULE_NAME, e.getMessage()); + } finally { + process.destroy(); + killOrphanedProcessesRunnable.run(); + } + } } diff --git a/daemon/src/org/eclipse/iofog/diagnostics/strace/StraceDiagnosticManger.java b/daemon/src/org/eclipse/iofog/diagnostics/strace/StraceDiagnosticManger.java index c8fdf28e..f1c64c54 100644 --- a/daemon/src/org/eclipse/iofog/diagnostics/strace/StraceDiagnosticManger.java +++ b/daemon/src/org/eclipse/iofog/diagnostics/strace/StraceDiagnosticManger.java @@ -117,7 +117,21 @@ private int getPidByMicroserviceUuid(String microserviceUuid) throws IllegalArgu private void runStrace(MicroserviceStraceData microserviceStraceData) { String straceCommand = "strace -p " + microserviceStraceData.getPid(); CommandShellResultSet, List> resultSet = new CommandShellResultSet<>(null, microserviceStraceData.getResultBuffer()); - CommandShellExecutor.executeDynamicCommand(straceCommand, resultSet, microserviceStraceData.getStraceRun()); + CommandShellExecutor.executeDynamicCommand( + straceCommand, + resultSet, + microserviceStraceData.getStraceRun(), + killOrphanedStraceProcessesRunnable() + ); + } + + private Runnable killOrphanedStraceProcessesRunnable() { + return () -> { + CommandShellResultSet, List> resultSet = CommandShellExecutor.executeCommand("pgrep strace"); + if (resultSet.getValue() != null) { + resultSet.getValue().forEach(value -> CommandShellExecutor.executeCommand(String.format("kill -9 %s", value))); + } + }; } } From ffa91375934cc8a6c63f9c97a261c7fa56cdb17b Mon Sep 17 00:00:00 2001 From: epankou Date: Thu, 3 Jan 2019 12:37:13 +0300 Subject: [PATCH 11/11] Bug(fix) strace: added method to kill orphaned processes (EWC-421) --- .../eclipse/iofog/command_line/util/CommandShellExecutor.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/daemon/src/org/eclipse/iofog/command_line/util/CommandShellExecutor.java b/daemon/src/org/eclipse/iofog/command_line/util/CommandShellExecutor.java index 63499462..d16d1dd8 100755 --- a/daemon/src/org/eclipse/iofog/command_line/util/CommandShellExecutor.java +++ b/daemon/src/org/eclipse/iofog/command_line/util/CommandShellExecutor.java @@ -160,7 +160,9 @@ private static void readOutputDynamic(Process process, LoggingService.logWarning(MODULE_NAME, e.getMessage()); } finally { process.destroy(); - killOrphanedProcessesRunnable.run(); + if (killOrphanedProcessesRunnable != null) { + killOrphanedProcessesRunnable.run(); + } } } }