package org.zstack.compute.cluster; import org.springframework.beans.factory.annotation.Autowired; import org.zstack.core.componentloader.PluginExtension; import org.zstack.core.componentloader.PluginRegistry; import org.zstack.header.Component; import org.zstack.header.cluster.*; import org.zstack.utils.CollectionUtils; import org.zstack.utils.Utils; import org.zstack.utils.function.ForEachFunction; import org.zstack.utils.logging.CLogger; import java.util.List; class ClusterExtensionPointEmitter implements Component { private static final CLogger logger = Utils.getLogger(ClusterExtensionPointEmitter.class); @Autowired private PluginRegistry pluginRgty; private List<ClusterDeleteExtensionPoint> deleteExts; private List<ClusterChangeStateExtensionPoint> changeExts; void preDelete(ClusterInventory cinv) throws ClusterException { for (ClusterDeleteExtensionPoint extp : deleteExts) { try { extp.preDeleteCluster(cinv); } catch (ClusterException ce) { logger.warn(String.format("extension[%s] refused to delete cluster[name: %s, uuid: %s], %s", extp.getClass().getName(), cinv.getName(), cinv.getUuid(), ce.getMessage()), ce); throw ce; } catch (Exception e) { logger.warn("Exception happened while calling " + extp.getClass().getCanonicalName() + ".preDeleteCluster(), " + "cluster name: " + cinv.getName() + " uuid: " + cinv.getUuid(), e); } } } void preChange(ClusterVO vo, ClusterStateEvent event) throws ClusterException { ClusterState next = AbstractCluster.getNextState(vo.getState(), event); ClusterInventory cinv = ClusterInventory.valueOf(vo); for (ClusterChangeStateExtensionPoint extp : changeExts) { try { extp.preChangeClusterState(cinv, event, next); } catch (ClusterException ce) { logger.debug(String.format("Extension: %s refused cluster change state operation[ClusterStateEvent:%s] because %s", extp.getClass() .getCanonicalName(), event, ce.getMessage())); throw ce; } catch (Exception e) { logger.warn("Exception happened while calling " + extp.getClass().getCanonicalName() + ".preChangeClusterState(), " + "cluster name: " + cinv.getName() + " uuid: " + cinv.getUuid(), e); } } } void preChange(List<ClusterVO> vos, ClusterStateEvent event) throws ClusterException { for (ClusterVO vo : vos) { preChange(vo, event); } } void beforeChange(ClusterVO vo, final ClusterStateEvent event) { final ClusterInventory cinv = ClusterInventory.valueOf(vo); final ClusterState next = AbstractCluster.getNextState(vo.getState(), event); CollectionUtils.safeForEach(changeExts, new ForEachFunction<ClusterChangeStateExtensionPoint>() { @Override public void run(ClusterChangeStateExtensionPoint extp) { extp.beforeChangeClusterState(cinv, event, next); } }); } void afterChange(ClusterVO vo, final ClusterStateEvent event, final ClusterState prevState) { final ClusterInventory cinv = ClusterInventory.valueOf(vo); CollectionUtils.safeForEach(changeExts, new ForEachFunction<ClusterChangeStateExtensionPoint>() { @Override public void run(ClusterChangeStateExtensionPoint extp) { extp.afterChangeClusterState(cinv, event, prevState); } }); } void beforeDelete(final ClusterInventory cinv) { CollectionUtils.safeForEach(deleteExts, new ForEachFunction<ClusterDeleteExtensionPoint>() { @Override public void run(ClusterDeleteExtensionPoint arg) { arg.beforeDeleteCluster(cinv); } }); } void afterDelete(final ClusterInventory cinv) { CollectionUtils.safeForEach(deleteExts, new ForEachFunction<ClusterDeleteExtensionPoint>() { @Override public void run(ClusterDeleteExtensionPoint arg) { arg.afterDeleteCluster(cinv); } }); } private void populateExtensions() { deleteExts = pluginRgty.getExtensionList(ClusterDeleteExtensionPoint.class); changeExts = pluginRgty.getExtensionList(ClusterChangeStateExtensionPoint.class); } @Override public boolean start() { populateExtensions(); return true; } @Override public boolean stop() { return true; } }