/** * Counts active integrations (in DB) of the owner of the specified integration. * * @param deployment The specified IntegrationDeployment. * @return The number of integrations (excluding the current). */ private int countActiveIntegrationsOfSameUserAs(IntegrationDeployment deployment) { Integration integration = deployment.getSpec(); String integrationId = integration.getId().orElseThrow(() -> new IllegalStateException("Couldn't find the id of the integration.")); String username = deployment.getUserId().orElseThrow(() -> new IllegalStateException("Couldn't find the user of the integration")); return (int) dataManager.fetchAll(IntegrationDeployment.class).getItems() .stream() .filter(i -> !i.getIntegrationId().get().equals(integrationId)) //The "current" integration will already be in the database. .filter(i -> IntegrationDeploymentState.Published == i.getCurrentState()) .filter(i -> i.getUserId().map(username::equals).orElse(Boolean.FALSE)) .count(); }
/** * Re-conciliates the state of the deployment between the database and Openshift. * This is mostly needed for cases where an active integration has been tampered with external tools. * For example: Deleted or Scaled down DeploymentConfig. */ private IntegrationDeployment reconcileDeployment(IntegrationDeployment integrationDeployment) { IntegrationDeploymentState actualState = determineState(integrationDeployment); LOG.debug("Actual state: {}, Persisted state: {}, Desired state: {}", actualState, integrationDeployment.getCurrentState(), integrationDeployment.getTargetState()); //We also need to compare with current state to make sure we only call the unpublished() once. Calling it multiple times, might loose the steps perfromed, causing an infinite loop. if (actualState == IntegrationDeploymentState.Unpublished && actualState != integrationDeployment.getCurrentState()) { return integrationDeployment.unpublished(); } else { return integrationDeployment.withCurrentState(actualState); } } }
private IntegrationDeploymentState determineState(IntegrationDeployment integrationDeployment) { Map<String, String> labels = new HashMap<>(); labels.put(OpenShiftService.INTEGRATION_ID_LABEL, Labels.validate(integrationDeployment.getIntegrationId().get())); labels.put(OpenShiftService.DEPLOYMENT_VERSION_LABEL, String.valueOf(integrationDeployment.getVersion())); if (!openShiftService.exists(integrationDeployment.getSpec().getName()) || !openShiftService.isScaled(integrationDeployment.getSpec().getName(), 1, labels)) { return IntegrationDeploymentState.Unpublished; } else { return IntegrationDeploymentState.Published; } }
private String getIntegrationMarkerKey(IntegrationDeployment integrationDeployment) { return integrationDeployment.getTargetState() + ":" + integrationDeployment.getId().orElseThrow(() -> new IllegalArgumentException("No id set in integration " + integrationDeployment)); }
private boolean stale(StateChangeHandler handler, IntegrationDeployment integrationDeployment) { if (integrationDeployment == null || handler == null) { return true; } IntegrationDeploymentState desiredState = integrationDeployment.getTargetState(); return desiredState.equals(integrationDeployment.getCurrentState()); }
private Collection<? extends LeveledMessage> computeDeploymentDifferences(Integration integration, Collection<IntegrationDeployment> allDeployments) { List<IntegrationDeployment> deployments = allDeployments.stream() .filter(d -> d.getIntegrationId().equals(integration.getId())) .filter(d -> d.getCurrentState().equals(IntegrationDeploymentState.Published)) .collect(Collectors.toList()); final Supplier<LeveledMessage.Builder> supplier = () -> new LeveledMessage.Builder().putMetadata("deployment", deployment.getId().get()); final Integration deployedInteg = deployment.getSpec();
@Override public StateUpdate execute(IntegrationDeployment integrationDeployment) { Map<String, String> stepsDone = new HashMap<>(integrationDeployment.getStepsDone()); stepsDone.remove("deploy"); //we are literally undoing this step. IntegrationDeploymentState currentState = IntegrationDeploymentState.Pending; Map<String, String> labels = new HashMap<>(); labels.put(OpenShiftService.INTEGRATION_ID_LABEL, Labels.validate(integrationDeployment.getIntegrationId().get())); labels.put(OpenShiftService.DEPLOYMENT_VERSION_LABEL, String.valueOf(integrationDeployment.getVersion())); List<DeploymentConfig> deployments = openShiftService().getDeploymentsByLabel(labels); Boolean isDeployed = !deployments.stream().filter(d -> d.getSpec().getReplicas() != 0).collect(Collectors.toList()).isEmpty(); if (isDeployed) { try { LOG.info("Undeploying integration deployment:{} version:{}", integrationDeployment.getSpec().getName(), integrationDeployment.getVersion()); openShiftService().scale(integrationDeployment.getSpec().getName(), labels, 0, 1, TimeUnit.MINUTES); } catch (InterruptedException e) { Thread.currentThread().interrupt(); return new StateUpdate(currentState, stepsDone); } } Boolean isUndeployed = !deployments.stream().filter(d -> d.getStatus().getAvailableReplicas() == 0).collect(Collectors.toList()).isEmpty(); if(isUndeployed){ currentState = IntegrationDeploymentState.Unpublished; } return new StateUpdate(currentState, stepsDone); }
public void accept(IntegrationDeployment integrationDeployment) { final String integrationId = integrationDeployment.getIntegrationId().get(); final String version = String.valueOf(integrationDeployment.getVersion()); final String compositeId = IntegrationDeployment.compositeId(integrationId, integrationDeployment.getVersion()); final IntegrationDeploymentState targetState = integrationDeployment.getTargetState();
void callStateChangeHandler(StateChangeHandler handler, IntegrationDeployment integrationDeployment) { String integrationDeploymentId = integrationDeployment.getId().get(); executor.execute(() -> { String checkKey = getIntegrationMarkerKey(integrationDeployment); final String integrationId = integrationDeployment.getIntegrationId().get(); LOG.info("Integration {} : Start processing integration: {}, version: {} with handler:{}", integrationId, integrationId, integrationDeployment.getVersion(), handler.getClass().getSimpleName()); handler.execute(integrationDeployment, update->{ if (LOG.isInfoEnabled()) { final IntegrationDeployment updated = current.builder() .statusMessage(Optional.ofNullable(update.getStatusMessage())) .currentState(update.getState()) .build(); if (!(updated.equals(current))) { dataManager.update(updated.builder().updatedAt(System.currentTimeMillis()).build());
private void checkIntegrationStatus(IntegrationDeployment integrationDeployment) { if (integrationDeployment == null) { return; } IntegrationDeployment reconciled = reconcileDeployment(integrationDeployment); IntegrationDeploymentState desiredState = reconciled.getTargetState(); IntegrationDeploymentState currentState = reconciled.getCurrentState(); if (!currentState.equals(desiredState)) { reconciled.getId().ifPresent(integrationDeploymentId -> { StateChangeHandler statusChangeHandler = handlers.get(desiredState); if (statusChangeHandler != null) { LOG.info("Integration {} : Desired status \"{}\" != current status \"{}\" --> calling status change handler", integrationDeploymentId, desiredState.toString(), currentState); callStateChangeHandler(statusChangeHandler, reconciled); } }); } else if (reconciled.getCurrentState() != integrationDeployment.getCurrentState()) { dataManager.update(reconciled); scheduledChecks.remove(getIntegrationMarkerKey(reconciled)); } else { scheduledChecks.remove(getIntegrationMarkerKey(reconciled)); } }
private static Integration integrationOf(IntegrationDeployment integrationDeployment) { return integrationDeployment.getSpec(); }
private void deactivatePreviousDeployments(IntegrationDeployment integrationDeployment) { dataManager.fetchIdsByPropertyValue(IntegrationDeployment.class, "integrationId", integrationDeployment.getIntegrationId().get(), "targetState", IntegrationDeploymentState.Published.name()) .stream() .map(id -> dataManager.fetch(IntegrationDeployment.class, id)) .filter(r -> r.getVersion() != integrationDeployment.getVersion()) .map(r -> r.unpublishing()) .forEach(r -> { dataManager.update(r); }); }
private DeploymentData createDeploymentData(Integration integration, IntegrationDeployment integrationDeployment) { Properties applicationProperties = projectGenerator.generateApplicationProperties(integration); String username = integrationDeployment.getUserId().orElseThrow(() -> new IllegalStateException("Couldn't find the user of the integration")); String integrationId = integrationDeployment.getIntegrationId().orElseThrow(() -> new IllegalStateException("IntegrationDeployment should have an integrationId")); String version = Integer.toString(integrationDeployment.getVersion()); final Builder deploymentDataBuilder = DeploymentData.builder() .withVersion(integrationDeployment.getVersion()) .addLabel(OpenShiftService.INTEGRATION_ID_LABEL, Labels.validate(integrationId)) .addLabel(OpenShiftService.DEPLOYMENT_VERSION_LABEL, version) .addLabel(OpenShiftService.USERNAME_LABEL, Labels.sanitize(username)) .addAnnotation(OpenShiftService.INTEGRATION_NAME_ANNOTATION, integration.getName()) .addAnnotation(OpenShiftService.INTEGRATION_ID_LABEL, integrationId) .addAnnotation(OpenShiftService.DEPLOYMENT_VERSION_LABEL, version) .addSecretEntry("application.properties", propsToString(applicationProperties)); integration.getConfiguredProperties().forEach((k, v) -> deploymentDataBuilder.addProperty(k, v)); DeploymentData data = deploymentDataBuilder.build(); if (this.customizers != null && !this.customizers.isEmpty()) { for (DeploymentDataCustomizer customizer : customizers) { data = customizer.customize(data, integrationDeployment); } } return data; }
private void setVersion(IntegrationDeployment integrationDeployment) { Integration integration = integrationDeployment.getIntegrationId().map(i -> dataManager.fetch(Integration.class, i)).orElseThrow(()-> new IllegalStateException("Integration not found!")); dataManager.update(new Integration.Builder().createFrom(integration).version(integrationDeployment.getVersion()).build()); }
integrationId(instance.getIntegrationId()); Integration specValue = instance.getSpec(); if (specValue != null) { spec(specValue);
private void updateIntegrationEndpoint(IntegrationDeployment deployment) { if (deployment.getId().isPresent()) { IntegrationEndpoint endpoint = dataManager.fetch(IntegrationEndpoint.class, deployment.getId().get()); boolean endpointPresent = endpoint != null; Optional<String> host = openShiftService.getExposedHost(deployment.getSpec().getName()); Optional<IntegrationEndpoint> expectedEndpoint = expectedEndpoint(deployment, host); // Synchronize internal model if (!endpointPresent && expectedEndpoint.isPresent()) { LOG.info("Adding endpoint {} to integration deployment {}", expectedEndpoint.get(), deployment.getId().get()); dataManager.create(expectedEndpoint.get()); } else if (endpointPresent && expectedEndpoint.isPresent()) { if (!endpoint.equals(expectedEndpoint.get())) { LOG.info("Updating endpoint for deployment {} to {}", deployment.getId().get(), expectedEndpoint.get()); dataManager.update(expectedEndpoint.get()); } } else if (endpointPresent) { LOG.info("Deleting endpoint for deployment {}", deployment.getId().get()); dataManager.delete(IntegrationEndpoint.class, deployment.getId().get()); } } }
default IntegrationDeployment unpublished() { Map<String, String> stepsDone = new HashMap<>(getStepsDone()); stepsDone.remove("deploy"); return builder().currentState(IntegrationDeploymentState.Unpublished).stepsDone(stepsDone).build(); }
private IntegrationDeploymentState getCurrentStateInitialize() { return IntegrationDeployment.super.getCurrentState(); }
private Optional<String> getIntegrationIdInitialize() { return IntegrationDeployment.super.getIntegrationId(); }