/* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.kie.server.services.impl.policy; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; import org.kie.server.api.model.KieContainerStatus; import org.kie.server.api.model.ServiceResponse; import org.kie.server.services.api.KieServer; import org.kie.server.services.api.KieServerRegistry; import org.kie.server.services.api.Policy; import org.kie.server.services.impl.KieContainerInstanceImpl; import org.kie.server.services.impl.controller.DefaultRestControllerImpl; import org.kie.server.services.impl.locator.LatestContainerLocator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Policy that will dispose older container and leave only latest one - latest according to version of ReleaseId. * * Policy by default is scheduled to run once a day, though it can be reconfigured with system properties: * <ul> * <li>policy.klo.interval - interval how often (expressed as duration) the policy should be applied</li> * <li>policy.klo.unit - time unit that the interval was specified in - if not given milliseconds are assumed</li> * </ul> * * Name of this policy (to be used to activate it) is <code>KeepLatestOnly</code> */ public class KeepLatestContainerOnlyPolicy implements Policy { private static final Logger logger = LoggerFactory.getLogger(KeepLatestContainerOnlyPolicy.class); private static final String INTERVAL_VALUE = "policy.klo.interval"; private static final String INTERVAL_TIME_UNIT = "policy.klo.unit"; private static final String NAME = "KeepLatestOnly"; private long interval; @Override public String getName() { return NAME; } @Override public long getInterval() { return interval; } @Override public void start() { logger.debug("Starting KeepLatestContainerOnlyPolicy policy..."); TimeUnit timeUnit = TimeUnit.valueOf(System.getProperty(INTERVAL_TIME_UNIT, TimeUnit.MILLISECONDS.toString())); long givenInterval = Long.parseLong(System.getProperty(INTERVAL_VALUE, "0")); if (givenInterval > 0) { timeUnit.convert(givenInterval, timeUnit); this.interval = TimeUnit.MILLISECONDS.convert(givenInterval, timeUnit); } else { // default once a day this.interval = TimeUnit.MILLISECONDS.convert(1L, TimeUnit.DAYS); } logger.debug("Started {} policy", this); } @Override public void stop() { this.interval = -1; logger.debug("Stopped {} policy", this); } @Override public void apply(KieServerRegistry kieServerRegistry, KieServer kieServer) { DefaultRestControllerImpl controller = new DefaultRestControllerImpl(kieServerRegistry); List<String> containerAliases = kieServerRegistry.getContainerAliases(); if (containerAliases.isEmpty()) { logger.debug("No containers found, quiting"); return; } for (String alias : containerAliases) { List<KieContainerInstanceImpl> containerInstances = kieServerRegistry.getContainersForAlias(alias); if (containerInstances.isEmpty() || containerInstances.size() == 1) { logger.debug("Containers for alias {} are already on expected level (number of containers is {})", alias, containerInstances.size()); continue; } String latestContainerId = LatestContainerLocator.get().locateContainer(alias, containerInstances); final Map<String, String> report = new HashMap<>(); containerInstances.stream() .filter(kci -> !kci.getContainerId().equals(latestContainerId)) .filter(kci -> !kci.getStatus().equals(KieContainerStatus.CREATING)) .forEach(kci -> { ServiceResponse<Void> response = kieServer.disposeContainer(kci.getContainerId()); report.put(kci.getContainerId(), response.getType().toString()); logger.debug("Dispose of container {} completed with {} message {}", kci.getContainerId(), response.getType().toString(), response.getMsg()); if (response.getType().equals(ServiceResponse.ResponseType.SUCCESS)) { controller.stopContainer(kci.getContainerId()); } }); logger.info("KeepLatestContainerOnlyPolicy applied to {} successfully (report {})", alias, report); } } @Override public String toString() { return "KeepLatestContainerOnlyPolicy{" + "interval=" + interval + " ms" + '}'; } }