@javax.annotation.Resource
private Map<CloudPlatform, ResourceBuilderInit> resourceBuilderInits;
public void buildStack(final CloudPlatform cloudPlatform, Long stackId, Map<String, Object> setupProperties, Map<String, String> userDataParams) {
Stack stack = stackRepository.findById(stackId);
MDCBuilder.buildMdcContext(stack);
try {
if (stack.getStatus().equals(Status.REQUESTED)) {
stack = stackUpdater.updateStackStatus(stack.getId(), Status.CREATE_IN_PROGRESS);
websocketService.sendToTopicUser(stack.getOwner(), WebsocketEndPoint.STACK, new StatusMessage(stack.getId(), stack.getName(), stack
.getStatus().name()));
stackUpdater.updateStackStatusReason(stack.getId(), stack.getStatus().name());
if (!cloudPlatform.isWithTemplate()) {
stackUpdater.updateStackStatus(stack.getId(), Status.REQUESTED);
Set<Resource> resourceSet = new HashSet<>();
ResourceBuilderInit resourceBuilderInit = resourceBuilderInits.get(cloudPlatform);
final ProvisionContextObject pCO =
resourceBuilderInit.provisionInit(stack, userDataBuilder.build(cloudPlatform, stack.getHash(), userDataParams));
for (ResourceBuilder resourceBuilder : networkResourceBuilders.get(cloudPlatform)) {
List<Resource> resourceList = resourceBuilder.create(pCO, 0, new ArrayList<Resource>());
resourceSet.addAll(resourceList);
pCO.getNetworkResources().addAll(resourceList);
}
List<Future<List<Resource>>> futures = new ArrayList<>();
for (int i = 0; i < stack.getNodeCount(); i++) {
final int index = i;
Future<List<Resource>> submit = resourceBuilderExecutor.submit(new Callable<List<Resource>>() {
@Override
public List<Resource> call() throws Exception {
List<Resource> resources = new ArrayList<>();
for (final ResourceBuilder resourceBuilder : instanceResourceBuilders.get(cloudPlatform)) {
List<Resource> resourceList = resourceBuilder.create(pCO, index, resources);
resources.addAll(resourceList);
}
return resources;
}
});
futures.add(submit);
}
Exception exception = null;
for (Future<List<Resource>> future : futures) {
try {
resourceSet.addAll(future.get());
} catch (Exception e) {
exception = e;
}
}
if (exception != null) {
throw new BuildStackFailureException(exception.getMessage(), exception, resourceSet);
}
LOGGER.info("Publishing {} event [StackId: '{}']", ReactorConfig.PROVISION_COMPLETE_EVENT, stack.getId());
reactor.notify(ReactorConfig.PROVISION_COMPLETE_EVENT, Event.wrap(new ProvisionComplete(cloudPlatform, stack.getId(), resourceSet)));
} else {
CloudPlatformConnector cloudPlatformConnector = cloudPlatformConnectors.get(cloudPlatform);
cloudPlatformConnector.buildStack(stack, userDataBuilder.build(cloudPlatform, stack.getHash(), userDataParams), setupProperties);
}
} else {
LOGGER.info("CloudFormation stack creation was requested for a stack, that is not in REQUESTED status anymore. [stackId: '{}', status: '{}']",
stack.getId(), stack.getStatus());
}
} catch (BuildStackFailureException e) {
stackUpdater.updateStackResources(stackId, e.getResourceSet());
LOGGER.error("Unhandled exception occured while creating stack.", e);
LOGGER.info("Publishing {} event.", ReactorConfig.STACK_CREATE_FAILED_EVENT);