Package lcmc.crm.ui.resource

Source Code of lcmc.crm.ui.resource.GroupInfo

/*
* This file is part of DRBD Management Console by LINBIT HA-Solutions GmbH
* written by Rasto Levrinc.
*
* Copyright (C) 2009-2010, LINBIT HA-Solutions GmbH.
* Copyright (C) 2009-2010, Rasto Levrinc
*
* DRBD Management Console is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published
* by the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* DRBD Management Console is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with drbd; see the file COPYING.  If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package lcmc.crm.ui.resource;

import java.awt.Color;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.regex.Matcher;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Provider;
import javax.swing.ImageIcon;
import javax.swing.tree.DefaultMutableTreeNode;
import lcmc.common.domain.Application;
import lcmc.common.domain.ColorText;
import lcmc.common.ui.treemenu.TreeMenuController;
import lcmc.crm.domain.CrmXml;
import lcmc.crm.domain.ClusterStatus;
import lcmc.host.domain.Host;
import lcmc.crm.domain.ResourceAgent;
import lcmc.common.domain.Value;
import lcmc.common.ui.Browser;
import lcmc.cluster.ui.widget.Check;
import lcmc.cluster.ui.widget.Widget;
import lcmc.crm.service.CRM;
import lcmc.logger.Logger;
import lcmc.logger.LoggerFactory;
import lcmc.common.ui.utils.MyButton;
import lcmc.common.domain.util.Tools;
import lcmc.common.ui.utils.UpdatableItem;

/**
* GroupInfo class holds data for heartbeat group, that is in some ways
* like normal service, but it can contain other services.
*/
@Named
public class GroupInfo extends ServiceInfo {
    private static final Logger LOG = LoggerFactory.getLogger(GroupInfo.class);
    private final List<ServiceInfo> groupServices = new ArrayList<ServiceInfo>();

    private final ReadWriteLock mGroupServiceLock = new ReentrantReadWriteLock();
    private final Lock mGroupServiceReadLock = mGroupServiceLock.readLock();
    private final Lock mGroupServiceWriteLock = mGroupServiceLock.writeLock();
    @Inject
    private GroupMenu groupMenu;
    @Inject @Named("serviceInfo")
    private Provider<ServiceInfo> serviceInfoProvider;
    @Inject
    private Provider<FilesystemRaInfo> filesystemInfoProvider;
    @Inject
    private Provider<LinbitDrbdInfo> linbitDrbdInfoProvider;
    @Inject
    private Provider<DrbddiskInfo> drbddiskInfoProvider;
    @Inject
    private Provider<IPaddrInfo> ipaddrInfoProvider;
    @Inject
    private Provider<VirtualDomainInfo> virtualDomainInfoProvider;
    @Inject
    private Application application;
    @Inject
    private TreeMenuController treeMenuController;

    void init(final ResourceAgent ra, final Browser browser) {
        super.init(Application.PACEMAKER_GROUP_NAME, ra, browser);
    }

    /** Applies the the whole group if for example an order has changed. */
    void applyWhole(final Host dcHost,
                    final boolean createGroup,
                    final Iterable<String> newOrder,
                    final Application.RunMode runMode) {
        final String[] params = getParametersFromXML();
        if (Application.isLive(runMode)) {
            application.invokeAndWait(new Runnable() {
                @Override
                public void run() {
                    final MyButton ab = getApplyButton();
                    if (ab != null) {
                        ab.setEnabled(false);
                    }
                }
            });
        }
        getInfoPanel();
        waitForInfoPanel();

        final Map<String, String> groupMetaArgs = new LinkedHashMap<String, String>();
        for (final String param : params) {
            if (GUI_ID.equals(param) || PCMK_ID.equals(param)) {
                continue;
            }
            final Value value = getComboBoxValue(param);
            if (Tools.areEqual(value, getParamDefault(param))) {
                continue;
            }
            if (!value.isNothingSelected()) {
                if (CrmXml.GROUP_ORDERED_META_ATTR.equals(param)) {
                    groupMetaArgs.put("ordered", value.getValueForConfig());
                } else {
                    groupMetaArgs.put(param, value.getValueForConfig());
                }
            }
        }
        final Map<String, Map<String, String>> pacemakerResAttrs = new HashMap<String, Map<String, String>>();
        final Map<String, Map<String, String>> pacemakerResArgs = new HashMap<String, Map<String, String>>();
        final Map<String, Map<String, String>> pacemakerMetaArgs = new HashMap<String, Map<String, String>>();
        final Map<String, String> instanceAttrId = new HashMap<String, String>();
        final Map<String, Map<String, String>> nvpairIdsHash = new HashMap<String, Map<String, String>>();
        final Map<String, Map<String, Map<String, String>>> pacemakerOps =
                                                             new HashMap<String, Map<String, Map<String, String>>>();
        final Map<String, String> operationsId = new HashMap<String, String>();
        final Map<String, String> metaAttrsRefId = new HashMap<String, String>();
        final Map<String, String> operationsRefId = new HashMap<String, String>();
        final Map<String, Boolean> stonith = new HashMap<String, Boolean>();

        final ClusterStatus cs = getBrowser().getClusterStatus();
        for (final String resId : newOrder) {
            final ServiceInfo gsi = getBrowser().getServiceInfoFromCRMId(resId);
            if (gsi == null) {
                continue;
            }
            application.invokeAndWait(new Runnable() {
                @Override
                public void run() {
                    gsi.getInfoPanel();
                }
            });
        }
        application.waitForSwing();
        for (final String resId : newOrder) {
            final ServiceInfo gsi = getBrowser().getServiceInfoFromCRMId(resId);
            if (gsi == null) {
                continue;
            }
            pacemakerResAttrs.put(resId, gsi.getPacemakerResAttrs(runMode));
            pacemakerResArgs.put(resId, gsi.getPacemakerResArgs());
            pacemakerMetaArgs.put(resId, gsi.getPacemakerMetaArgs());
            instanceAttrId.put(resId, cs.getResourceInstanceAttrId(resId));
            nvpairIdsHash.put(resId, cs.getParametersNvpairsIds(resId));
            pacemakerOps.put(resId, gsi.getOperations(resId));
            operationsId.put(resId, cs.getOperationsId(resId));
            metaAttrsRefId.put(resId, gsi.getMetaAttrsRefId());
            operationsRefId.put(resId, gsi.getOperationsRefId());
            stonith.put(resId, gsi.getResourceAgent().isStonith());
        }
        final CloneInfo ci = getCloneInfo();
        String cloneId = null;
        boolean master = false;
        final Map<String, String> cloneMetaArgs = new LinkedHashMap<String, String>();
        String cloneMetaAttrsRefIds = null;
        if (createGroup && ci != null) {
            cloneId = ci.getHeartbeatId(runMode);
            final String[] cloneParams = ci.getParametersFromXML();
            master = ci.getService().isMaster();
            cloneMetaAttrsRefIds = ci.getMetaAttrsRefId();
            for (final String param : cloneParams) {
                if (GUI_ID.equals(param) || PCMK_ID.equals(param)) {
                    continue;
                }
                final Value value = ci.getComboBoxValue(param);
                if (Tools.areEqual(value, ci.getParamDefault(param))) {
                    continue;
                }
                if (!GUI_ID.equals(param) && !value.isNothingSelected()) {
                    cloneMetaArgs.put(param, value.getValueForConfig());
                }
            }
        }
        CRM.replaceGroup(createGroup,
                         dcHost,
                         cloneId,
                         master,
                         cloneMetaArgs,
                         cloneMetaAttrsRefIds,
                         newOrder,
                         groupMetaArgs,
                         getHeartbeatId(runMode),
                         pacemakerResAttrs,
                         pacemakerResArgs,
                         pacemakerMetaArgs,
                         instanceAttrId,
                         nvpairIdsHash,
                         pacemakerOps,
                         operationsId,
                         metaAttrsRefId,
                         getMetaAttrsRefId(),
                         operationsRefId,
                         stonith,
                         runMode);
        if (Application.isLive(runMode)) {
            storeComboBoxValues(params);
            treeMenuController.reloadNode(getNode(), false);
        }
        getBrowser().getCrmGraph().repaint();
    }

    /** Applies the changes to the group parameters. */
    @Override
    public void apply(final Host dcHost, final Application.RunMode runMode) {
        if (Application.isLive(runMode)) {
            application.invokeAndWait(new Runnable() {
                @Override
                public void run() {
                    getApplyButton().setEnabled(false);
                    getRevertButton().setEnabled(false);
                }
            });
        }
        getInfoPanel();
        waitForInfoPanel();
        final String[] params = getParametersFromXML();
        if (Application.isLive(runMode)) {
            application.invokeLater(new Runnable() {
                @Override
                public void run() {
                    getApplyButton().setToolTipText("");
                    final Widget idField = getWidget(GUI_ID, null);
                    idField.setEnabled(false);
                }
            });

            /* add myself to the hash with service name and id as
             * keys */
            getBrowser().removeFromServiceInfoHash(this);
            final String oldHeartbeatId = getHeartbeatId(runMode);
            if (oldHeartbeatId != null) {
                getBrowser().mHeartbeatIdToServiceLock();
                getBrowser().getHeartbeatIdToServiceInfo().remove(oldHeartbeatId);
                getBrowser().mHeartbeatIdToServiceUnlock();
            }
            if (getService().isNew()) {
                final String id = getComboBoxValue(GUI_ID).getValueForConfig();
                getService().setIdAndCrmId(id);
                if (getTypeRadioGroup() != null) {
                    getTypeRadioGroup().setEnabled(false);
                }
            }
            getBrowser().addNameToServiceInfoHash(this);
            getBrowser().addToHeartbeatIdList(this);
        }

        /*
            MSG_ADD_GRP group
                    param_id1 param_name1 param_value1
                    param_id2 param_name2 param_value2
                    ...
                    param_idn param_namen param_valuen
        */
        final String heartbeatId = getHeartbeatId(runMode);
        if (getService().isNew()) {
            final Set<ServiceInfo> parents = getBrowser().getCrmGraph().getParents(this);
            final List<Map<String, String>> colAttrsList = new ArrayList<Map<String, String>>();
            final List<Map<String, String>> ordAttrsList = new ArrayList<Map<String, String>>();
            final List<String> parentIds = new ArrayList<String>();
            for (final ServiceInfo parentInfo : parents) {
                final String parentId = parentInfo.getService().getCrmId();
                parentIds.add(parentId);
                final Map<String, String> colAttrs = new LinkedHashMap<String, String>();
                final Map<String, String> ordAttrs = new LinkedHashMap<String, String>();
                colAttrs.put(CrmXml.SCORE_CONSTRAINT_PARAM, CrmXml.INFINITY_VALUE.getValueForConfig());
                ordAttrs.put(CrmXml.SCORE_CONSTRAINT_PARAM, CrmXml.INFINITY_VALUE.getValueForConfig());
                if (getService().isMaster()) {
                    colAttrs.put("with-rsc-role", "Master");
                    ordAttrs.put("first-action", "promote");
                    ordAttrs.put("then-action", "start");
                }
                colAttrsList.add(colAttrs);
                ordAttrsList.add(ordAttrs);
            }
            CRM.setOrderAndColocation(dcHost,
                                      heartbeatId,
                                      parentIds.toArray(new String [parentIds.size()]),
                                      colAttrsList,
                                      ordAttrsList,
                                      runMode);
            final Collection<String> newOrder = new ArrayList<String>();
            for (final ServiceInfo child : getGroupServices()) {
                newOrder.add(child.getHeartbeatId(runMode));
            }
            applyWhole(dcHost, true, newOrder, runMode);
            if (Application.isLive(runMode)) {
                setApplyButtons(null, params);
            }
            getBrowser().getCrmGraph().repaint();
            return;
        } else {
            final Map<String, String> groupMetaArgs = new LinkedHashMap<String, String>();
            for (final String param : params) {
                if (GUI_ID.equals(param) || PCMK_ID.equals(param)) {
                    continue;
                }
                final Value value = getComboBoxValue(param);
                if (Tools.areEqual(value, getParamDefault(param))) {
                    continue;
                }
                if (value != null && !value.isNothingSelected()) {
                    if (CrmXml.GROUP_ORDERED_META_ATTR.equals(param)) {
                        groupMetaArgs.put("ordered", value.getValueForConfig());
                    } else {
                        groupMetaArgs.put(param, value.getValueForConfig());
                    }
                }
            }
            CRM.setParameters(dcHost,
                              "-R",
                              null,  /* crm id */
                              null,  /* TODO: clone id */
                              false, /* master */
                              null,  /* cloneMetaArgs, */
                              groupMetaArgs,
                              heartbeatId, /* group id */
                              null,  /* pacemakerResAttrs, */
                              null,  /* pacemakerResArgs, */
                              null,  /* pacemakerMetaArgs, */
                              null,  /* cs.getResourceInstanceAttrId(heartbeatId), */
                              null,  /* cs.getParametersNvpairsIds(heartbeatId), */
                              null,  /* getOperations(heartbeatId), */
                              null,  /* cs.getOperationsId(heartbeatId), */
                              null,  /* getMetaAttrsRefId(), */
                              null,  /* cloneMetaAttrsRefIds, */
                              getMetaAttrsRefId(),
                              null,  /* getOperationsRefId(), */
                              false, /* stonith */
                              runMode);
        }
        final CloneInfo ci = getCloneInfo();
        if (ci == null) {
            setLocations(heartbeatId, dcHost, runMode);
        } else {
            ci.setLocations(heartbeatId, dcHost, runMode);

        }
        if (Application.isLive(runMode)) {
            storeComboBoxValues(params);
            treeMenuController.reloadNode(getNode(), false);
        }
        for (final ServiceInfo child : getGroupServices()) {
            final Check childCheck = child.checkResourceFields(null,
                                                               child.getParametersFromXML(),
                                                               false,
                                                               false,
                                                               true);
            if (childCheck.isCorrect() && childCheck.isChanged()) {
                child.apply(dcHost, runMode);
            }
        }
        if (Application.isLive(runMode)) {
            setApplyButtons(null, params);
        }
        getBrowser().getCrmGraph().repaint();
    }

    Iterable<ResourceAgent> getAddGroupServiceList(final String cl) {
        return getBrowser().getCrmXml().getServices(cl);
    }

    /**
     * Adds service to this group. Adds it in the submenu in the menu tree
     * and initializes it.
     *
     * @param newServiceInfo
     *      service info object of the new service
     */
    void addGroupServicePanel(final ServiceInfo newServiceInfo, final boolean reloadNode) {
        final DefaultMutableTreeNode groupNode = getNode();
        if (groupNode == null) {
            return;
        }
        newServiceInfo.getService().setResourceClass(newServiceInfo.getResourceAgent().getResourceClass());
        newServiceInfo.setGroupInfo(this);
        getBrowser().addNameToServiceInfoHash(newServiceInfo);
        getBrowser().addToHeartbeatIdList(newServiceInfo);
        final DefaultMutableTreeNode newServiceNode = treeMenuController.createMenuItem(groupNode, newServiceInfo);
        mGroupServiceWriteLock.lock();
        try {
            groupServices.add(newServiceInfo);
        } finally {
            mGroupServiceWriteLock.unlock();
        }
        if (reloadNode) {
            treeMenuController.reloadNode(groupNode, false);
            treeMenuController.reloadNode(newServiceNode, true);
        }
    }

    ServiceInfo addGroupServicePanel(final ResourceAgent newRA, final boolean reloadNode) {
        final ServiceInfo newServiceInfo;

        final String name = newRA.getServiceName();
        if (newRA.isFilesystem()) {
            newServiceInfo = filesystemInfoProvider.get();
        } else if (newRA.isLinbitDrbd()) {
            newServiceInfo = linbitDrbdInfoProvider.get();
        } else if (newRA.isDrbddisk()) {
            newServiceInfo = drbddiskInfoProvider.get();
        } else if (newRA.isIPaddr()) {
            newServiceInfo = ipaddrInfoProvider.get();
        } else if (newRA.isVirtualDomain()) {
            newServiceInfo = virtualDomainInfoProvider.get();
        } else if (newRA.isGroup()) {
            LOG.appError("addGroupServicePanel: no groups in group allowed");
            return null;
        } else {
            newServiceInfo = serviceInfoProvider.get();
        }
        newServiceInfo.init(name, newRA, getBrowser());
        addGroupServicePanel(newServiceInfo, reloadNode);
        return newServiceInfo;
    }

    /**
     * Returns on which node this group is running, meaning on which node
     * all the services are running. Null if they running on different
     * nodes or not at all.
     */
    @Override
    protected List<String> getRunningOnNodes(final Application.RunMode runMode) {
        final ClusterStatus cs = getBrowser().getClusterStatus();
        final List<String> resources = cs.getGroupResources(getHeartbeatId(runMode), runMode);
        final List<String> allNodes = new ArrayList<String>();
        if (resources != null) {
            for (final String hbId : resources) {
                final List<String> ns = cs.getRunningOnNodes(hbId, runMode);
                if (ns != null) {
                    for (final String n : ns) {
                        if (!allNodes.contains(n)) {
                            allNodes.add(n);
                        }
                    }
                }
            }
        }
        return allNodes;
    }

    /** Returns node name of the host where this service is running. */
    @Override
    List<String> getMasterOnNodes(final Application.RunMode runMode) {
        final ClusterStatus cs = getBrowser().getClusterStatus();
        final List<String> resources = cs.getGroupResources(getHeartbeatId(runMode), runMode);
        final List<String> allNodes = new ArrayList<String>();
        if (resources != null) {
            for (final String hbId : resources) {
                final List<String> ns = cs.getMasterOnNodes(hbId, runMode);
                if (ns != null) {
                    for (final String n : ns) {
                        if (!allNodes.contains(n)) {
                            allNodes.add(n);
                        }
                    }
                }
            }
        }
        return allNodes;
    }

    /** Starts all resources in the group. */
    @Override
    void startResource(final Host dcHost, final Application.RunMode runMode) {
        if (Application.isLive(runMode)) {
            setUpdated(true);
        }
        for (final ServiceInfo child : getGroupServices()) {
            CRM.startResource(dcHost, child.getHeartbeatId(runMode), runMode);
        }
    }

    /** Stops all resources in the group. */
    @Override
    void stopResource(final Host dcHost, final Application.RunMode runMode) {
        if (Application.isLive(runMode)) {
            setUpdated(true);
        }
        for (final ServiceInfo child : getGroupServices()) {
            CRM.stopResource(dcHost, child.getHeartbeatId(runMode), runMode);
        }
    }

    /** Cleans up all resources in the group. */
    @Override
    void cleanupResource(final Host dcHost, final Application.RunMode runMode) {
        if (Application.isLive(runMode)) {
            setUpdated(true);
        }
        for (final ServiceInfo child : getGroupServices()) {
            child.cleanupResource(dcHost, runMode);
        }
    }

    /** Sets whether the group services are managed. */
    @Override
    void setManaged(final boolean isManaged, final Host dcHost, final Application.RunMode runMode) {
        if (Application.isLive(runMode)) {
            setUpdated(true);
        }
        for (final ServiceInfo child : getGroupServices()) {
            CRM.setManaged(dcHost, child.getHeartbeatId(runMode), isManaged, runMode);
        }
    }

    @Override
    public List<UpdatableItem> createPopup() {
        return groupMenu.getPulldownMenu(this);
    }

    /** Removes this group from the cib. */
    @Override
    public void removeMyself(final Application.RunMode runMode) {
        if (getService().isNew()) {
            removeMyselfNoConfirm(getBrowser().getDCHost(), runMode);
            getService().setNew(false);
            super.removeInfo();
            getService().doneRemoving();
            return;
        }
        String desc = Tools.getString("ClusterBrowser.confirmRemoveGroup.Description");

        final StringBuilder services = new StringBuilder();

        boolean first = true;
        for (final ServiceInfo child : getGroupServices()) {
            if (!first) {
                services.append(", ");
            }
            services.append(child);
            first = false;
        }

        desc  = desc.replaceAll("@GROUP@", '\'' + Matcher.quoteReplacement(toString()) + '\'');
        desc  = desc.replaceAll("@SERVICES@", Matcher.quoteReplacement(services.toString()));
        if (application.confirmDialog(Tools.getString("ClusterBrowser.confirmRemoveGroup.Title"),
                                desc,
                                Tools.getString("ClusterBrowser.confirmRemoveGroup.Yes"),
                                Tools.getString("ClusterBrowser.confirmRemoveGroup.No"))) {
            if (Application.isLive(runMode)) {
                getService().setRemoved(true);
            }
            removeMyselfNoConfirm(getBrowser().getDCHost(), runMode);
            super.removeInfo();
            getService().setNew(false);
        }
        getService().doneRemoving();
    }

    @Override
    public void removeInfo() {
        for (final ServiceInfo child : getGroupServices()) {
            child.removeInfo();
        }
        super.removeInfo();
    }

    /** Remove all the services in the group and the group. */
    @Override
    public void removeMyselfNoConfirm(final Host dcHost, final Application.RunMode runMode) {
        final Collection<ServiceInfo> children = new ArrayList<ServiceInfo>();
        if (Application.isLive(runMode)) {
            for (final ServiceInfo child : getGroupServices()) {
                child.getService().setRemoved(true);
                children.add(child);
            }
        }
        if (getService().isNew()) {
            if (Application.isLive(runMode)) {
                getService().setNew(false);
                getBrowser().getCrmGraph().killRemovedVertices();
                getService().doneRemoving();
            }
        } else {
            String cloneId = null;
            boolean master = false;
            final CloneInfo ci = getCloneInfo();
            if (ci != null) {
                cloneId = ci.getHeartbeatId(runMode);
                master = ci.getService().isMaster();
            }
            super.removeMyselfNoConfirm(dcHost, runMode);
            for (final ServiceInfo child : children) {
                child.removeConstraints(dcHost, runMode);
            }
            CRM.removeResource(dcHost, null, getHeartbeatId(runMode), cloneId, master, runMode);
            for (final ServiceInfo child : children) {
                child.cleanupResource(dcHost, runMode);
            }
        }
        if (Application.isLive(runMode)) {
            for (final ServiceInfo child : children) {
                getBrowser().mHeartbeatIdToServiceLock();
                getBrowser().getHeartbeatIdToServiceInfo().remove(child.getService().getCrmId());
                getBrowser().mHeartbeatIdToServiceUnlock();
                getBrowser().removeFromServiceInfoHash(child);
                child.cleanup();
                child.getService().doneRemoving();
            }
        }
    }

    /** Removes the group, but not the services. */
    void removeMyselfNoConfirmFromChild(final Host dcHost, final Application.RunMode runMode) {
        super.removeMyselfNoConfirm(dcHost, runMode);
    }

    /** Returns tool tip for the group vertex. */
    @Override
    public String getToolTipText(final Application.RunMode runMode) {
        final List<String> hostNames = getRunningOnNodes(runMode);
        final StringBuilder sb = new StringBuilder(220);
        sb.append("<b>");
        sb.append(this);
        if (hostNames == null || hostNames.isEmpty()) {
            sb.append(" not running");
        } else if (hostNames.size() == 1) {
            sb.append(" running on node: ");
        } else {
            sb.append(" running on nodes: ");
        }
        if (hostNames != null && !hostNames.isEmpty()) {
            sb.append(Tools.join(", ", hostNames.toArray(new String[hostNames.size()])));
        }
        sb.append("</b>");

        for (final ServiceInfo child : getGroupServices()) {
            sb.append("\n&nbsp;&nbsp;&nbsp;");
            sb.append(child.getToolTipText(runMode));
        }

        return sb.toString();
    }

    @Override
    boolean isOneFailed(final Application.RunMode runMode) {
        for (final ServiceInfo child : getGroupServices()) {
            if (child.isOneFailed(runMode)) {
                return true;
            }
        }
        return false;
    }

    @Override
    boolean isOneFailedCount(final Application.RunMode runMode) {
        for (final ServiceInfo child : getGroupServices()) {
            if (child.isOneFailedCount(runMode)) {
                return true;
            }
        }
        return false;
    }

    /** Returns whether one of the services failed to start. */
    @Override
    public boolean isFailed(final Application.RunMode runMode) {
        for (final ServiceInfo child : getGroupServices()) {
            if (child.isFailed(runMode)) {
                return true;
            }
        }
        return false;
    }

    /** Returns subtexts that appears in the service vertex. */
    @Override
    public ColorText[] getSubtextsForGraph(final Application.RunMode runMode) {
        final List<ColorText> texts = new ArrayList<ColorText>();
        ColorText prevColorText = null;

        for (final ServiceInfo child : getGroupServices()) {
            final ColorText[] colorTexts = child.getSubtextsForGraph(runMode);

            if (colorTexts == null || colorTexts.length == 0) {
                continue;
            }
            final ColorText sColorText = colorTexts[0];
            if (prevColorText == null || !sColorText.getSubtext().equals(prevColorText.getSubtext())) {
                texts.add(new ColorText(sColorText.getSubtext() + ':', sColorText.getColor(), Color.BLACK));
                prevColorText = sColorText;
            }
            String unmanaged = "";
            if (!child.isManaged(runMode)) {
                unmanaged = " / unmanaged";
            }
            String migrated = "";
            if (child.getMigratedTo(runMode) != null || child.getMigratedFrom(runMode) != null) {
                migrated = " / migrated";
            }
            final HbConnectionInfo[] hbcis = getBrowser().getCrmGraph().getHbConnections(child);
            String constraintLeft = "";
            String constraint = "";
            if (hbcis != null) {
                boolean scoreFirst = false;
                boolean scoreThen = false;
                boolean someConnection = false;
                for (final HbConnectionInfo hbci : hbcis) {
                    if (hbci == null) {
                        continue;
                    }
                    if (!someConnection && hbci.hasColocationOrOrder(child)) {
                        someConnection = true;
                    }
                    if (!scoreFirst && !hbci.isOrdScoreNull(child, null)) {
                        scoreFirst = true;
                    }
                    if (!scoreThen && !hbci.isOrdScoreNull(null, child)) {
                        scoreThen = true;
                    }
                }
                if (someConnection) {
                    if (scoreFirst || scoreThen) {
                        if (scoreFirst) {
                            constraint = " \u2192"; /* -> */
                        }
                        if (scoreThen) {
                            constraintLeft = "\u2192 "; /* -> */
                        }
                    } else {
                        /* just colocation */
                        constraint = " --"; /* -- */
                    }
                }
            }
            texts.add(new ColorText("   " + constraintLeft + child + unmanaged + migrated + constraint,
                                  sColorText.getColor(),
                                  Color.BLACK));
            boolean skip = true;
            for (final ColorText st : colorTexts) {
                if (skip) {
                    skip = false;
                    continue;
                }
                texts.add(new ColorText("   " + st.getSubtext(), st.getColor(), Color.BLACK));
            }
        }
        return texts.toArray(new ColorText[texts.size()]);
    }

    /**
     * Returns from which hosts the services or the whole group was migrated.
     */
    @Override
    public List<Host> getMigratedFrom(final Application.RunMode runMode) {
        List<Host> hosts = super.getMigratedFrom(runMode);
        final List<ServiceInfo> gs = getGroupServices();
        if (gs.isEmpty()) {
            return null;
        }
        for (final ServiceInfo child : gs) {
            final List<Host> siHosts = child.getMigratedFrom(runMode);
            if (siHosts != null) {
                if (hosts == null) {
                    hosts = new ArrayList<Host>();
                }
                hosts.addAll(siHosts);
            }
        }
        return hosts;
    }

    /** Returns whether at least one service is unmanaged. */
    @Override
    public boolean isManaged(final Application.RunMode runMode) {
        final List<ServiceInfo> gs = getGroupServices();
        if (gs.isEmpty()) {
            return true;
        }
        for (final ServiceInfo child : gs) {
            if (!child.isManaged(runMode)) {
                return false;
            }
        }
        return true;
    }

    /** Returns whether all of the services are started. */
    @Override
    boolean isStarted(final Application.RunMode runMode) {
        for (final ServiceInfo child : getGroupServices()) {
            if (!child.isStarted(runMode)) {
                return false;
            }
        }
        return true;
    }

    /** Returns whether one of the services is stopped. */
    @Override
    public boolean isStopped(final Application.RunMode runMode) {
        for (final ServiceInfo child : getGroupServices()) {
            if (child.isStopped(runMode)) {
                return true;
            }
        }
        return false;
    }

    /** Returns whether the group is stopped. */
    @Override
    boolean isGroupStopped(final Application.RunMode runMode) {
        return super.isStopped(runMode);
    }

    /** Returns true if at least one service in the group are running. */
    boolean isOneRunning(final Application.RunMode runMode) {
        for (final ServiceInfo child : getGroupServices()) {
            if (child.isRunning(runMode)) {
                return true;
            }
        }
        return false;
    }

    /** Returns true if all services in the group are running. */
    @Override
    public boolean isRunning(final Application.RunMode runMode) {
        for (final ServiceInfo child : getGroupServices()) {
            if (!child.isRunning(runMode)) {
                return false;
            }
        }
        return true;
    }

    /**
     * Returns whether the specified parameter or any of the parameters
     * have changed. If group does not have any services, its changes
     * cannot by applied.
     */
    @Override
    public Check checkResourceFields(final String param, final String[] params) {
        return checkResourceFields(param, params, false, false);
    }

    /**
     * Returns whether all the parameters are correct. If param is null,
     * all paremeters will be checked, otherwise only the param, but other
     * parameters will be checked only in the cache. This is good if only
     * one value is changed and we don't want to check everything.
     */
    Check checkResourceFields(final String param,
                              final String[] params,
                              final boolean fromServicesInfo,
                              final boolean fromCloneInfo) {
        final List<String> incorrect = new ArrayList<String>();
        final List<String> changed = new ArrayList<String>();
        final Check check = new Check(incorrect, changed);
        check.addCheck(super.checkResourceFields(param, params, fromServicesInfo, fromCloneInfo, true));
        boolean hasSevices = false;
        for (final ServiceInfo child : getGroupServices()) {
            check.addCheck(child.checkResourceFields(null,
                                                     child.getParametersFromXML(),
                                                     fromServicesInfo,
                                                     fromCloneInfo,
                                                     true));
            hasSevices = true;
        }
        if (!hasSevices) {
            incorrect.add("no services");
        }
        return check;
    }

    /** Update menus with positions and calles their update methods. */
    @Override
    public void updateMenus(final Point2D pos) {
        super.updateMenus(pos);
        if (!application.isSlow()) {
            for (final ServiceInfo child : getGroupServices()) {
                child.updateMenus(pos);
            }
        }
    }

    @Override
    public ImageIcon getCategoryIcon(final Application.RunMode runMode) {
        if (getBrowser().allHostsWithoutClusterStatus() || !isOneRunning(runMode)) {
            return ServiceInfo.SERVICE_STOPPED_ICON_SMALL;
        }
        return ServiceInfo.SERVICE_RUNNING_ICON_SMALL;
    }

    /** Revert all values. */
    @Override
    public void revert() {
        super.revert();
        for (final ServiceInfo child : getGroupServices()) {
            if (child.checkResourceFields(null, child.getParametersFromXML(), true, false, false).isChanged()) {
                child.revert();
            }
        }
    }

    /** Return copy of the group services. */
    public List<ServiceInfo> getGroupServices() {
        mGroupServiceReadLock.lock();
        try {
            return Collections.unmodifiableList(new ArrayList<ServiceInfo>(groupServices));
        } finally {
            mGroupServiceReadLock.unlock();
        }
    }
}
TOP

Related Classes of lcmc.crm.ui.resource.GroupInfo

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.