usr/src/lib/libslp/javalib/com/sun/slp/ActiveDiscoverer.java
author Mark J. Nelson <Mark.J.Nelson@Sun.COM>
Wed, 06 Aug 2008 16:29:39 -0600
changeset 7298 b69e27387f74
parent 0 68f95e015346
permissions -rw-r--r--
6733918 Teamware has retired, please welcome your new manager, Mercurial 4758439 some files use "current date" sccs keywords 6560843 asm sources should not rely on .file "%M%" for naming STT_FILE symbols 6560958 Solaris:: perl modules should not use SCCS keywords in version information 6729074 webrev doesn't deal well with remote ssh hg parents

/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright (c) 2001 by Sun Microsystems, Inc.
 * All rights reserved.
 *
 */

//  ActiveDiscoverer.java: Object to perform active DA discovery.
//  Author:           James Kempf
//  Created On:       Thu Sep  3 08:45:21 1998
//  Last Modified By: James Kempf
//  Last Modified On: Thu Jan 28 15:45:45 1999
//  Update Count:     32
//

package com.sun.slp;

import java.util.*;
import java.net.*;

/*
 * The ActiveDiscover does active discovery DA discovery by periodically
 * sending out a SrvRqst for "service:directory-agent". Replies are
 * entered into the DA table.
 *
 * @author James Kempf
 */

class ActiveDiscoverer extends Thread {

    // Config object.

    static private SLPConfig config = null;

    // Message for active DA discovery.

    private CSrvMsg activeMsg = null;

    // Version of protocol to use for advertisements.

    private int version = 0;

    // DATable where discovered DAs are recorded.

    private ServerDATable table = null;

    // Scopes to advertise for.

    private Vector useScopes = null;

    // Address on which to advertise.

    private InetAddress address = null;

    // Create an active discoverer.

    ActiveDiscoverer(int version,
		     ServerDATable table,
		     Vector useScopes,
		     InetAddress address) {

	this.version = version;

	this.table = table;

	this.useScopes = useScopes;

	this.address = address;

	if (config == null) {
	    config = SLPConfig.getSLPConfig();

	}

    }

    // Do an initial active discovery then start a thread to
    //  do one periodically.

    public void start() {

	// Initial sleepy time.

	long sleepyTime = config.getRandomWait();

	// Create a message for active discovery.

	try {

	    activeMsg = new CSrvMsg(config.getLocale(),
				    Defaults.DA_SERVICE_TYPE,
				    useScopes,
				    "");

	} catch (ServiceLocationException ex) {
	    Assert.slpassert(false,
			  "sdat_active_err",
			  new Object[] {
		new Integer(ex.getErrorCode()),
		    ex.getMessage()});

	}

	// Initialize preconfigured DAs.

	addPreconfiguredDAs();

	// Do an initial round of active discovery, waiting for
	//  a random period first. Only do it if active
	//  discovery is on.

	if (config.getActiveDiscoveryInterval() > 0) {
	    try {
		Thread.currentThread().sleep(sleepyTime);

	    } catch (InterruptedException ex) {

	    }

	    activeDiscovery();

	} else {

	    // Report that active discovery is off.

	    config.writeLog("ad_active_off",
			    new Object[0]);

	}

	// Start the active discovery thread.

	super.start();
    }



    // Implement the Runnable interface for a thread to start.

    public void run() {

	// Set the Thread name.

	Thread.currentThread().setName("SLP Active DA Discovery");

	// Sleepy time until discovery.

	long sleepyTime = config.getActiveDiscoveryInterval() * 1000;

	// If the sleep time is zero, then active discovery is turned off.
	//  Use the service URL maximum lifetime.

	if (sleepyTime <= 0) {
	    sleepyTime = (ServiceURL.LIFETIME_MAXIMUM / 2) * 1000;

	}

	// Register ourselves at startup if we are a DA. We may not be
	//  listening for the active discovery message at startup
	//  because the listener thread goes on-line last of all.

	if (config.isDA()) {
	    Vector interfaces = config.getInterfaces();
	    int i, n = interfaces.size();

	    for (i = 0; i < n; i++) {
		InetAddress interfac = (InetAddress)interfaces.elementAt(i);
		ServiceURL url = new ServiceURL(Defaults.DA_SERVICE_TYPE + 
						"://" +
						interfac.getHostAddress(),
						ServiceURL.LIFETIME_MAXIMUM);
		Vector scopes = config.getSAConfiguredScopes();
		long timestamp = 0; // later adverts will cause replacement,
				    // but noforwarding because it is to us...

		String mySPIs = System.getProperty("sun.net.slp.SPIs");
		mySPIs = mySPIs == null ? "" : mySPIs;

		table.recordNewDA(url,
				  scopes,
				  timestamp,
				  version,
				  config.getDAAttributes(),
				  mySPIs);
	    }
	}

	// Sleep, then perform active discovery or polling of preconfigured
	//  DAs when we awake.

	do {

	    try {

		sleep(sleepyTime);

		if (config.getActiveDiscoveryInterval() > 0) {
		    activeDiscovery();

		} else {
		    addPreconfiguredDAs();

		}

	    } catch (InterruptedException ex) {

	    }

	} while (true);

    }

    // Perform active DA discovery.

    synchronized private void activeDiscovery() {

	// Set the previous responders list to null. Otherwise,
	//  the previous responders from the last time we did
	//  this may interfere.

	SrvLocHeader hdr = activeMsg.getHeader();

	hdr.previousResponders.removeAllElements();


	// Perform the active discovery message transaction.

	try {
	    Transact.transactActiveAdvertRequest(Defaults.DA_SERVICE_TYPE,
						 activeMsg,
						 table);

	} catch (ServiceLocationException ex) {

	    config.writeLog("ad_multi_error",
			    new Object[] { new Integer(ex.getErrorCode()),
					       ex.getMessage() });

	}

    }

    // Add preconfigured DAs to the DA table. Note that we poll the
    // preconfigured DAs once every 9 hours to make sure they are still around.

    synchronized private void addPreconfiguredDAs() {

	Vector daAddrs = config.getPreconfiguredDAs();
	int i, n = daAddrs.size();

	// Go through the DA addresses, contacting them for their
	// information. Better not be any SLPv1 DAs there.

	for (i = 0; i < n; i++) {
	    InetAddress daAddr = (InetAddress)daAddrs.elementAt(i);

	    // Use a TCP connection. DAs must support TCP so why not?

	    SrvLocMsg reply = null;

	    try {
		reply = Transact.transactTCPMsg(daAddr, activeMsg, false);

	    } catch (ServiceLocationException ex) {

		if (config.traceDrop()) {
		    config.writeLog("ad_trans_error", new Object[] {
			new Integer(ex.getErrorCode()),
			    daAddr,
			    ex.getMessage() });
		}

		continue;
	    }

	    // Report if there's an error in configuration.

	    if (!(reply instanceof CDAAdvert)) {
		if (config.traceDrop()) {
		    config.writeLog("ad_preconfig_not_advert",
				    new Object[] { daAddr, reply });

		}

		continue;
	    }


	    CDAAdvert advert = (CDAAdvert)reply;
	    SrvLocHeader hdr = advert.getHeader();

	    // We need to make the URL long lived if active 
	    // discovery is off. Otherwise, we let the DA time out like all the
	    // rest.

	    if (config.getActiveDiscoveryInterval() <= 0) {
		advert.URL =
		    new ServiceURL(advert.URL.toString(),
				   ServiceURL.LIFETIME_MAXIMUM);

	    }

	    // Add the scopes to the configured scopes. Scopes from configured 
	    //  DAs count as configured scopes.

	    config.addPreconfiguredDAScopes(hdr.scopes);

	    // Record it. Note that we don't have to forward here
	    //  because it's the very beginning.
      
	    table.recordNewDA(advert.URL,
			      hdr.scopes,
			      advert.timestamp,
			      hdr.version,
			      advert.attrs,
			      advert.spis);
	
	}
    }

}