Package org.rioproject.impl.servicebean

Source Code of org.rioproject.impl.servicebean.ServiceElementUtil

/*
* Copyright to the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      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.rioproject.impl.servicebean;

import com.sun.jini.lookup.entry.LookupAttributes;
import net.jini.config.Configuration;
import net.jini.config.ConfigurationException;
import net.jini.config.ConfigurationProvider;
import net.jini.core.discovery.LookupLocator;
import net.jini.core.entry.Entry;
import net.jini.discovery.DiscoveryGroupManagement;
import org.rioproject.associations.AssociationDescriptor;
import org.rioproject.associations.AssociationType;
import org.rioproject.servicebean.ServiceBeanContext;
import org.rioproject.deploy.SystemComponent;
import org.rioproject.log.LoggerConfig;
import org.rioproject.opstring.ClassBundle;
import org.rioproject.opstring.ServiceBeanConfig;
import org.rioproject.opstring.ServiceElement;
import org.rioproject.resolver.RemoteRepository;
import org.rioproject.sla.SLA;
import org.rioproject.impl.sla.SLAPolicyHandler;
import org.rioproject.sla.ServiceLevelAgreements;
import org.rioproject.system.capability.PlatformCapability;
import org.rioproject.impl.watch.ThreadDeadlockMonitor;
import org.rioproject.watch.WatchDescriptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.management.MBeanServerConnection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
* The ServiceElementUtil class provides static methods to assist in working
* with a {@link org.rioproject.opstring.ServiceElement}
*
* @author Dennis Reedy
*/
public final class ServiceElementUtil {
    private static Logger logger = LoggerFactory.getLogger("org.rioproject.impl.servicebean.ServiceElementUtil");

    private ServiceElementUtil() {}

    public static String getLoggingName(ServiceBeanContext context) {
        if(context==null)
            return "<unknown>";
        return getLoggingName(context.getServiceElement());
    }

    public static String getLoggingName(ServiceElement element) {
        StringBuilder sb = new StringBuilder();
        sb.append(element.getOperationalStringName()).append("/").append(element.getName());
        Long id = element.getServiceBeanConfig().getInstanceID();
        if(id!=null) {
            sb.append(":").append(id.toString());
        }
        return sb.toString();
    }

    /**
     * Check to see if the ThreadDeadlockMonitor has been declared as an SLA.
     * If not, add the default setup for the ThreadDeadlockMonitor
     *
     * @param sElem The ServiceElement to use
     * @param mbsc An optional MBeanServerConnection to set to the
     * ThreadDeadlockDetector
     *
     * @throws IllegalArgumentException if the ServiceElement parameter is null
     */
    public static void setThreadDeadlockDetector(ServiceElement sElem, MBeanServerConnection mbsc) {
        WatchDescriptor threadDeadlockDesc = getWatchDescriptor(sElem, ThreadDeadlockMonitor.ID);

        if(threadDeadlockDesc == null) {
            SLA sla = new SLA(ThreadDeadlockMonitor.ID, 0, 1);
            sla.setSlaPolicyHandler(SLAPolicyHandler.class.getName());
            threadDeadlockDesc = ThreadDeadlockMonitor.getWatchDescriptor();
            threadDeadlockDesc.setMBeanServerConnection(mbsc);
            sla.setWatchDescriptors(threadDeadlockDesc);
            sElem.getServiceLevelAgreements().addServiceSLA(sla);
        } else {
            threadDeadlockDesc.setMBeanServerConnection(mbsc);
        }
    }

    /**
     * Get the WatchDescriptor from an SLA for the given ID
     *
     * @param sElem The ServiceElement to use
     * @param name The WatchDescriptor name
     *
     * @return The matching WatchDescriptor or null if not found
     *
     * @throws IllegalArgumentException if either of the parameters are null
     */
    public static WatchDescriptor getWatchDescriptor(ServiceElement sElem, String name) {
        if(sElem == null)
            throw new IllegalArgumentException("ServiceElement cannot be null");
        if(name == null)
            throw new IllegalArgumentException("name cannot be null");
        WatchDescriptor wDesc = null;
        ServiceLevelAgreements slas = sElem.getServiceLevelAgreements();
        for(SLA sla : slas.getServiceSLAs()) {
            WatchDescriptor[] wDescs = sla.getWatchDescriptors();
            for(WatchDescriptor wd : wDescs) {
                if(wd.getName().equals(name)) {
                    wDesc = wd;
                    break;
                }
            }
        }
        return wDesc;
    }

    /**
     * Determine if the LoggerConfig attributes are different between
     * the two ServiceElement instances
     *
     * @param sElem1 ServiceElement to compare
     * @param sElem2 ServiceElement to compare
     *
     * @return True if there is a difference between the LoggerConfig attributes,
     * false otherwise
     */
    public static boolean hasDifferentLoggerConfig(ServiceElement sElem1, ServiceElement sElem2) {
        if(sElem1==null || sElem2==null)
            throw new IllegalArgumentException("parameters cannot be null");
        boolean different = false;
        LoggerConfig[] loggerConfigs2 = sElem2.getServiceBeanConfig().getLoggerConfigs();
        LoggerConfig[] loggerConfigs1 = sElem1.getServiceBeanConfig().getLoggerConfigs();

        if(loggerConfigs1!=null && loggerConfigs2!=null) {
            for (LoggerConfig aLoggerConfigs2 : loggerConfigs2) {
                if (LoggerConfig.isNewLogger(aLoggerConfigs2, loggerConfigs1)) {
                    different = true;
                    break;
                } else if (LoggerConfig.levelChanged(aLoggerConfigs2, loggerConfigs1)) {
                    different = true;
                    break;
                }
            }
        }
        return(different);
    }

    /**
     * Determine if there are different ServiceUI declarations in the
     * ServiceElement instance
     *
     * @param serviceUIs Array of attributes
     * @param sElem2 ServiceElement to compare
     * @param codebase The codebase to use
     *
     * @return True if there are differences. false if the same
     */
    public static boolean hasDifferentServiceUIs(Entry[] serviceUIs, ServiceElement sElem2, String codebase) {
        if(serviceUIs==null || sElem2==null || codebase==null) {
            StringBuilder sb = new StringBuilder();
            if(serviceUIs==null)
                sb.append("serviceUIs");
            if(sElem2==null) {
                if(sb.length()>0)
                    sb.append(", ");
                sb.append("sElem2");
            }
            if(codebase==null) {
                if(sb.length()>0)
                    sb.append(", ");
                sb.append("codebase");
            }
            throw new IllegalArgumentException("The provided parameters " +
                                               "("+sb.toString()+") were passed " +
                                               "in with null values, they cannot be " +
                                               "null");
        }
        try {
            Configuration config2 =
                ConfigurationProvider.getInstance(sElem2.getServiceBeanConfig().getConfigArgs());
            String className = sElem2.getComponentBundle().getClassName();
            String serviceBeanComponent = className.substring(0, className.lastIndexOf("."));
            /* Get any configured ServiceUIs */
            Entry[] serviceUIs1 = (Entry[])config2.getEntry(serviceBeanComponent,
                                                            "serviceUIs",
                                                            Entry[].class,
                                                            new Entry[0],
                                                            codebase);           
            return(!LookupAttributes.equal(serviceUIs, serviceUIs1));
        } catch (ConfigurationException e) {
            if(logger.isTraceEnabled())
                logger.trace("Getting ServiceUIs from ServiceElement", e);
        }
        return(false);
    }
   
    /**
     * Determine if the Discovery groups are different between
     * the two ServiceElement instances
     *
     * @param sElem1 ServiceElement to compare
     * @param sElem2 ServiceElement to compare
     *
     * @return True if there is a difference between the Discovery groups,
     * false otherwise
     */
    public static boolean hasDifferentGroups(ServiceElement sElem1, ServiceElement sElem2) {
        if(sElem1==null || sElem2==null)
            throw new IllegalArgumentException("parameters cannot be null");
        boolean different = false;
        String[] groups1 = sElem1.getServiceBeanConfig().getGroups();
        String[] groups2 = sElem2.getServiceBeanConfig().getGroups();
        if (groups1 == DiscoveryGroupManagement.ALL_GROUPS && groups2 == DiscoveryGroupManagement.ALL_GROUPS)
            return false;
        else if (groups1 == null && groups2 == null)
            return false;
        else if (groups1 == null || groups2 == null)
            return true;
        else if (groups1.length != groups2.length) {
            different = true;
        } else {
            for (String aGroups1 : groups1) {
                boolean matched = false;
                for (String aGroups2 : groups2) {
                    if (aGroups1.equals(aGroups2)) {
                        matched = true;
                        break;
                    }
                }
                if (logger.isTraceEnabled()) {
                    StringBuilder builder = new StringBuilder();
                    builder.append("[");
                    builder.append(sElem1.getName()).append(":").append(sElem1.getServiceBeanConfig().getInstanceID());
                    builder.append("] groups [").append(aGroups1).append("] matched in groups2 ?").append(matched);
                    logger.trace(builder.toString());
                }
                if (!matched) {
                    different = true;
                    break;
                }
            }
        }
        return(different);
    }
   
    /**
     * Determine if the LookupLocators are different between
     * the two ServiceElement instances
     *
     * @param sElem1 ServiceElement to compare
     * @param sElem2 ServiceElement to compare
     *
     * @return True if there is a difference between the LookupLocators,
     * false otherwise
     */
    public static boolean hasDifferentLocators(ServiceElement sElem1, ServiceElement sElem2) {
        if(sElem1==null || sElem2==null)
            throw new IllegalArgumentException("parameters cannot be null");
        boolean different = false;
        LookupLocator[] locs1 = sElem1.getServiceBeanConfig().getLocators();
        LookupLocator[] locs2 = sElem2.getServiceBeanConfig().getLocators();
        if(locs1 == null && locs2 == null)
            return(false);
        if(locs1 == null || locs2 == null)
            return (true);
        if(locs1.length != locs2.length) {
            different = true;
        } else {
            for (LookupLocator aLocs1 : locs1) {
                boolean matched = false;
                for (LookupLocator aLocs2 : locs2) {
                    if (aLocs1.equals(aLocs2)) {
                        matched = true;
                        break;
                    }
                }
                if (!matched) {
                    different = true;
                    break;
                }
            }
        }
        return(different);
    }
   
    /**
     * Set the instanceID, optionally making a copy of the ServiceElement
     *
     * @param sElem The ServiceElement to use
     * @param copy If true, make a copy of the ServiceElement before assigning
     * the instanceID
     * @param id The instanceID to assign
     *
     * @return A ServiceElement with it's instanceID set to the value provided
     */
    public static ServiceElement prepareInstanceID(ServiceElement sElem,  boolean copy, long id) {
        ServiceElement elem = sElem;
        if(copy)
            elem = copyServiceElement(sElem);
       
        /* set the instance id */
        Map<String, Object> parms = elem.getServiceBeanConfig().getConfigurationParameters();
        parms.put(ServiceBeanConfig.INSTANCE_ID, id);
        ServiceBeanConfig sbConfig = new ServiceBeanConfig(parms, elem.getServiceBeanConfig().getConfigArgs());
        /* Get the initialization parameters and add them */
        Map<String, Object> initParms = elem.getServiceBeanConfig().getInitParameters();
        for (Map.Entry<String, Object> e : initParms.entrySet()) {
            sbConfig.addInitParameter(e.getKey(), e.getValue());
        }
        if(!elem.getServiceBeanConfig().getAdditionalEntries().isEmpty()) {
            List<Entry> entries = elem.getServiceBeanConfig().getAdditionalEntries();
            sbConfig.addAdditionalEntries(entries.toArray(new Entry[entries.size()]));
        }
        elem.setServiceBeanConfig(sbConfig);       
        return(elem);
    }
   
    /**
     * Make a copy of the ServiceElement and set the instance ID
     *
     * @param sElem ServiceElement to use
     * @param id the id to set
     *
     * @return A new ServiceElement
     */
    public static ServiceElement prepareInstanceID(ServiceElement sElem, long id) {
        return(prepareInstanceID(sElem, true, id));
    }
       
    /**
     * Get the next instance ID
     *
     * @param lArray An array of ids
     *
     * @return The next instanceID
     */
    public static synchronized long getNextID(long[] lArray) {
        long nextID = 1;
        if(lArray.length>0) {
            Arrays.sort(lArray);
            for(int i=0,x=1; i<lArray.length; i++,x++) {
                if(lArray[i]!=x) {
                    nextID = x;
                    break;
                } else {
                    nextID=x+1;
                }
            }
        }
        return(nextID);
    }
   
    /**
     * Make a copy of the ServiceElement
     *
     * @param sElem The ServiceElement to copy
     *
     * @return A new ServiceElement
     */
    public static ServiceElement copyServiceElement(ServiceElement sElem) {
        ServiceBeanConfig oldSBC = sElem.getServiceBeanConfig();
        ServiceBeanConfig sbc = new ServiceBeanConfig(oldSBC.getConfigurationParameters(), oldSBC.getConfigArgs());
        for(Map.Entry<String, Object> entry : oldSBC.getInitParameters().entrySet()) {
            sbc.addInitParameter(entry.getKey(), entry.getValue());
        }
        sbc.addLoggerConfig(oldSBC.getLoggerConfigs());
        if(!oldSBC.getAdditionalEntries().isEmpty()) {
            List<Entry> entries = oldSBC.getAdditionalEntries();
            sbc.addAdditionalEntries(entries.toArray(new Entry[entries.size()]));
        }
        ServiceElement elem = new ServiceElement(sElem.getProvisionType(),
                                                 sbc,
                                                 sElem.getServiceLevelAgreements(),
                                                 sElem.getExportBundles(),
                                                 sElem.getFaultDetectionHandlerBundle(),
                                                 sElem.getComponentBundle());
        elem.setPlanned(sElem.getPlanned());
        elem.setCluster(sElem.getCluster());
        elem.setMaxPerMachine(sElem.getMaxPerMachine());
        elem.setMatchOnName(sElem.getMatchOnName());
        elem.setMachineBoundary(sElem.getMachineBoundary());
        elem.setAutoAdvertise(sElem.getAutoAdvertise());
        elem.setDiscoveryManagementPooling(sElem.getDiscoveryManagementPooling());
        elem.setAssociationDescriptors(sElem.getAssociationDescriptors());
        elem.setExecDescriptor(sElem.getExecDescriptor());
        elem.setStagedData(sElem.getStagedData());
        elem.setFork(sElem.forkService());
        List<RemoteRepository> rr = new ArrayList<RemoteRepository>();
        rr.addAll(Arrays.asList(sElem.getRemoteRepositories()));
        elem.setRemoteRepositories(rr);
        elem.setRuleMaps(sElem.getRuleMaps());
        return(elem);
    }

    /**
     * Add a name,value pair to the ServiceBeanConfig
     *
     * @param sbc The current ServiceBeanConfig to set
     * @param key The key to set
     * @param value The value for the key
     *
     * @return A ServiceBeanConfig with the added properties
     */
    public static ServiceBeanConfig addConfigParameter(final ServiceBeanConfig sbc,
                                                       final String key,
                                                       final Integer value) {
        if(sbc == null || key == null || value == null)
            throw new IllegalArgumentException("parameters cannot be null");
        Map<String, Object> configParms = sbc.getConfigurationParameters();
        configParms.put(key, value);
        ServiceBeanConfig newConfig = new ServiceBeanConfig(configParms, sbc.getConfigArgs());
        Map<String, Object> initParms = sbc.getInitParameters();

        for (Map.Entry<String, Object> e : initParms.entrySet()) {
            newConfig.addInitParameter(e.getKey(), e.getValue());
        }
        if(!sbc.getAdditionalEntries().isEmpty()) {
            List<Entry> entries = sbc.getAdditionalEntries();
            newConfig.addAdditionalEntries(entries.toArray(new Entry[entries.size()]));
        }
        return (newConfig);
    }

    /**
     * Determines if the name, interfaces and opStringName equate to
     * attributes found in the provided ServiceElement
     *
     * @param sElem The ServiceElement to test, must not be null
     * @param name The name to check, may be null
     * @param interfaces The ames of the interfaces the service advertises,
     * must not be null
     * @param opStringName The name of the operationalString, may be null
     * @return If the attributes can be found in the ServiceElement, return
     * true
     */
    public static boolean matchesServiceElement(ServiceElement sElem,
                                                String name,
                                                String[] interfaces,
                                                String opStringName) {
        if(sElem==null)
            throw new IllegalArgumentException("sElem is null");
        if(interfaces == null)
            throw new IllegalArgumentException("interfaces is null");
        boolean found = false;
        ClassBundle[] exports = sElem.getExportBundles();
        for (ClassBundle export : exports) {
            boolean matched = false;
            for (String anInterface : interfaces) {
                if (export.getClassName().equals(anInterface))
                    matched = true;
            }
            if (matched) {
                found = true;
                break;
            }
        }

        if(found) {
            boolean attrsMatch = true;
            if(opStringName!=null) {
                if(!sElem.getOperationalStringName().equals(opStringName)) {
                    attrsMatch = false;
                }
            }
            if(attrsMatch) {
                if(name!=null) {
                    if(!name.equals(sElem.getName()))
                        attrsMatch = false;
                }
            }
            return(attrsMatch);
        }
        return(false);
    }

    /**
     * Get the PlatformCapability instances that match declared operational
     * requirements
     *
     * @param sElem The ServiceElement to use
     * @param pCaps Array of PlatformCapability objects
     * objects
     * @return Array of matching
     * {@link org.rioproject.system.capability.PlatformCapability} objects. If there
     * are no matching PlatformCapability instances, a zero-length array is
     * returned. A new array is allocated each time.
     *
     */
    public static PlatformCapability[] getMatchedPlatformCapabilities(ServiceElement sElem,
                                                                      PlatformCapability[] pCaps) {
        ServiceLevelAgreements slas = sElem.getServiceLevelAgreements();
        SystemComponent[] requirements = slas.getSystemRequirements().getSystemComponents();
        List<PlatformCapability> list = new ArrayList<PlatformCapability>();
        if(requirements.length >= 0) {
            /*
             * Iterate through all resource PlatformCapability objects to
             * determine which ones support our declared requirements
             */
            for (SystemComponent requirement : requirements) {
                for (PlatformCapability pCap : pCaps) {
                    if (pCap.supports(requirement)) {
                        list.add(pCap);
                    }
                }
            }
        }
        return (list.toArray(new PlatformCapability[list.size()]));
    }

    /**
     * Get the AssociationDescriptors from the ServiceElement that match the
     * {@link org.rioproject.associations.AssociationType} type
     *
     * @param elem The ServiceElement
     * @param type The AssociationType type
     * @return An array of AssociationDescriptor instances that match the
     * AssociationType type. If there are no matching AssociationDescriptors,
     * return an empty array. A new array is allocated each time
     */
    public static AssociationDescriptor[] getAssociationDescriptors(ServiceElement elem, AssociationType type) {
        AssociationDescriptor[] aDescs = elem.getAssociationDescriptors();
        List<AssociationDescriptor> list = new ArrayList<AssociationDescriptor>();
        for (AssociationDescriptor aDesc : aDescs) {
            if (aDesc.getAssociationType() == type) {
                list.add(aDesc);
            }
        }
        return(list.toArray(new AssociationDescriptor[list.size()]));
    }

    /**
     * Format discovery settings
     *
     * @param sbConfig The ServiceElement to use
     *
     * @return a String with discovery settings formatted
     */
    public static String formatDiscoverySettings(ServiceBeanConfig sbConfig) {
        if(sbConfig==null)
            return "";
        Map<String, Object> conf = sbConfig.getConfigurationParameters();
        StringBuilder buff = new StringBuilder();
        String[] groups = (String[])conf.get(ServiceBeanConfig.GROUPS);
        buff.append("Groups: ");
        if(groups == null || groups.length == 0)
            buff.append("<none>");
        if(groups != null && groups.length > 0) {
            if(groups.length == 1 && groups[0].equals("all")) {
                buff.append("all");
            } else {
                for(int i = 0; i < groups.length; i++) {
                    if(i>0)
                        buff.append(", ");
                    buff.append(groups[i]);
                }
            }
        }
        buff.append("\n");
        buff.append("Locators: ");
        LookupLocator[] locs = (LookupLocator[])conf.get(ServiceBeanConfig.LOCATORS);
        if(locs == null || locs.length == 0)
            buff.append("<none>");
        if(locs != null && locs.length > 0) {
            for(int i=0; i<locs.length; i++) {
                if(i>0)
                    buff.append(", ");
                buff.append("jini://").append(locs[i].getHost()).append(":").append(locs[i].getPort());
            }
        }
        return buff.toString();
    }
}
TOP

Related Classes of org.rioproject.impl.servicebean.ServiceElementUtil

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.