17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 59a70fc3bSMark J. Nelson * Common Development and Distribution License (the "License"). 69a70fc3bSMark J. Nelson * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 227c478bd9Sstevel@tonic-gate * Copyright 2001,2003 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate * 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate // SunDATable.java: A DATable implementation that uses the IPC connection. 287c478bd9Sstevel@tonic-gate // Author: James Kempf 297c478bd9Sstevel@tonic-gate // Created On: Mon May 11 15:00:23 1998 307c478bd9Sstevel@tonic-gate // Last Modified By: James Kempf 317c478bd9Sstevel@tonic-gate // Last Modified On: Thu Mar 11 15:00:58 1999 327c478bd9Sstevel@tonic-gate // Update Count: 71 337c478bd9Sstevel@tonic-gate // 347c478bd9Sstevel@tonic-gate 357c478bd9Sstevel@tonic-gate package com.sun.slp; 367c478bd9Sstevel@tonic-gate 377c478bd9Sstevel@tonic-gate import java.util.*; 387c478bd9Sstevel@tonic-gate import java.net.*; 397c478bd9Sstevel@tonic-gate import java.io.*; 407c478bd9Sstevel@tonic-gate 417c478bd9Sstevel@tonic-gate /** 427c478bd9Sstevel@tonic-gate * The SunDATable class uses the IPC connection to obtain DA information 437c478bd9Sstevel@tonic-gate * from the SA server. By convention, the SA server answers service 447c478bd9Sstevel@tonic-gate * requests for the service type "directory-agent.sun" and including 457c478bd9Sstevel@tonic-gate * a filter for the scopes formatted as: 467c478bd9Sstevel@tonic-gate * 477c478bd9Sstevel@tonic-gate * "(&(|(scopes=<scope1>)(scopes=<scope2>)(scopes=<scope3>)...)(version=2))" 487c478bd9Sstevel@tonic-gate * 497c478bd9Sstevel@tonic-gate * with a collection of URLs that fit the request. The scope of the 507c478bd9Sstevel@tonic-gate * request is the hostname of the local machine, which will not be 517c478bd9Sstevel@tonic-gate * forwarded to any DAs. The URLs contain the 527c478bd9Sstevel@tonic-gate * DA IP address in the host field and a list of scopes in the URL 537c478bd9Sstevel@tonic-gate * part in the form of an attribute value assignment, i.e.: 547c478bd9Sstevel@tonic-gate * 557c478bd9Sstevel@tonic-gate * service:directory-agent.sun:// 199.200.200.5/scopes=eng, corp, freeb 567c478bd9Sstevel@tonic-gate * 577c478bd9Sstevel@tonic-gate * The DA/scope table is initially obtained for all scopes in the 587c478bd9Sstevel@tonic-gate * useScopes list, then refreshed periodically when the 597c478bd9Sstevel@tonic-gate * time stamp runs out. The time stamp is determined as the minimum 607c478bd9Sstevel@tonic-gate * expiration time of the service URLs. 617c478bd9Sstevel@tonic-gate * 627c478bd9Sstevel@tonic-gate * @author James Kempf 637c478bd9Sstevel@tonic-gate */ 647c478bd9Sstevel@tonic-gate 657c478bd9Sstevel@tonic-gate class SunDATable extends DATable { 667c478bd9Sstevel@tonic-gate 677c478bd9Sstevel@tonic-gate // The scopes identifier. 687c478bd9Sstevel@tonic-gate 697c478bd9Sstevel@tonic-gate final static String SCOPES_ID = "424242SUN-TABLE-SCOPES424242"; 707c478bd9Sstevel@tonic-gate 717c478bd9Sstevel@tonic-gate // DA version number. 727c478bd9Sstevel@tonic-gate 737c478bd9Sstevel@tonic-gate final static String VERSION_ID = "424242SUN-TABLE-VERSION424242"; 747c478bd9Sstevel@tonic-gate 757c478bd9Sstevel@tonic-gate // The scopes which reside on the SA only. 767c478bd9Sstevel@tonic-gate 777c478bd9Sstevel@tonic-gate private Vector saOnlyScopes = new Vector(); 787c478bd9Sstevel@tonic-gate 797c478bd9Sstevel@tonic-gate // The cached vector of DA equivalence classes. 807c478bd9Sstevel@tonic-gate 817c478bd9Sstevel@tonic-gate private Vector cache = null; 827c478bd9Sstevel@tonic-gate 837c478bd9Sstevel@tonic-gate // The time when the cache should be refreshed. 847c478bd9Sstevel@tonic-gate 857c478bd9Sstevel@tonic-gate private long timeStamp = -1; 867c478bd9Sstevel@tonic-gate 877c478bd9Sstevel@tonic-gate /** 887c478bd9Sstevel@tonic-gate * Construct a DATable. We get a cached table of accessable 897c478bd9Sstevel@tonic-gate * DAs and scopes and the SA scope names to use for querying. 907c478bd9Sstevel@tonic-gate */ 917c478bd9Sstevel@tonic-gate SunDATable()927c478bd9Sstevel@tonic-gate SunDATable() throws ServiceLocationException { 937c478bd9Sstevel@tonic-gate 947c478bd9Sstevel@tonic-gate // Remove the common scopes from the SA scopes. This will leave 957c478bd9Sstevel@tonic-gate // the private, SA only scopes. 967c478bd9Sstevel@tonic-gate 977c478bd9Sstevel@tonic-gate saOnlyScopes = conf.getSAOnlyScopes(); 987c478bd9Sstevel@tonic-gate 997c478bd9Sstevel@tonic-gate Assert.slpassert(saOnlyScopes.size() > 0, 1007c478bd9Sstevel@tonic-gate "no_sa_scopes", 1017c478bd9Sstevel@tonic-gate new Object[0]); 1027c478bd9Sstevel@tonic-gate 1037c478bd9Sstevel@tonic-gate // Initialize the cache. We want the scopes that can be dynamically 1047c478bd9Sstevel@tonic-gate // discovered. If we have been configured with scopes, then 1057c478bd9Sstevel@tonic-gate // it will be those. If not, then we want whatever we can discovery. 1067c478bd9Sstevel@tonic-gate // we only want the default version for client side. 1077c478bd9Sstevel@tonic-gate 1087c478bd9Sstevel@tonic-gate cache = getWireTable(conf.getConfiguredScopes(), Defaults.version); 1097c478bd9Sstevel@tonic-gate 1107c478bd9Sstevel@tonic-gate } 1117c478bd9Sstevel@tonic-gate 1127c478bd9Sstevel@tonic-gate /** 1137c478bd9Sstevel@tonic-gate * Return a hashtable of DA equivalence classes and multicast 1147c478bd9Sstevel@tonic-gate * scopes. Multicast scopes are stored in the special hashtable 1157c478bd9Sstevel@tonic-gate * key MULTICAST_KEY. Unicast DA equivalence classes are stored 1167c478bd9Sstevel@tonic-gate * under the key UNICAST_KEY. 1177c478bd9Sstevel@tonic-gate * 1187c478bd9Sstevel@tonic-gate * @param scopes Scope list for DAs needed. 1197c478bd9Sstevel@tonic-gate * @return Hashtable with DA addresses as keys and scopes to contact 1207c478bd9Sstevel@tonic-gate * them with as values. Any scopes not associated with a 1217c478bd9Sstevel@tonic-gate * DA come back stored under the key MULTICAST_KEY. 1227c478bd9Sstevel@tonic-gate * Unicast DA equivalence classes are stored 1237c478bd9Sstevel@tonic-gate * under the key UNICAST_KEY. 1247c478bd9Sstevel@tonic-gate */ 1257c478bd9Sstevel@tonic-gate findDAScopes(Vector scopes)1267c478bd9Sstevel@tonic-gate synchronized Hashtable findDAScopes(Vector scopes) 1277c478bd9Sstevel@tonic-gate throws ServiceLocationException { 1287c478bd9Sstevel@tonic-gate 1297c478bd9Sstevel@tonic-gate Hashtable ret = new Hashtable(); 1307c478bd9Sstevel@tonic-gate 1317c478bd9Sstevel@tonic-gate Vector equivClasses = null; 1327c478bd9Sstevel@tonic-gate 1337c478bd9Sstevel@tonic-gate // Refresh the local cache if necessary. 1347c478bd9Sstevel@tonic-gate 1357c478bd9Sstevel@tonic-gate if (timeStamp <= System.currentTimeMillis()) { 1367c478bd9Sstevel@tonic-gate Vector useScopes = conf.getConfiguredScopes(); 1377c478bd9Sstevel@tonic-gate 1387c478bd9Sstevel@tonic-gate cache = getWireTable(useScopes, Defaults.version); 1397c478bd9Sstevel@tonic-gate 1407c478bd9Sstevel@tonic-gate } 1417c478bd9Sstevel@tonic-gate 1427c478bd9Sstevel@tonic-gate equivClasses = (Vector)cache.clone(); 1437c478bd9Sstevel@tonic-gate int i; 1447c478bd9Sstevel@tonic-gate 1457c478bd9Sstevel@tonic-gate // Sort through the local cache, matching against the input parameter. 1467c478bd9Sstevel@tonic-gate // Collect multicast scopes. 1477c478bd9Sstevel@tonic-gate 1487c478bd9Sstevel@tonic-gate Vector multicastScopes = (Vector)scopes.clone(); 1497c478bd9Sstevel@tonic-gate 1507c478bd9Sstevel@tonic-gate for (i = 0; i < equivClasses.size(); i++) { 1517c478bd9Sstevel@tonic-gate DARecord rec = (DARecord)equivClasses.elementAt(i); 1527c478bd9Sstevel@tonic-gate Vector daScopes = (Vector)rec.scopes.clone(); 1537c478bd9Sstevel@tonic-gate 1547c478bd9Sstevel@tonic-gate // Filter multicast scopes first. Remove any from the multicast 1557c478bd9Sstevel@tonic-gate // scope list that are in daScopes. 1567c478bd9Sstevel@tonic-gate 1577c478bd9Sstevel@tonic-gate filterScopes(multicastScopes, daScopes, true); 1587c478bd9Sstevel@tonic-gate 1597c478bd9Sstevel@tonic-gate // Now filter daScopes. Remove any from the daScopes that are 1607c478bd9Sstevel@tonic-gate // not in the input scopes. 1617c478bd9Sstevel@tonic-gate 1627c478bd9Sstevel@tonic-gate filterScopes(daScopes, scopes, false); 1637c478bd9Sstevel@tonic-gate 1647c478bd9Sstevel@tonic-gate // Remove this record if there are none left. 1657c478bd9Sstevel@tonic-gate 1667c478bd9Sstevel@tonic-gate if (daScopes.size() <= 0) { 1677c478bd9Sstevel@tonic-gate /* 1687c478bd9Sstevel@tonic-gate * Must decrement the index 'i' otherwise the next iteration 1697c478bd9Sstevel@tonic-gate * around the loop will miss the element immediately after 1707c478bd9Sstevel@tonic-gate * the element removed. 1717c478bd9Sstevel@tonic-gate * 1727c478bd9Sstevel@tonic-gate * WARNING: Do not use 'i' again until the loop has 1737c478bd9Sstevel@tonic-gate * iterated as it may, after decrementing, 1747c478bd9Sstevel@tonic-gate * be negative. 1757c478bd9Sstevel@tonic-gate */ 1767c478bd9Sstevel@tonic-gate equivClasses.removeElementAt(i); 1777c478bd9Sstevel@tonic-gate i--; 1787c478bd9Sstevel@tonic-gate continue; 1797c478bd9Sstevel@tonic-gate } 1807c478bd9Sstevel@tonic-gate } 1817c478bd9Sstevel@tonic-gate 1827c478bd9Sstevel@tonic-gate // Install the unicast and multicast scopes if any. 1837c478bd9Sstevel@tonic-gate 1847c478bd9Sstevel@tonic-gate if (multicastScopes.size() > 0) { 1857c478bd9Sstevel@tonic-gate ret.put(MULTICAST_KEY, multicastScopes); 1867c478bd9Sstevel@tonic-gate 1877c478bd9Sstevel@tonic-gate } 1887c478bd9Sstevel@tonic-gate 1897c478bd9Sstevel@tonic-gate if (equivClasses.size() > 0) { 1907c478bd9Sstevel@tonic-gate ret.put(UNICAST_KEY, equivClasses); 1917c478bd9Sstevel@tonic-gate 1927c478bd9Sstevel@tonic-gate } 1937c478bd9Sstevel@tonic-gate 1947c478bd9Sstevel@tonic-gate return ret; 1957c478bd9Sstevel@tonic-gate 1967c478bd9Sstevel@tonic-gate } 1977c478bd9Sstevel@tonic-gate 1987c478bd9Sstevel@tonic-gate /** 1997c478bd9Sstevel@tonic-gate * Remove a DA by address. We only remove it from the wire table 2007c478bd9Sstevel@tonic-gate * so if it's down temporarily, we'll get it back again. 2017c478bd9Sstevel@tonic-gate * 2027c478bd9Sstevel@tonic-gate * @param address The host address of the DA. 2037c478bd9Sstevel@tonic-gate * @param scopes The scopes. 2047c478bd9Sstevel@tonic-gate * @return True if removed, false if not. 2057c478bd9Sstevel@tonic-gate */ 2067c478bd9Sstevel@tonic-gate removeDA(InetAddress address, Vector scopes)2077c478bd9Sstevel@tonic-gate boolean removeDA(InetAddress address, Vector scopes) { 2087c478bd9Sstevel@tonic-gate 2097c478bd9Sstevel@tonic-gate // Sort through the table of equivalence classes in cache. 2107c478bd9Sstevel@tonic-gate 2117c478bd9Sstevel@tonic-gate boolean foundit = false; 2127c478bd9Sstevel@tonic-gate int i; 2137c478bd9Sstevel@tonic-gate 2147c478bd9Sstevel@tonic-gate for (i = 0; i < cache.size(); i++) { 2157c478bd9Sstevel@tonic-gate DARecord rec = (DARecord)cache.elementAt(i); 2167c478bd9Sstevel@tonic-gate Vector daAddresses = rec.daAddresses; 2177c478bd9Sstevel@tonic-gate 2187c478bd9Sstevel@tonic-gate // Ignore scopes, delete if there. Scopes will always be the 2197c478bd9Sstevel@tonic-gate // ones for which this DA is to be removed. 2207c478bd9Sstevel@tonic-gate 2217c478bd9Sstevel@tonic-gate int j, m = daAddresses.size(); 2227c478bd9Sstevel@tonic-gate 2237c478bd9Sstevel@tonic-gate for (j = 0; j < m; j++) { 2247c478bd9Sstevel@tonic-gate InetAddress daaddr = (InetAddress)daAddresses.elementAt(j); 2257c478bd9Sstevel@tonic-gate 2267c478bd9Sstevel@tonic-gate // If they are equal, remove it, exit loop. 2277c478bd9Sstevel@tonic-gate 2287c478bd9Sstevel@tonic-gate if (address.equals(daaddr)) { 2297c478bd9Sstevel@tonic-gate foundit = true; 2307c478bd9Sstevel@tonic-gate daAddresses.removeElementAt(j); 2317c478bd9Sstevel@tonic-gate 2327c478bd9Sstevel@tonic-gate // If the cache entry is empty, remove it. 2337c478bd9Sstevel@tonic-gate 2347c478bd9Sstevel@tonic-gate if (daAddresses.size() <= 0) { 2357c478bd9Sstevel@tonic-gate cache.removeElementAt(i); 2367c478bd9Sstevel@tonic-gate 2377c478bd9Sstevel@tonic-gate } 2387c478bd9Sstevel@tonic-gate 2397c478bd9Sstevel@tonic-gate break; 2407c478bd9Sstevel@tonic-gate 2417c478bd9Sstevel@tonic-gate } 2427c478bd9Sstevel@tonic-gate } 2437c478bd9Sstevel@tonic-gate } 2447c478bd9Sstevel@tonic-gate 2457c478bd9Sstevel@tonic-gate return foundit; 2467c478bd9Sstevel@tonic-gate 2477c478bd9Sstevel@tonic-gate } 2487c478bd9Sstevel@tonic-gate 2497c478bd9Sstevel@tonic-gate // Return a vector of DARecord equivalence classes by going out to the 2507c478bd9Sstevel@tonic-gate // wire for them. Merge any that are in the current process' 2517c478bd9Sstevel@tonic-gate // DAAddresses property. 2527c478bd9Sstevel@tonic-gate getWireTable(Vector scopes, int version)2537c478bd9Sstevel@tonic-gate private Vector getWireTable(Vector scopes, int version) 2547c478bd9Sstevel@tonic-gate throws ServiceLocationException { 2557c478bd9Sstevel@tonic-gate 2567c478bd9Sstevel@tonic-gate Vector ret = new Vector(); 2577c478bd9Sstevel@tonic-gate 2587c478bd9Sstevel@tonic-gate // Get replies from the SA server. These will be CSrvMsg replies. 2597c478bd9Sstevel@tonic-gate 2607c478bd9Sstevel@tonic-gate CSrvMsg msg = getSrvReply(scopes, version); 2617c478bd9Sstevel@tonic-gate 2627c478bd9Sstevel@tonic-gate // Process reply into the vector of equivalence classes by adding to 2637c478bd9Sstevel@tonic-gate // to those from the preconfigured DAs. 2647c478bd9Sstevel@tonic-gate 2657c478bd9Sstevel@tonic-gate processReply(msg, ret); 2667c478bd9Sstevel@tonic-gate 2677c478bd9Sstevel@tonic-gate // Return vector. 2687c478bd9Sstevel@tonic-gate 2697c478bd9Sstevel@tonic-gate return ret; 2707c478bd9Sstevel@tonic-gate } 2717c478bd9Sstevel@tonic-gate getSrvReply(Vector scopes, int version)2727c478bd9Sstevel@tonic-gate private CSrvMsg getSrvReply(Vector scopes, int version) 2737c478bd9Sstevel@tonic-gate throws ServiceLocationException { 2747c478bd9Sstevel@tonic-gate 2757c478bd9Sstevel@tonic-gate // Form the query. 2767c478bd9Sstevel@tonic-gate 2777c478bd9Sstevel@tonic-gate StringBuffer buf = new StringBuffer(); 2787c478bd9Sstevel@tonic-gate int i, n = scopes.size(); 2797c478bd9Sstevel@tonic-gate 2807c478bd9Sstevel@tonic-gate for (i = 0; i < n; i++) { 2817c478bd9Sstevel@tonic-gate buf.append("("); 2827c478bd9Sstevel@tonic-gate buf.append(SCOPES_ID); 2837c478bd9Sstevel@tonic-gate buf.append("="); 2847c478bd9Sstevel@tonic-gate buf.append((String)scopes.elementAt(i)); 2857c478bd9Sstevel@tonic-gate buf.append(")"); 2867c478bd9Sstevel@tonic-gate } 2877c478bd9Sstevel@tonic-gate 2887c478bd9Sstevel@tonic-gate // Add logical disjunction if there is more than one scope. 2897c478bd9Sstevel@tonic-gate 2907c478bd9Sstevel@tonic-gate if (i > 1) { 2917c478bd9Sstevel@tonic-gate buf.insert(0, "(|"); 2927c478bd9Sstevel@tonic-gate buf.append(")"); 2937c478bd9Sstevel@tonic-gate 2947c478bd9Sstevel@tonic-gate } 2957c478bd9Sstevel@tonic-gate 2967c478bd9Sstevel@tonic-gate // Add version number restriction. 2977c478bd9Sstevel@tonic-gate 2987c478bd9Sstevel@tonic-gate if (i > 0) { 2997c478bd9Sstevel@tonic-gate buf.insert(0, "(&"); 3007c478bd9Sstevel@tonic-gate 3017c478bd9Sstevel@tonic-gate } 3027c478bd9Sstevel@tonic-gate 3037c478bd9Sstevel@tonic-gate buf.append("("); 3047c478bd9Sstevel@tonic-gate buf.append(VERSION_ID); 3057c478bd9Sstevel@tonic-gate buf.append("="); 3067c478bd9Sstevel@tonic-gate buf.append((new Integer(version)).toString()); 3077c478bd9Sstevel@tonic-gate buf.append(")"); 3087c478bd9Sstevel@tonic-gate 3097c478bd9Sstevel@tonic-gate // Add closing paren if there were any scopes. 3107c478bd9Sstevel@tonic-gate 3117c478bd9Sstevel@tonic-gate if (i > 0) { 3127c478bd9Sstevel@tonic-gate buf.append(")"); 3137c478bd9Sstevel@tonic-gate 3147c478bd9Sstevel@tonic-gate } 3157c478bd9Sstevel@tonic-gate 3167c478bd9Sstevel@tonic-gate // Create the message object. Note that if scope vector is 3177c478bd9Sstevel@tonic-gate // empty, the query is the null string, and so all DAs 3187c478bd9Sstevel@tonic-gate // will be returned. 3197c478bd9Sstevel@tonic-gate 3207c478bd9Sstevel@tonic-gate CSrvMsg msg = new CSrvMsg(Defaults.locale, 3217c478bd9Sstevel@tonic-gate Defaults.SUN_DA_SERVICE_TYPE, 3227c478bd9Sstevel@tonic-gate saOnlyScopes, 3237c478bd9Sstevel@tonic-gate buf.toString()); 3247c478bd9Sstevel@tonic-gate 3257c478bd9Sstevel@tonic-gate // Send it down the pipe to the IPC process. It's a bad bug 3267c478bd9Sstevel@tonic-gate // if the reply comes back as not a CSrvMsg. 3277c478bd9Sstevel@tonic-gate 3287c478bd9Sstevel@tonic-gate SrvLocMsg rply = 3297c478bd9Sstevel@tonic-gate Transact.transactTCPMsg(conf.getLoopback(), msg, true); 3307c478bd9Sstevel@tonic-gate 3317c478bd9Sstevel@tonic-gate // Check error code. 3327c478bd9Sstevel@tonic-gate 3337c478bd9Sstevel@tonic-gate if (rply == null || 3347c478bd9Sstevel@tonic-gate rply.getErrorCode() != ServiceLocationException.OK) { 3357c478bd9Sstevel@tonic-gate short errCode = 3367c478bd9Sstevel@tonic-gate (rply == null ? 3377c478bd9Sstevel@tonic-gate ServiceLocationException.INTERNAL_SYSTEM_ERROR : 3387c478bd9Sstevel@tonic-gate rply.getErrorCode()); 3397c478bd9Sstevel@tonic-gate throw 3407c478bd9Sstevel@tonic-gate new ServiceLocationException(errCode, 3417c478bd9Sstevel@tonic-gate "loopback_error", 3427c478bd9Sstevel@tonic-gate new Object[] { 3437c478bd9Sstevel@tonic-gate new Short(errCode)}); 3447c478bd9Sstevel@tonic-gate 3457c478bd9Sstevel@tonic-gate } 3467c478bd9Sstevel@tonic-gate 3477c478bd9Sstevel@tonic-gate return (CSrvMsg)rply; 3487c478bd9Sstevel@tonic-gate } 3497c478bd9Sstevel@tonic-gate 3507c478bd9Sstevel@tonic-gate // Process CSrvMsg reply into DA equivalence class vector 3517c478bd9Sstevel@tonic-gate processReply(CSrvMsg msg, Vector ret)3527c478bd9Sstevel@tonic-gate private void processReply(CSrvMsg msg, Vector ret) 3537c478bd9Sstevel@tonic-gate throws ServiceLocationException { 3547c478bd9Sstevel@tonic-gate 3557c478bd9Sstevel@tonic-gate int shortTimer = Integer.MAX_VALUE; 3567c478bd9Sstevel@tonic-gate 3577c478bd9Sstevel@tonic-gate // Get the URLs. 3587c478bd9Sstevel@tonic-gate 3597c478bd9Sstevel@tonic-gate Vector serviceURLs = msg.serviceURLs; 3607c478bd9Sstevel@tonic-gate 3617c478bd9Sstevel@tonic-gate // Process each service URL. 3627c478bd9Sstevel@tonic-gate 3637c478bd9Sstevel@tonic-gate int i, n = serviceURLs.size(); 3647c478bd9Sstevel@tonic-gate 3657c478bd9Sstevel@tonic-gate for (i = 0; i < n; i++) { 3667c478bd9Sstevel@tonic-gate ServiceURL url = (ServiceURL)serviceURLs.elementAt(i); 367*55fea89dSDan Cross 3687c478bd9Sstevel@tonic-gate // If the time to live is less than the current minimum, 3697c478bd9Sstevel@tonic-gate // save it. 3707c478bd9Sstevel@tonic-gate 3717c478bd9Sstevel@tonic-gate int lifetime = url.getLifetime(); 3727c478bd9Sstevel@tonic-gate 3737c478bd9Sstevel@tonic-gate if (lifetime < shortTimer) { 3747c478bd9Sstevel@tonic-gate shortTimer = lifetime; 3757c478bd9Sstevel@tonic-gate 3767c478bd9Sstevel@tonic-gate } 3777c478bd9Sstevel@tonic-gate 3787c478bd9Sstevel@tonic-gate // Get the host name and URL part. 3797c478bd9Sstevel@tonic-gate 3807c478bd9Sstevel@tonic-gate String daaddr = url.getHost(); 3817c478bd9Sstevel@tonic-gate String urlpart = url.getURLPath(); 3827c478bd9Sstevel@tonic-gate 3837c478bd9Sstevel@tonic-gate // Parse URL part into scope list. Be 3847c478bd9Sstevel@tonic-gate // sure not to include the initial `/' in the parse. 3857c478bd9Sstevel@tonic-gate 3867c478bd9Sstevel@tonic-gate StringTokenizer tk = 3877c478bd9Sstevel@tonic-gate new StringTokenizer(urlpart.substring(1, 3887c478bd9Sstevel@tonic-gate urlpart.length()), 3897c478bd9Sstevel@tonic-gate ";"); 3907c478bd9Sstevel@tonic-gate Vector daScopes = null; 3917c478bd9Sstevel@tonic-gate 3927c478bd9Sstevel@tonic-gate while (tk.hasMoreElements()) { 3937c478bd9Sstevel@tonic-gate String attrExp = tk.nextToken(); 3947c478bd9Sstevel@tonic-gate 3957c478bd9Sstevel@tonic-gate // Convert to an SLP attribute. 3967c478bd9Sstevel@tonic-gate 3977c478bd9Sstevel@tonic-gate ServiceLocationAttribute attr = 3987c478bd9Sstevel@tonic-gate new ServiceLocationAttribute("(" + attrExp + ")", false); 3997c478bd9Sstevel@tonic-gate 4007c478bd9Sstevel@tonic-gate // Depending on the attribute id, do something. 4017c478bd9Sstevel@tonic-gate 4027c478bd9Sstevel@tonic-gate String id = attr.getId(); 4037c478bd9Sstevel@tonic-gate Vector vals = attr.getValues(); 4047c478bd9Sstevel@tonic-gate 4057c478bd9Sstevel@tonic-gate if (id.equals(SCOPES_ID)) { 4067c478bd9Sstevel@tonic-gate daScopes = vals; 4077c478bd9Sstevel@tonic-gate 4087c478bd9Sstevel@tonic-gate } else { 4097c478bd9Sstevel@tonic-gate throw 4107c478bd9Sstevel@tonic-gate new ServiceLocationException( 4117c478bd9Sstevel@tonic-gate ServiceLocationException.PARSE_ERROR, 4127c478bd9Sstevel@tonic-gate "loopback_parse_error", 4137c478bd9Sstevel@tonic-gate new Object[] {url}); 4147c478bd9Sstevel@tonic-gate } 4157c478bd9Sstevel@tonic-gate } 4167c478bd9Sstevel@tonic-gate 4177c478bd9Sstevel@tonic-gate // Add it to the equivalence class. 4187c478bd9Sstevel@tonic-gate 4197c478bd9Sstevel@tonic-gate addToEquivClass(daaddr, daScopes, ret); 4207c478bd9Sstevel@tonic-gate 4217c478bd9Sstevel@tonic-gate } 4227c478bd9Sstevel@tonic-gate 4237c478bd9Sstevel@tonic-gate // Reset the timestamp. 4247c478bd9Sstevel@tonic-gate 4257c478bd9Sstevel@tonic-gate timeStamp = System.currentTimeMillis() + (long)(shortTimer * 1000); 4267c478bd9Sstevel@tonic-gate 4277c478bd9Sstevel@tonic-gate } 4287c478bd9Sstevel@tonic-gate 4297c478bd9Sstevel@tonic-gate } 430