The Artima Developer Community
Sponsored Link

The Journal of Spontaneous Networking
Using Objects to Configure Jini Network Services
by John McClain
June 29, 2004

<<  Page 4 of 4

Advertisement

Configure Service Administration

The article's final example summarizes the key config model capabilities. All of the Sun-contributed Jini 2.0 Starter Kit service implementations have persistent modes . They also offer administrative proxies that implement JoinAdmin. JoinAdmin's methods allow clients to set the groups and locators the service must use for discovery. The services' administrative proxies expect those changes to be part of the service's persisted state.

JoinAdmin also lets clients change the attributes a service registers with. Again, any changes to the set of attributes must persist. The service also needs an initial set of groups, locators, and attributes. The obvious place to get these values from is the configuration.

The entries for the initial groups, lookup locators, and attributes should only be read the very first time a service instance starts. If the service instance crashes and then restarts, the service should use the persisted values for groups, locators, and attributes.

In addition, lookup discovery object has to implement DiscoveryGroupManagement and DiscoveryLocatorManagement in addition to DiscoveryManagement. Otherwise, the implementations would be unable to implement the methods of JoinAdmin that change the sets of groups and locators.

Finally, because most of the time the sets of groups and locators to use for discovery must be recovered from the service's persistent store, the DiscoveryManagement object obtained from the configuration should start with empty sets of groups and locators.

As a result, the Sun-contributed service implementations use the following sort of code for creating a JoinManager:


    private DiscoveryManagement discoveryManager;
    private JoinManager joinManager;

    ....

    void join(Configuration config, Object service)
        throws IOException, ConfigurationException
    {
        // Get a non-null value for DiscoveryManagement instance and
        // make sure it implements DiscoveryGroupManagement and
        // DiscoveryLocatorManagement
        try {
            discoveryManager = (DiscoveryManagement)config.getEntry(
                "org.jini.user.jmcclain.myservice",
                "discoveryManager",
                DiscoveryManagement.class)
            if (discoveryManager == null) {
                throw new ConfigurationException("entry for component "  +
                      "org.jini.user.jmcclain.myservice, name " +
                      "discoveryManager must be non-null");
            }

        } catch (NoSuchEntryException e) {
               discoveryManager = new LookupDiscoveryManager(
                   new String[] {""}, null, null, config);
        }


        if (!(discoveryManager instanceof DiscoveryGroupManagement))
            throw new ConfigurationException("Entry for component " +
                "org.jini.user.jmcclain.myservice, name  discoveryManager" +
                "must implement  net.jini.discovery.DiscoveryGroupManagement");

        if (!(discoveryManager instanceof DiscoveryLocatorManagement))
            throw new ConfigurationException("Entry for component " +
                "org.jini.user.jmcclain.myservice, name  discoveryManager" +
                "must implement " +
                "net.jini.discovery.DiscoveryLocatorManagement");

        // Ensure that discoveryManager is initially set to no groups no
        // locators
        final String[] toCheck =
            ((DiscoveryGroupManagement)discoveryManager).getGroups();
        if (toCheck == null || toCheck.length != 0)
            throw new ConfigurationException("Entry for component " +
                "org.jini.user.jmcclain.myservice, name  discoveryManager " +
                "must be initially configured with no groups");

        if (((DiscoveryLocatorManagement)dgm).getLocators().length != 0)
            throw new ConfigurationException("Entry for component " +
                "org.jini.user.jmcclain.myservice, name  discoveryManager " +
                "must be initially configured with no locators");

        // if this is the first incarnation, consult config for groups,
        // locators and attributes.
        String[] groups;
        LookupLocators locators;
        Entry[] attributes;
        ServiceID serviceID;

        // noPersistentState() returns true if there is no existing  store,
        // implying that this is first incarnation of this service  instance.
        if (noPersistentState()) {
            // No state, get initial values from configuration

            groups = (String[])config.getEntry(
                "org.jini.user.jmcclain.myservice"
                "initialLookupGroups",
                String[].class,
                new String[]{""}); // the "public" group

            locators = (LookupLocator[])config.getEntry(
                "org.jini.user.jmcclain.myservice"
                "initialLookupLocators",
                LookupLocator[].class,
                new LookupLocator[0]);

            if (locators == null) {
                throw new ConfigurationException("entry for component "  +
                      "org.jini.user.jmcclain.myservice, name " +
                      "initialLookupLocators must be non-null");
            }

            final Entry[] cAttrs = (Entry[])config.getEntry(
                "org.jini.user.jmcclain.myservice"
                "initialLookupAttributes",
                Entry[].class,
                new Entry[0]);

            if (cAttrs == null) {
                throw new ConfigurationException("entry for component "  +
                      "org.jini.user.jmcclain.myservice, name " +
                      "initialLookupAttributes must be non-null");
            }


            // stdAttributes() returns ServiceType and ServiceInfo
            // attributes for this service
            Entry[] baseAttributes = stdAttributes()
            if (cAttrs.length == 0) {
                // No attributes from config, just use standard  attributes
                attributes = baseAttributes;
            } else {
                // Combine attributes from config with standard  attributes
                attributes =
                    new Entry[cAttrs.length + baseAttributes.length];
                System.arraycopy(baseAttributes, 0, attributes,
                                 0, baseAttributes.length);
                System.arraycopy(cAttrs, 0, attributes,
                                 baseAttributes.length, cAttrs.length);
            }

            serviceID = newServiceID() // Calc random ServiceID
        } else {
            // Recover pervious state
            groups = getGroupsFromStore();
            locators = getLocatorsFromStore();
            attributes = getAttributesFromStore();
            serviceID = getServiceIDFromStore();
        }

        ((DiscoveryGroupManagement)discoveryManager).setGroups(groups);
         ((DiscoveryLocatorManagement)discoveryManager).setLocators(locators);

        joinManager = new JoinManager(service, attributes, serviceID,
                                      discoveryManager, null, config);


Summary

While you don't have to use the net.jini.config package to write a Jini service or client, it is a powerful tool for writing applications that adapt to their environment. The Sun-contributed service implementations and utilities in the JSK use it extensively. The config model also eases the task of configuring the RMI implementation a service uses, paving the way for a pluggable RMI framework with comprehensive security features.

Talk Back!

Discuss this article in the Articles Forum topic, Using Objects to Configure Jini Network Services.

About the Author

John McClain is a member of Sun's Jini Network Technology development team. His current responsibilities include technical lead of the Outrigger development team and ownership of the JavaSpaces Service Specification. Prior to joining Sun, John worked at Lockheed Martin on distributed simulation and at DEC on network printers.

<<  Page 4 of 4


Sponsored Links



Google
  Web Artima.com   
Copyright © 1996-2017 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use - Advertise with Us