1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  *
26  */
27 
28 package com.sun.solaris.service.pools;
29 
30 import java.util.List;
31 import java.util.ArrayList;
32 import java.util.Map;
33 import java.util.HashMap;
34 
35 /**
36  * The <code>Configuration</code> class represents a pools configuration.
37  */
38 public class Configuration extends Element
39 {
40 	/**
41 	 * Indicates whether the configuration represents a usable
42 	 * configuration.
43 	 */
44 	private boolean _valid = false;
45 
46 	/**
47 	 * A reference to the native libpool object represented by
48 	 * this instance.
49 	 */
50 	private long _this;
51 
52 	/**
53 	 * The name of this instance.
54 	 */
55 	private String name;
56 
57 	/**
58 	 * The cache of elements known to this configuration.
59 	 */
60 	private Map elements;
61 
62 	/**
63 	 * The key of the configuration.
64 	 */
65 	private String key;
66 
67 	/**
68 	 * Constructor
69 	 * @param location The location of the configuration.
70 	 * @param perms The OR'd permissions used when opening this
71 	 * configuration.
72 	 * @exception PoolsException The error message generated by
73 	 * libpool.
74 	 */
Configuration(String location, int perms)75 	public Configuration(String location, int perms) throws PoolsException
76 	{
77 		if (((_this = PoolInternal.pool_conf_alloc())) == 0)
78 			throw new PoolsException();
79 		_conf = this;
80 		open(location, perms);
81 		elements = new HashMap();
82 	}
83 
84         /**
85          * Reclaim the memory allocated for this configuration by the C
86 	 * proxy.
87          *
88          * @throws Throwable If freeing this configuration fails.
89          */
finalize()90 	protected void finalize() throws Throwable
91 	{
92 		try
93 		{
94 			close();
95 			if (_this != 0) {
96 				PoolInternal.pool_conf_free(_this);
97 				_this = 0;
98 			}
99 		}
100 		finally
101 		{
102 			super.finalize();
103 		}
104 	}
105 
106 	/**
107 	 * Returns a pointer to the native configuration, wrapped by this
108 	 * instance.
109 	 *
110 	 * @return the configuration pointer.
111 	 */
getConf()112 	final long getConf()
113 	{
114 		return (_this);
115 	}
116 
117 	/**
118 	 * Opens the configuration at the supplied location and with the
119 	 * supplied permissions.
120 	 *
121 	 * @throws PoolsException if there is an error opening the
122 	 * configuration.
123 	 */
open(String location, int perms)124 	public void open(String location, int perms) throws PoolsException
125 	{
126 		if (_valid == false) {
127 			if (PoolInternal.pool_conf_open(getConf(), location,
128 				perms) != PoolInternal.PO_SUCCESS) {
129 				throw new PoolsException();
130 			}
131 			_valid = true;
132 			name = getStringProperty("system.name");
133 			key = "system." + name;
134 		}
135 	}
136 
137 	/**
138 	 * Closes the configuration.
139 	 *
140 	 */
close()141 	public void close()
142 	{
143 		if (_valid == true) {
144 			elements.clear();
145 			PoolInternal.pool_conf_close(getConf());
146 			name = key = null;
147 		}
148 		_valid = false;
149 	}
150 
151 	/**
152 	 * Returns the location of the configuration.
153 	 *
154 	 * @return the location of the configuration.
155 	 */
getLocation()156 	public String getLocation()
157 	{
158 		return (PoolInternal.pool_conf_location(getConf()));
159 	}
160 
161 	/**
162 	 * Returns the status of the configuration.
163 	 *
164 	 * @return the status of the configuration.
165 	 */
status()166 	public int status()
167 	{
168 		return (PoolInternal.pool_conf_status(getConf()));
169 	}
170 
171 	/**
172 	 * Remove the configuration.
173 	 *
174 	 * @throws PoolsException If the removal fails.
175 	 */
remove()176 	public void remove() throws PoolsException
177 	{
178 		if (PoolInternal.pool_conf_remove(getConf()) !=
179 		    PoolInternal.PO_SUCCESS)
180 			throw new PoolsException();
181 	}
182 
183 	/**
184 	 * Rollback the configuration, undoing any changes which have been
185 	 * made since the last commit or (if there are no commits) since the
186 	 * configuration was opened.
187 	 *
188 	 * @throws PoolsException If the rollback fails.
189 	 */
rollback()190 	public void rollback() throws PoolsException
191 	{
192 		if (PoolInternal.pool_conf_rollback(getConf()) !=
193 		    PoolInternal.PO_SUCCESS)
194 			throw new PoolsException();
195 	}
196 
197 	/**
198 	 * Commit the configuration, making any changes since the configuration
199 	 * was last committed (or opened if there have been no prior commits)
200 	 * permanent.
201 	 *
202 	 * @throws PoolsException If the commit fails.
203 	 */
commit(int active)204 	public void commit(int active) throws PoolsException
205 	{
206 		if (PoolInternal.pool_conf_commit(getConf(), active) !=
207 		    PoolInternal.PO_SUCCESS)
208 			throw new PoolsException();
209 	}
210 
211 	/**
212 	 * Export the configuration, storing the current state of the
213 	 * configuration at the supplied location in the supplied format.
214 	 *
215 	 * @param location The location of the export.
216 	 * @param format The format of the export.
217 	 * @throws PoolsException If the export fails.
218 	 */
export(String location, int format)219 	public void export(String location, int format) throws PoolsException
220 	{
221 		if (PoolInternal.pool_conf_export(getConf(), location, format)
222 		    != PoolInternal.PO_SUCCESS)
223 			throw new PoolsException();
224 	}
225 
226 	/**
227 	 * Validate the configuration, ensuring that the current state of the
228 	 * configuration satisfies the supplied validation level.
229 	 *
230 	 * @param level The desired level of validation.
231 	 * @throws PoolsException If the validation fails.
232 	 */
validate(int level)233 	public void validate(int level) throws PoolsException
234 	{
235 		if (PoolInternal.pool_conf_validate(getConf(), level)
236 		    != PoolInternal.PO_SUCCESS)
237 			throw new PoolsException();
238 	}
239 
240 	/**
241 	 * Update the configuration, ensuring that the current state of the
242 	 * configuration reflects that of the kernel.
243 	 *
244 	 * @throws PoolsException If the update fails.
245 	 * @return a bitmap of the changed types.
246 	 */
update()247 	public int update() throws PoolsException
248 	{
249 		return (PoolInternal.pool_conf_update(getConf()));
250 	}
251 
252 	/**
253 	 * Create a pool with the supplied name.
254 	 *
255 	 * @param name The name of the PoolInternal.
256 	 * @throws PoolsException If the pool creation fails.
257 	 * @return a pool with the supplied name.
258 	 */
createPool(String name)259 	public Pool createPool(String name) throws PoolsException
260 	{
261 		long aPool;
262 
263 		if ((aPool = PoolInternal.pool_create(getConf(), name)) == 0) {
264 			throw new PoolsException();
265 		}
266 		Pool p = new Pool(this, aPool);
267 		elements.put(p.getKey(), p);
268 		return (p);
269 	}
270 
271 	/**
272 	 * Destroy the supplied PoolInternal.
273 	 *
274 	 * @param aPool The pool to be destroyed.
275 	 * @throws PoolsException If the pool cannot be located.
276 	 */
destroyPool(Pool aPool)277 	public void destroyPool(Pool aPool) throws PoolsException
278 	{
279 		elements.remove(aPool.getKey());
280 		PoolInternal.pool_destroy(getConf(), aPool.getPool());
281 	}
282 
283 	/**
284 	 * Get the pool with the supplied name.
285 	 *
286 	 * @param name The name of the pool to be found.
287 	 * @throws PoolsException If the pool cannot be located.
288 	 * @return a pool with the supplied name.
289 	 */
getPool(String name)290 	public Pool getPool(String name) throws PoolsException
291 	{
292 		long aPool;
293 
294 		if ((aPool = PoolInternal.pool_get_pool(getConf(), name)) ==
295 		    0) {
296 			throw new PoolsException();
297 		}
298 		if (elements.containsKey("PoolInternal." + name))
299 			return ((Pool) elements.get("PoolInternal." + name));
300 		else {
301 			Pool p = new Pool(this, aPool);
302 			elements.put(p.getKey(), p);
303 			return (p);
304 		}
305 	}
306 
307 	/**
308 	 * Get the proxy for the pool with the supplied name.
309 	 *
310 	 * @param name The name of the pool to be found.
311 	 * @throws PoolsException If the pool cannot be located.
312 	 * @return the proxy for the pool with the supplied name.
313 	 */
checkPool(String name)314 	long checkPool(String name) throws PoolsException
315 	{
316 		long aPool;
317 
318 		if ((aPool = PoolInternal.pool_get_pool(getConf(), name)) ==
319 		    0) {
320 			throw new PoolsException();
321 		}
322 		return (aPool);
323 	}
324 
325 	/**
326 	 * Get a list of pools which match the supplied selection criteria
327 	 * in values.
328 	 *
329 	 * @param values A list of values to be used to qualify the search.
330 	 * @throws PoolsException If there is an error executing the query.
331 	 * @return a list of pools which match the supplied criteria
332 	 */
getPools(List values)333 	public List getPools(List values) throws PoolsException
334 	{
335 		List pools;
336 
337 		if ((pools = PoolInternal.pool_query_pools(getConf(), values))
338 		    == null) {
339 			if (PoolInternal.pool_error() ==
340 			    PoolInternal.POE_INVALID_SEARCH)
341 				return new ArrayList();
342 			else
343 				throw new PoolsException();
344 		}
345 		ArrayList aList = new ArrayList(pools.size());
346 		for (int i = 0; i < pools.size(); i++)
347 			aList.add(new Pool(this,
348 			    ((Long)pools.get(i)).longValue()));
349 		return (aList);
350 	}
351 
352 	/**
353 	 * Create a resource with the supplied type and name.
354 	 *
355 	 * @param type The type of the resource.
356 	 * @param name The name of the resource.
357 	 * @throws PoolsException If the resource creation fails.
358 	 * @return a resource of the supplied type and name.
359 	 */
createResource(String type, String name)360 	public Resource createResource(String type, String name)
361 	    throws PoolsException
362 	{
363 		long aResource;
364 
365 		if ((aResource = PoolInternal.pool_resource_create(getConf(),
366 			 type, name)) == 0) {
367 			throw new PoolsException();
368 		}
369 		Resource res = new Resource(this, aResource);
370 		elements.put(res.getKey(), res);
371 		return (res);
372 	}
373 
374 	/**
375 	 * Destroy the supplied resource.
376 	 *
377 	 * @param res The resource to be destroyed.
378 	 * @throws PoolsException If the resource cannot be located.
379 	 */
destroyResource(Resource res)380 	public void destroyResource(Resource res) throws PoolsException
381 	{
382 		elements.remove(res.getKey());
383 		PoolInternal.pool_resource_destroy(getConf(),
384 		    res.getResource());
385 	}
386 
387 	/**
388 	 * Get the resource with the supplied name.
389 	 *
390 	 * @param type The type of the resource to be found.
391 	 * @param name The name of the resource to be found.
392 	 * @throws PoolsException If the resource cannot be located.
393 	 * @return a resource with the supplied name.
394 	 */
getResource(String type, String name)395 	public Resource getResource(String type, String name)
396 	    throws PoolsException
397 	{
398 		long res;
399 
400 		if ((res = PoolInternal.pool_get_resource(getConf(), type,
401 			 name)) == 0) {
402 			throw new PoolsException();
403 		}
404 		if (elements.containsKey(type + "." + name))
405 			return ((Resource) elements.get(type + "." + name));
406 		else {
407 			Resource r = new Resource(this, res);
408 			elements.put(r.getKey(), r);
409 			return (r);
410 		}
411 	}
412 
413 	/**
414 	 * Get the proxy for the resource with the supplied type and
415 	 * name.
416 	 *
417 	 * @param type The type of the resource to be found.
418 	 * @param name The name of the resource to be found.
419 	 * @throws PoolsException If the resource cannot be located.
420 	 * @return the proxy for the resource with the supplied name.
421 	 */
checkResource(String type, String name)422 	long checkResource(String type, String name) throws PoolsException
423 	{
424 		long res;
425 
426 		if ((res = PoolInternal.pool_get_resource(getConf(), type,
427 			 name)) == 0) {
428 			throw new PoolsException();
429 		}
430 		return (res);
431 	}
432 
433 	/**
434 	 * Get a list of resources which match the supplied selection criteria
435 	 * in values.
436 	 *
437 	 * @param values A list of values to be used to qualify the search.
438 	 * @throws PoolsException If there is an error executing the query.
439 	 * @return a list of resources which match the supplied criteria
440 	 */
getResources(List values)441 	public List getResources(List values) throws PoolsException
442 	{
443 		List resources;
444 
445 		if ((resources = PoolInternal.pool_query_resources(getConf(),
446 		    values)) == null) {
447 			if (PoolInternal.pool_error() ==
448 			    PoolInternal.POE_INVALID_SEARCH)
449 				return new ArrayList();
450 			else
451 				throw new PoolsException();
452 		}
453 		ArrayList aList = new ArrayList(resources.size());
454 		for (int i = 0; i < resources.size(); i++)
455 			aList.add(new Resource(this,
456 			    ((Long)resources.get(i)).longValue()));
457 		return (aList);
458 	}
459 
460 	/**
461 	 * Get the component with the supplied name.
462 	 *
463 	 * @param type The type of the component to be found.
464 	 * @param sys_id The sys_id of the component to be found.
465 	 * @throws PoolsException If the component cannot be located.
466 	 * @return a component with the supplied name.
467 	 */
getComponent(String type, long sys_id)468 	public Component getComponent(String type, long sys_id)
469 	    throws PoolsException
470 	{
471 		List props = new ArrayList();
472 		Value ptype = new Value("type", type);
473 		Value psys_id = new Value(type + ".sys_id", sys_id);
474 
475 		props.add(ptype);
476 		props.add(psys_id);
477 		List comps = getComponents(props);
478 		ptype.close();
479 		psys_id.close();
480 		if (comps.size() != 1)
481 			throw new PoolsException();
482 		return ((Component) comps.get(0));
483 	}
484 
485 	/**
486 	 * Get the component proxy with the supplied type and sys_id.
487 	 *
488 	 * @param type The type of the component to be found.
489 	 * @param sys_id The sys_id of the component to be found.
490 	 * @throws PoolsException If the component cannot be located.
491 	 * @return a component with the supplied name.
492 	 */
checkComponent(String type, long sys_id)493 	long checkComponent(String type, long sys_id)
494 	    throws PoolsException
495 	{
496 		List props = new ArrayList();
497 		Value ptype = new Value("type", type);
498 		Value psys_id = new Value(type + ".sys_id", sys_id);
499 
500 		props.add(ptype);
501 		props.add(psys_id);
502 		List comps = checkComponents(props);
503 		ptype.close();
504 		psys_id.close();
505 		if (comps.size() != 1)
506 			throw new PoolsException();
507 		return (((Long)comps.get(0)).longValue());
508 	}
509 
510 	/**
511 	 * Get a list of components which match the supplied selection criteria
512 	 * in values.
513 	 *
514 	 * @param values A list of values to be used to qualify the search.
515 	 * @throws PoolsException If there is an error executing the query.
516 	 * @return a list of components which match the supplied criteria
517 	 */
getComponents(List values)518 	public List getComponents(List values) throws PoolsException
519 	{
520 		List components;
521 
522 		if ((components = PoolInternal.pool_query_components(getConf(),
523 		    values)) == null) {
524 			if (PoolInternal.pool_error() ==
525 			    PoolInternal.POE_INVALID_SEARCH)
526 				return new ArrayList();
527 			else
528 				throw new PoolsException();
529 		}
530 		ArrayList aList = new ArrayList(components.size());
531 		for (int i = 0; i < components.size(); i++) {
532 			/*
533 			 * Extract type information
534 			 */
535 			Value typeVal = new Value(name);
536 
537 			if (PoolInternal.pool_get_property(getConf(),
538 			    ((Long)components.get(i)).longValue(), "type",
539 			    typeVal.getValue()) == PoolInternal.POC_INVAL)
540 				throw new PoolsException();
541 			if (typeVal == null)
542 				throw new PoolsException();
543 			String type = typeVal.getString();
544 			typeVal.close();
545 
546 			Value idValue = new Value(name);
547 
548 			if (PoolInternal.pool_get_property(getConf(),
549 			    ((Long)components.get(i)).longValue(),
550 			    type + ".sys_id", idValue.getValue()) ==
551 			    PoolInternal.POC_INVAL)
552 				throw new PoolsException();
553 			if (idValue == null)
554 				throw new PoolsException();
555 			long sys_id = idValue.getLong();
556 			idValue.close();
557 
558 			if (elements.containsKey(type + "." + sys_id))
559 				aList.add((Component)elements.get(type + "." +
560 					  sys_id));
561 			else
562 				aList.add(new Component(this, ((Long)components.
563 							get(i)).longValue()));
564 		}
565 		return (aList);
566 
567 	}
568 
569 	/**
570 	 * Get a list of component proxies which match the supplied
571 	 * selection criteria in values.
572 	 *
573 	 * @param values A list of values to be used to qualify the search.
574 	 * @throws PoolsException If there is an error executing the query.
575 	 * @return a list of component proxies which match the
576 	 * supplied criteria
577 	 */
checkComponents(List values)578 	List checkComponents(List values) throws PoolsException
579 	{
580 		List components;
581 
582 		if ((components = PoolInternal.pool_query_components(getConf(),
583 		    values)) == null) {
584 			if (PoolInternal.pool_error() ==
585 			    PoolInternal.POE_INVALID_SEARCH)
586 				return new ArrayList();
587 			else
588 				throw new PoolsException();
589 		}
590 		return (components);
591 	}
592 	/**
593 	 * Returns a descriptive string which describes the configuration.
594 	 *
595 	 * @param deep Whether the information should contain information about
596 	 * all contained elements.
597 	 * @return a descriptive string which describes the configuration.
598 	 */
getInformation(int deep)599 	public String getInformation(int deep)
600 	{
601 		return (PoolInternal.pool_conf_info(_conf.getConf(), deep));
602 	}
603 
604         /**
605          * Returns a string representation of this configuration.
606          *
607          * @return  a string representation of this configuration.
608          */
toString()609 	public String toString()
610 	{
611 		StringBuffer buf = new StringBuffer();
612 
613 		buf.append("system: ");
614 		buf.append(name);
615 		return (buf.toString());
616 	}
617 
618 	/**
619 	 * Indicates whether some other Configuration is "equal to this one.
620 	 * @param o the reference object with which to compare.
621 	 * @return <code>true</code> if this object is the same as the
622 	 * o argument; <code>false</code> otherwise.
623 	 * @see	#hashCode()
624 	 */
equals(Object o)625 	public boolean equals(Object o)
626 	{
627 		if (o == this)
628 			return (true);
629 		if (!(o instanceof Configuration))
630 			return (false);
631 		Configuration other = (Configuration) o;
632 		if (name.compareTo(other.getName()) != 0)
633 			return (false);
634 		return (true);
635 	}
636 
637 	/**
638 	 * Returns a hash code value for the object. This method is
639 	 * supported for the benefit of hashtables such as those provided by
640 	 * <code>java.util.Hashtable</code>.
641 	 *
642 	 * @return a hash code value for this object.
643 	 * @see	#equals(java.lang.Object)
644 	 * @see	java.util.Hashtable
645 	 */
hashCode()646 	public int hashCode()
647 	{
648 		return name.hashCode();
649 	}
650 
651 	/**
652 	 * Return the pointer to this configuration as an element.
653 	 *
654 	 * @return The pointer to the native configuration which this object
655 	 * wraps.
656 	 * @throws PoolsException If there is an error converting the native
657 	 * configuration pointer to a native elem pointer.
658 	 */
getElem()659 	protected long getElem() throws PoolsException
660 	{
661 		long elem;
662 
663 		if ((elem = PoolInternal.pool_conf_to_elem(getConf())) == 0)
664 			throw new PoolsException();
665 		return (elem);
666 	}
667 
668 	/**
669 	 * Return the name of the configuration.
670 	 */
getName()671 	String getName()
672 	{
673 		return (name);
674 	}
675 
676 	/**
677 	 * Return the key of the configuration.
678 	 */
getKey()679 	String getKey()
680 	{
681 		return (key);
682 	}
683 }
684