diff --git a/.gitignore b/.gitignore
index ed439f2..015127e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,6 +15,7 @@ test-output/
.classpath
.settings/
.metadata/
+**TestingPivotalClient.java
.idea/
*.iml
@@ -30,3 +31,4 @@ brooklyn*.log.*
*brooklyn-persisted-state/
ignored
+**pivotal.properties
diff --git a/README.md b/README.md
index 0b07061..25ed90c 100644
--- a/README.md
+++ b/README.md
@@ -5,3 +5,4 @@
- Integrate TOSCA-based object model.
- Integrate Lombok
- Dockerized testing
+
diff --git a/core/pom.xml b/core/pom.xml
index 3ad71bf..c21b35c 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -65,7 +65,41 @@
test
+
+
+
+
+ org.apache.commons
+ commons-math3
+ 3.6
+ test
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/core/src/main/java/org/scenic/orchestrator/Application.java b/core/src/main/java/org/scenic/orchestrator/Application.java
index cd2d451..cb124e6 100644
--- a/core/src/main/java/org/scenic/orchestrator/Application.java
+++ b/core/src/main/java/org/scenic/orchestrator/Application.java
@@ -3,6 +3,7 @@
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
+import org.springframework.context.annotation.PropertySource;
import org.springframework.scheduling.annotation.EnableScheduling;
/**
diff --git a/core/src/main/java/org/scenic/orchestrator/config/PivotalClientConfiguration.java b/core/src/main/java/org/scenic/orchestrator/config/PivotalClientConfiguration.java
new file mode 100644
index 0000000..c67eac1
--- /dev/null
+++ b/core/src/main/java/org/scenic/orchestrator/config/PivotalClientConfiguration.java
@@ -0,0 +1,26 @@
+package org.scenic.orchestrator.config;
+
+import org.scenic.orchestrator.core.pivotal.PivotalClient;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.PropertySource;
+
+/**
+ * Created by Jose on 10/12/19.
+ */
+@Configuration
+@PropertySource("classpath:pivotal.properties")
+public class PivotalClientConfiguration {
+
+ @Value("${pivotalUser}")
+ private String pivotalUser;
+
+ @Value("${pivotalPass}")
+ private String pivotalPass;
+
+ @Bean
+ public PivotalClient pivotalClient() {
+ return new PivotalClient(pivotalUser, pivotalPass);
+ }
+}
diff --git a/core/src/main/java/org/scenic/orchestrator/config/ThreadPoolExecutorConfig.java b/core/src/main/java/org/scenic/orchestrator/config/ThreadPoolExecutorConfig.java
new file mode 100644
index 0000000..6afff10
--- /dev/null
+++ b/core/src/main/java/org/scenic/orchestrator/config/ThreadPoolExecutorConfig.java
@@ -0,0 +1,53 @@
+package org.scenic.orchestrator.config;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import org.scenic.orchestrator.core.service.plan.PlanStepExecutor;
+import org.scenic.orchestrator.core.service.plan.strategy.ParallelStepExecutorStrategy;
+import org.scenic.orchestrator.core.service.plan.strategy.SingleStepExecutorStrategy;
+import org.scenic.orchestrator.manager.ManagerAnalyzerClient;
+import org.scenic.orchestrator.manager.SecuentialManagerAnalyzerClient;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Profile;
+import org.springframework.web.client.RestTemplate;
+
+/**
+ * Created by Jose on 01/10/19.
+ */
+@Configuration
+public class ThreadPoolExecutorConfig {
+
+ @Bean(destroyMethod = "shutdown")
+ public ExecutorService executorService() {
+ return Executors.newFixedThreadPool(10);
+ }
+
+ @Bean
+ @Profile("!secuential")
+ ParallelStepExecutorStrategy parallelStepExecutorStrategy(PlanStepExecutor planStepExecutor,
+ ExecutorService executorService) {
+ return new ParallelStepExecutorStrategy(planStepExecutor, executorService);
+ }
+
+ @Bean
+ @Profile("!secuential")
+ ManagerAnalyzerClient managerAnalyzerClient(RestTemplate restTemplate){
+ return new ManagerAnalyzerClient(restTemplate);
+ }
+
+ @Bean
+ @Profile("secuential")
+ SingleStepExecutorStrategy singleStepExecutorStrategy(PlanStepExecutor planStepExecutor) {
+ return new SingleStepExecutorStrategy(planStepExecutor);
+ }
+
+
+ @Bean
+ @Profile("secuential")
+ ManagerAnalyzerClient secuentialManagerAnalyzerClient(RestTemplate restTemplate){
+ return new SecuentialManagerAnalyzerClient(restTemplate);
+ }
+}
diff --git a/core/src/main/java/org/scenic/orchestrator/core/UpdateStatusScheduler.java b/core/src/main/java/org/scenic/orchestrator/core/UpdateStatusScheduler.java
new file mode 100644
index 0000000..5fd6a69
--- /dev/null
+++ b/core/src/main/java/org/scenic/orchestrator/core/UpdateStatusScheduler.java
@@ -0,0 +1,25 @@
+package org.scenic.orchestrator.core;
+
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+/**
+ * Created by Jose on 17/10/19.
+ */
+@ConditionalOnProperty(name="scheduleUpdating")
+@Component
+public class UpdateStatusScheduler {
+
+ private final UpdaterManagement updaterManagement;
+
+ public UpdateStatusScheduler(UpdaterManagement updaterManagement) {
+ this.updaterManagement = updaterManagement;
+ }
+
+ @Scheduled(fixedRateString = "${instructionSchedularTime}")
+ public void deployApp() throws InterruptedException {
+ updaterManagement.updateApplication();
+ }
+
+}
diff --git a/core/src/main/java/org/scenic/orchestrator/core/UpdaterManagement.java b/core/src/main/java/org/scenic/orchestrator/core/UpdaterManagement.java
index 124b89c..a1f13ca 100644
--- a/core/src/main/java/org/scenic/orchestrator/core/UpdaterManagement.java
+++ b/core/src/main/java/org/scenic/orchestrator/core/UpdaterManagement.java
@@ -15,7 +15,6 @@
@Component
public class UpdaterManagement {
-
private final ManagementContext managementContext;
private PlanManager planManager;
@@ -24,8 +23,7 @@ public UpdaterManagement(ManagementContext managementContext, PlanManager planMa
this.planManager = planManager;
}
-
- @Scheduled(fixedRateString = "${instructionSchedularTime}")
+ //@Scheduled(fixedRateString = "${instructionSchedularTime}")
public void updateApplication() {
List applicationsToUpdate = MutableList.of();
@@ -41,6 +39,7 @@ public void updateApplication() {
@Async("threadPoolTaskExecutor")
public void manageApplication(RunningAppContext appContext){
+ System.out.println("Checking updating");
planManager.update(appContext);
managementContext.addRunningAppContext(appContext);
}
diff --git a/core/src/main/java/org/scenic/orchestrator/core/deployer/DeployerProxy.java b/core/src/main/java/org/scenic/orchestrator/core/deployer/DeployerProxy.java
index ac70aeb..4b02f00 100644
--- a/core/src/main/java/org/scenic/orchestrator/core/deployer/DeployerProxy.java
+++ b/core/src/main/java/org/scenic/orchestrator/core/deployer/DeployerProxy.java
@@ -27,9 +27,14 @@ public class DeployerProxy {
private static final String START_EFFECTOR_NAME = "start";
private static final String STOP_EFFECTOR_NAME = "stop";
+ private static final String RESTART_EFFECTOR_NAME = "restart";
+
private static final String STOP_MACHINE_MODE = "stopMachineMode";
private static final String STOP_MACHINE_IF_NOT_STOPPED = "IF_NOT_STOPPED";
+ private static final String STOP_PROCESS_MODE = "stopProcessMode";
+ private static final String STOP_PROCESS_MODE_NEVER = "NEVER";
+
private final BrooklynApi brooklynApi;
private final ApplicationApi applicationApi;
@@ -74,6 +79,19 @@ public void stopEffector(RunningAppContext app, String entityId) {
executeEffector(effectorTemplate);
}
+ public void restartEffector(RunningAppContext app, String entityId) {
+ EffectorTemplate effectorTemplate =
+ new EffectorTemplate(app, entityId, RESTART_EFFECTOR_NAME, getRestartBody());
+ executeEffector(effectorTemplate);
+ }
+
+
+ public void releaseEffector(RunningAppContext app, String entityId) {
+ EffectorTemplate effectorTemplate =
+ new EffectorTemplate(app, entityId, STOP_EFFECTOR_NAME, getReleaseBody());
+ executeEffector(effectorTemplate);
+ }
+
private void executeEffector(EffectorTemplate effectorTemplate) {
try {
restBrooklynClient.executeEffector(effectorTemplate);
@@ -87,6 +105,29 @@ private void executeEffector(EffectorTemplate effectorTemplate) {
}
public String getStopBody() {
+ try {
+ return objectMapper.writeValueAsString(MutableMap.of(
+ STOP_MACHINE_MODE, STOP_PROCESS_MODE_NEVER,
+ STOP_PROCESS_MODE, STOP_MACHINE_IF_NOT_STOPPED
+ ));
+ } catch (Exception e) {
+ throw new RuntimeException("STOP params can not be generated", e);
+ }
+ }
+ public String getRestartBody() {
+ try {
+ return objectMapper.writeValueAsString(MutableMap.of(
+
+ ));
+ } catch (Exception e) {
+ throw new RuntimeException("STOP params can not be generated", e);
+ }
+ }
+
+
+
+
+ public String getReleaseBody() {
try {
return objectMapper.writeValueAsString(MutableMap.of(STOP_MACHINE_MODE, STOP_MACHINE_IF_NOT_STOPPED));
} catch (Exception e) {
diff --git a/core/src/main/java/org/scenic/orchestrator/core/deployer/dto/BrooklynEntityStatus.java b/core/src/main/java/org/scenic/orchestrator/core/deployer/dto/BrooklynEntityStatus.java
index 237b659..f997438 100644
--- a/core/src/main/java/org/scenic/orchestrator/core/deployer/dto/BrooklynEntityStatus.java
+++ b/core/src/main/java/org/scenic/orchestrator/core/deployer/dto/BrooklynEntityStatus.java
@@ -6,9 +6,10 @@
public enum BrooklynEntityStatus {
RUNNING,
+ STARTING,
ON_FIRE,
CREATED,
- STOPPED
-
+ STOPPED,
+ STOPPING
}
diff --git a/core/src/main/java/org/scenic/orchestrator/core/deployer/dto/CustomEntity.java b/core/src/main/java/org/scenic/orchestrator/core/deployer/dto/CustomEntity.java
index da04780..75c4417 100644
--- a/core/src/main/java/org/scenic/orchestrator/core/deployer/dto/CustomEntity.java
+++ b/core/src/main/java/org/scenic/orchestrator/core/deployer/dto/CustomEntity.java
@@ -1,7 +1,12 @@
package org.scenic.orchestrator.core.deployer.dto;
+import static java.util.Arrays.stream;
+
+import java.util.List;
import java.util.Map;
+import org.apache.brooklyn.rest.domain.LocationSummary;
+import org.springframework.core.ParameterizedTypeReference;
import org.springframework.web.client.RestTemplate;
/**
@@ -71,10 +76,55 @@ public Boolean isUp() {
return brooklynRestTemplate.getForEntity(sensorlink + IS_UP_SENSOR, Boolean.class).getBody();
}
- public BrooklynEntityStatus status() {
+ public BrooklynEntityStatus getStatus() {
return brooklynRestTemplate.getForEntity(sensorlink + STATUS_SENSOR, BrooklynEntityStatus.class).getBody();
}
+ public String getSensor(String sensorName){
+ return brooklynRestTemplate.getForEntity(sensorlink +"/" +sensorName, String.class).getBody();
+ }
+
+ public boolean hasSshLiveCloudResources(){
+ return stream(brooklynRestTemplate.getForEntity(getLinks().get("locations"), LocationSummary[].class).getBody())
+ .anyMatch(this::hasSshResources);
+ }
+
+ private boolean hasSshResources(LocationSummary l){
+ return l.getType().toLowerCase().contains("ssh");
+ }
+
+ public boolean isInPaas(){
+ return stream(brooklynRestTemplate.getForEntity(getLinks().get("locations"), LocationSummary[].class).getBody())
+ .anyMatch(l -> l.getType().toLowerCase().contains("cloudfoundrypaaslocation"));
+ }
+
+ public static class LocationSummary{
+
+ String id;
+ String type;
+
+ public LocationSummary(){
+ this.id=null;
+ this.type=null;
+ }
+
+ public String getId(){
+ return id;
+ }
+
+ public String getType(){
+ return type;
+ }
+
+ public String setId(String id){
+ return this.id=id;
+ }
+
+ public String getType(String type){
+ return this.type=type;
+ }
+ }
+
/*"id": "nDQUMK7J",
"name": "SoftcareWS",
"type": "org.apache.brooklyn.entity.webapp.tomcat.TomcatServer",
@@ -97,6 +147,4 @@ public BrooklynEntityStatus status() {
"catalog": "/v1/catalog/entities/org.apache.brooklyn.entity.webapp.tomcat.TomcatServer/0.9.0"
}
*/
-
-
}
diff --git a/core/src/main/java/org/scenic/orchestrator/core/dto/EntityStatus.java b/core/src/main/java/org/scenic/orchestrator/core/dto/EntityStatus.java
index 1bfc509..dca5bc3 100644
--- a/core/src/main/java/org/scenic/orchestrator/core/dto/EntityStatus.java
+++ b/core/src/main/java/org/scenic/orchestrator/core/dto/EntityStatus.java
@@ -11,7 +11,9 @@ public enum EntityStatus {
UNAVAILABLE("unavailable"),
STARTED("started"),
STOPPED("stopped"),
- FAILED("failed");
+ FAILED("failed"),
+ RELEASED("failed"),
+ ;
private final String alias;
diff --git a/core/src/main/java/org/scenic/orchestrator/core/dto/InitialAppStatusService.java b/core/src/main/java/org/scenic/orchestrator/core/dto/InitialAppStatusService.java
index 446a3fc..e50ceff 100644
--- a/core/src/main/java/org/scenic/orchestrator/core/dto/InitialAppStatusService.java
+++ b/core/src/main/java/org/scenic/orchestrator/core/dto/InitialAppStatusService.java
@@ -27,6 +27,10 @@ public ApplicationStatus build(String appTopology) {
return build(getNodeTemplateNames(appTopology));
}
+ public ApplicationStatus buildSycn(String appTopology) {
+ return buildSycn(getNodeTemplateNames(appTopology));
+ }
+
public ApplicationStatus build(List entityNames) {
Map current = new HashMap<>();
Map target = new HashMap<>();
@@ -38,6 +42,17 @@ public ApplicationStatus build(List entityNames) {
return new ApplicationStatus(current, target);
}
+ public ApplicationStatus buildSycn(List entityNames) {
+ Map current = new HashMap<>();
+ Map target = new HashMap<>();
+ for (String entityName : entityNames) {
+ current.put(entityName, EntityStatus.STARTED);
+ target.put(entityName, EntityStatus.STARTED);
+ }
+
+ return new ApplicationStatus(current, target);
+ }
+
private List getNodeTemplateNames(String app) {
final Map obj = yaml.load(app);
return new LinkedList<>(((Map) ((Map) obj.get(TOPOLOGY_TEMPLATE)).get(NODE_TEMPLATES)).keySet());
diff --git a/core/src/main/java/org/scenic/orchestrator/core/dto/Plan.java b/core/src/main/java/org/scenic/orchestrator/core/dto/Plan.java
index 619c5f3..61dac7a 100644
--- a/core/src/main/java/org/scenic/orchestrator/core/dto/Plan.java
+++ b/core/src/main/java/org/scenic/orchestrator/core/dto/Plan.java
@@ -4,10 +4,12 @@
import java.util.List;
import java.util.stream.Collectors;
+import com.fasterxml.jackson.annotation.JsonAlias;
import com.fasterxml.jackson.annotation.JsonIgnore;
public class Plan {
+ @JsonAlias({"parallelSteps", "plan"})
private List plan;
public Plan() {
diff --git a/core/src/main/java/org/scenic/orchestrator/core/dto/PlanOperation.java b/core/src/main/java/org/scenic/orchestrator/core/dto/PlanOperation.java
index c4e9070..b5dd62b 100644
--- a/core/src/main/java/org/scenic/orchestrator/core/dto/PlanOperation.java
+++ b/core/src/main/java/org/scenic/orchestrator/core/dto/PlanOperation.java
@@ -10,7 +10,8 @@ public enum PlanOperation {
START("start"),
STOP("stop"),
- RELEASE("release");
+ RELEASE("release"),
+ RESTART("restart");
private String alias;
diff --git a/core/src/main/java/org/scenic/orchestrator/core/dto/RunningAppContext.java b/core/src/main/java/org/scenic/orchestrator/core/dto/RunningAppContext.java
index eb0b753..1e2aa16 100644
--- a/core/src/main/java/org/scenic/orchestrator/core/dto/RunningAppContext.java
+++ b/core/src/main/java/org/scenic/orchestrator/core/dto/RunningAppContext.java
@@ -1,8 +1,14 @@
package org.scenic.orchestrator.core.dto;
+import static java.util.Arrays.stream;
+import static java.util.stream.Collectors.toList;
+
+import java.util.List;
+
import org.scenic.orchestrator.core.deployer.dto.BrooklynEntityStatus;
import org.scenic.orchestrator.core.deployer.dto.CustomApplicationEntities;
import org.scenic.orchestrator.core.deployer.dto.CustomEntity;
+import org.scenic.orchestrator.core.pivotal.PivotalClient;
/**
* Created by Jose on 23/01/19.
@@ -18,13 +24,15 @@ public class RunningAppContext {
private String applicationTopology;
private String appId;
private CustomApplicationEntities entities;
+ private PivotalClient pivotalClient;
- public RunningAppContext(String applicationName, ApplicationStatus status, Plan plan, String applicationTopology) {
+ public RunningAppContext(String applicationName, ApplicationStatus status, Plan plan, String applicationTopology, PivotalClient pivotalClient) {
this.status = status;
this.applicationName = applicationName;
this.plan = plan;
this.applicationTopology = applicationTopology;
+ this.pivotalClient = pivotalClient;
}
public ApplicationStatus getStatus() {
@@ -76,16 +84,40 @@ public boolean isUp() {
}
public void updateStatus() {
+ System.out.println("-- Update the status from brooklyn -- ");
for (CustomEntity entity : entities.entities()) {
- EntityStatus entityStatus = mapEntityStatus(entity.status());
+ EntityStatus entityStatus = mapEntityStatus(entity);
status.setCurrentEntityStatus(entity.getName(), entityStatus);
+ System.out.println(String.format("%s: %s", entity.getName(), entityStatus));
}
+ System.out.println("[End] -- ");
}
- private EntityStatus mapEntityStatus(BrooklynEntityStatus status) {
+ boolean hasCloudResources(CustomEntity entity) {
+ return entity.hasSshLiveCloudResources() || hasPaasResourcesAssociated(entity);
+ }
+
+
+ private EntityStatus mapEntityStatus(CustomEntity entity) {
+
+ BrooklynEntityStatus status = entity.getStatus();
+
+ while (status == BrooklynEntityStatus.STOPPING) {
+ System.out.println("## UNSUPPORTED STOPPING status for entity " + entity.getName());
+ try {
+ Thread.sleep(5000l);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ status = entity.getStatus();
+ }
+ boolean hasLiveCloudResources = hasCloudResources(entity);
switch (status) {
case RUNNING:
+ case STARTING:
return EntityStatus.STARTED;
+ case STOPPED:
+ return hasLiveCloudResources ? EntityStatus.STOPPED : EntityStatus.UNAVAILABLE;
case ON_FIRE:
return EntityStatus.FAILED;
case CREATED:
@@ -93,4 +125,45 @@ private EntityStatus mapEntityStatus(BrooklynEntityStatus status) {
return EntityStatus.UNAVAILABLE;
}
}
+
+ private boolean hasPaasResourcesAssociated(CustomEntity entity) {
+ System.out.println("checking if pass " + entity.getName());
+ if (entity.isInPaas()) {
+ System.out.println("is pass ");
+ boolean r = applicationExistsInPivotal(entity);
+ System.out.println("Application exist?" + r);
+ System.out.println("-------------------------");
+ return r;
+ }
+ System.out.println("is NOt pass ");
+ System.out.println("-------------------------");
+ return false;
+ }
+
+ private boolean applicationExistsInPivotal(CustomEntity entity) {
+ String webName = webAppDeployedWar(entity).replace("\"", "");
+ System.out.println("checking paas resources with name==> " + webName);
+ Boolean result = null;
+ int loop = 0;
+ while (result == null) {
+ try {
+ result = pivotalClient.applicationExist(webName);
+ } catch (Exception e) {
+ loop++;
+ if (loop > 11) {
+ throw e;
+ }
+ }
+ }
+ return result;
+ }
+
+ private String webAppDeployedWar(CustomEntity entity) {
+ return toStringList(entity.getSensor("webapp.deployedWars")).get(0);
+ }
+
+ private List toStringList(String value) {
+ return stream(value.replace("[", "").replace("]", "").split(",")).map(String::trim).collect(toList());
+ }
+
}
diff --git a/core/src/main/java/org/scenic/orchestrator/core/pivotal/PivotalClient.java b/core/src/main/java/org/scenic/orchestrator/core/pivotal/PivotalClient.java
new file mode 100644
index 0000000..3664924
--- /dev/null
+++ b/core/src/main/java/org/scenic/orchestrator/core/pivotal/PivotalClient.java
@@ -0,0 +1,103 @@
+package org.scenic.orchestrator.core.pivotal;
+
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URL;
+import java.util.List;
+
+import org.cloudfoundry.client.lib.CloudCredentials;
+import org.cloudfoundry.client.lib.CloudFoundryClient;
+import org.cloudfoundry.client.lib.CloudFoundryException;
+import org.cloudfoundry.client.lib.domain.CloudApplication;
+import org.springframework.http.HttpStatus;
+
+/**
+ * Created by Jose on 10/12/19.
+ */
+
+public class PivotalClient {
+
+ private static CloudFoundryClient CLIENT;
+
+ public PivotalClient(String user, String pass) {
+ setUpClient(user, pass);
+ }
+
+ private static void setUpClient(String pivotalUser, String pivotalPass) {
+ if (CLIENT == null) {
+ CloudCredentials credentials =
+ new CloudCredentials(pivotalUser, pivotalPass);
+ CLIENT = new CloudFoundryClient(credentials, getTargetURL("https://api.run.pivotal.io"),
+ "gsoc", "development", true);
+ CLIENT.login();
+ }
+ }
+
+ public CloudFoundryClient client(){
+ return CLIENT;
+ }
+
+ public void refresh() {
+ int i = 0;
+ while (i < 10)
+ try {
+ CLIENT.login().getRefreshToken();
+ return;
+ } catch (Exception e) {
+ System.out.println("Error in refresh: retrying");
+ i++;
+ if (i == 10) {
+ throw e;
+ }
+ }
+ }
+
+ private static URL getTargetURL(String target) {
+ try {
+ return URI.create(target).toURL();
+ } catch (MalformedURLException e) {
+ throw new RuntimeException("The target URL is not valid: " + e.getMessage());
+ }
+ }
+
+ public List getApplications() {
+ return CLIENT.getApplications();
+ }
+
+ private CloudApplication getApplication(String name) {
+ return CLIENT.getApplication(name);
+
+ }
+
+ public boolean applicationExist(String appName) {
+ System.out.println("Checking if application exist");
+ //int i=0;
+ //int limit=20;
+ //while(i appName.equals(a.getName()));
+ } catch (CloudFoundryException e) {
+ if (e.getStatusCode().equals(HttpStatus.NOT_FOUND)) {
+ System.out.println("NotFoundApplication" + e.getCause());
+ return false;
+ }
+ System.out.println("Retring checking because" + e.getCause());
+ // if(i>limit){
+ throw e;
+ // }
+ } catch (Exception ee) {
+ System.out.println("Retring checking because" + ee.getCause());
+ //if(i>limit){
+ throw ee;
+ //}
+
+ }
+ // i++;
+ //}
+ //return false;
+ }
+}
diff --git a/core/src/main/java/org/scenic/orchestrator/core/pivotal/PivotalHeartbeat.java b/core/src/main/java/org/scenic/orchestrator/core/pivotal/PivotalHeartbeat.java
new file mode 100644
index 0000000..5e01cc6
--- /dev/null
+++ b/core/src/main/java/org/scenic/orchestrator/core/pivotal/PivotalHeartbeat.java
@@ -0,0 +1,44 @@
+package org.scenic.orchestrator.core.pivotal;
+
+import java.time.Instant;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.security.oauth2.common.OAuth2AccessToken;
+
+@Configuration
+public class PivotalHeartbeat {
+
+ private final PivotalClient pivotalClient;
+ OAuth2AccessToken login;
+ public int status=0;
+
+ public PivotalHeartbeat(PivotalClient pivotalClient) {
+ this.pivotalClient = pivotalClient;
+ login = pivotalClient.client().login();
+ }
+
+ @Scheduled(initialDelay = 3_000, fixedRate = 60_000l)
+ public void checkApplications() {
+ try {
+ System.out.println(Instant.now()+": *Heartbeat: " + login.getExpiresIn());
+
+
+ if(status >= 300){
+ System.out.println(Instant.now()+": Status has to been refresed ");
+ this.pivotalClient.refresh();
+ status=0;
+ } else {
+ status = status + 60;
+ }
+
+
+ this.pivotalClient.getApplications();
+ System.out.println(Instant.now()+":Fin refresh: "+ login.getExpiresIn());
+ } catch (Exception e) {
+ System.out.println("------------------------------------------------------------------------------------------------");
+ System.out.println(Instant.now().toString() + ": Error with Pivotal heartbat -----------------------------------> " + e.getCause());
+ System.out.println("------------------------------------------------------------------------------------------------");
+ }
+ }
+}
diff --git a/core/src/main/java/org/scenic/orchestrator/core/service/ApplicationContextManagerService.java b/core/src/main/java/org/scenic/orchestrator/core/service/ApplicationContextManagerService.java
index ca03edf..99986e5 100644
--- a/core/src/main/java/org/scenic/orchestrator/core/service/ApplicationContextManagerService.java
+++ b/core/src/main/java/org/scenic/orchestrator/core/service/ApplicationContextManagerService.java
@@ -2,11 +2,14 @@
import java.util.Map;
+import org.scenic.orchestrator.core.deployer.DeployerProxy;
import org.scenic.orchestrator.core.dto.ApplicationStatus;
import org.scenic.orchestrator.core.dto.InitialAppStatusService;
import org.scenic.orchestrator.core.dto.Plan;
import org.scenic.orchestrator.core.dto.RunningAppContext;
import org.scenic.orchestrator.core.modifier.TopologyModifierService;
+import org.scenic.orchestrator.core.pivotal.PivotalClient;
+import org.scenic.orchestrator.manager.ManagerAnalyzerClient;
import org.springframework.stereotype.Service;
import org.yaml.snakeyaml.Yaml;
@@ -26,27 +29,63 @@ public class ApplicationContextManagerService {
private final TopologyModifierService topologyModifierService;
+ private final DeployerProxy deployerProxy;
+
+ private final PivotalClient pivotalClient;
+
public ApplicationContextManagerService(ManagerAnalyzerClient managerAnalyzerClient, Yaml yaml,
InitialAppStatusService initialAppStatusService,
- TopologyModifierService topologyModifierService) {
+ TopologyModifierService topologyModifierService, DeployerProxy deployerProxy,
+ PivotalClient pivotalClient) {
this.managerAnalyzerClient = managerAnalyzerClient;
this.yaml = yaml;
this.initialAppStatusService = initialAppStatusService;
this.topologyModifierService = topologyModifierService;
+ this.deployerProxy = deployerProxy;
+ this.pivotalClient = pivotalClient;
}
+ //Crea RunningApplication Context
public RunningAppContext postApplicationContext(String applicationTopology) {
+
final String applicationName = getApplicationName(applicationTopology);
+
+ //manda la app a analyzer
managerAnalyzerClient.deployApplication(applicationTopology);
+
+ //actualiza el estado (source) unavailable to (target) started
managerAnalyzerClient.putStatus(applicationName, initialAppStatusService.build(applicationTopology));
+
+ //coge el plan
final Plan plan = managerAnalyzerClient.getPlan(getApplicationName(applicationTopology));
+
+ //Application status es el estado actual de la app
final ApplicationStatus status = initialAppStatusService.build(plan.getEntities());
- return new RunningAppContext(applicationName, status, plan, topologyModifierService.apply(applicationTopology));
+ //Genera un RunningAppContext y lo (guardando la topologia con los midificadores necesarios)
+ return new RunningAppContext(applicationName, status, plan, topologyModifierService.apply(applicationTopology), pivotalClient);
}
private String getApplicationName(String applicationTopology) {
final Map obj = yaml.load(applicationTopology);
return obj.get("template_name").toString();
}
+
+ public RunningAppContext sycnApplication(String applicationTopology, String appId) {
+ //RunningAppContext runningAppContext = postApplicationContext(applicationTopology);
+ final String applicationName = getApplicationName(applicationTopology);
+ managerAnalyzerClient.deployApplication(applicationTopology);
+ ApplicationStatus status = initialAppStatusService.buildSycn(applicationTopology);
+ managerAnalyzerClient.putStatus(applicationName, status);
+
+ //Tiene que ser vacio el plan
+ final Plan plan = managerAnalyzerClient.getPlan(getApplicationName(applicationTopology));
+ RunningAppContext runningAppContext = new RunningAppContext(applicationName, status, plan, topologyModifierService.apply(applicationTopology), pivotalClient);
+ runningAppContext.setAppId(appId);
+
+ System.out.println("Sync the deployed application: " + runningAppContext.getApplicationName() + " with id " + appId);
+ runningAppContext.setEntities(deployerProxy.getApplicationEntities(appId));
+
+ return runningAppContext;
+ }
}
diff --git a/core/src/main/java/org/scenic/orchestrator/core/service/ApplicationSynchronizerService.java b/core/src/main/java/org/scenic/orchestrator/core/service/ApplicationSynchronizerService.java
new file mode 100644
index 0000000..cf55518
--- /dev/null
+++ b/core/src/main/java/org/scenic/orchestrator/core/service/ApplicationSynchronizerService.java
@@ -0,0 +1,33 @@
+package org.scenic.orchestrator.core.service;
+
+import org.scenic.orchestrator.core.ManagementContext;
+import org.scenic.orchestrator.core.dto.RunningAppContext;
+import org.springframework.stereotype.Service;
+
+/**
+ * Contains the logic to orchestrate an application deployment.
+ */
+@Service
+public class ApplicationSynchronizerService {
+
+ private final ApplicationContextManagerService applicationContextManagerService;
+ private final DeploymentOrchestrator deploymentOrchestrator;
+ private final ManagementContext managementContext;
+
+ public ApplicationSynchronizerService(ApplicationContextManagerService applicationContextManagerService,
+ DeploymentOrchestrator deploymentOrchestrator, ManagementContext managementContext) {
+ this.applicationContextManagerService = applicationContextManagerService;
+ this.deploymentOrchestrator=deploymentOrchestrator;
+ this.managementContext=managementContext;
+ }
+
+ public void syncApplication(String applicationTopology, String appId)
+ throws InterruptedException {
+ RunningAppContext runningAppContext = applicationContextManagerService.sycnApplication(applicationTopology, appId);
+ managementContext.addRunningAppContext(runningAppContext);
+ }
+
+
+
+
+}
diff --git a/core/src/main/java/org/scenic/orchestrator/core/service/AsycnDeploymentOrchestrator.java b/core/src/main/java/org/scenic/orchestrator/core/service/AsycnDeploymentOrchestrator.java
index 10aef86..544be3e 100644
--- a/core/src/main/java/org/scenic/orchestrator/core/service/AsycnDeploymentOrchestrator.java
+++ b/core/src/main/java/org/scenic/orchestrator/core/service/AsycnDeploymentOrchestrator.java
@@ -27,12 +27,18 @@ public AsycnDeploymentOrchestrator(DeployerProxy deployerProxy, PlanManager plan
@Override
@Async("threadPoolTaskExecutor")
public void deploy(RunningAppContext runningAppContext) throws InterruptedException {
+
+ //Esto se hace bajo demanda cuando se hace deploy
System.out.println("Start to deploy application: " + runningAppContext.getApplicationName());
String appId = deployerProxy.deployApp(runningAppContext.getApplicationName(), runningAppContext.getApplicationTopology());
+ //Crea la app sin iniciar en brooklyn
+
runningAppContext.setAppId(appId);
System.out.println("Add to the deployer application: " + runningAppContext.getApplicationName() + " with id " + appId);
+ //Pones las entidades en el runnign context
runningAppContext.setEntities(deployerProxy.getApplicationEntities(appId));
System.out.println("Start the management");
+ //
planManager.deploy(runningAppContext);
managementContext.addRunningAppContext(runningAppContext);
}
diff --git a/core/src/main/java/org/scenic/orchestrator/core/service/DeployerService.java b/core/src/main/java/org/scenic/orchestrator/core/service/DeployerService.java
index 2092727..b14540c 100644
--- a/core/src/main/java/org/scenic/orchestrator/core/service/DeployerService.java
+++ b/core/src/main/java/org/scenic/orchestrator/core/service/DeployerService.java
@@ -18,6 +18,12 @@ public DeployerService(ApplicationContextManagerService applicationContextManage
this.deploymentOrchestrator=deploymentOrchestrator;
}
+
+ //Crea la app sin iniciar en brooklyn
+// runningAppContext.setAppId(appId);
+// System.out.println("Add to the deployer application: " + runningAppContext.getApplicationName() + " with id " + appId);
+ // runningAppContext.setEntities(deployerProxy.getApplicationEntities(appId));
+
public void deploy(String applicationTopology)
throws InterruptedException {
RunningAppContext runningAppContext = applicationContextManagerService.postApplicationContext(applicationTopology);
@@ -25,4 +31,6 @@ public void deploy(String applicationTopology)
}
+
+
}
diff --git a/core/src/main/java/org/scenic/orchestrator/core/service/plan/PlanManager.java b/core/src/main/java/org/scenic/orchestrator/core/service/plan/PlanManager.java
index 334fca4..bab22db 100644
--- a/core/src/main/java/org/scenic/orchestrator/core/service/plan/PlanManager.java
+++ b/core/src/main/java/org/scenic/orchestrator/core/service/plan/PlanManager.java
@@ -2,6 +2,7 @@
import org.scenic.orchestrator.core.dto.PlanStep;
import org.scenic.orchestrator.core.dto.RunningAppContext;
+import org.scenic.orchestrator.core.service.plan.strategy.PlanStepExecutorStrategy;
import org.springframework.stereotype.Service;
/**
@@ -11,17 +12,20 @@
public class PlanManager {
- private final PlanExecutor planExecutor;
+ //private final PlanExecutor planExecutor;
private final RunningAppContextSynchronizer runningAppContextSynchronizer;
- private final PlanStepExecutor planStepExecutor;
+ //private final PlanStepExecutor planStepExecutor;
+ private final PlanStepExecutorStrategy strategy;
public PlanManager(PlanExecutor planExecutor,
RunningAppContextSynchronizer runningAppContextSynchronizer,
- PlanStepExecutor planStepExecutor
+ //PlanStepExecutor planStepExecutor
+ PlanStepExecutorStrategy strategy
) {
- this.planExecutor = planExecutor;
+ //this.planExecutor = planExecutor;
this.runningAppContextSynchronizer = runningAppContextSynchronizer;
- this.planStepExecutor = planStepExecutor;
+ //this.planStepExecutor = planStepExecutor;
+ this.strategy = strategy;
}
@@ -32,19 +36,23 @@ public void update(RunningAppContext appContext) {
}
public void deploy(RunningAppContext appContext) {
- /*try {
- this.executePlan(appContext);
- } catch (Exception e) {
- synchronizeAppContext(appContext);
- deploy(appContext);
- }*/
+
System.out.println("Executing application plan for: " + appContext.getApplicationName() + " " + appContext.getAppId());
+
+ //Coge el plan y lo ejecuta en paralelo
while (!appContext.getPlan().isEmpty()) {
- PlanStep firstStep = appContext.getPlan().getPlan().get(0);
- executeStep(appContext, firstStep);
+
+
+ //Cambiar esta linea para coger todo lo que nos de y ejecutarlo en paralelo (hay que cambir el endpoint)
+ //PlanStep firstStep = appContext.getPlan().getPlan().get(0);
+ //executeStep(appContext, firstStep);
+ strategy.executePlan(appContext);
+
+ synchronizeAppContext(appContext);
}
}
+ /*
private void executeStep(RunningAppContext appContext, PlanStep step) {
try {
planStepExecutor.executeStep(step, appContext);
@@ -53,15 +61,18 @@ private void executeStep(RunningAppContext appContext, PlanStep step) {
}
synchronizeAppContext(appContext);
}
-
- private void executePlan(RunningAppContext appContext) {
- planExecutor.executePlan(appContext);
- }
+ */
private void synchronizeAppContext(RunningAppContext appContext) {
- System.out.println("Synchronizing App Context");
+ System.out.println("-------Synchronizing App Context");
appContext.updateStatus();
+
+ //Actualiza el estado en el manager y carga el plan de nuevo
runningAppContextSynchronizer.updateContext(appContext);
}
+ //private void executePlan(RunningAppContext appContext) {
+ // planExecutor.executePlan(appContext);
+ //}
+
}
diff --git a/core/src/main/java/org/scenic/orchestrator/core/service/plan/PlanStepExecutor.java b/core/src/main/java/org/scenic/orchestrator/core/service/plan/PlanStepExecutor.java
index cd44b0d..c245f3d 100644
--- a/core/src/main/java/org/scenic/orchestrator/core/service/plan/PlanStepExecutor.java
+++ b/core/src/main/java/org/scenic/orchestrator/core/service/plan/PlanStepExecutor.java
@@ -23,26 +23,41 @@ public PlanStepExecutor(DeployerProxy deployerProxy) {
public void executeStep(PlanStep step, RunningAppContext context) {
- try{
+ try {
+ System.out.println("PlanStepExecutor.class -- Execute taks: " + step.getOperation());
- if(step.getOperation() == PlanOperation.START) {
- String entityId = context.getEntityByDisplayName(step.getNode()).getId();
- System.out.println(String.format(EXECUTION_MESSAGE, step.getNode(), entityId, step.getOperation()));
- deployerProxy.startEffector(context, entityId);
- context.getStatus().setCurrentEntityStatus(step.getNode(), EntityStatus.STARTED);
- }
- else if((step.getOperation() == PlanOperation.RELEASE ) || (step.getOperation() == PlanOperation.STOP) ){
- String entityId = context.getEntityByDisplayName(step.getNode()).getId();
- System.out.println(String.format(EXECUTION_MESSAGE, step.getNode(), entityId, step.getOperation()));
- deployerProxy.stopEffector(context, entityId);
- context.getStatus().setCurrentEntityStatus(step.getNode(), EntityStatus.UNAVAILABLE);
- }
+ if (step.getOperation() == PlanOperation.START) {
+ String entityId = context.getEntityByDisplayName(step.getNode()).getId();
+ System.out.println(String.format(EXECUTION_MESSAGE, step.getNode(), entityId, step.getOperation()));
+ deployerProxy.startEffector(context, entityId);
+ context.getStatus().setCurrentEntityStatus(step.getNode(), EntityStatus.STARTED);
+ } else if (step.getOperation() == PlanOperation.STOP) {
+ String entityId = context.getEntityByDisplayName(step.getNode()).getId();
+ System.out.println(String.format("[STOP]" + EXECUTION_MESSAGE, step.getNode(), entityId, step.getOperation()));
+
+ deployerProxy.stopEffector(context, entityId);
+
+ context.getStatus().setCurrentEntityStatus(step.getNode(), EntityStatus.STOPPED);
+ } else if (step.getOperation() == PlanOperation.RELEASE) {
+ String entityId = context.getEntityByDisplayName(step.getNode()).getId();
+ System.out.println(String.format("[RELEASING]" + EXECUTION_MESSAGE, step.getNode(), entityId, step.getOperation()));
+ deployerProxy.releaseEffector(context, entityId);
+ context.getStatus().setCurrentEntityStatus(step.getNode(), EntityStatus.UNAVAILABLE);
+
+ } else if (step.getOperation() == PlanOperation.RESTART) {
+ String entityId = context.getEntityByDisplayName(step.getNode()).getId();
+ System.out.println(String.format("[RESTART]" + EXECUTION_MESSAGE, step.getNode(), entityId, step.getOperation()));
+ deployerProxy.restartEffector(context, entityId);
+ context.getStatus().setCurrentEntityStatus(step.getNode(), EntityStatus.UNAVAILABLE);
+
+ }
} catch (Exception e) {
+ String entityId = context.getEntityByDisplayName(step.getNode()).getId();
+ System.out.println(String.format("[ERROR: ]" + EXECUTION_MESSAGE, step.getNode(), entityId, step.getOperation()));
context.getStatus().setCurrentEntityStatus(step.getNode(), EntityStatus.FAILED);
throw e;
}
-
}
diff --git a/core/src/main/java/org/scenic/orchestrator/core/service/plan/RunningAppContextSynchronizer.java b/core/src/main/java/org/scenic/orchestrator/core/service/plan/RunningAppContextSynchronizer.java
index b220052..ee1f6f4 100644
--- a/core/src/main/java/org/scenic/orchestrator/core/service/plan/RunningAppContextSynchronizer.java
+++ b/core/src/main/java/org/scenic/orchestrator/core/service/plan/RunningAppContextSynchronizer.java
@@ -3,7 +3,7 @@
import org.scenic.orchestrator.core.dto.ApplicationStatus;
import org.scenic.orchestrator.core.dto.Plan;
import org.scenic.orchestrator.core.dto.RunningAppContext;
-import org.scenic.orchestrator.core.service.ManagerAnalyzerClient;
+import org.scenic.orchestrator.manager.ManagerAnalyzerClient;
import org.springframework.stereotype.Service;
import com.fasterxml.jackson.databind.ObjectMapper;
@@ -32,8 +32,6 @@ public void updateContext(RunningAppContext appContext) {
System.out.println("--------**");
}
-
- //TODO: avoid this... **** ... with lombok
public String planToString(Plan plan){
try{
return new ObjectMapper().writeValueAsString(plan);
@@ -42,7 +40,6 @@ public String planToString(Plan plan){
}
}
- //TODO: avoid this... **** ... with lombok
public String statusToString(ApplicationStatus status){
try{
return new ObjectMapper().writeValueAsString(status);
diff --git a/core/src/main/java/org/scenic/orchestrator/core/service/plan/strategy/ParallelStepExecutorStrategy.java b/core/src/main/java/org/scenic/orchestrator/core/service/plan/strategy/ParallelStepExecutorStrategy.java
new file mode 100644
index 0000000..ba58d04
--- /dev/null
+++ b/core/src/main/java/org/scenic/orchestrator/core/service/plan/strategy/ParallelStepExecutorStrategy.java
@@ -0,0 +1,67 @@
+package org.scenic.orchestrator.core.service.plan.strategy;
+
+import static java.util.stream.Collectors.toList;
+
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+
+import org.scenic.orchestrator.core.dto.PlanStep;
+import org.scenic.orchestrator.core.dto.RunningAppContext;
+import org.scenic.orchestrator.core.service.plan.PlanStepExecutor;
+
+/**
+ * Ejecuta todos los steps que hay en el plan de manera paralela.
+ */
+public class ParallelStepExecutorStrategy extends PlanStepExecutorStrategy {
+
+ private final ExecutorService executorService;
+
+ public ParallelStepExecutorStrategy(PlanStepExecutor planStepExecutor,
+ ExecutorService executorService) {
+ super(planStepExecutor);
+ this.executorService = executorService;
+ }
+
+ @Override
+ public void executePlan(RunningAppContext appContext) {
+
+
+
+ List stepExecutions = appContext.getPlan().getPlan().stream()
+ .map(p -> {
+ System.out.println(String.format("Creating task for Node=%s, Operation=%s, Intf=%s", p.getNode(), p.getOperation(), p.getIntf()));
+ return new StepExecutionTask(planStepExecutor, p, appContext);
+ })
+ .collect(toList());
+
+ try {
+ System.out.println("Executing tasks");
+ executorService.invokeAll(stepExecutions);
+
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ System.out.println("[END] Executed tasks");
+ }
+
+
+ public class StepExecutionTask implements Callable {
+
+ private final PlanStepExecutor planStepExecutor;
+ private final PlanStep planStep;
+ private final RunningAppContext appContext;
+
+ public StepExecutionTask(PlanStepExecutor planStepExecutor, PlanStep planStep, RunningAppContext appContext) {
+ this.planStepExecutor = planStepExecutor;
+ this.planStep = planStep;
+ this.appContext = appContext;
+ }
+
+ @Override
+ public Void call() throws Exception {
+ planStepExecutor.executeStep(planStep, appContext);
+ return null;
+ }
+ }
+}
diff --git a/core/src/main/java/org/scenic/orchestrator/core/service/plan/strategy/PlanStepExecutorStrategy.java b/core/src/main/java/org/scenic/orchestrator/core/service/plan/strategy/PlanStepExecutorStrategy.java
new file mode 100644
index 0000000..170740d
--- /dev/null
+++ b/core/src/main/java/org/scenic/orchestrator/core/service/plan/strategy/PlanStepExecutorStrategy.java
@@ -0,0 +1,27 @@
+package org.scenic.orchestrator.core.service.plan.strategy;
+
+import org.scenic.orchestrator.core.dto.PlanStep;
+import org.scenic.orchestrator.core.dto.RunningAppContext;
+import org.scenic.orchestrator.core.service.plan.PlanStepExecutor;
+
+public abstract class PlanStepExecutorStrategy {
+
+ final PlanStepExecutor planStepExecutor;
+
+ public PlanStepExecutorStrategy(PlanStepExecutor planStepExecutor) {
+ this.planStepExecutor = planStepExecutor;
+ }
+
+
+ public abstract void executePlan(RunningAppContext appContext);
+
+ void executeStep(RunningAppContext appContext, PlanStep step) {
+ try {
+ planStepExecutor.executeStep(step, appContext);
+ } catch (Exception e) {
+ System.out.println("Error managed");
+ }
+ }
+
+
+}
diff --git a/core/src/main/java/org/scenic/orchestrator/core/service/plan/strategy/SingleStepExecutorStrategy.java b/core/src/main/java/org/scenic/orchestrator/core/service/plan/strategy/SingleStepExecutorStrategy.java
new file mode 100644
index 0000000..ab24127
--- /dev/null
+++ b/core/src/main/java/org/scenic/orchestrator/core/service/plan/strategy/SingleStepExecutorStrategy.java
@@ -0,0 +1,23 @@
+package org.scenic.orchestrator.core.service.plan.strategy;
+
+import org.scenic.orchestrator.core.dto.PlanStep;
+import org.scenic.orchestrator.core.dto.RunningAppContext;
+import org.scenic.orchestrator.core.service.plan.PlanStepExecutor;
+
+/**
+ * Ejecuta el primer step del plan
+ */
+public class SingleStepExecutorStrategy extends PlanStepExecutorStrategy{
+
+ public SingleStepExecutorStrategy(PlanStepExecutor planStepExecutor) {
+ super(planStepExecutor);
+ }
+
+ @Override
+ public void executePlan(RunningAppContext appContext) {
+ PlanStep firstStep = appContext.getPlan().getPlan().get(0);
+ executeStep(appContext, firstStep);
+ }
+
+
+}
diff --git a/core/src/main/java/org/scenic/orchestrator/core/service/ManagerAnalyzerClient.java b/core/src/main/java/org/scenic/orchestrator/manager/ManagerAnalyzerClient.java
similarity index 50%
rename from core/src/main/java/org/scenic/orchestrator/core/service/ManagerAnalyzerClient.java
rename to core/src/main/java/org/scenic/orchestrator/manager/ManagerAnalyzerClient.java
index 0efdff8..51ffde2 100644
--- a/core/src/main/java/org/scenic/orchestrator/core/service/ManagerAnalyzerClient.java
+++ b/core/src/main/java/org/scenic/orchestrator/manager/ManagerAnalyzerClient.java
@@ -1,6 +1,4 @@
-package org.scenic.orchestrator.core.service;
-
-import java.util.Map;
+package org.scenic.orchestrator.manager;
import org.scenic.orchestrator.core.dto.ApplicationStatus;
import org.scenic.orchestrator.core.dto.Plan;
@@ -8,25 +6,19 @@
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
-import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
-import com.fasterxml.jackson.databind.ObjectMapper;
-
/**
* Created by Jose on 22/01/19.
*/
-@Service
public class ManagerAnalyzerClient {
- private static final String BASE = "/mm";
- private static final String APPLICATION_RESOURCE = BASE + "/%s";
- private static final String GET_PLAN_TEMPLATE = APPLICATION_RESOURCE + "/plan";
+ protected static final String BASE = "/mm";
+ protected static final String APPLICATION_RESOURCE = BASE + "/%s";
+ private static final String GET_PARALLEL_PLAN_TEMPLATE = APPLICATION_RESOURCE + "/psteps";
private final RestTemplate restTemplate;
-
-
@Autowired
public ManagerAnalyzerClient(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
@@ -37,7 +29,11 @@ public void deployApplication(String application) {
}
public Plan getPlan(String applicationName) {
- return restTemplate.getForEntity(String.format(GET_PLAN_TEMPLATE, applicationName), Plan.class).getBody();
+ return restTemplate.getForEntity(String.format(getPlanResource(), applicationName), Plan.class).getBody();
+ }
+
+ protected String getPlanResource() {
+ return GET_PARALLEL_PLAN_TEMPLATE;
}
public void putStatus(String applicationName, ApplicationStatus applicationStatus) {
@@ -46,9 +42,25 @@ public void putStatus(String applicationName, ApplicationStatus applicationStatu
headers.setContentType(MediaType.APPLICATION_JSON);
- HttpEntity entity = new HttpEntity<>(applicationStatus,headers);
+ HttpEntity entity = new HttpEntity<>(applicationStatus, headers);
+
+ putStatusWithRetries(applicationName, entity);
+ }
- restTemplate.put(String.format(APPLICATION_RESOURCE, applicationName), entity);
+ private void putStatusWithRetries(String applicationName, HttpEntity entity) {
+ int i = 0;
+ boolean pushed = false;
+ while ((i <= 20) && (!pushed)) {
+ try {
+ i++;
+ restTemplate.put(String.format(APPLICATION_RESOURCE, applicationName), entity);
+ pushed = true;
+ } catch (Exception e) {
+ if (i == 20) {
+ throw e;
+ }
+ }
+ }//while
}
diff --git a/core/src/main/java/org/scenic/orchestrator/manager/SecuentialManagerAnalyzerClient.java b/core/src/main/java/org/scenic/orchestrator/manager/SecuentialManagerAnalyzerClient.java
new file mode 100644
index 0000000..91d1c79
--- /dev/null
+++ b/core/src/main/java/org/scenic/orchestrator/manager/SecuentialManagerAnalyzerClient.java
@@ -0,0 +1,22 @@
+package org.scenic.orchestrator.manager;
+
+import org.scenic.orchestrator.core.dto.Plan;
+import org.springframework.web.client.RestTemplate;
+
+
+public class SecuentialManagerAnalyzerClient extends ManagerAnalyzerClient {
+
+ private static final String GET_PLAN_TEMPLATE = APPLICATION_RESOURCE + "/plan";
+
+ public SecuentialManagerAnalyzerClient(RestTemplate restTemplate) {
+ super(restTemplate);
+ }
+
+
+ @Override
+ protected String getPlanResource(){
+ return GET_PLAN_TEMPLATE;
+ }
+
+
+}
diff --git a/core/src/main/java/org/scenic/orchestrator/webapp/DeployController.java b/core/src/main/java/org/scenic/orchestrator/webapp/DeployController.java
index 19d3e15..fd2666e 100644
--- a/core/src/main/java/org/scenic/orchestrator/webapp/DeployController.java
+++ b/core/src/main/java/org/scenic/orchestrator/webapp/DeployController.java
@@ -1,8 +1,11 @@
package org.scenic.orchestrator.webapp;
+import org.scenic.orchestrator.core.service.ApplicationSynchronizerService;
import org.scenic.orchestrator.core.service.DeployerService;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@@ -15,17 +18,22 @@
public class DeployController {
private final DeployerService deployerService;
+ private final ApplicationSynchronizerService applicationSynchronizerService;
@Autowired
- public DeployController(DeployerService deployerService) {
+ public DeployController(DeployerService deployerService, ApplicationSynchronizerService applicationSynchronizerService) {
this.deployerService = deployerService;
+ this.applicationSynchronizerService = applicationSynchronizerService;
}
-
@PostMapping("/deploy")
- public void deployApp(@RequestBody String app) throws InterruptedException {
- deployerService.deploy(app);
+ public void deployApp(@RequestBody String topology) throws InterruptedException {
+ deployerService.deploy(topology);
}
-
+ @PutMapping("/sync/{appId}")
+ public void syncApp(@PathVariable String appId, @RequestBody String topology) throws InterruptedException {
+ System.out.println("--Sync appId=" + appId);
+ applicationSynchronizerService.syncApplication(topology, appId);
+ }
}
diff --git a/core/src/main/java/org/scenic/orchestrator/webapp/UpdateStatusController.java b/core/src/main/java/org/scenic/orchestrator/webapp/UpdateStatusController.java
new file mode 100644
index 0000000..9db0018
--- /dev/null
+++ b/core/src/main/java/org/scenic/orchestrator/webapp/UpdateStatusController.java
@@ -0,0 +1,43 @@
+package org.scenic.orchestrator.webapp;
+
+import java.util.concurrent.ExecutorService;
+
+import org.scenic.orchestrator.core.UpdaterManagement;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping()
+public class UpdateStatusController {
+
+ private final UpdaterManagement updaterManagement;
+
+ private final ExecutorService executorService;
+
+ @Autowired
+ public UpdateStatusController(UpdaterManagement updaterManagement, ExecutorService executorService) {
+ this.updaterManagement = updaterManagement;
+ this.executorService = executorService;
+ }
+
+ @PutMapping("/update")
+ public void update() throws InterruptedException {
+ System.out.println("---Updating...");
+ executorService.execute(new Runnable() {
+ @Override
+ public void run() {
+ System.out.println("executing in background");
+ try{
+ updaterManagement.updateApplication();
+ } catch(Exception e){
+ System.out.println("Error in update " + e.getMessage() + e.getCause());
+ throw new RuntimeException(e);
+ }
+ }
+ });
+ System.out.println("Executing");
+ //updaterManagement.updateApplication();
+ }
+}
diff --git a/core/src/main/resources/application.properties b/core/src/main/resources/application.properties
index 475e375..64c49bd 100644
--- a/core/src/main/resources/application.properties
+++ b/core/src/main/resources/application.properties
@@ -7,6 +7,8 @@ brooklyn.url=http://127.0.0.1:8081
#ManagerAnalyzer
manager.analyzer.url=http://127.0.0.1:8080
+#This property is for boxplot testing (false) it should be always true to prod
+scheduleUpdating=true
instructionSchedularTime=30000
diff --git a/core/src/test/java/org/scenic/orchestrator/it/BaseIntegrationTest.java b/core/src/test/java/org/scenic/orchestrator/it/BaseIntegrationTest.java
index 549a1f5..de05040 100644
--- a/core/src/test/java/org/scenic/orchestrator/it/BaseIntegrationTest.java
+++ b/core/src/test/java/org/scenic/orchestrator/it/BaseIntegrationTest.java
@@ -15,7 +15,7 @@
@RunWith(SpringRunner.class)
@TestPropertySource("classpath:application-it.properties")
@SpringBootTest(classes = ITConfig.class)
-@AutoConfigureWireMock(port = 0)
+//@AutoConfigureWireMock(port = 8080)
public abstract class BaseIntegrationTest {
@MockBean
diff --git a/core/src/test/java/org/scenic/orchestrator/it/Parallel.java b/core/src/test/java/org/scenic/orchestrator/it/Parallel.java
new file mode 100644
index 0000000..2560465
--- /dev/null
+++ b/core/src/test/java/org/scenic/orchestrator/it/Parallel.java
@@ -0,0 +1,97 @@
+package org.scenic.orchestrator.it;
+
+import static java.util.stream.IntStream.range;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+import org.junit.Test;
+
+/**
+ * Created by Jose on 01/10/19.
+ */
+public class Parallel {
+
+
+ ExecutorService executor
+ //= Executors.newSingleThreadExecutor();
+ = Executors.newFixedThreadPool(20);
+
+
+ @Test
+ public void test() throws Exception {
+
+
+ assertTrue(true);
+ /*SquareCalculator squareCalculator = new SquareCalculator();
+
+ Future future1 = squareCalculator.calculate(10);
+ Future future2 = squareCalculator.calculate(100);
+
+ while (!(future1.isDone() && future2.isDone())) {
+ System.out.println(
+ String.format(
+ "future1 is %s and future2 is %s",
+ future1.isDone() ? "done" : "not done",
+ future2.isDone() ? "done" : "not done"
+ )
+ );
+ Thread.sleep(300);
+ }
+
+ Integer result1 = future1.get();
+ Integer result2 = future2.get();
+
+ System.out.println(result1 + " and " + result2);*/
+
+ //List> callables =
+ List> callables = range(1, 5)
+ .boxed()
+ .map(this.c())
+ .collect(Collectors.toList());
+
+
+ System.out.println("Start");long init = System.currentTimeMillis();
+ List> exists = executor.invokeAll(callables);
+ System.out.println("Finish " + (System.currentTimeMillis() -init ));
+
+ for(Future f : exists) {
+ System.out.println(f.isDone());
+ }
+ System.out.println("Bye");
+
+
+
+ }
+
+ public Function> c() {
+ return i ->
+ () -> {
+ try {
+ TimeUnit.MILLISECONDS.sleep(10_000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ return "Task's execution";
+
+ };
+ }
+
+ public class SquareCalculator {
+
+ public Future calculate(Integer input) {
+ return executor.submit(() -> {
+ Thread.sleep(1000);
+ return input * input;
+ });
+ }
+ }
+
+}
diff --git a/core/src/test/java/org/scenic/orchestrator/it/SmokeTest.java b/core/src/test/java/org/scenic/orchestrator/it/SmokeTest.java
index 47d4e03..baf926c 100644
--- a/core/src/test/java/org/scenic/orchestrator/it/SmokeTest.java
+++ b/core/src/test/java/org/scenic/orchestrator/it/SmokeTest.java
@@ -1,22 +1,35 @@
package org.scenic.orchestrator.it;
+//import org.apache.commons.
+
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.get;
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
+import static java.time.Instant.now;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.when;
+import java.time.Instant;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
import org.apache.brooklyn.rest.api.VersionApi;
+import org.apache.commons.math3.stat.descriptive.moment.StandardDeviation;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
-import org.scenic.orchestrator.it.BaseIntegrationTest;
+import org.scenic.orchestrator.core.dto.ApplicationStatus;
+import org.scenic.orchestrator.core.dto.EntityStatus;
+import org.scenic.orchestrator.manager.ManagerAnalyzerClient;
import org.scenic.orchestrator.webapp.CustomVersionsController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
+import com.google.common.collect.ImmutableMap;
+
/**
* Created by Jose on 21/01/19.
*/
@@ -33,6 +46,9 @@ public class SmokeTest extends BaseIntegrationTest {
@Autowired
private CustomVersionsController customVersionsController;
+ @Autowired
+ private ManagerAnalyzerClient mmClient;
+
@Before
public void setUp() {
when(brooklynApi.getVersionApi()).thenReturn(versionApi);
@@ -54,4 +70,57 @@ public void testWM() {
ResponseEntity value = restTemplate.getForEntity("/resource", String.class);
assertThat(value.getBody()).isEqualTo("Hello World!");
}
+
+ @Test
+ public void t() {
+
+ //org.apache.commons.math3.stat.descriptive.moment.
+ StandardDeviation math = new StandardDeviation();
+ Map current = ImmutableMap.builder()
+ .put("SoftcareDB", EntityStatus.UNAVAILABLE)
+ .put("SoftcareWS", EntityStatus.FAILED)
+ //.put("Forum", EntityStatus.STARTED)
+ //.put("ForumDB", EntityStatus.FAILED)
+ .put("Softcare_dashboard", EntityStatus.FAILED)
+ .put("Multimedia", EntityStatus.FAILED)
+ .put("MultimediaDB", EntityStatus.STARTED)
+ .build();
+
+
+ Map target = ImmutableMap.builder()
+ .put("SoftcareDB", EntityStatus.STARTED)
+ .put("SoftcareWS", EntityStatus.STARTED)
+ //.put("Forum", EntityStatus.STARTED)
+ //.put("ForumDB", EntityStatus.STARTED)
+ .put("Softcare_dashboard", EntityStatus.STARTED)
+ .put("Multimedia", EntityStatus.STARTED)
+ .put("MultimediaDB", EntityStatus.STARTED)
+ .build();
+
+
+ String name = "SoftcareApp";
+ ApplicationStatus status = new ApplicationStatus(current, target);
+ mmClient.putStatus(name, status);
+ List latencies = new ArrayList<>();
+
+
+ for (int i = 0; i < 20; i++) {
+ Instant before = now();
+ mmClient.getPlan(name);
+ Instant after = now();
+ Double latency = (double) (after.getEpochSecond() - before.getEpochSecond());
+ latencies.add(latency);
+ System.out.println(latency);
+ }
+
+ double[] j = latencies.stream()
+ .mapToDouble(k -> k)
+ .toArray();
+
+ double av = latencies.stream()
+ .mapToDouble(k -> k)
+ .average().getAsDouble();
+ System.out.println("Std. Desv.: " + math.evaluate(j));
+ System.out.println("Av: " + av);
+ }
}
diff --git a/core/src/test/java/org/scenic/orchestrator/it/config/TestRestTemplateConfig.java b/core/src/test/java/org/scenic/orchestrator/it/config/TestRestTemplateConfig.java
index 0c19584..a1788e6 100644
--- a/core/src/test/java/org/scenic/orchestrator/it/config/TestRestTemplateConfig.java
+++ b/core/src/test/java/org/scenic/orchestrator/it/config/TestRestTemplateConfig.java
@@ -12,8 +12,8 @@
@Configuration
public class TestRestTemplateConfig {
- @Value("${wiremock.server.port}")
- private int port;
+ //@Value("${wiremock.server.port}")
+ private int port=8080;
@Bean
public RestTemplate restTemplate() {
diff --git a/pom.xml b/pom.xml
index 2867c74..d774f39 100644
--- a/pom.xml
+++ b/pom.xml
@@ -58,6 +58,13 @@
0.9.0
+
+
org.springframework.boot