View Javadoc
1   /*
2     SLPConfig.java
3   
4     (C) Copyright IBM Corp. 2005, 2010
5   
6     THIS FILE IS PROVIDED UNDER THE TERMS OF THE ECLIPSE PUBLIC LICENSE
7     ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS FILE
8     CONSTITUTES RECIPIENTS ACCEPTANCE OF THE AGREEMENT.
9   
10    You can obtain a current copy of the Eclipse Public License from
11    http://www.opensource.org/licenses/eclipse-1.0.php
12  
13    @author : Roberto Pineiro, IBM, roberto.pineiro@us.ibm.com
14   * @author : Chung-hao Tan, IBM, chungtan@us.ibm.com
15   * 
16   * Change History
17   * Flag       Date        Prog         Description
18   * ------------------------------------------------------------------------------- 
19   * 1516246    2006-07-22  lupusalex    Integrate SLP client code
20   * 1535793    2006-09-14  lupusalex    Fix&Integrate CIM&SLP configuration classes
21   * 1804402    2007-09-28  ebak         IPv6 ready SLP
22   * 2003590    2008-06-30  blaschke-oss Change licensing from CPL to EPL
23   * 2414503    2008-12-10  raman_arora  parseList not returning populated list
24   * 2524131    2009-01-21  raman_arora  Upgrade client to JDK 1.5 (Phase 1)
25   * 2531371    2009-02-10  raman_arora  Upgrade client to JDK 1.5 (Phase 2)
26   * 2823494    2009-08-03  rgummada     Change Boolean constructor to static
27   * 3026311    2010-07-07  blaschke-oss Vacuous comparison of integer value
28   * 3026360    2010-07-07  blaschke-oss Handle unwritten fields
29   */
30  
31  package org.metricshub.wbem.sblim.slp.internal;
32  
33  /*-
34   * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲
35   * WBEM Java Client
36   * ჻჻჻჻჻჻
37   * Copyright 2023 - 2025 MetricsHub
38   * ჻჻჻჻჻჻
39   * Licensed under the Apache License, Version 2.0 (the "License");
40   * you may not use this file except in compliance with the License.
41   * You may obtain a copy of the License at
42   *
43   *      http://www.apache.org/licenses/LICENSE-2.0
44   *
45   * Unless required by applicable law or agreed to in writing, software
46   * distributed under the License is distributed on an "AS IS" BASIS,
47   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
48   * See the License for the specific language governing permissions and
49   * limitations under the License.
50   * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱
51   */
52  
53  import java.io.IOException;
54  import java.io.InputStream;
55  import java.net.InetAddress;
56  import java.net.MalformedURLException;
57  import java.net.URL;
58  import java.net.UnknownHostException;
59  import java.util.ArrayList;
60  import java.util.Iterator;
61  import java.util.List;
62  import java.util.Map.Entry;
63  import java.util.Properties;
64  import java.util.StringTokenizer;
65  import java.util.logging.Level;
66  import org.metricshub.wbem.sblim.slp.SLPConfigProperties;
67  
68  /**
69   * SLPConfig
70   *
71   */
72  public final class SLPConfig {
73  	private static InetAddress cBroadcastAddress;
74  
75  	private static SLPConfig cInstance = null;
76  
77  	private static InetAddress cLocalHostAddress;
78  
79  	private static InetAddress cLoopBackV4;
80  
81  	private static InetAddress cLoopBackV6;
82  
83  	private static InetAddress cMulticastAddress;
84  
85  	// SRVLOC_MulticastAddress requires scope (FF0s:0:0:0:0:0:0:116)
86  	private static InetAddress cSRVLOC_MulticastAddress = null;
87  
88  	// SRVLOC_DA_MulticastAddress requires scope (FF0s:0:0:0:0:0:0:123)
89  	private static InetAddress cSRVLOC_DA_MulticastAddress = null;
90  
91  	private static InetAddress getByName(String pName) {
92  		try {
93  			return InetAddress.getByName(pName);
94  		} catch (UnknownHostException e) {
95  			e.printStackTrace();
96  			return null;
97  		}
98  	}
99  
100 	static {
101 		cLoopBackV4 = getByName(SLPDefaults.LOOPBACK_ADDRESS_V4);
102 		cLoopBackV6 = getByName(SLPDefaults.LOOPBACK_ADDRESS_V6);
103 		cMulticastAddress = getByName(SLPDefaults.MULTICAST_ADDRESS);
104 		cBroadcastAddress = getByName(SLPDefaults.BROADCAST_ADDRESS);
105 		try {
106 			cLocalHostAddress = InetAddress.getLocalHost();
107 		} catch (UnknownHostException e) {
108 			e.printStackTrace();
109 		}
110 	}
111 
112 	/**
113 	 * getBroadcastAddress
114 	 *
115 	 * @return InetAddress
116 	 */
117 	public static InetAddress getBroadcastAddress() {
118 		return cBroadcastAddress;
119 	}
120 
121 	/**
122 	 * getGlobalCfg
123 	 *
124 	 * @return SLPConfig
125 	 */
126 	public static synchronized SLPConfig getGlobalCfg() {
127 		if (cInstance == null) {
128 			cInstance = new SLPConfig();
129 		}
130 		return cInstance;
131 	}
132 
133 	/**
134 	 * getLoopbackV4
135 	 *
136 	 * @return InetAddress
137 	 */
138 	public static InetAddress getLoopbackV4() {
139 		return cLoopBackV4;
140 	}
141 
142 	/**
143 	 * getLoopbackV6
144 	 *
145 	 * @return InetAddress
146 	 */
147 	public static InetAddress getLoopbackV6() {
148 		return cLoopBackV6;
149 	}
150 
151 	/**
152 	 * getMulticastAddress
153 	 *
154 	 * @return InetAddress
155 	 */
156 	public static InetAddress getMulticastAddress() {
157 		return cMulticastAddress;
158 	}
159 
160 	/**
161 	 * getSRVLOC_MulticastAddress
162 	 *
163 	 * @return InetAddress
164 	 */
165 	public static InetAddress getSRVLOC_MulticastAddress() {
166 		return cSRVLOC_MulticastAddress;
167 	}
168 
169 	/**
170 	 * getSRVLOC_DA_MulticastAddress
171 	 *
172 	 * @return InetAddress
173 	 */
174 	public static InetAddress getSRVLOC_DA_MulticastAddress() {
175 		return cSRVLOC_DA_MulticastAddress;
176 	}
177 
178 	private static int getIntProperty(String pName, int pDefaultValue, int pMinValue, int pMaxValue) {
179 		int value = Integer.getInteger(pName, pDefaultValue).intValue();
180 		return Math.min(pMaxValue, Math.max(pMinValue, value));
181 	}
182 
183 	private SLPConfig() {
184 		try {
185 			// try to load config class from CIM client. This will cause load of
186 			// the CIM client's config file.
187 			Class.forName("org.sblim.cimclient.internal.util.WBEMConfiguration");
188 		} catch (ClassNotFoundException e) {
189 			// nothing to do
190 		}
191 
192 		Properties slpProperties = new Properties(new Properties());
193 		try {
194 			InputStream inputstream = getConfigURLStream();
195 			if (inputstream != null) {
196 				slpProperties.load(inputstream);
197 			}
198 			for (Iterator<Entry<Object, Object>> iterator = slpProperties.entrySet().iterator(); iterator.hasNext();) {
199 				Entry<Object, Object> entry = iterator.next();
200 				System.setProperty(String.valueOf(entry.getKey()), String.valueOf(entry.getValue()));
201 			}
202 		} catch (IOException e) {
203 			System.out.println("Error while parsing property file");
204 			e.printStackTrace();
205 		}
206 	}
207 
208 	/**
209 	 * getActiveDiscoveryGranularity
210 	 *
211 	 * @return int
212 	 */
213 	public int getActiveDiscoveryGranularity() {
214 		return getIntProperty(
215 			SLPConfigProperties.NET_SLP_DA_ACTIVE_DISCOVERY_GRANULARITY,
216 			SLPDefaults.ACTIVE_DISCOVERY_GRANULARITY,
217 			SLPLimits.MIN_DISCOVERY_GRANULARITY,
218 			SLPLimits.MAX_DISCOVERY_GRANULARITY
219 		);
220 	}
221 
222 	/**
223 	 * getActiveDiscoveryInterval
224 	 *
225 	 * @return int
226 	 */
227 	public int getActiveDiscoveryInterval() {
228 		int interval = getIntProperty(
229 			SLPConfigProperties.NET_SLP_DA_ACTIVE_DISCOVERY_INTERVAL,
230 			SLPDefaults.ACTIVE_DISCOVERY_INTERVAL,
231 			SLPLimits.MIN_DISCOVERY_INTERVAL,
232 			SLPLimits.MAX_DISCOVERY_INTERVAL
233 		); // 3mins
234 		if (interval > 0 && interval < 300) {
235 			return 300;
236 			// prevent network flooding
237 		}
238 		return interval;
239 	}
240 
241 	/**
242 	 * getDADiscoveryTimeouts
243 	 *
244 	 * @return int[]
245 	 */
246 	public int[] getDADiscoveryTimeouts() {
247 		return parseTimeouts(SLPConfigProperties.NET_SLP_DA_DISCOVERY_TIMEOUTS, SLPDefaults.DA_DISCOVERY_TIMEOUTS);
248 	}
249 
250 	/**
251 	 * getDatagramTimeouts
252 	 *
253 	 * @return int[]
254 	 */
255 	public int[] getDatagramTimeouts() {
256 		return parseTimeouts(SLPConfigProperties.NET_SLP_DATAGRAM_TIMEOUTS, SLPDefaults.DATAGRAM_TIMEOUTS);
257 	}
258 
259 	/**
260 	 * getInterfaces
261 	 *
262 	 * @return List
263 	 */
264 	@SuppressWarnings("null")
265 	public List<InetAddress> getInterfaces() {
266 		String property = System.getProperty(SLPConfigProperties.NET_SLP_INTERFACES);
267 
268 		List<String> addresses = parseList(property);
269 
270 		final int count = addresses == null ? 0 : addresses.size();
271 		List<InetAddress> interfaces = new ArrayList<InetAddress>(count);
272 
273 		if (count == 0) {
274 			interfaces.add(cLocalHostAddress);
275 			interfaces.add(cLoopBackV4);
276 			interfaces.add(cLoopBackV6);
277 		} else {
278 			for (int i = 0; i < count; ++i) {
279 				String address = addresses.get(i);
280 				try {
281 					InetAddress inetAddress = InetAddress.getByName(address);
282 					if (!interfaces.contains(inetAddress)) {
283 						if (inetAddress.equals(cLocalHostAddress)) {
284 							interfaces.add(0, inetAddress);
285 						} else {
286 							interfaces.add(inetAddress);
287 						}
288 					}
289 				} catch (UnknownHostException e) {
290 					// TODO log this
291 					continue;
292 				}
293 			}
294 		}
295 		return interfaces;
296 	}
297 
298 	/**
299 	 * getPort
300 	 *
301 	 * @return int
302 	 */
303 	public int getPort() {
304 		return Integer.getInteger(SLPConfigProperties.NET_SLP_PORT, SLPDefaults.SLP_PORT).intValue();
305 	}
306 
307 	/**
308 	 * setPort
309 	 *
310 	 * @param pPort
311 	 */
312 	public void setPort(int pPort) {
313 		System.setProperty(SLPConfigProperties.NET_SLP_PORT, Integer.toString(pPort));
314 	}
315 
316 	/**
317 	 * getTraceLevel
318 	 *
319 	 * @return String
320 	 */
321 	public Level getTraceLevel() {
322 		String str = System.getProperty(SLPConfigProperties.NET_SLP_TRC_LEVEL);
323 		if ("OFF".equalsIgnoreCase(str)) return Level.OFF;
324 		if ("ERROR".equalsIgnoreCase(str)) return Level.SEVERE;
325 		if ("WARNING".equalsIgnoreCase(str)) return Level.WARNING;
326 		if ("INFO".equalsIgnoreCase(str)) return Level.INFO;
327 		if ("ALL".equalsIgnoreCase(str)) return Level.FINEST;
328 		return Level.SEVERE;
329 	}
330 
331 	/**
332 	 * setTraceLevel
333 	 *
334 	 * @param pLevel
335 	 */
336 	public void setTraceLevel(String pLevel) {
337 		System.setProperty(SLPConfigProperties.NET_SLP_TRC_LEVEL, pLevel);
338 	}
339 
340 	/**
341 	 * setUseIPv6
342 	 *
343 	 * @param pValue
344 	 */
345 	public void setUseIPv6(boolean pValue) {
346 		System.setProperty(SLPConfigProperties.NET_SLP_USEIPV6, Boolean.toString(pValue));
347 	}
348 
349 	/**
350 	 * useIPv6
351 	 *
352 	 * @return boolean
353 	 */
354 	public boolean useIPv6() {
355 		return getBoolean(SLPConfigProperties.NET_SLP_USEIPV6, SLPDefaults.USE_IPV6);
356 	}
357 
358 	/**
359 	 * setUseIPv4
360 	 *
361 	 * @param pValue
362 	 */
363 	public void setUseIPv4(boolean pValue) {
364 		System.setProperty(SLPConfigProperties.NET_SLP_USEIPV4, Boolean.valueOf(pValue).toString());
365 	}
366 
367 	/**
368 	 * useIPv4
369 	 *
370 	 * @return boolean
371 	 */
372 	public boolean useIPv4() {
373 		return getBoolean(SLPConfigProperties.NET_SLP_USEIPV4, SLPDefaults.USE_IPV4);
374 	}
375 
376 	/**
377 	 * getLocalHost
378 	 *
379 	 * @return InetAddress
380 	 */
381 	public InetAddress getLocalHost() {
382 		List<InetAddress> interfaces = getInterfaces();
383 		return interfaces.get(0);
384 	}
385 
386 	/**
387 	 * getMaximumResults
388 	 *
389 	 * @return int
390 	 */
391 	public int getMaximumResults() {
392 		int value = Integer.getInteger(SLPConfigProperties.NET_SLP_MAX_RESULTS, SLPDefaults.MAXIMUM_RESULTS).intValue();
393 		return (value >= 1 && value < SLPDefaults.MAXIMUM_RESULTS) ? value : SLPDefaults.MAXIMUM_RESULTS;
394 	}
395 
396 	/**
397 	 * getMTU
398 	 *
399 	 * @return int
400 	 */
401 	public int getMTU() {
402 		return getIntProperty(SLPConfigProperties.NET_SLP_MTU, SLPDefaults.MTU, SLPLimits.MIN_MTU, SLPLimits.MAX_MTU);
403 	}
404 
405 	/**
406 	 * getMulticastMaximumWait
407 	 *
408 	 * @return int
409 	 */
410 	public int getMulticastMaximumWait() {
411 		return getIntProperty(
412 			SLPConfigProperties.NET_SLP_MULTICAST_MAXIMUM_WAIT,
413 			SLPDefaults.MULTICAST_MAXIMUM_WAIT,
414 			SLPLimits.MIN_MULTICAST_MAXIMUM_WAIT,
415 			SLPLimits.MAX_MULTICAST_MAXIMUM_WAIT
416 		);
417 	}
418 
419 	/**
420 	 * getMulticastRadius
421 	 *
422 	 * @return int
423 	 */
424 	public int getMulticastRadius() {
425 		return getIntProperty(
426 			SLPConfigProperties.NET_SLP_MULTICAST_TTL,
427 			SLPDefaults.MULTICAST_RADIUS,
428 			SLPLimits.MIN_MULTICAST_RADIUS,
429 			SLPLimits.MAX_MULTICAST_RADIUS
430 		);
431 	}
432 
433 	/**
434 	 * getMulticastTimeouts
435 	 *
436 	 * @return int[]
437 	 */
438 	public int[] getMulticastTimeouts() {
439 		return parseTimeouts(SLPConfigProperties.NET_SLP_MULTICAST_TIMEOUTS, SLPDefaults.MULTICAST_TIMEOUTS);
440 	}
441 
442 	/**
443 	 * getPreconfiguredDAs
444 	 *
445 	 * @return List &lt;InetAddress&gt;
446 	 */
447 	public List<InetAddress> getPreconfiguredDAs() {
448 		String addressString = System.getProperty(SLPConfigProperties.NET_SLP_DA_ADDRESSES, "");
449 		List<String> addresses = parseList(addressString);
450 		if (addresses == null) return null;
451 		List<InetAddress> result = new ArrayList<InetAddress>();
452 		for (Iterator<String> iter = addresses.iterator(); iter.hasNext();) {
453 			try {
454 				result.add(InetAddress.getByName(iter.next()));
455 			} catch (UnknownHostException e) {
456 				// TODO: log this
457 			}
458 		}
459 		return result;
460 	}
461 
462 	/**
463 	 * getConfiguredScopes
464 	 *
465 	 * @return List&lt;String&gt;
466 	 */
467 	public List<String> getConfiguredScopes() {
468 		List<String> scopes = parseList(SLPConfigProperties.NET_SLP_USE_SCOPES);
469 		if (scopes == null) scopes = new ArrayList<String>();
470 		if (scopes.size() == 0) scopes.add(SLPDefaults.DEFAULT_SCOPE);
471 		return scopes;
472 	}
473 
474 	/**
475 	 * getSAOnlyScopes
476 	 *
477 	 * @return List&lt;String&gt;
478 	 */
479 	public List<String> getSAOnlyScopes() {
480 		return parseList(SLPConfigProperties.NET_SLP_SAONLY_SCOPES);
481 	}
482 
483 	/**
484 	 * getServerSocketQueueLength
485 	 *
486 	 * @return int
487 	 */
488 	public int getServerSocketQueueLength() {
489 		return getIntProperty(
490 			SLPConfigProperties.NET_SLP_SERVER_SOCKET_QUEUE_LENGTH,
491 			SLPDefaults.SERVER_SOCKET_QUEUE_LENGTH,
492 			SLPLimits.MIN_SERVER_SOCKET_QUEUE_LENGTH,
493 			SLPLimits.MAX_SERVER_SOCKET_QUEUE_LENGTH
494 		);
495 	}
496 
497 	/**
498 	 * getTCPTimeout
499 	 *
500 	 * @return int
501 	 */
502 	public int getTCPTimeout() {
503 		return getIntProperty(
504 			SLPConfigProperties.NET_SLP_TCPTIMEOUT,
505 			SLPDefaults.TCP_TIMEOUT,
506 			SLPLimits.MIN_TCP_TIMEOUT,
507 			SLPLimits.MAX_TCP_TIMEOUT
508 		);
509 	}
510 
511 	/**
512 	 * getTraceMsg
513 	 *
514 	 * @return boolean
515 	 */
516 	public boolean getTraceMsg() {
517 		return Boolean.getBoolean(SLPConfigProperties.NET_SLP_TRACE_MSG);
518 	}
519 
520 	/**
521 	 * isBroadcastOnly
522 	 *
523 	 * @return boolean
524 	 */
525 	public boolean isBroadcastOnly() {
526 		return Boolean.getBoolean(SLPConfigProperties.NET_SLP_IS_BROADCAST_ONLY);
527 	}
528 
529 	/**
530 	 * isDA
531 	 *
532 	 * @return boolean
533 	 */
534 	public boolean isDA() {
535 		return Boolean.getBoolean(SLPConfigProperties.NET_SLP_IS_DA);
536 	}
537 
538 	/**
539 	 * isSA
540 	 *
541 	 * @return boolean
542 	 */
543 	public boolean isSA() {
544 		return !isDA();
545 	}
546 
547 	private static boolean getBoolean(String pPropName, boolean pDefaultValue) {
548 		if (System.getProperty(pPropName) == null) return pDefaultValue;
549 		return Boolean.getBoolean(pPropName);
550 	}
551 
552 	private InputStream getConfigURLStream() {
553 		String configURL = System.getProperty(SLPConfigProperties.NET_SLP_CONFIG_URL);
554 
555 		if (configURL != null) {
556 			if (configURL.trim().length() > 0) {
557 				try {
558 					URL url = new URL(configURL);
559 					InputStream inputstream = url.openStream();
560 					return inputstream;
561 				} catch (MalformedURLException e) {
562 					// TODO log this
563 				} catch (IOException e) {
564 					// TODO LOG this... config file not found
565 				}
566 			}
567 			return null;
568 		}
569 		for (int i = 0; i < SLPDefaults.CONF_URLS.length; ++i) {
570 			configURL = SLPDefaults.CONF_URLS[i];
571 			try {
572 				URL url = new URL(configURL);
573 				InputStream inputstream = url.openStream();
574 				return inputstream;
575 			} catch (Exception e) {
576 				// Nothing to do
577 			}
578 		}
579 		return null;
580 	}
581 
582 	/**
583 	 * Parses comma separated list.
584 	 *
585 	 * @param pList
586 	 * @return List of Strings
587 	 */
588 	private static List<String> parseList(String pListStr) {
589 		if (pListStr == null || pListStr.length() == 0) return null;
590 		// TODO
591 		StringTokenizer tokenizer = new StringTokenizer(pListStr, ",");
592 		if (tokenizer.countTokens() == 0) return null;
593 		List<String> list = new ArrayList<String>(tokenizer.countTokens());
594 		while (tokenizer.hasMoreTokens()) {
595 			String str = tokenizer.nextToken().trim();
596 			if (str.length() == 0) continue;
597 			list.add(str);
598 		}
599 		return list.size() == 0 ? null : list;
600 	}
601 
602 	private int[] parseTimeouts(String pPropertyName, int[] pDefaultTimeouts) {
603 		String value = System.getProperty(pPropertyName);
604 
605 		List<String> list = parseList(value);
606 		if (list == null) return pDefaultTimeouts;
607 
608 		int timeouts[] = new int[list.size()];
609 		for (int pos = 0; pos < list.size(); pos++) {
610 			String timeoutElem = list.get(pos);
611 			try {
612 				timeouts[pos] = Integer.parseInt(timeoutElem);
613 			} catch (NumberFormatException e) {
614 				return pDefaultTimeouts;
615 			}
616 		}
617 		return timeouts;
618 	}
619 }