418b42a4663d89392493ab0d9a0beb30ca57b303
[public/netxms.git] / src / java / netxms-client / src / main / java / org / netxms / client / objects / AbstractObject.java
1 /**
2 * NetXMS - open source network management system
3 * Copyright (C) 2003-2013 Victor Kirhenshtein
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 package org.netxms.client.objects;
20
21 import java.net.InetAddress;
22 import java.net.UnknownHostException;
23 import java.util.Arrays;
24 import java.util.HashMap;
25 import java.util.HashSet;
26 import java.util.Iterator;
27 import java.util.Map;
28 import java.util.Set;
29 import java.util.UUID;
30 import org.netxms.base.GeoLocation;
31 import org.netxms.base.NXCPCodes;
32 import org.netxms.base.NXCPMessage;
33 import org.netxms.base.NXCommon;
34 import org.netxms.client.AccessListElement;
35 import org.netxms.client.NXCSession;
36 import org.netxms.client.constants.Severity;
37
38 /**
39 * Abstract base class for all NetXMS objects (both built-in and provided by extensions)
40 */
41 public abstract class AbstractObject
42 {
43 /** Entire network */
44 public static final int NETWORK = 1;
45 /** Infrastructure Services */
46 public static final int SERVICEROOT = 2;
47 /** Templates */
48 public static final int TEMPLATEROOT = 3;
49 /** Default zone */
50 public static final int ZONE0 = 4;
51 /** Configuration Policies */
52 public static final int POLICYROOT = 5;
53 /** Network Maps */
54 public static final int NETWORKMAPROOT = 6;
55 /** Dashboards */
56 public static final int DASHBOARDROOT = 7;
57 /** Reports */
58 public static final int REPORTROOT = 8;
59 /** Business Services */
60 public static final int BUSINESSSERVICEROOT = 9;
61
62 // Object classes
63 public static final int OBJECT_GENERIC = 0;
64 public static final int OBJECT_SUBNET = 1;
65 public static final int OBJECT_NODE = 2;
66 public static final int OBJECT_INTERFACE = 3;
67 public static final int OBJECT_NETWORK = 4;
68 public static final int OBJECT_CONTAINER = 5;
69 public static final int OBJECT_ZONE = 6;
70 public static final int OBJECT_SERVICEROOT = 7;
71 public static final int OBJECT_TEMPLATE = 8;
72 public static final int OBJECT_TEMPLATEGROUP = 9;
73 public static final int OBJECT_TEMPLATEROOT = 10;
74 public static final int OBJECT_NETWORKSERVICE = 11;
75 public static final int OBJECT_VPNCONNECTOR = 12;
76 public static final int OBJECT_CONDITION = 13;
77 public static final int OBJECT_CLUSTER = 14;
78 public static final int OBJECT_POLICYGROUP = 15;
79 public static final int OBJECT_POLICYROOT = 16;
80 public static final int OBJECT_AGENTPOLICY = 17;
81 public static final int OBJECT_AGENTPOLICY_CONFIG = 18;
82 public static final int OBJECT_NETWORKMAPROOT = 19;
83 public static final int OBJECT_NETWORKMAPGROUP = 20;
84 public static final int OBJECT_NETWORKMAP = 21;
85 public static final int OBJECT_DASHBOARDROOT = 22;
86 public static final int OBJECT_DASHBOARD = 23;
87 public static final int OBJECT_REPORTROOT = 24;
88 public static final int OBJECT_REPORTGROUP = 25;
89 public static final int OBJECT_REPORT = 26;
90 public static final int OBJECT_BUSINESSSERVICEROOT = 27;
91 public static final int OBJECT_BUSINESSSERVICE = 28;
92 public static final int OBJECT_NODELINK = 29;
93 public static final int OBJECT_SLMCHECK = 30;
94 public static final int OBJECT_MOBILEDEVICE = 31;
95 public static final int OBJECT_RACK = 32;
96 public static final int OBJECT_ACCESSPOINT = 33;
97 public static final int OBJECT_CUSTOM = 10000;
98
99 // Status calculation methods
100 public static final int CALCULATE_DEFAULT = 0;
101 public static final int CALCULATE_MOST_CRITICAL = 1;
102 public static final int CALCULATE_SINGLE_THRESHOLD = 2;
103 public static final int CALCULATE_MULTIPLE_THRESHOLDS = 3;
104
105 // Status propagation methods
106 public static final int PROPAGATE_DEFAULT = 0;
107 public static final int PROPAGATE_UNCHANGED = 1;
108 public static final int PROPAGATE_FIXED = 2;
109 public static final int PROPAGATE_RELATIVE = 3;
110 public static final int PROPAGATE_TRANSLATED = 4;
111
112 protected NXCSession session = null;
113 protected long objectId = 0;
114 protected UUID guid;
115 protected String objectName;
116 protected int objectClass;
117 protected int status = Severity.UNKNOWN;
118 protected boolean isDeleted = false;
119 protected InetAddress primaryIP;
120 protected String comments;
121 protected GeoLocation geolocation;
122 protected UUID image;
123 protected long submapId;
124 protected HashSet<Long> trustedNodes = new HashSet<Long>(0);
125 protected boolean inheritAccessRights = true;
126 protected HashSet<AccessListElement> accessList = new HashSet<AccessListElement>(0);
127 protected int statusCalculationMethod;
128 protected int statusPropagationMethod;
129 protected int fixedPropagatedStatus;
130 protected int statusShift;
131 protected int[] statusTransformation;
132 protected int statusSingleThreshold;
133 protected int[] statusThresholds;
134 protected HashSet<Long> parents = new HashSet<Long>(0);
135 protected HashSet<Long> children = new HashSet<Long>(0);
136 protected Map<String, String> customAttributes = new HashMap<String, String>(0);
137
138 /**
139 * Create dummy object of GENERIC class
140 *
141 * @param id object ID to set
142 * @param session associated session
143 */
144 protected AbstractObject(final long id, final NXCSession session)
145 {
146 objectId = id;
147 this.session = session;
148 guid = UUID.randomUUID();
149 objectName = "unknown";
150 objectClass = OBJECT_GENERIC;
151 try
152 {
153 primaryIP = InetAddress.getByName("0.0.0.0");
154 }
155 catch(UnknownHostException e)
156 {
157 }
158 comments = "";
159 geolocation = new GeoLocation(false);
160 image = NXCommon.EMPTY_GUID;
161
162 statusCalculationMethod = CALCULATE_DEFAULT;
163 statusPropagationMethod = PROPAGATE_DEFAULT;
164 fixedPropagatedStatus = Severity.NORMAL;
165 statusShift = 0;
166 statusTransformation = new int[4];
167 statusTransformation[0] = Severity.WARNING;
168 statusTransformation[1] = Severity.MINOR;
169 statusTransformation[2] = Severity.MAJOR;
170 statusTransformation[3] = Severity.CRITICAL;
171 statusSingleThreshold = 75;
172 statusThresholds = new int[4];
173 statusThresholds[0] = 75;
174 statusThresholds[1] = 75;
175 statusThresholds[2] = 75;
176 statusThresholds[3] = 75;
177 }
178
179 /**
180 * Create object from NXCP message
181 * @param msg Message to create object from
182 * @param session Associated client session
183 */
184 public AbstractObject(final NXCPMessage msg, final NXCSession session)
185 {
186 int i, count;
187 long id, id2;
188
189 this.session = session;
190
191 objectId = msg.getVariableAsInteger(NXCPCodes.VID_OBJECT_ID);
192 guid = msg.getVariableAsUUID(NXCPCodes.VID_GUID);
193 objectName = msg.getVariableAsString(NXCPCodes.VID_OBJECT_NAME);
194 objectClass = msg.getVariableAsInteger(NXCPCodes.VID_OBJECT_CLASS);
195 primaryIP = msg.getVariableAsInetAddress(NXCPCodes.VID_IP_ADDRESS);
196 isDeleted = msg.getVariableAsBoolean(NXCPCodes.VID_IS_DELETED);
197 status = msg.getVariableAsInteger(NXCPCodes.VID_OBJECT_STATUS);
198 comments = msg.getVariableAsString(NXCPCodes.VID_COMMENTS);
199 geolocation = new GeoLocation(msg);
200 image = msg.getVariableAsUUID(NXCPCodes.VID_IMAGE);
201 submapId = msg.getVariableAsInt64(NXCPCodes.VID_SUBMAP_ID);
202 if (image == null)
203 image = NXCommon.EMPTY_GUID;
204
205 statusCalculationMethod = msg.getVariableAsInteger(NXCPCodes.VID_STATUS_CALCULATION_ALG);
206 statusPropagationMethod = msg.getVariableAsInteger(NXCPCodes.VID_STATUS_PROPAGATION_ALG);
207 fixedPropagatedStatus = msg.getVariableAsInteger(NXCPCodes.VID_FIXED_STATUS);
208 statusShift = msg.getVariableAsInteger(NXCPCodes.VID_STATUS_SHIFT);
209 statusTransformation = new int[4];
210 statusTransformation[0] = msg.getVariableAsInteger(NXCPCodes.VID_STATUS_TRANSLATION_1);
211 statusTransformation[1] = msg.getVariableAsInteger(NXCPCodes.VID_STATUS_TRANSLATION_2);
212 statusTransformation[2] = msg.getVariableAsInteger(NXCPCodes.VID_STATUS_TRANSLATION_3);
213 statusTransformation[3] = msg.getVariableAsInteger(NXCPCodes.VID_STATUS_TRANSLATION_4);
214 statusSingleThreshold = msg.getVariableAsInteger(NXCPCodes.VID_STATUS_SINGLE_THRESHOLD);
215 statusThresholds = new int[4];
216 statusThresholds[0] = msg.getVariableAsInteger(NXCPCodes.VID_STATUS_THRESHOLD_1);
217 statusThresholds[1] = msg.getVariableAsInteger(NXCPCodes.VID_STATUS_THRESHOLD_2);
218 statusThresholds[2] = msg.getVariableAsInteger(NXCPCodes.VID_STATUS_THRESHOLD_3);
219 statusThresholds[3] = msg.getVariableAsInteger(NXCPCodes.VID_STATUS_THRESHOLD_4);
220
221 // Status shift can be negative, but all int16 values read from message
222 // as unsigned, so we need to convert shift value
223 if (statusShift > 32767)
224 statusShift = statusShift - 65536;
225
226 // Parents
227 count = msg.getVariableAsInteger(NXCPCodes.VID_PARENT_CNT);
228 for(i = 0, id = NXCPCodes.VID_PARENT_ID_BASE; i < count; i++, id++)
229 {
230 parents.add(msg.getVariableAsInt64(id));
231 }
232
233 // Childs
234 count = msg.getVariableAsInteger(NXCPCodes.VID_CHILD_CNT);
235 for(i = 0, id = NXCPCodes.VID_CHILD_ID_BASE; i < count; i++, id++)
236 {
237 children.add(msg.getVariableAsInt64(id));
238 }
239
240 // Trusted nodes
241 count = msg.getVariableAsInteger(NXCPCodes.VID_NUM_TRUSTED_NODES);
242 if (count > 0)
243 {
244 Long[] nodes = msg.getVariableAsUInt32ArrayEx(NXCPCodes.VID_TRUSTED_NODES);
245 trustedNodes.addAll(Arrays.asList(nodes));
246 }
247 for(i = 0, id = NXCPCodes.VID_CHILD_ID_BASE; i < count; i++, id++)
248 {
249 children.add(msg.getVariableAsInt64(id));
250 }
251
252 // Custom attributes
253 count = msg.getVariableAsInteger(NXCPCodes.VID_NUM_CUSTOM_ATTRIBUTES);
254 for(i = 0, id = NXCPCodes.VID_CUSTOM_ATTRIBUTES_BASE; i < count; i++, id += 2)
255 {
256 customAttributes.put(msg.getVariableAsString(id), msg.getVariableAsString(id + 1));
257 }
258
259 // Access list
260 inheritAccessRights = msg.getVariableAsBoolean(NXCPCodes.VID_INHERIT_RIGHTS);
261 count = msg.getVariableAsInteger(NXCPCodes.VID_ACL_SIZE);
262 for(i = 0, id = NXCPCodes.VID_ACL_USER_BASE, id2 = NXCPCodes.VID_ACL_RIGHTS_BASE; i < count; i++, id++, id2++)
263 {
264 accessList.add(new AccessListElement(msg.getVariableAsInt64(id), msg.getVariableAsInteger(id2)));
265 }
266 }
267
268 /**
269 * Check if object should be represented by class default image
270 *
271 * @return true if default image should be used
272 */
273 public boolean isDefaultImage()
274 {
275 return image.equals(NXCommon.EMPTY_GUID);
276 }
277
278 /**
279 * @return Iterator for list of parent objects
280 */
281 public Iterator<Long> getParents()
282 {
283 return parents.iterator();
284 }
285
286 /**
287 * @return Iterator for list of child objects
288 */
289 public Iterator<Long> getChildren()
290 {
291 return children.iterator();
292 }
293
294 /**
295 * @return Access list
296 */
297 public AccessListElement[] getAccessList()
298 {
299 return accessList.toArray(new AccessListElement[accessList.size()]);
300 }
301
302 /**
303 * @return the comments
304 */
305 public String getComments()
306 {
307 return comments;
308 }
309
310 /**
311 * @return the objectId
312 */
313 public long getObjectId()
314 {
315 return objectId;
316 }
317
318 /**
319 * @return the objectName
320 */
321 public String getObjectName()
322 {
323 return objectName;
324 }
325
326 /**
327 * @return the primaryIP
328 */
329 public InetAddress getPrimaryIP()
330 {
331 return primaryIP;
332 }
333
334 /**
335 * @return the status
336 */
337 public int getStatus()
338 {
339 return status;
340 }
341
342 /**
343 * @return the isDeleted
344 */
345 public boolean isDeleted()
346 {
347 return isDeleted;
348 }
349
350 /**
351 * @return the inheritAccessRights
352 */
353 public boolean isInheritAccessRights()
354 {
355 return inheritAccessRights;
356 }
357
358 /**
359 * Check if given object is direct or indirect parent
360 *
361 * @param objectId ID of object to check
362 */
363 public boolean isChildOf(final long objectId)
364 {
365 boolean rc = false;
366
367 synchronized(parents)
368 {
369 final Iterator<Long> it = parents.iterator();
370 while(it.hasNext())
371 {
372 long id = it.next();
373 if (id == objectId)
374 {
375 // Direct parent
376 rc = true;
377 break;
378 }
379 AbstractObject object = session.findObjectById(id);
380 if (object != null)
381 {
382 if (object.isChildOf(objectId))
383 {
384 rc = true;
385 break;
386 }
387 }
388 }
389 }
390 return rc;
391 }
392
393 /**
394 * Check if at least one of given objects is direct or indirect parent
395 * @param objects List of object ID to check
396 */
397 public boolean isChildOf(final long[] objects)
398 {
399 for(int i = 0; i < objects.length; i++)
400 if (isChildOf(objects[i]))
401 return true;
402 return false;
403 }
404
405 /**
406 * Check if given object is direct parent
407 *
408 * @param objectId ID of object to check
409 */
410 public boolean isDirectChildOf(final long objectId)
411 {
412 boolean rc = false;
413
414 synchronized(parents)
415 {
416 final Iterator<Long> it = parents.iterator();
417 while(it.hasNext())
418 {
419 long id = it.next();
420 if (id == objectId)
421 {
422 // Direct parent
423 rc = true;
424 break;
425 }
426 }
427 }
428 return rc;
429 }
430
431 /**
432 * @return List of parent objects
433 */
434 public AbstractObject[] getParentsAsArray()
435 {
436 final Set<AbstractObject> list;
437 synchronized(parents)
438 {
439 list = new HashSet<AbstractObject>(children.size());
440 final Iterator<Long> it = parents.iterator();
441 while(it.hasNext())
442 {
443 AbstractObject obj = session.findObjectById(it.next());
444 if (obj != null)
445 list.add(obj);
446 }
447 }
448 return list.toArray(new AbstractObject[list.size()]);
449 }
450
451 /**
452 * @return List of child objects
453 */
454 public AbstractObject[] getChildsAsArray()
455 {
456 final Set<AbstractObject> list;
457 synchronized(children)
458 {
459 list = new HashSet<AbstractObject>(children.size());
460 final Iterator<Long> it = children.iterator();
461 while(it.hasNext())
462 {
463 AbstractObject obj = session.findObjectById(it.next());
464 if (obj != null)
465 list.add(obj);
466 }
467 }
468 return list.toArray(new AbstractObject[list.size()]);
469 }
470
471 /**
472 * Return identifiers of all child objects
473 *
474 * @return
475 */
476 public long[] getChildIdList()
477 {
478 long[] list;
479 synchronized(children)
480 {
481 list = new long[children.size()];
482 int i = 0;
483 for(Long id : children)
484 list[i++] = id;
485 }
486 return list;
487 }
488
489 /**
490 * Return identifiers of all parent objects
491 *
492 * @return
493 */
494 public long[] getParentIdList()
495 {
496 long[] list;
497 synchronized(parents)
498 {
499 list = new long[parents.size()];
500 int i = 0;
501 for(Long id : parents)
502 list[i++] = id;
503 }
504 return list;
505 }
506
507 /**
508 * Internal worker function for getAllChilds
509 * @param classFilter class filter
510 * @param set result set
511 */
512 private void getAllChildsInternal(int classFilter, Set<AbstractObject> set)
513 {
514 synchronized(children)
515 {
516 final Iterator<Long> it = children.iterator();
517 while(it.hasNext())
518 {
519 AbstractObject obj = session.findObjectById(it.next());
520 if (obj != null)
521 {
522 if ((classFilter == -1) || (obj.getObjectClass() == classFilter))
523 set.add(obj);
524 obj.getAllChildsInternal(classFilter, set);
525 }
526 }
527 }
528 }
529
530 /**
531 * Get all child objects, direct and indirect
532 *
533 * @param classFilter -1 to get all childs, or NetXMS class id to retrieve objects of given class
534 * @return set of child objects
535 */
536 public Set<AbstractObject> getAllChilds(int classFilter)
537 {
538 Set<AbstractObject> result = new HashSet<AbstractObject>();
539 getAllChildsInternal(classFilter, result);
540 return result;
541 }
542
543 /**
544 * Internal worker function for getAllParents
545 * @param classFilter class filter
546 * @param set result set
547 */
548 private void getAllParentsInternal(int classFilter, Set<AbstractObject> set)
549 {
550 synchronized(parents)
551 {
552 final Iterator<Long> it = parents.iterator();
553 while(it.hasNext())
554 {
555 AbstractObject obj = session.findObjectById(it.next());
556 if (obj != null)
557 {
558 if ((classFilter == -1) || (obj.getObjectClass() == classFilter))
559 set.add(obj);
560 obj.getAllParentsInternal(classFilter, set);
561 }
562 }
563 }
564 }
565
566 /**
567 * Get all parent objects, direct and indirect
568 *
569 * @param classFilter -1 to get all parents, or NetXMS class id to retrieve objects of given class
570 * @return set of parent objects
571 */
572 public Set<AbstractObject> getAllParents(int classFilter)
573 {
574 Set<AbstractObject> result = new HashSet<AbstractObject>();
575 getAllParentsInternal(classFilter, result);
576 return result;
577 }
578
579 /**
580 * @return List of trusted nodes
581 */
582 public AbstractObject[] getTrustedNodes()
583 {
584 final AbstractObject[] list;
585 synchronized(trustedNodes)
586 {
587 list = new AbstractObject[trustedNodes.size()];
588 final Iterator<Long> it = trustedNodes.iterator();
589 for(int i = 0; it.hasNext(); i++)
590 {
591 list[i] = session.findObjectById(it.next());
592 }
593 }
594 return list;
595 }
596
597 /**
598 * @return true if object has parents
599 */
600 public boolean hasParents()
601 {
602 return parents.size() > 0;
603 }
604
605 /**
606 * @return true if object has children
607 */
608 public boolean hasChildren()
609 {
610 return children.size() > 0;
611 }
612
613 /**
614 * @return true if object has children accessible by this session
615 */
616 public boolean hasAccessibleChildren()
617 {
618 for(Long id : children)
619 if (session.findObjectById(id) != null)
620 return true;
621 return false;
622 }
623
624 /**
625 * @return the objectClass
626 */
627 public int getObjectClass()
628 {
629 return objectClass;
630 }
631
632 /**
633 * @return Name of NetXMS object's class
634 */
635 public String getObjectClassName()
636 {
637 return "Class " + Integer.toString(objectClass);
638 }
639
640 /**
641 * Get object's custom attributes
642 */
643 public Map<String, String> getCustomAttributes()
644 {
645 return customAttributes;
646 }
647
648 /**
649 * @return the geolocation
650 */
651 public GeoLocation getGeolocation()
652 {
653 return geolocation;
654 }
655
656 @Override
657 public int hashCode()
658 {
659 return (int)objectId;
660 }
661
662 /**
663 * @return the guid
664 */
665 public UUID getGuid()
666 {
667 return guid;
668 }
669
670 /**
671 * @return the image
672 */
673 public UUID getImage()
674 {
675 return image;
676 }
677
678 /**
679 * @return the submapId
680 */
681 public long getSubmapId()
682 {
683 return submapId;
684 }
685
686 /**
687 * @return the statusCalculationMethod
688 */
689 public int getStatusCalculationMethod()
690 {
691 return statusCalculationMethod;
692 }
693
694 /**
695 * @return the statusPropagationMethod
696 */
697 public int getStatusPropagationMethod()
698 {
699 return statusPropagationMethod;
700 }
701
702 /**
703 * @return the fixedPropagatedStatus
704 */
705 public int getFixedPropagatedStatus()
706 {
707 return fixedPropagatedStatus;
708 }
709
710 /**
711 * @return the statusShift
712 */
713 public int getStatusShift()
714 {
715 return statusShift;
716 }
717
718 /**
719 * @return the statusTransformation
720 */
721 public int[] getStatusTransformation()
722 {
723 return statusTransformation;
724 }
725
726 /**
727 * @return the statusSingleThreshold
728 */
729 public int getStatusSingleThreshold()
730 {
731 return statusSingleThreshold;
732 }
733
734 /**
735 * @return the statusThresholds
736 */
737 public int[] getStatusThresholds()
738 {
739 return statusThresholds;
740 }
741
742 /**
743 * Update internal session reference during session handover. This method should not be called directly!
744 *
745 * @param session new session object
746 */
747 public final void setSession(NXCSession session)
748 {
749 this.session = session;
750 }
751
752 }