@Override public List<StateChangeHandler> getStatusChangeHandlers() { return Arrays.asList( new DemoHandler(IntegrationDeploymentState.Active, 5000L), new DemoHandler(IntegrationDeploymentState.Inactive, 5000L), new DemoHandler(IntegrationDeploymentState.Undeployed, 5000L)); }
@PostConstruct public void start() { executor = Executors.newSingleThreadExecutor(threadFactory("Integration Controller")); scheduler = Executors.newScheduledThreadPool(1, threadFactory("Integration Controller Scheduler")); scanIntegrationsForWork(); eventBus.subscribe(EVENT_BUS_ID, getChangeEventSubscription()); }
private void checkIntegrationStatusIfNotAlreadyInProgress(String id) { executor.execute(() -> { IntegrationDeployment integrationDeployment = dataManager.fetch(IntegrationDeployment.class, id); if( integrationDeployment!=null ) { String scheduledKey = getIntegrationMarkerKey(integrationDeployment); // Don't start check is already a check is running if (!scheduledChecks.contains(scheduledKey)) { checkIntegrationStatus(integrationDeployment); } } }); }
@Override public StateUpdate execute(IntegrationDeployment integrationDeploymentDefinition) { final IntegrationDeployment integrationDeployment = IntegrationSupport.sanitize(integrationDeploymentDefinition, dataManager, encryptionComponent); final Integration integration = integrationOf(integrationDeployment); int userIntegrations = countActiveIntegrationsOfSameUserAs(integration); if (userIntegrations >= maxIntegrationsPerUser) { int userDeployments = countDeployments(integration); if (userDeployments >= maxDeploymentsPerUser) { logInfo(integrationDeployment, "Build started: {}, isRunning: {}, Deployment ready: {}", isBuildStarted(integrationDeployment), isRunning(integrationDeployment), isReady(integrationDeployment)); BuildStepPerformer stepPerformer = new BuildStepPerformer(integrationDeployment); logInfo(integrationDeployment, "Steps performed so far: " + stepPerformer.getStepsPerformed()); try { deactivatePreviousDeployments(integrationDeployment); DeploymentData deploymentData = createDeploymentData(integration, integrationDeployment); stepPerformer.perform("build", this::build, deploymentData); stepPerformer.perform("deploy", this::deploy, deploymentData); } catch (@SuppressWarnings("PMD.AvoidCatchingGenericException") Exception e) { logError(integrationDeployment, "[ERROR] Activation failure"); if (isRunning(integrationDeployment)) { logInfo(integrationDeployment, "[ACTIVATED] bc. integration is running with 1 pod"); updateIntegration(integrationDeployment, IntegrationDeploymentState.Active); return new StateUpdate(IntegrationDeploymentState.Active);
void callStateChangeHandler(StateChangeHandler handler, String integrationDeploymentId) { executor.execute(() -> { IntegrationDeployment integrationDeployment = dataManager.fetch(IntegrationDeployment.class, integrationDeploymentId); String checkKey = getIntegrationMarkerKey(integrationDeployment); scheduledChecks.add(checkKey); if (stale(handler, integrationDeployment)) { scheduledChecks.remove(checkKey); return; if (LOG.isInfoEnabled()) { LOG.info("{} : Setting status to {}{}", getLabel(integrationDeployment), update.getState(), Optional.ofNullable(update.getStatusMessage()).map(x->" ("+x+")").orElse("")); reschedule(integrationDeploymentId);
private void checkIntegrationStatus(IntegrationDeployment integrationDeployment) { if (integrationDeployment == null) { return; } IntegrationDeploymentState desiredState = integrationDeployment.getTargetState(); IntegrationDeploymentState currentState = integrationDeployment.getCurrentState(); if (!currentState.equals(desiredState)) { integrationDeployment.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, integrationDeploymentId); } }); } else { scheduledChecks.remove(getIntegrationMarkerKey(integrationDeployment)); } }
@PostConstruct public void start() { executor = Executors.newSingleThreadExecutor(); scheduler = Executors.newScheduledThreadPool(1); scanIntegrationsForWork(); eventBus.subscribe("integration-deployment-controller", getChangeEventSubscription()); }
@SuppressWarnings("FutureReturnValueIgnored") private void reschedule(String integrationId) { scheduler.schedule(() -> { IntegrationDeployment i = dataManager.fetch(IntegrationDeployment.class, integrationId); checkIntegrationStatus(i); }, SCHEDULE_INTERVAL_IN_SECONDS, TimeUnit.SECONDS); }
private EventBus.Subscription getChangeEventSubscription() { return (event, data) -> { // Never do anything that could block in this callback! if (event!=null && "change-event".equals(event)) { try { ChangeEvent changeEvent = Json.mapper().readValue(data, ChangeEvent.class); if (changeEvent != null) { changeEvent.getId().ifPresent(id -> { changeEvent.getKind() .map(Kind::from) .filter(k -> k == Kind.IntegrationDeployment) .ifPresent(k -> { checkIntegrationStatusIfNotAlreadyInProgress(id); }); }); } } catch (IOException e) { LOG.error("Error while subscribing to change-event {}", data, e); } } }; }
private DeploymentData createDeploymentData(Integration integration, IntegrationDeployment integrationDeployment) { Properties applicationProperties = IntegrationSupport.buildApplicationProperties(integrationDeployment, dataManager, encryptionComponent); String username = integration.getUserId().orElseThrow(() -> new IllegalStateException("Couldn't find the user of the integration")); return DeploymentData.builder() .addLabel(OpenShiftService.INTEGRATION_ID_LABEL, Labels.sanitize(integrationDeployment.getIntegrationId().orElseThrow(() -> new IllegalStateException("IntegrationDeployment should have an integrationId")))) .addLabel(OpenShiftService.DEPLOYMENT_ID_LABEL, integrationDeployment.getVersion().orElse(0).toString()) .addLabel(OpenShiftService.USERNAME_LABEL, Labels.sanitize(username)) .addSecretEntry("application.properties", propsToString(applicationProperties)) .build(); }
final ConnectorAction action = ConnectorAction.class.cast(step.getAction().get()); final ConnectorDescriptor descriptor = action.getDescriptor(); final Connector connector = resolveConnector(connection, dataManager);
/* default */ void callStateChangeHandler(StateChangeHandler handler, String integrationDeploymentId) { executor.execute(() -> { IntegrationDeployment integrationDeployment = dataManager.fetch(IntegrationDeployment.class, integrationDeploymentId); String checkKey = getIntegrationMarkerKey(integrationDeployment); scheduledChecks.add(checkKey); if (stale(handler, integrationDeployment)) { scheduledChecks.remove(checkKey); return; if (update!=null) { if (LOG.isInfoEnabled()) { LOG.info("{} : Setting status to {}{}", getLabel(integrationDeployment), update.getState(), (update.getStatusMessage() != null ? " (" + update.getStatusMessage() + ")" : "")); reschedule(integrationDeploymentId);
private void checkIntegrationStatusIfNotAlreadyInProgress(String id) { executor.execute(() -> { IntegrationDeployment integrationDeployment = dataManager.fetch(IntegrationDeployment.class, id); if( integrationDeployment != null) { String scheduledKey = getIntegrationMarkerKey(integrationDeployment); LOG.debug("Check if IntegrationStatus {} is already in progress for key: {} (keys: {})", id, scheduledKey, scheduledChecks); // Don't start check is already a check is running if (!scheduledChecks.contains(scheduledKey)) { checkIntegrationStatus(integrationDeployment); } else { LOG.debug("A check for IntegrationDeployment {} is already configured with key {}", id, scheduledKey); } } else { LOG.debug("No IntegrationDeployment with id: {}", id); } }); }
private void checkIntegrationStatus(IntegrationDeployment integrationDeployment) { if (integrationDeployment == null) { return; } IntegrationDeploymentState desiredState = integrationDeployment.getTargetState(); IntegrationDeploymentState currentState = integrationDeployment.getCurrentState(); if (!currentState.equals(desiredState)) { integrationDeployment.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, integrationDeploymentId); } }); } else { scheduledChecks.remove(getIntegrationMarkerKey(integrationDeployment)); } }
@SuppressWarnings("FutureReturnValueIgnored") private void reschedule(String integrationId) { LOG.debug("Reschedule IntegrationDeployment check, id:{}, keys: {}", integrationId, scheduledChecks); scheduler.schedule(() -> { IntegrationDeployment i = dataManager.fetch(IntegrationDeployment.class, integrationId); LOG.debug("Trigger checkIntegrationStatus, id:{}", integrationId); checkIntegrationStatus(i); }, SCHEDULE_INTERVAL_IN_SECONDS, TimeUnit.SECONDS ); }
@Override public List<StateChangeHandler> getStatusChangeHandlers() { return Arrays.asList( new DemoHandler(IntegrationDeploymentState.Published, 5000L), new DemoHandler(IntegrationDeploymentState.Unpublished, 5000L)); }
private EventBus.Subscription getChangeEventSubscription() { return (event, data) -> { // Never do anything that could block in this callback! if (event!=null && "change-event".equals(event)) { try { ChangeEvent changeEvent = Json.reader().forType(ChangeEvent.class).readValue(data); if (changeEvent != null) { changeEvent.getId().ifPresent(id -> { changeEvent.getKind() .map(Kind::from) .filter(k -> k == Kind.IntegrationDeployment) .ifPresent(k -> { checkIntegrationStatusIfNotAlreadyInProgress(id); }); }); } } catch (IOException e) { LOG.error("Error while subscribing to change-event {}", data, e); } } }; }
private void scanIntegrationsForWork() { executor.execute(() -> { dataManager.fetchAll(IntegrationDeployment.class).getItems().forEach(integration -> { LOG.info("Checking integrations for their status."); checkIntegrationStatus(integration); }); }); }
private void scanIntegrationsForWork() { executor.execute(() -> { dataManager.fetchAll(IntegrationDeployment.class).getItems().forEach(integration -> { LOG.info("Checking integrations for their status."); checkIntegrationStatus(integration); }); }); }