2 * NetXMS - open source network management system
3 * Copyright (C) 2003-2016 Victor Kirhenshtein
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.
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.
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.
19 package org
.netxms
.client
;
21 import java
.io
.BufferedInputStream
;
22 import java
.io
.ByteArrayInputStream
;
24 import java
.io
.FileInputStream
;
25 import java
.io
.IOException
;
26 import java
.io
.InputStream
;
27 import java
.io
.OutputStream
;
28 import java
.io
.Writer
;
29 import java
.net
.InetAddress
;
30 import java
.net
.InetSocketAddress
;
31 import java
.net
.Socket
;
32 import java
.net
.UnknownHostException
;
33 import java
.security
.GeneralSecurityException
;
34 import java
.security
.Signature
;
35 import java
.security
.SignatureException
;
36 import java
.security
.cert
.Certificate
;
37 import java
.security
.cert
.CertificateEncodingException
;
38 import java
.util
.ArrayList
;
39 import java
.util
.Arrays
;
40 import java
.util
.Collection
;
41 import java
.util
.Collections
;
42 import java
.util
.Comparator
;
43 import java
.util
.Date
;
44 import java
.util
.HashMap
;
45 import java
.util
.HashSet
;
46 import java
.util
.Iterator
;
47 import java
.util
.List
;
48 import java
.util
.Locale
;
50 import java
.util
.Map
.Entry
;
52 import java
.util
.UUID
;
53 import java
.util
.concurrent
.LinkedBlockingQueue
;
54 import java
.util
.concurrent
.Semaphore
;
55 import java
.util
.concurrent
.TimeUnit
;
56 import java
.util
.concurrent
.atomic
.AtomicLong
;
57 import java
.util
.regex
.Matcher
;
58 import java
.util
.regex
.Pattern
;
59 import org
.netxms
.base
.EncryptionContext
;
60 import org
.netxms
.base
.GeoLocation
;
61 import org
.netxms
.base
.InetAddressEx
;
62 import org
.netxms
.base
.Logger
;
63 import org
.netxms
.base
.NXCPCodes
;
64 import org
.netxms
.base
.NXCPDataInputStream
;
65 import org
.netxms
.base
.NXCPException
;
66 import org
.netxms
.base
.NXCPMessage
;
67 import org
.netxms
.base
.NXCPMessageReceiver
;
68 import org
.netxms
.base
.NXCPMsgWaitQueue
;
69 import org
.netxms
.base
.NXCommon
;
70 import org
.netxms
.client
.agent
.config
.ConfigContent
;
71 import org
.netxms
.client
.agent
.config
.ConfigListElement
;
72 import org
.netxms
.client
.constants
.AggregationFunction
;
73 import org
.netxms
.client
.constants
.AuthenticationType
;
74 import org
.netxms
.client
.constants
.NodePollType
;
75 import org
.netxms
.client
.constants
.ObjectStatus
;
76 import org
.netxms
.client
.constants
.RCC
;
77 import org
.netxms
.client
.dashboards
.DashboardElement
;
78 import org
.netxms
.client
.datacollection
.ConditionDciInfo
;
79 import org
.netxms
.client
.datacollection
.DataCollectionConfiguration
;
80 import org
.netxms
.client
.datacollection
.DataCollectionItem
;
81 import org
.netxms
.client
.datacollection
.DciData
;
82 import org
.netxms
.client
.datacollection
.DciDataRow
;
83 import org
.netxms
.client
.datacollection
.DciPushData
;
84 import org
.netxms
.client
.datacollection
.DciSummaryTable
;
85 import org
.netxms
.client
.datacollection
.DciSummaryTableColumn
;
86 import org
.netxms
.client
.datacollection
.DciSummaryTableDescriptor
;
87 import org
.netxms
.client
.datacollection
.DciValue
;
88 import org
.netxms
.client
.datacollection
.GraphSettings
;
89 import org
.netxms
.client
.datacollection
.PerfTabDci
;
90 import org
.netxms
.client
.datacollection
.SimpleDciValue
;
91 import org
.netxms
.client
.datacollection
.Threshold
;
92 import org
.netxms
.client
.datacollection
.ThresholdViolationSummary
;
93 import org
.netxms
.client
.datacollection
.TransformationTestResult
;
94 import org
.netxms
.client
.datacollection
.WinPerfObject
;
95 import org
.netxms
.client
.events
.Alarm
;
96 import org
.netxms
.client
.events
.AlarmComment
;
97 import org
.netxms
.client
.events
.Event
;
98 import org
.netxms
.client
.events
.EventInfo
;
99 import org
.netxms
.client
.events
.EventProcessingPolicy
;
100 import org
.netxms
.client
.events
.EventProcessingPolicyRule
;
101 import org
.netxms
.client
.events
.EventTemplate
;
102 import org
.netxms
.client
.events
.SyslogRecord
;
103 import org
.netxms
.client
.log
.Log
;
104 import org
.netxms
.client
.maps
.MapDCIInstance
;
105 import org
.netxms
.client
.maps
.NetworkMapLink
;
106 import org
.netxms
.client
.maps
.NetworkMapPage
;
107 import org
.netxms
.client
.maps
.elements
.NetworkMapElement
;
108 import org
.netxms
.client
.maps
.elements
.NetworkMapObject
;
109 import org
.netxms
.client
.market
.Repository
;
110 import org
.netxms
.client
.mt
.MappingTable
;
111 import org
.netxms
.client
.mt
.MappingTableDescriptor
;
112 import org
.netxms
.client
.objects
.AbstractObject
;
113 import org
.netxms
.client
.objects
.AccessPoint
;
114 import org
.netxms
.client
.objects
.AgentPolicy
;
115 import org
.netxms
.client
.objects
.AgentPolicyConfig
;
116 import org
.netxms
.client
.objects
.AgentPolicyLogParser
;
117 import org
.netxms
.client
.objects
.BusinessService
;
118 import org
.netxms
.client
.objects
.BusinessServiceRoot
;
119 import org
.netxms
.client
.objects
.Chassis
;
120 import org
.netxms
.client
.objects
.Cluster
;
121 import org
.netxms
.client
.objects
.ClusterResource
;
122 import org
.netxms
.client
.objects
.Condition
;
123 import org
.netxms
.client
.objects
.Container
;
124 import org
.netxms
.client
.objects
.Dashboard
;
125 import org
.netxms
.client
.objects
.DashboardRoot
;
126 import org
.netxms
.client
.objects
.EntireNetwork
;
127 import org
.netxms
.client
.objects
.GenericObject
;
128 import org
.netxms
.client
.objects
.Interface
;
129 import org
.netxms
.client
.objects
.MobileDevice
;
130 import org
.netxms
.client
.objects
.NetworkMap
;
131 import org
.netxms
.client
.objects
.NetworkMapGroup
;
132 import org
.netxms
.client
.objects
.NetworkMapRoot
;
133 import org
.netxms
.client
.objects
.NetworkService
;
134 import org
.netxms
.client
.objects
.Node
;
135 import org
.netxms
.client
.objects
.NodeLink
;
136 import org
.netxms
.client
.objects
.PolicyGroup
;
137 import org
.netxms
.client
.objects
.PolicyRoot
;
138 import org
.netxms
.client
.objects
.Rack
;
139 import org
.netxms
.client
.objects
.ServiceCheck
;
140 import org
.netxms
.client
.objects
.ServiceRoot
;
141 import org
.netxms
.client
.objects
.Subnet
;
142 import org
.netxms
.client
.objects
.Template
;
143 import org
.netxms
.client
.objects
.TemplateGroup
;
144 import org
.netxms
.client
.objects
.TemplateRoot
;
145 import org
.netxms
.client
.objects
.UnknownObject
;
146 import org
.netxms
.client
.objects
.VPNConnector
;
147 import org
.netxms
.client
.objects
.Zone
;
148 import org
.netxms
.client
.objecttools
.ObjectTool
;
149 import org
.netxms
.client
.objecttools
.ObjectToolDetails
;
150 import org
.netxms
.client
.packages
.PackageDeploymentListener
;
151 import org
.netxms
.client
.packages
.PackageInfo
;
152 import org
.netxms
.client
.reporting
.ReportDefinition
;
153 import org
.netxms
.client
.reporting
.ReportRenderFormat
;
154 import org
.netxms
.client
.reporting
.ReportResult
;
155 import org
.netxms
.client
.reporting
.ReportingJob
;
156 import org
.netxms
.client
.server
.AgentFile
;
157 import org
.netxms
.client
.server
.ServerConsoleListener
;
158 import org
.netxms
.client
.server
.ServerFile
;
159 import org
.netxms
.client
.server
.ServerJob
;
160 import org
.netxms
.client
.server
.ServerVariable
;
161 import org
.netxms
.client
.situations
.Situation
;
162 import org
.netxms
.client
.snmp
.SnmpTrap
;
163 import org
.netxms
.client
.snmp
.SnmpTrapLogRecord
;
164 import org
.netxms
.client
.snmp
.SnmpUsmCredential
;
165 import org
.netxms
.client
.snmp
.SnmpValue
;
166 import org
.netxms
.client
.snmp
.SnmpWalkListener
;
167 import org
.netxms
.client
.topology
.ConnectionPoint
;
168 import org
.netxms
.client
.topology
.FdbEntry
;
169 import org
.netxms
.client
.topology
.NetworkPath
;
170 import org
.netxms
.client
.topology
.Route
;
171 import org
.netxms
.client
.topology
.VlanInfo
;
172 import org
.netxms
.client
.topology
.WirelessStation
;
173 import org
.netxms
.client
.users
.AbstractUserObject
;
174 import org
.netxms
.client
.users
.AuthCertificate
;
175 import org
.netxms
.client
.users
.User
;
176 import org
.netxms
.client
.users
.UserGroup
;
177 import org
.netxms
.client
.zeromq
.ZmqSubscription
;
178 import org
.netxms
.client
.zeromq
.ZmqSubscriptionType
;
181 * Communication session with NetXMS server.
183 public class NXCSession
185 // Various public constants
186 public static final int DEFAULT_CONN_PORT
= 4701;
188 // Core notification channels
189 public static final String CHANNEL_EVENTS
= "Core.Events";
190 public static final String CHANNEL_SYSLOG
= "Core.Syslog";
191 public static final String CHANNEL_ALARMS
= "Core.Alarms";
192 public static final String CHANNEL_OBJECTS
= "Core.Objects";
193 public static final String CHANNEL_SNMP_TRAPS
= "Core.SNMP.Traps";
194 public static final String CHANNEL_AUDIT_LOG
= "Core.Audit";
195 public static final String CHANNEL_SITUATIONS
= "Core.Situations";
196 public static final String CHANNEL_USERDB
= "Core.UserDB";
198 // Object sync options
199 public static final int OBJECT_SYNC_NOTIFY
= 0x0001;
200 public static final int OBJECT_SYNC_WAIT
= 0x0002;
202 // Configuration import options
203 public static final int CFG_IMPORT_REPLACE_EVENT_BY_CODE
= 0x0001;
204 public static final int CFG_IMPORT_REPLACE_EVENT_BY_NAME
= 0x0002;
207 public static final int ADDRESS_LIST_DISCOVERY_TARGETS
= 1;
208 public static final int ADDRESS_LIST_DISCOVERY_FILTER
= 2;
211 public static final int SERVER_COMPONENT_DISCOVERY_MANAGER
= 1;
214 public static final int DESKTOP_CLIENT
= 0;
215 public static final int WEB_CLIENT
= 1;
216 public static final int MOBILE_CLIENT
= 2;
217 public static final int TABLET_CLIENT
= 3;
218 public static final int APPLICATION_CLIENT
= 4;
221 private static final int CLIENT_CHALLENGE_SIZE
= 256;
222 private static final int MAX_DCI_DATA_ROWS
= 200000;
223 private static final int MAX_DCI_STRING_VALUE_LENGTH
= 256;
224 private static final int RECEIVED_FILE_TTL
= 300000; // 300 seconds
225 private static final int FILE_BUFFER_SIZE
= 128 * 1024; // 128k
227 // Internal synchronization objects
228 private final Semaphore syncObjects
= new Semaphore(1);
229 private final Semaphore syncUserDB
= new Semaphore(1);
231 // Connection-related attributes
232 private String connAddress
;
233 private int connPort
;
234 private boolean connUseEncryption
;
235 private String connClientInfo
= "nxjclient/" + NXCommon
.VERSION
;
236 private int clientType
= DESKTOP_CLIENT
;
237 private String clientAddress
= null;
238 private boolean ignoreProtocolVersion
= false;
239 private String clientLanguage
= "en";
241 // Information about logged in user
242 private int sessionId
;
244 private String userName
;
245 private AuthenticationType authenticationMethod
;
246 private long userSystemRights
;
247 private boolean passwordExpired
;
249 // Internal communication data
250 private Socket socket
= null;
251 private NXCPMsgWaitQueue msgWaitQueue
= null;
252 private ReceiverThread recvThread
= null;
253 private HousekeeperThread housekeeperThread
= null;
254 private AtomicLong requestId
= new AtomicLong(1);
255 private boolean isConnected
= false;
256 private boolean isDisconnected
= false;
257 private boolean serverConsoleConnected
= false;
258 private EncryptionContext encryptionContext
= null;
260 // Communication parameters
261 private int defaultRecvBufferSize
= 4194304; // Default is 4MB
262 private int maxRecvBufferSize
= 33554432; // Max is 32MB
263 private int connectTimeout
= 10000; // Default is 10 seconds
264 private int commandTimeout
= 30000; // Default is 30 seconds
265 private int serverCommandOutputTimeout
= 60000;
267 // Notification listeners and queue
268 private LinkedBlockingQueue
<SessionNotification
> notificationQueue
= new LinkedBlockingQueue
<SessionNotification
>(8192);
269 private Set
<SessionListener
> listeners
= new HashSet
<SessionListener
>(0);
270 private Set
<ServerConsoleListener
> consoleListeners
= new HashSet
<ServerConsoleListener
>(0);
272 // Message subscriptions
273 private Map
<MessageSubscription
, MessageHandler
> messageSubscriptions
= new HashMap
<MessageSubscription
, MessageHandler
>(0);
276 private Map
<Long
, NXCReceivedFile
> receivedFiles
= new HashMap
<Long
, NXCReceivedFile
>();
278 // Received file updates(for file monitoring)
279 private Map
<String
, String
> recievedUpdates
= new HashMap
<String
, String
>();
281 // Server information
282 private ProtocolVersion protocolVersion
;
283 private String serverVersion
= "(unknown)";
284 private long serverId
= 0;
285 private String serverTimeZone
;
286 private byte[] serverChallenge
= new byte[CLIENT_CHALLENGE_SIZE
];
287 private boolean zoningEnabled
= false;
288 private boolean helpdeskLinkActive
= false;
289 private String tileServerURL
;
290 private String dateFormat
;
291 private String timeFormat
;
292 private String shortTimeFormat
;
293 private int defaultDciRetentionTime
;
294 private int defaultDciPollingInterval
;
295 private boolean strictAlarmStatusFlow
;
296 private boolean timedAlarmAckEnabled
;
297 private int minViewRefreshInterval
;
298 private long serverTime
= System
.currentTimeMillis();
299 private long serverTimeRecvTime
= System
.currentTimeMillis();
300 private int alarmListDisplayLimit
;
303 private Map
<Long
, AbstractObject
> objectList
= new HashMap
<Long
, AbstractObject
>();
304 private boolean objectsSynchronized
= false;
307 private Map
<Long
, AbstractUserObject
> userDB
= new HashMap
<Long
, AbstractUserObject
>();
310 private Map
<Long
, EventTemplate
> eventTemplates
= new HashMap
<Long
, EventTemplate
>();
311 private boolean eventTemplatesNeedSync
= false;
314 * Message subscription class
316 final protected class MessageSubscription
318 protected int messageCode
;
319 protected long messageId
;
326 protected MessageSubscription(int messageCode
, long messageId
)
328 this.messageCode
= messageCode
;
329 this.messageId
= messageId
;
333 * @see java.lang.Object#hashCode()
336 public int hashCode()
338 final int prime
= 31;
340 result
= prime
* result
+ messageCode
;
341 result
= prime
* result
+ (int)(messageId ^
(messageId
>>> 32));
346 * @see java.lang.Object#equals(java.lang.Object)
349 public boolean equals(Object obj
)
355 if (getClass() != obj
.getClass())
357 MessageSubscription other
= (MessageSubscription
)obj
;
358 if (messageCode
!= other
.messageCode
)
360 if (messageId
!= other
.messageId
)
367 * Receiver thread for NXCSession
369 private class ReceiverThread
extends Thread
380 final NXCPMessageReceiver receiver
= new NXCPMessageReceiver(defaultRecvBufferSize
, maxRecvBufferSize
);
385 in
= socket
.getInputStream();
389 return; // Stop receiver thread if input stream cannot be obtained
392 while(socket
.isConnected())
396 NXCPMessage msg
= receiver
.receiveMessage(in
, encryptionContext
);
397 switch(msg
.getMessageCode())
399 case NXCPCodes
.CMD_REQUEST_SESSION_KEY
:
400 setupEncryption(msg
);
402 case NXCPCodes
.CMD_KEEPALIVE
:
403 serverTime
= msg
.getFieldAsInt64(NXCPCodes
.VID_TIMESTAMP
) * 1000;
404 serverTimeRecvTime
= System
.currentTimeMillis();
406 case NXCPCodes
.CMD_OBJECT
:
407 case NXCPCodes
.CMD_OBJECT_UPDATE
:
408 if (!msg
.getFieldAsBoolean(NXCPCodes
.VID_IS_DELETED
))
410 final AbstractObject obj
= createObjectFromMessage(msg
);
411 synchronized(objectList
)
413 objectList
.put(obj
.getObjectId(), obj
);
415 if (msg
.getMessageCode() == NXCPCodes
.CMD_OBJECT_UPDATE
)
417 sendNotification(new SessionNotification(SessionNotification
.OBJECT_CHANGED
, obj
.getObjectId(), obj
));
422 long objectId
= msg
.getFieldAsInt32(NXCPCodes
.VID_OBJECT_ID
);
423 synchronized(objectList
)
425 objectList
.remove(objectId
);
427 sendNotification(new SessionNotification(SessionNotification
.OBJECT_DELETED
, objectId
));
430 case NXCPCodes
.CMD_OBJECT_LIST_END
:
431 completeSync(syncObjects
);
433 case NXCPCodes
.CMD_USER_DATA
:
434 final User user
= new User(msg
);
437 if (user
.isDeleted())
439 userDB
.remove(user
.getId());
443 userDB
.put(user
.getId(), user
);
447 case NXCPCodes
.CMD_GROUP_DATA
:
448 final UserGroup group
= new UserGroup(msg
);
451 if (group
.isDeleted())
453 userDB
.remove(group
.getId());
457 userDB
.put(group
.getId(), group
);
461 case NXCPCodes
.CMD_USER_DB_EOF
:
462 completeSync(syncUserDB
);
464 case NXCPCodes
.CMD_USER_DB_UPDATE
:
465 processUserDBUpdate(msg
);
467 case NXCPCodes
.CMD_ALARM_UPDATE
:
468 sendNotification(new SessionNotification(
469 msg
.getFieldAsInt32(NXCPCodes
.VID_NOTIFICATION_CODE
) + SessionNotification
.NOTIFY_BASE
,
472 case NXCPCodes
.CMD_JOB_CHANGE_NOTIFICATION
:
473 sendNotification(new SessionNotification(SessionNotification
.JOB_CHANGE
, new ServerJob(msg
)));
475 case NXCPCodes
.CMD_FILE_DATA
:
476 processFileData(msg
);
478 case NXCPCodes
.CMD_FILE_MONITORING
:
479 processFileTail(msg
);
481 case NXCPCodes
.CMD_ABORT_FILE_TRANSFER
:
482 processFileTransferError(msg
);
484 case NXCPCodes
.CMD_NOTIFY
:
485 processNotificationMessage(msg
, true);
487 case NXCPCodes
.CMD_RS_NOTIFY
:
488 processNotificationMessage(msg
, false);
490 case NXCPCodes
.CMD_EVENTLOG_RECORDS
:
491 processNewEvents(msg
);
493 case NXCPCodes
.CMD_TRAP_LOG_RECORDS
:
494 processNewTraps(msg
);
496 case NXCPCodes
.CMD_SYSLOG_RECORDS
:
497 processSyslogRecords(msg
);
499 case NXCPCodes
.CMD_ACTION_DB_UPDATE
:
500 processActionConfigChange(msg
);
502 case NXCPCodes
.CMD_EVENT_DB_UPDATE
:
503 processEventConfigChange(msg
);
505 case NXCPCodes
.CMD_TRAP_CFG_UPDATE
:
506 processTrapConfigChange(msg
);
508 case NXCPCodes
.CMD_SITUATION_CHANGE
:
509 processSituationChange(msg
);
511 case NXCPCodes
.CMD_ADM_MESSAGE
:
512 processConsoleOutput(msg
);
514 case NXCPCodes
.CMD_IMAGE_LIBRARY_UPDATE
:
515 processImageLibraryUpdate(msg
);
517 case NXCPCodes
.CMD_GRAPH_UPDATE
:
518 GraphSettings graph
= new GraphSettings(msg
, NXCPCodes
.VID_GRAPH_LIST_BASE
);
519 sendNotification(new SessionNotification(SessionNotification
.PREDEFINED_GRAPHS_CHANGED
, graph
.getId(), graph
));
522 // Check subscriptions
523 synchronized(messageSubscriptions
)
525 MessageSubscription s
= new MessageSubscription(msg
.getMessageCode(), msg
.getMessageId());
526 MessageHandler handler
= messageSubscriptions
.get(s
);
529 if (handler
.processMessage(msg
))
531 if (handler
.isComplete())
532 messageSubscriptions
.remove(s
);
534 handler
.setLastMessageTimestamp(System
.currentTimeMillis());
539 if (msg
.getMessageCode() >= 0x1000)
542 sendNotification(new SessionNotification(SessionNotification
.CUSTOM_MESSAGE
, msg
));
544 msgWaitQueue
.putMessage(msg
);
551 break; // Stop on read errors
553 catch(NXCPException e
)
555 if (e
.getErrorCode() == NXCPException
.SESSION_CLOSED
) break;
557 catch(NXCException e
)
559 if (e
.getErrorCode() == RCC
.ENCRYPTION_ERROR
) break;
565 * Process server console output
567 * @param msg notification message
569 private void processConsoleOutput(NXCPMessage msg
)
571 final String text
= msg
.getFieldAsString(NXCPCodes
.VID_MESSAGE
);
572 synchronized(consoleListeners
)
574 for(ServerConsoleListener l
: consoleListeners
)
576 l
.onConsoleOutput(text
);
582 * Process event notification messages.
584 * @param msg NXCP message
586 private void processNewEvents(final NXCPMessage msg
)
588 int count
= msg
.getFieldAsInt32(NXCPCodes
.VID_NUM_RECORDS
);
589 int order
= msg
.getFieldAsInt32(NXCPCodes
.VID_RECORDS_ORDER
);
590 long varId
= NXCPCodes
.VID_EVENTLOG_MSG_BASE
;
591 for(int i
= 0; i
< count
; i
++)
593 Event event
= new Event(msg
, varId
);
594 sendNotification(new SessionNotification(SessionNotification
.NEW_EVENTLOG_RECORD
, order
, event
));
599 * Process SNMP trap notification messages.
601 * @param msg NXCP message
603 private void processNewTraps(final NXCPMessage msg
)
605 int count
= msg
.getFieldAsInt32(NXCPCodes
.VID_NUM_RECORDS
);
606 int order
= msg
.getFieldAsInt32(NXCPCodes
.VID_RECORDS_ORDER
);
607 long varId
= NXCPCodes
.VID_TRAP_LOG_MSG_BASE
;
608 for(int i
= 0; i
< count
; i
++)
610 SnmpTrapLogRecord trap
= new SnmpTrapLogRecord(msg
, varId
);
611 sendNotification(new SessionNotification(SessionNotification
.NEW_SNMP_TRAP
, order
, trap
));
616 * Process syslog messages.
618 * @param msg NXCP message
620 private void processSyslogRecords(final NXCPMessage msg
)
622 int count
= msg
.getFieldAsInt32(NXCPCodes
.VID_NUM_RECORDS
);
623 int order
= msg
.getFieldAsInt32(NXCPCodes
.VID_RECORDS_ORDER
);
624 long varId
= NXCPCodes
.VID_SYSLOG_MSG_BASE
;
625 for(int i
= 0; i
< count
; i
++)
627 SyslogRecord record
= new SyslogRecord(msg
, varId
);
628 sendNotification(new SessionNotification(SessionNotification
.NEW_SYSLOG_RECORD
, order
, record
));
633 * Process CMD_NOTIFY message
635 * @param msg NXCP message
637 private void processNotificationMessage(final NXCPMessage msg
, boolean shiftCode
)
639 int code
= msg
.getFieldAsInt32(NXCPCodes
.VID_NOTIFICATION_CODE
);
641 code
+= SessionNotification
.NOTIFY_BASE
;
642 long data
= msg
.getFieldAsInt64(NXCPCodes
.VID_NOTIFICATION_DATA
);
646 case SessionNotification
.ALARM_STATUS_FLOW_CHANGED
:
647 strictAlarmStatusFlow
= ((int)data
!= 0);
649 case SessionNotification
.RELOAD_EVENT_DB
:
650 if (eventTemplatesNeedSync
)
652 resyncEventTemplates();
657 sendNotification(new SessionNotification(code
, data
));
661 * Process CMD_FILE_MONITORING message
663 * @param msg NXCP message
665 private void processFileTail(final NXCPMessage msg
)
667 String fileName
= msg
.getFieldAsString(NXCPCodes
.VID_FILE_NAME
);
668 String fileContent
= msg
.getFieldAsString(NXCPCodes
.VID_FILE_DATA
);
670 synchronized(recievedUpdates
)
672 recievedUpdates
.put(fileName
, fileContent
);
673 recievedUpdates
.notifyAll();
682 private void processFileData(final NXCPMessage msg
)
684 long id
= msg
.getMessageId();
685 NXCReceivedFile file
;
686 synchronized(receivedFiles
)
688 file
= receivedFiles
.get(id
);
691 file
= new NXCReceivedFile(id
);
692 receivedFiles
.put(id
, file
);
695 file
.writeData(msg
.getBinaryData());
696 if (msg
.isEndOfFile())
699 synchronized(receivedFiles
)
701 receivedFiles
.notifyAll();
707 * Process file transfer error
711 private void processFileTransferError(final NXCPMessage msg
)
713 long id
= msg
.getMessageId();
714 NXCReceivedFile file
;
715 synchronized(receivedFiles
)
717 file
= receivedFiles
.get(id
);
720 file
= new NXCReceivedFile(id
);
721 receivedFiles
.put(id
, file
);
723 file
.abortTransfer();
724 receivedFiles
.notifyAll();
729 * Process updates in user database
731 * @param msg Notification message
733 private void processUserDBUpdate(final NXCPMessage msg
)
735 final int code
= msg
.getFieldAsInt32(NXCPCodes
.VID_UPDATE_TYPE
);
736 final long id
= msg
.getFieldAsInt64(NXCPCodes
.VID_USER_ID
);
738 AbstractUserObject object
= null;
741 case SessionNotification
.USER_DB_OBJECT_CREATED
:
742 case SessionNotification
.USER_DB_OBJECT_MODIFIED
:
743 object
= ((id
& 0x80000000) != 0) ?
new UserGroup(msg
) : new User(msg
);
746 userDB
.put(id
, object
);
749 case SessionNotification
.USER_DB_OBJECT_DELETED
:
752 object
= userDB
.get(id
);
761 // Send notification if changed object was found in local database copy
762 // or added to it and notification code was known
764 sendNotification(new SessionNotification(SessionNotification
.USER_DB_CHANGED
, code
, object
));
768 * Process server notification on SNMP trap configuration change
770 * @param msg notification message
772 private void processTrapConfigChange(final NXCPMessage msg
)
774 int code
= msg
.getFieldAsInt32(NXCPCodes
.VID_NOTIFICATION_CODE
) + SessionNotification
.NOTIFY_BASE
;
775 long id
= msg
.getFieldAsInt64(NXCPCodes
.VID_TRAP_ID
);
776 SnmpTrap trap
= (code
!= SessionNotification
.TRAP_CONFIGURATION_DELETED
) ?
new SnmpTrap(msg
) : null;
777 sendNotification(new SessionNotification(code
, id
, trap
));
781 * Process server notification on situation object change
783 * @param msg notification message
785 private void processSituationChange(final NXCPMessage msg
)
787 int code
= msg
.getFieldAsInt32(NXCPCodes
.VID_NOTIFICATION_CODE
) + SessionNotification
.SITUATION_BASE
;
788 Situation s
= new Situation(msg
);
789 sendNotification(new SessionNotification(code
, s
.getId(), s
));
793 * Process server notification on action configuration change
795 * @param msg notification message
797 private void processActionConfigChange(final NXCPMessage msg
)
799 int code
= msg
.getFieldAsInt32(NXCPCodes
.VID_NOTIFICATION_CODE
) + SessionNotification
.NOTIFY_BASE
;
800 long id
= msg
.getFieldAsInt64(NXCPCodes
.VID_ACTION_ID
);
801 ServerAction action
= (code
!= SessionNotification
.ACTION_DELETED
) ?
new ServerAction(msg
) : null;
802 sendNotification(new SessionNotification(code
, id
, action
));
806 * Process server notification on event configuration change
808 * @param msg notification message
810 private void processEventConfigChange(final NXCPMessage msg
)
812 int code
= msg
.getFieldAsInt32(NXCPCodes
.VID_NOTIFICATION_CODE
) + SessionNotification
.NOTIFY_BASE
;
813 long eventCode
= msg
.getFieldAsInt64(NXCPCodes
.VID_EVENT_CODE
);
814 EventTemplate et
= (code
!= SessionNotification
.EVENT_TEMPLATE_DELETED
) ?
new EventTemplate(msg
) : null;
815 if (eventTemplatesNeedSync
)
817 synchronized(eventTemplates
)
819 if (code
== SessionNotification
.EVENT_TEMPLATE_DELETED
)
821 eventTemplates
.remove(eventCode
);
825 eventTemplates
.put(eventCode
, et
);
829 sendNotification(new SessionNotification(code
, eventCode
, et
));
833 * Process server notification on image library change
835 * @param msg notification message
837 public void processImageLibraryUpdate(NXCPMessage msg
)
839 final UUID imageGuid
= msg
.getFieldAsUUID(NXCPCodes
.VID_GUID
);
840 final int flags
= msg
.getFieldAsInt32(NXCPCodes
.VID_FLAGS
);
841 sendNotification(new SessionNotification(SessionNotification
.IMAGE_LIBRARY_CHANGED
,
842 flags
== 0 ? SessionNotification
.IMAGE_UPDATED
: SessionNotification
.IMAGE_DELETED
, imageGuid
));
847 * Housekeeper thread - cleans received files, etc.
851 private class HousekeeperThread
extends Thread
853 private boolean stopFlag
= false;
864 * @see java.lang.Thread#run()
875 catch(InterruptedException e
)
879 long currTime
= System
.currentTimeMillis();
881 // Check for old entries in received files
882 synchronized(receivedFiles
)
884 Iterator
<NXCReceivedFile
> it
= receivedFiles
.values().iterator();
887 NXCReceivedFile file
= it
.next();
888 if (file
.getTimestamp() + RECEIVED_FILE_TTL
< currTime
)
890 file
.getFile().delete();
896 // Check timeouts on message subscriptions
897 synchronized(messageSubscriptions
)
899 Iterator
<Entry
<MessageSubscription
, MessageHandler
>> it
= messageSubscriptions
.entrySet().iterator();
902 Entry
<MessageSubscription
, MessageHandler
> e
= it
.next();
903 MessageHandler h
= e
.getValue();
904 if (currTime
- h
.getLastMessageTimestamp() > h
.getMessageWaitTimeout())
916 * @param stopFlag the stopFlag to set
918 public void setStopFlag(boolean stopFlag
)
920 this.stopFlag
= stopFlag
;
925 * Notification processor
927 private class NotificationProcessor
extends Thread
929 private SessionListener
[] cachedListenerList
= new SessionListener
[0];
931 NotificationProcessor()
933 setName("Session Notification Processor");
939 * @see java.lang.Thread#run()
946 SessionNotification n
;
949 n
= notificationQueue
.take();
951 catch(InterruptedException e
)
956 if (n
.getCode() == SessionNotification
.STOP_PROCESSING_THREAD
)
959 if (n
.getCode() == SessionNotification
.UPDATE_LISTENER_LIST
)
961 synchronized(listeners
)
963 cachedListenerList
= listeners
.toArray(new SessionListener
[listeners
.size()]);
968 // loop must be on listeners set copy to prevent
969 // possible deadlock when one of the listeners calls
970 // syncExec on UI thread while UI thread trying to add
971 // new listener and stays locked inside addListener
972 for(SessionListener l
: cachedListenerList
)
976 l
.notificationHandler(n
);
980 Logger
.error("NXCSession.NotificationProcessor", "Unhandled exception in notification handler", e
);
989 * @param connLoginName
990 * @param connPassword
992 public NXCSession(String connAddress
)
994 this(connAddress
, DEFAULT_CONN_PORT
, false);
1000 * @param connLoginName
1001 * @param connPassword
1003 public NXCSession(String connAddress
, int connPort
)
1005 this(connAddress
, connPort
, false);
1009 * @param connAddress
1011 * @param connLoginName
1012 * @param connPassword
1013 * @param connUseEncryption
1015 public NXCSession(String connAddress
, int connPort
, boolean connUseEncryption
)
1017 this.connAddress
= connAddress
;
1018 this.connPort
= connPort
;
1019 this.connUseEncryption
= connUseEncryption
;
1023 * @see java.lang.Object#finalize()
1026 protected void finalize() throws Throwable
1039 * Create custom object from NXCP message. May be overridden by derived classes to create custom
1040 * NetXMS objects. This method called before standard object creation, so it can be used for
1041 * overriding standard object classes. If this method returns null, standard object
1042 * creation mechanism will be used. Default implementation will always return null.
1044 * @param objectClass NetXMS object class ID
1045 * @param msg Source NXCP message
1046 * @return NetXMS object or null if object cannot be created
1048 protected AbstractObject
createCustomObjectFromMessage(int objectClass
, NXCPMessage msg
)
1054 * Create object from message
1056 * @param msg Source NXCP message
1057 * @return NetXMS object
1059 private AbstractObject
createObjectFromMessage(NXCPMessage msg
)
1061 final int objectClass
= msg
.getFieldAsInt32(NXCPCodes
.VID_OBJECT_CLASS
);
1063 AbstractObject object
= createCustomObjectFromMessage(objectClass
, msg
);
1069 case AbstractObject
.OBJECT_ACCESSPOINT
:
1070 object
= new AccessPoint(msg
, this);
1072 case AbstractObject
.OBJECT_AGENTPOLICY
:
1073 object
= new AgentPolicy(msg
, this);
1075 case AbstractObject
.OBJECT_AGENTPOLICY_CONFIG
:
1076 object
= new AgentPolicyConfig(msg
, this);
1078 case AbstractObject
.OBJECT_AGENTPOLICY_LOGPARSER
:
1079 object
= new AgentPolicyLogParser(msg
, this);
1081 case AbstractObject
.OBJECT_BUSINESSSERVICE
:
1082 object
= new BusinessService(msg
, this);
1084 case AbstractObject
.OBJECT_BUSINESSSERVICEROOT
:
1085 object
= new BusinessServiceRoot(msg
, this);
1087 case AbstractObject
.OBJECT_CHASSIS
:
1088 object
= new Chassis(msg
, this);
1090 case AbstractObject
.OBJECT_CLUSTER
:
1091 object
= new Cluster(msg
, this);
1093 case AbstractObject
.OBJECT_CONDITION
:
1094 object
= new Condition(msg
, this);
1096 case AbstractObject
.OBJECT_CONTAINER
:
1097 object
= new Container(msg
, this);
1099 case AbstractObject
.OBJECT_DASHBOARD
:
1100 object
= new Dashboard(msg
, this);
1102 case AbstractObject
.OBJECT_DASHBOARDROOT
:
1103 object
= new DashboardRoot(msg
, this);
1105 case AbstractObject
.OBJECT_INTERFACE
:
1106 object
= new Interface(msg
, this);
1108 case AbstractObject
.OBJECT_MOBILEDEVICE
:
1109 object
= new MobileDevice(msg
, this);
1111 case AbstractObject
.OBJECT_NETWORK
:
1112 object
= new EntireNetwork(msg
, this);
1114 case AbstractObject
.OBJECT_NETWORKMAP
:
1115 object
= new NetworkMap(msg
, this);
1117 case AbstractObject
.OBJECT_NETWORKMAPGROUP
:
1118 object
= new NetworkMapGroup(msg
, this);
1120 case AbstractObject
.OBJECT_NETWORKMAPROOT
:
1121 object
= new NetworkMapRoot(msg
, this);
1123 case AbstractObject
.OBJECT_NETWORKSERVICE
:
1124 object
= new NetworkService(msg
, this);
1126 case AbstractObject
.OBJECT_NODE
:
1127 object
= new Node(msg
, this);
1129 case AbstractObject
.OBJECT_NODELINK
:
1130 object
= new NodeLink(msg
, this);
1132 case AbstractObject
.OBJECT_POLICYGROUP
:
1133 object
= new PolicyGroup(msg
, this);
1135 case AbstractObject
.OBJECT_POLICYROOT
:
1136 object
= new PolicyRoot(msg
, this);
1138 case AbstractObject
.OBJECT_RACK
:
1139 object
= new Rack(msg
, this);
1141 case AbstractObject
.OBJECT_SERVICEROOT
:
1142 object
= new ServiceRoot(msg
, this);
1144 case AbstractObject
.OBJECT_SLMCHECK
:
1145 object
= new ServiceCheck(msg
, this);
1147 case AbstractObject
.OBJECT_SUBNET
:
1148 object
= new Subnet(msg
, this);
1150 case AbstractObject
.OBJECT_TEMPLATE
:
1151 object
= new Template(msg
, this);
1153 case AbstractObject
.OBJECT_TEMPLATEGROUP
:
1154 object
= new TemplateGroup(msg
, this);
1156 case AbstractObject
.OBJECT_TEMPLATEROOT
:
1157 object
= new TemplateRoot(msg
, this);
1159 case AbstractObject
.OBJECT_VPNCONNECTOR
:
1160 object
= new VPNConnector(msg
, this);
1162 case AbstractObject
.OBJECT_ZONE
:
1163 object
= new Zone(msg
, this);
1166 object
= new GenericObject(msg
, this);
1176 * @param msg CMD_REQUEST_SESSION_KEY message
1177 * @throws IOException
1178 * @throws NXCException
1180 private void setupEncryption(NXCPMessage msg
) throws IOException
, NXCException
1182 final NXCPMessage response
= new NXCPMessage(NXCPCodes
.CMD_SESSION_KEY
, msg
.getMessageId());
1183 response
.setEncryptionDisabled(true);
1187 encryptionContext
= EncryptionContext
.createInstance(msg
);
1188 response
.setField(NXCPCodes
.VID_SESSION_KEY
, encryptionContext
.getEncryptedSessionKey(msg
));
1189 response
.setField(NXCPCodes
.VID_SESSION_IV
, encryptionContext
.getEncryptedIv(msg
));
1190 response
.setFieldInt16(NXCPCodes
.VID_CIPHER
, encryptionContext
.getCipher());
1191 response
.setFieldInt16(NXCPCodes
.VID_KEY_LENGTH
, encryptionContext
.getKeyLength());
1192 response
.setFieldInt16(NXCPCodes
.VID_IV_LENGTH
, encryptionContext
.getIvLength());
1193 response
.setFieldInt32(NXCPCodes
.VID_RCC
, RCC
.SUCCESS
);
1194 Logger
.debug("NXCSession.setupEncryption", "Cipher selected: " + EncryptionContext
.getCipherName(encryptionContext
.getCipher()));
1198 response
.setFieldInt32(NXCPCodes
.VID_RCC
, RCC
.NO_CIPHERS
);
1201 sendMessage(response
);
1205 * Wait for synchronization completion
1207 private void waitForSync(final Semaphore syncObject
, final int timeout
) throws NXCException
1211 syncObject
.acquireUninterruptibly();
1215 long actualTimeout
= timeout
;
1216 boolean success
= false;
1218 while(actualTimeout
> 0)
1220 long startTime
= System
.currentTimeMillis();
1223 if (syncObjects
.tryAcquire(actualTimeout
, TimeUnit
.MILLISECONDS
))
1226 syncObjects
.release();
1230 catch(InterruptedException e
)
1233 actualTimeout
-= System
.currentTimeMillis() - startTime
;
1235 if (!success
) throw new NXCException(RCC
.TIMEOUT
);
1240 * Report synchronization completion
1242 * @param syncObject Synchronization object
1244 private void completeSync(final Semaphore syncObject
)
1246 syncObject
.release();
1250 * Add notification listener
1252 * @param listener Listener to add
1254 public void addListener(SessionListener listener
)
1257 synchronized(listeners
)
1259 changed
= listeners
.add(listener
);
1262 notificationQueue
.offer(new SessionNotification(SessionNotification
.UPDATE_LISTENER_LIST
));
1266 * Remove notification listener
1268 * @param listener Listener to remove
1270 public void removeListener(SessionListener listener
)
1273 synchronized(listeners
)
1275 changed
= listeners
.remove(listener
);
1278 notificationQueue
.offer(new SessionNotification(SessionNotification
.UPDATE_LISTENER_LIST
));
1282 * Add server console listener
1286 public void addConsoleListener(ServerConsoleListener listener
)
1288 synchronized(consoleListeners
)
1290 consoleListeners
.add(listener
);
1295 * Remove server console listener
1299 public void removeConsoleListener(ServerConsoleListener listener
)
1301 synchronized(consoleListeners
)
1303 consoleListeners
.remove(listener
);
1308 * Subscribe to specific messages
1310 * @param messageCode
1314 public void addMessageSubscription(int messageCode
, long messageId
, MessageHandler handler
)
1316 synchronized(messageSubscriptions
)
1318 messageSubscriptions
.put(new MessageSubscription(messageCode
, messageId
), handler
);
1323 * @param messageCode
1326 public void removeMessageSubscription(int messageCode
, long messageId
)
1328 synchronized(messageSubscriptions
)
1330 messageSubscriptions
.remove(new MessageSubscription(messageCode
, messageId
));
1335 * Call notification handlers on all registered listeners
1337 * @param n Notification object
1339 protected void sendNotification(SessionNotification n
)
1341 if (!notificationQueue
.offer(n
))
1343 Logger
.debug("NXCSession.sendNotification", "Notification processing queue is full");
1348 * Send message to server
1350 * @param msg Message to sent
1351 * @throws IOException in case of socket communication failure
1352 * @throws NXCException in case of encryption error
1354 public synchronized void sendMessage(final NXCPMessage msg
) throws IOException
, NXCException
1358 throw new IllegalStateException("Not connected to the server. Did you forgot to call connect() first?");
1360 final OutputStream outputStream
= socket
.getOutputStream();
1362 if ((encryptionContext
!= null) && !msg
.isEncryptionDisabled())
1366 message
= encryptionContext
.encryptMessage(msg
);
1368 catch(GeneralSecurityException e
)
1370 throw new NXCException(RCC
.ENCRYPTION_ERROR
);
1375 message
= msg
.createNXCPMessage();
1377 outputStream
.write(message
);
1381 * Send file over CSCP
1384 * @param file source file to be sent
1385 * @throws IOException
1386 * @throws NXCException
1388 protected void sendFile(final long requestId
, final File file
, ProgressListener listener
)
1389 throws IOException
, NXCException
1391 if (listener
!= null)
1392 listener
.setTotalWorkAmount(file
.length());
1393 final InputStream inputStream
= new BufferedInputStream(new FileInputStream(file
));
1394 sendFileStream(requestId
, inputStream
, listener
);
1395 inputStream
.close();
1399 * Send block of data as binary message
1403 * @throws IOException
1404 * @throws NXCException
1406 protected void sendFile(final long requestId
, final byte[] data
, ProgressListener listener
) throws IOException
, NXCException
1408 if (listener
!= null)
1409 listener
.setTotalWorkAmount(data
.length
);
1410 final InputStream inputStream
= new ByteArrayInputStream(data
);
1411 sendFileStream(requestId
, inputStream
, listener
);
1412 inputStream
.close();
1416 * Send binary message, data loaded from provided input stream and splitted
1417 * into chunks of {@value FILE_BUFFER_SIZE} bytes
1420 * @param inputStream
1421 * @throws IOException
1422 * @throws NXCException
1424 private void sendFileStream(final long requestId
, final InputStream inputStream
, ProgressListener listener
) throws IOException
, NXCException
1426 NXCPMessage msg
= new NXCPMessage(NXCPCodes
.CMD_FILE_DATA
, requestId
);
1427 msg
.setBinaryMessage(true);
1429 boolean success
= false;
1430 final byte[] buffer
= new byte[FILE_BUFFER_SIZE
];
1434 final int bytesRead
= inputStream
.read(buffer
);
1435 if (bytesRead
< FILE_BUFFER_SIZE
)
1437 msg
.setEndOfFile(true);
1440 msg
.setBinaryData(bytesRead
== -1 ?
new byte[0] : Arrays
.copyOf(buffer
, bytesRead
));
1443 bytesSent
+= bytesRead
== -1 ?
0 : bytesRead
;
1444 if (listener
!= null)
1445 listener
.markProgress(bytesSent
);
1447 if (bytesRead
< FILE_BUFFER_SIZE
)
1456 NXCPMessage abortMessage
= new NXCPMessage(NXCPCodes
.CMD_ABORT_FILE_TRANSFER
, requestId
);
1457 abortMessage
.setBinaryMessage(true);
1458 sendMessage(abortMessage
);
1459 waitForRCC(abortMessage
.getMessageId());
1464 * Wait for message with specific code and id.
1471 * Wait timeout in milliseconds
1472 * @return Message object
1473 * @throws NXCException
1474 * if message was not arrived within timeout interval
1476 public NXCPMessage
waitForMessage(final int code
, final long id
, final int timeout
) throws NXCException
1478 final NXCPMessage msg
= msgWaitQueue
.waitForMessage(code
, id
, timeout
);
1480 throw new NXCException(RCC
.TIMEOUT
);
1485 * Wait for message with specific code and id.
1491 * @return Message object
1492 * @throws NXCException
1493 * if message was not arrived within timeout interval
1495 public NXCPMessage
waitForMessage(final int code
, final long id
) throws NXCException
1497 final NXCPMessage msg
= msgWaitQueue
.waitForMessage(code
, id
);
1499 throw new NXCException(RCC
.TIMEOUT
);
1504 * Wait for CMD_REQUEST_COMPLETED message with given id using default timeout
1508 * @return received message
1509 * @throws NXCException
1510 * if message was not arrived within timeout interval or contains RCC other than RCC.SUCCESS
1512 public NXCPMessage
waitForRCC(final long id
) throws NXCException
1514 return waitForRCC(id
, msgWaitQueue
.getDefaultTimeout());
1518 * Wait for CMD_REQUEST_COMPLETED message with given id
1522 * @param timeout Timeout in milliseconds
1523 * @return received message
1524 * @throws NXCException
1525 * if message was not arrived within timeout interval or contains RCC other than RCC.SUCCESS
1527 public NXCPMessage
waitForRCC(final long id
, final int timeout
) throws NXCException
1529 final NXCPMessage msg
= waitForMessage(NXCPCodes
.CMD_REQUEST_COMPLETED
, id
, timeout
);
1530 final int rcc
= msg
.getFieldAsInt32(NXCPCodes
.VID_RCC
);
1531 if (rcc
!= RCC
.SUCCESS
)
1533 if ((rcc
== RCC
.COMPONENT_LOCKED
) && (msg
.findField(NXCPCodes
.VID_LOCKED_BY
) != null))
1535 throw new NXCException(rcc
, msg
.getFieldAsString(NXCPCodes
.VID_LOCKED_BY
));
1537 else if (msg
.findField(NXCPCodes
.VID_ERROR_TEXT
) != null)
1539 throw new NXCException(rcc
, msg
.getFieldAsString(NXCPCodes
.VID_ERROR_TEXT
));
1541 else if (msg
.findField(NXCPCodes
.VID_VALUE
) != null)
1543 throw new NXCException(rcc
, msg
.getFieldAsString(NXCPCodes
.VID_VALUE
));
1547 throw new NXCException(rcc
);
1554 * Create new NXCP message with unique id
1558 * @return New message object
1560 public final NXCPMessage
newMessage(int code
)
1562 return new NXCPMessage(code
, requestId
.getAndIncrement());
1566 * Wait for specific file to arrive
1568 * @param id Message ID
1569 * @param timeout Wait timeout in milliseconds
1570 * @return Received file or null in case of failure
1572 public File
waitForFile(final long id
, final int timeout
)
1574 int timeRemaining
= timeout
;
1577 while(timeRemaining
> 0)
1579 synchronized(receivedFiles
)
1581 NXCReceivedFile rf
= receivedFiles
.get(id
);
1584 if (rf
.getStatus() != NXCReceivedFile
.OPEN
)
1586 if (rf
.getStatus() == NXCReceivedFile
.RECEIVED
)
1587 file
= rf
.getFile();
1592 long startTime
= System
.currentTimeMillis();
1595 receivedFiles
.wait(timeRemaining
);
1597 catch(InterruptedException e
)
1600 timeRemaining
-= System
.currentTimeMillis() - startTime
;
1607 * Wait for specific file tail to arrive
1609 * @param fileName Waiting file name
1610 * @param timeout Wait timeout in milliseconds
1611 * @return Received tail string or null in case of failure
1613 public String
waitForFileTail(String fileName
, final int timeout
)
1615 int timeRemaining
= timeout
;
1618 while(timeRemaining
> 0)
1620 synchronized(recievedUpdates
)
1622 tail
= recievedUpdates
.get(fileName
);
1625 recievedUpdates
.remove(fileName
);
1629 long startTime
= System
.currentTimeMillis();
1632 recievedUpdates
.wait(timeRemaining
);
1634 catch(InterruptedException e
)
1637 timeRemaining
-= System
.currentTimeMillis() - startTime
;
1644 * Execute simple commands (without arguments and only returning RCC)
1646 * @param command Command code
1647 * @throws IOException
1648 * @throws NXCException
1650 protected void executeSimpleCommand(int command
) throws IOException
, NXCException
1652 final NXCPMessage msg
= newMessage(command
);
1654 waitForRCC(msg
.getMessageId());
1658 * Receive table from server.
1660 * @param requestId request ID
1661 * @param msgCode Message code
1662 * @return Received table
1663 * @throws NXCException if operation was timed out
1665 public Table
receiveTable(long requestId
, int msgCode
) throws NXCException
1667 NXCPMessage msg
= waitForMessage(msgCode
, requestId
);
1668 Table table
= new Table(msg
);
1669 while(!msg
.isEndOfSequence())
1671 msg
= waitForMessage(msgCode
, requestId
);
1672 table
.addDataFromMessage(msg
);
1678 * Connect to NetMS server. Establish connection with the server and set up encryption if required.
1679 * Only base protocol version check will be performed. Login must be performed before using session
1680 * after successful connect.
1682 * @throws IOException
1683 * @throws UnknownHostException
1684 * @throws NXCException
1685 * @throws IllegalStateException
1687 public void connect() throws IOException
, UnknownHostException
, NXCException
, IllegalStateException
1693 * Connect to NetMS server. Establish connection with the server and set up encryption if required.
1694 * Versions of protocol components given in *componentVersions* will be validated. Login must be
1695 * performed before using session after successful connect.
1697 * @param componentVersions
1698 * @throws IOException
1699 * @throws UnknownHostException
1700 * @throws NXCException
1701 * @throws IllegalStateException
1703 public void connect(int[] componentVersions
) throws IOException
, UnknownHostException
, NXCException
, IllegalStateException
1706 throw new IllegalStateException("Session already connected");
1709 throw new IllegalStateException("Session already disconnected and cannot be reused");
1711 encryptionContext
= null;
1712 Logger
.info("NXCSession.connect", "Connecting to " + connAddress
+ ":" + connPort
);
1715 socket
= new Socket();
1716 socket
.connect(new InetSocketAddress(connAddress
, connPort
), connectTimeout
);
1717 msgWaitQueue
= new NXCPMsgWaitQueue(commandTimeout
);
1718 recvThread
= new ReceiverThread();
1719 housekeeperThread
= new HousekeeperThread();
1720 new NotificationProcessor();
1722 // get server information
1723 Logger
.debug("NXCSession.connect", "connection established, retrieving server info");
1724 NXCPMessage request
= newMessage(NXCPCodes
.CMD_GET_SERVER_INFO
);
1725 sendMessage(request
);
1726 NXCPMessage response
= waitForMessage(NXCPCodes
.CMD_REQUEST_COMPLETED
, request
.getMessageId());
1728 protocolVersion
= new ProtocolVersion(response
);
1729 if (!ignoreProtocolVersion
)
1731 if (!protocolVersion
.isCorrectVersion(ProtocolVersion
.INDEX_BASE
) ||
1732 ((componentVersions
!= null) && !validateProtocolVersions(componentVersions
)))
1734 Logger
.warning("NXCSession.connect", "connection failed (" + protocolVersion
.toString() + ")");
1735 throw new NXCException(RCC
.BAD_PROTOCOL
);
1740 Logger
.debug("NXCSession.connect", "protocol version ignored");
1743 serverVersion
= response
.getFieldAsString(NXCPCodes
.VID_SERVER_VERSION
);
1744 serverId
= response
.getFieldAsInt64(NXCPCodes
.VID_SERVER_ID
);
1745 serverTimeZone
= response
.getFieldAsString(NXCPCodes
.VID_TIMEZONE
);
1746 serverTime
= response
.getFieldAsInt64(NXCPCodes
.VID_TIMESTAMP
) * 1000;
1747 serverTimeRecvTime
= System
.currentTimeMillis();
1748 serverChallenge
= response
.getFieldAsBinary(NXCPCodes
.VID_CHALLENGE
);
1750 tileServerURL
= response
.getFieldAsString(NXCPCodes
.VID_TILE_SERVER_URL
);
1751 if (tileServerURL
!= null)
1753 if (!tileServerURL
.endsWith("/")) tileServerURL
= tileServerURL
.concat("/");
1757 tileServerURL
= "http://tile.openstreetmap.org/";
1760 dateFormat
= response
.getFieldAsString(NXCPCodes
.VID_DATE_FORMAT
);
1761 if ((dateFormat
== null) || (dateFormat
.length() == 0))
1762 dateFormat
= "dd.MM.yyyy";
1764 timeFormat
= response
.getFieldAsString(NXCPCodes
.VID_TIME_FORMAT
);
1765 if ((timeFormat
== null) || (timeFormat
.length() == 0))
1766 timeFormat
= "HH:mm:ss";
1768 shortTimeFormat
= response
.getFieldAsString(NXCPCodes
.VID_SHORT_TIME_FORMAT
);
1769 if ((shortTimeFormat
== null) || (shortTimeFormat
.length() == 0))
1770 shortTimeFormat
= "HH:mm";
1772 // Setup encryption if required
1773 if (connUseEncryption
)
1775 request
= newMessage(NXCPCodes
.CMD_REQUEST_ENCRYPTION
);
1776 request
.setFieldInt16(NXCPCodes
.VID_USE_X509_KEY_FORMAT
, 1);
1777 sendMessage(request
);
1778 waitForRCC(request
.getMessageId());
1781 Logger
.debug("NXCSession.connect", "Connected to server version " + serverVersion
);
1792 * Login to server using login name and password.
1794 * @param login login name
1795 * @param password password
1796 * @throws NXCException
1797 * @throws IOException
1798 * @throws IllegalStateException
1800 public void login(String login
, String password
) throws NXCException
, IOException
, IllegalStateException
1802 login(AuthenticationType
.PASSWORD
, login
, password
, null, null);
1806 * Login to server using certificate.
1808 * @param authType authentication type
1809 * @param login login name
1810 * @param certificate user's certificate
1811 * @param signature user's digital signature
1812 * @throws NXCException
1813 * @throws IOException
1814 * @throws IllegalStateException
1816 public void login(String login
, Certificate certificate
, Signature signature
) throws NXCException
, IOException
, IllegalStateException
1818 login(AuthenticationType
.CERTIFICATE
, login
, null, certificate
, signature
);
1824 * @param authType authentication type
1825 * @param login login name
1826 * @param password password
1827 * @param certificate user's certificate
1828 * @param signature user's digital signature
1829 * @throws NXCException
1830 * @throws IOException
1831 * @throws IllegalStateException
1833 public void login(AuthenticationType authType
, String login
, String password
, Certificate certificate
, Signature signature
) throws NXCException
, IOException
, IllegalStateException
1836 throw new IllegalStateException("Session not connected");
1839 throw new IllegalStateException("Session already disconnected and cannot be reused");
1841 authenticationMethod
= authType
;
1844 final NXCPMessage request
= newMessage(NXCPCodes
.CMD_LOGIN
);
1845 request
.setFieldInt16(NXCPCodes
.VID_AUTH_TYPE
, authType
.getValue());
1846 request
.setField(NXCPCodes
.VID_LOGIN_NAME
, login
);
1848 if ((authType
== AuthenticationType
.PASSWORD
) || (authType
== AuthenticationType
.SSO_TICKET
))
1850 request
.setField(NXCPCodes
.VID_PASSWORD
, password
);
1852 else if (authType
== AuthenticationType
.CERTIFICATE
)
1854 if ((serverChallenge
== null) || (signature
== null) || (certificate
== null))
1856 throw new NXCException(RCC
.ENCRYPTION_ERROR
);
1858 byte[] signedChallenge
= signChallenge(signature
, serverChallenge
);
1859 request
.setField(NXCPCodes
.VID_SIGNATURE
, signedChallenge
);
1862 request
.setField(NXCPCodes
.VID_CERTIFICATE
, certificate
.getEncoded());
1864 catch(CertificateEncodingException e
)
1866 throw new NXCException(RCC
.ENCRYPTION_ERROR
);
1870 request
.setField(NXCPCodes
.VID_LIBNXCL_VERSION
, NXCommon
.VERSION
);
1871 request
.setField(NXCPCodes
.VID_CLIENT_INFO
, connClientInfo
);
1872 request
.setField(NXCPCodes
.VID_OS_INFO
, System
.getProperty("os.name") + " " + System
.getProperty("os.version"));
1873 request
.setFieldInt16(NXCPCodes
.VID_CLIENT_TYPE
, clientType
);
1874 if (clientAddress
!= null)
1875 request
.setField(NXCPCodes
.VID_CLIENT_ADDRESS
, clientAddress
);
1876 if (clientLanguage
!= null)
1877 request
.setField(NXCPCodes
.VID_LANGUAGE
, clientLanguage
);
1878 sendMessage(request
);
1880 final NXCPMessage response
= waitForMessage(NXCPCodes
.CMD_LOGIN_RESP
, request
.getMessageId());
1881 int rcc
= response
.getFieldAsInt32(NXCPCodes
.VID_RCC
);
1882 Logger
.debug("NXCSession.connect", "CMD_LOGIN_RESP received, RCC=" + rcc
);
1883 if (rcc
!= RCC
.SUCCESS
)
1885 Logger
.warning("NXCSession.connect", "Login failed, RCC=" + rcc
);
1886 throw new NXCException(rcc
);
1888 userId
= response
.getFieldAsInt32(NXCPCodes
.VID_USER_ID
);
1889 sessionId
= response
.getFieldAsInt32(NXCPCodes
.VID_SESSION_ID
);
1890 userSystemRights
= response
.getFieldAsInt64(NXCPCodes
.VID_USER_SYS_RIGHTS
);
1891 passwordExpired
= response
.getFieldAsBoolean(NXCPCodes
.VID_CHANGE_PASSWD_FLAG
);
1892 zoningEnabled
= response
.getFieldAsBoolean(NXCPCodes
.VID_ZONING_ENABLED
);
1893 helpdeskLinkActive
= response
.getFieldAsBoolean(NXCPCodes
.VID_HELPDESK_LINK_ACTIVE
);
1895 defaultDciPollingInterval
= response
.getFieldAsInt32(NXCPCodes
.VID_POLLING_INTERVAL
);
1896 if (defaultDciPollingInterval
== 0)
1897 defaultDciPollingInterval
= 60;
1899 defaultDciRetentionTime
= response
.getFieldAsInt32(NXCPCodes
.VID_RETENTION_TIME
);
1900 if (defaultDciRetentionTime
== 0)
1901 defaultDciRetentionTime
= 30;
1903 minViewRefreshInterval
= response
.getFieldAsInt32(NXCPCodes
.VID_VIEW_REFRESH_INTERVAL
);
1904 if (minViewRefreshInterval
<= 0)
1905 minViewRefreshInterval
= 200;
1907 strictAlarmStatusFlow
= response
.getFieldAsBoolean(NXCPCodes
.VID_ALARM_STATUS_FLOW_STATE
);
1908 timedAlarmAckEnabled
= response
.getFieldAsBoolean(NXCPCodes
.VID_TIMED_ALARM_ACK_ENABLED
);
1910 serverCommandOutputTimeout
= response
.getFieldAsInt32(NXCPCodes
.VID_SERVERCMD_TIMEOUT
) * 1000;
1912 alarmListDisplayLimit
= response
.getFieldAsInt32(NXCPCodes
.VID_ALARM_LIST_DISP_LIMIT
);
1913 Logger
.info("NXCSession.connect", "alarmListDisplayLimit = " + alarmListDisplayLimit
);
1915 Logger
.info("NXCSession.connect", "succesfully logged in, userId=" + userId
);
1919 * Disconnect from server.
1921 public void disconnect()
1927 socket
.shutdownInput();
1928 socket
.shutdownOutput();
1930 catch(IOException e
)
1938 catch(IOException e
)
1943 // cause notification processing thread to stop
1944 notificationQueue
.clear();
1945 notificationQueue
.offer(new SessionNotification(SessionNotification
.STOP_PROCESSING_THREAD
));
1947 if (recvThread
!= null)
1949 while(recvThread
.isAlive())
1955 catch(InterruptedException e
)
1962 if (housekeeperThread
!= null)
1964 housekeeperThread
.setStopFlag(true);
1965 while(housekeeperThread
.isAlive())
1969 housekeeperThread
.join();
1971 catch(InterruptedException e
)
1975 housekeeperThread
= null;
1980 if (msgWaitQueue
!= null)
1982 msgWaitQueue
.shutdown();
1983 msgWaitQueue
= null;
1986 isConnected
= false;
1987 isDisconnected
= true;
1990 consoleListeners
.clear();
1991 messageSubscriptions
.clear();
1992 receivedFiles
.clear();
1993 recievedUpdates
.clear();
1997 * Get connection state
1998 * @return connection state
2000 public boolean isConnected()
2006 * Get encryption state for current session.
2008 * @return true if session is encrypted
2010 public boolean isEncrypted()
2012 return connUseEncryption
;
2018 public boolean isIgnoreProtocolVersion()
2020 return ignoreProtocolVersion
;
2024 * If set to true, protocol version is not checked at connect.
2026 * @param ignoreProtocolVersion
2028 public void setIgnoreProtocolVersion(boolean ignoreProtocolVersion
)
2030 this.ignoreProtocolVersion
= ignoreProtocolVersion
;
2034 * Validate protocol versions
2039 public boolean validateProtocolVersions(int[] versions
)
2041 if (protocolVersion
== null)
2043 for(int index
: versions
)
2044 if (!protocolVersion
.isCorrectVersion(index
))
2050 * Get default receiver buffer size.
2052 * @return Default receiver buffer size in bytes.
2054 public int getDefaultRecvBufferSize()
2056 return defaultRecvBufferSize
;
2060 * Get max receiver buffer size.
2062 * @return Max receiver buffer size in bytes.
2064 public int getMaxRecvBufferSize()
2066 return maxRecvBufferSize
;
2070 * Set receiver buffer size. This method should be called before connect(). It will not have any effect after
2073 * @param defaultBufferSize default size of receiver buffer in bytes.
2074 * @param maxBufferSize max size of receiver buffer in bytes.
2076 public void setRecvBufferSize(int defaultBufferSize
, int maxBufferSize
)
2078 this.defaultRecvBufferSize
= defaultBufferSize
;
2079 this.maxRecvBufferSize
= maxBufferSize
;
2083 * Get server address
2085 * @return Server address
2087 public String
getServerAddress()
2093 * Get NetXMS server version.
2095 * @return Server version
2097 public String
getServerVersion()
2099 return serverVersion
;
2103 * Get NetXMS server UID.
2105 * @return Server UID
2107 public long getServerId()
2113 * Get server time zone.
2115 * @return server's time zone string
2117 public String
getServerTimeZone()
2119 return serverTimeZone
;
2125 * @return the serverTime
2127 public long getServerTime()
2129 long offset
= System
.currentTimeMillis() - serverTimeRecvTime
;
2130 return serverTime
+ offset
;
2134 * @return the serverChallenge
2136 public byte[] getServerChallenge()
2138 return serverChallenge
;
2142 * @return the tileServerURL
2144 public String
getTileServerURL()
2146 return tileServerURL
;
2150 * @return the zoningEnabled
2152 public boolean isZoningEnabled()
2154 return zoningEnabled
;
2158 * Get status of helpdesk integration module on server.
2160 * @return true if helpdesk integration module loaded on server
2162 public boolean isHelpdeskLinkActive()
2164 return helpdeskLinkActive
;
2168 * Get client information string
2172 public String
getClientInfo()
2174 return connClientInfo
;
2178 * Set client information string
2180 * @param connClientInfo
2182 public void setClientInfo(final String connClientInfo
)
2184 this.connClientInfo
= connClientInfo
;
2188 * Set command execution timeout.
2190 * @param commandTimeout
2191 * New command timeout
2193 public void setCommandTimeout(final int commandTimeout
)
2195 this.commandTimeout
= commandTimeout
;
2199 * Set connect call timeout (must be set before connect call)
2201 * @param connectTimeout connect timeout in milliseconds
2203 public void setConnectTimeout(int connectTimeout
)
2205 this.connectTimeout
= connectTimeout
;
2209 * Get identifier of logged in user.
2211 * @return Identifier of logged in user
2213 public int getUserId()
2219 * @return the userName
2221 public String
getUserName()
2227 * @return the authenticationMethod
2229 public AuthenticationType
getAuthenticationMethod()
2231 return authenticationMethod
;
2235 * Get system-wide rights of currently logged in user.
2237 * @return System-wide rights of currently logged in user
2239 public long getUserSystemRights()
2241 return userSystemRights
;
2245 * Check if password is expired for currently logged in user.
2247 * @return true if password is expired
2249 public boolean isPasswordExpired()
2251 return passwordExpired
;
2255 * Get maximum number of records allowed to be displayed in alarm list
2257 public int getAlarmListDisplayLimit()
2259 return alarmListDisplayLimit
;
2263 * Synchronizes NetXMS objects between server and client. After successful
2264 * sync, subscribe client to object change notifications.
2266 * @throws IOException if socket I/O error occurs
2267 * @throws NXCException if NetXMS server returns an error or operation was timed out
2269 public synchronized void syncObjects() throws IOException
, NXCException
2271 syncObjects
.acquireUninterruptibly();
2272 NXCPMessage msg
= newMessage(NXCPCodes
.CMD_GET_OBJECTS
);
2273 msg
.setFieldInt16(NXCPCodes
.VID_SYNC_COMMENTS
, 1);
2275 waitForRCC(msg
.getMessageId());
2276 waitForSync(syncObjects
, commandTimeout
* 10);
2277 objectsSynchronized
= true;
2278 sendNotification(new SessionNotification(SessionNotification
.OBJECT_SYNC_COMPLETED
));
2279 subscribe(CHANNEL_OBJECTS
);
2283 * Synchronizes selected object set with the server.
2285 * @param objects identifiers of objects need to be synchronized
2286 * @param syncComments if true, comments for objects will be synchronized as well
2287 * @throws IOException if socket I/O error occurs
2288 * @throws NXCException if NetXMS server returns an error or operation was timed out
2290 public void syncObjectSet(long[] objects
, boolean syncComments
) throws IOException
, NXCException
2292 syncObjectSet(objects
, syncComments
, 0);
2296 * Synchronizes selected object set with the server. The following options are accepted:
2297 * OBJECT_SYNC_NOTIFY - send object update notification for each received object
2298 * OBJECT_SYNC_WAIT - wait until all requested objects received
2300 * @param objects identifiers of objects need to be synchronized
2301 * @param syncComments if true, comments for objects will be synchronized as well
2302 * @param options sync options (see above)
2303 * @throws IOException if socket I/O error occurs
2304 * @throws NXCException if NetXMS server returns an error or operation was timed out
2306 public void syncObjectSet(long[] objects
, boolean syncComments
, int options
) throws IOException
, NXCException
2308 NXCPMessage msg
= newMessage(NXCPCodes
.CMD_GET_SELECTED_OBJECTS
);
2309 msg
.setFieldInt16(NXCPCodes
.VID_SYNC_COMMENTS
, syncComments ?
1 : 0);
2310 msg
.setFieldInt16(NXCPCodes
.VID_FLAGS
, options
);
2311 msg
.setFieldInt32(NXCPCodes
.VID_NUM_OBJECTS
, objects
.length
);
2312 msg
.setField(NXCPCodes
.VID_OBJECT_LIST
, objects
);
2314 waitForRCC(msg
.getMessageId());
2316 if ((options
& OBJECT_SYNC_WAIT
) != 0) waitForRCC(msg
.getMessageId());
2320 * Synchronize only those objects from given set which are not synchronized yet.
2322 * @param objects identifiers of objects need to be synchronized
2323 * @param syncComments if true, comments for objects will be synchronized as well
2324 * @throws IOException if socket I/O error occurs
2325 * @throws NXCException if NetXMS server returns an error or operation was timed out
2327 public void syncMissingObjects(long[] objects
, boolean syncComments
) throws IOException
, NXCException
2329 syncMissingObjects(objects
, syncComments
, 0);
2333 * Synchronize only those objects from given set which are not synchronized yet.
2334 * Accepts all options which are valid for syncObjectSet.
2336 * @param objects identifiers of objects need to be synchronized
2337 * @param syncComments if true, comments for objects will be synchronized as well
2338 * @param options sync options (see comments for syncObjectSet)
2339 * @throws IOException if socket I/O error occurs
2340 * @throws NXCException if NetXMS server returns an error or operation was timed out
2342 public void syncMissingObjects(long[] objects
, boolean syncComments
, int options
) throws IOException
, NXCException
2344 final long[] syncList
= Arrays
.copyOf(objects
, objects
.length
);
2345 int count
= syncList
.length
;
2346 synchronized(objectList
)
2348 for(int i
= 0; i
< syncList
.length
; i
++)
2350 if (objectList
.containsKey(syncList
[i
]))
2360 syncObjectSet(syncList
, syncComments
, options
);
2365 * Find NetXMS object by it's identifier.
2367 * @param id Object identifier
2368 * @return Object with given ID or null if object cannot be found
2370 public AbstractObject
findObjectById(final long id
)
2374 synchronized(objectList
)
2376 obj
= objectList
.get(id
);
2382 * Find NetXMS object by it's identifier with additional class checking.
2384 * @param id object identifier
2385 * @param requiredClass required object class
2386 * @return Object with given ID or null if object cannot be found or is not an instance of required class
2388 @SuppressWarnings("unchecked")
2389 public <T
extends AbstractObject
> T
findObjectById(final long id
, final Class
<T
> requiredClass
)
2391 AbstractObject object
= findObjectById(id
);
2392 return requiredClass
.isInstance(object
) ?
(T
)object
: null;
2396 * Find multiple NetXMS objects by identifiers
2398 * @param idList array of object identifiers
2399 * @param returnUnknown if true, this method will return UnknownObject placeholders for unknown object identifiers
2400 * @return list of found objects
2402 public List
<AbstractObject
> findMultipleObjects(final long[] idList
, boolean returnUnknown
)
2404 return findMultipleObjects(idList
, null, returnUnknown
);
2408 * Find multiple NetXMS objects by identifiers
2410 * @param idList array of object identifiers
2411 * @param classFilter class filter for objects, or null to disable filtering
2412 * @param returnUnknown if true, this method will return UnknownObject placeholders for unknown object identifiers
2413 * @return list of found objects
2415 public List
<AbstractObject
> findMultipleObjects(final long[] idList
, Class
<?
extends AbstractObject
> classFilter
, boolean returnUnknown
)
2417 List
<AbstractObject
> result
= new ArrayList
<AbstractObject
>(idList
.length
);
2419 synchronized(objectList
)
2421 for(int i
= 0; i
< idList
.length
; i
++)
2423 final AbstractObject object
= objectList
.get(idList
[i
]);
2424 if ((object
!= null) && ((classFilter
== null) || classFilter
.isInstance(object
)))
2428 else if (returnUnknown
)
2430 result
.add(new UnknownObject(idList
[i
], this));
2439 * Find multiple NetXMS objects by identifiers
2441 * @param idList array of object identifiers
2442 * @param returnUnknown if true, this method will return UnknownObject placeholders for unknown object identifiers
2443 * @return array of found objects
2445 public List
<AbstractObject
> findMultipleObjects(final Long
[] idList
, boolean returnUnknown
)
2447 return findMultipleObjects(idList
, null, returnUnknown
);
2451 * Find multiple NetXMS objects by identifiers
2453 * @param idList array of object identifiers
2454 * @param classFilter class filter for objects, or null to disable filtering
2455 * @param returnUnknown if true, this method will return UnknownObject placeholders for unknown object identifiers
2456 * @return array of found objects
2458 public List
<AbstractObject
> findMultipleObjects(final Long
[] idList
, Class
<?
extends AbstractObject
> classFilter
, boolean returnUnknown
)
2460 List
<AbstractObject
> result
= new ArrayList
<AbstractObject
>(idList
.length
);
2462 synchronized(objectList
)
2464 for(int i
= 0; i
< idList
.length
; i
++)
2466 final AbstractObject object
= objectList
.get(idList
[i
]);
2467 if ((object
!= null) && ((classFilter
== null) || classFilter
.isInstance(object
)))
2471 else if (returnUnknown
)
2473 result
.add(new UnknownObject(idList
[i
], this));
2482 * Find zone object by zone ID.
2484 * @param zoneId zone ID to find
2485 * @return zone object or null
2487 public Zone
findZone(long zoneId
)
2490 synchronized(objectList
)
2492 AbstractObject entireNetwork
= objectList
.get(1L);
2493 Collection
<AbstractObject
> objects
= (entireNetwork
!= null) ?
2494 entireNetwork
.getAllChilds(AbstractObject
.OBJECT_ZONE
) : objectList
.values();
2495 for(AbstractObject object
: objects
)
2497 if ((object
instanceof Zone
) && ((Zone
)object
).getZoneId() == zoneId
)
2499 result
= (Zone
)object
;
2509 * Find object by name. If multiple objects with same name exist,
2510 * it is not determined what object will be returned. Name comparison
2511 * is case-insensitive.
2513 * @param name object name to find
2514 * @return object with matching name or null
2516 public AbstractObject
findObjectByName(final String name
)
2518 AbstractObject result
= null;
2519 synchronized(objectList
)
2521 for(AbstractObject object
: objectList
.values())
2523 if (object
.getObjectName().equalsIgnoreCase(name
))
2534 * Find object by name using regular expression. If multiple objects with same name exist,
2535 * it is not determined what object will be returned. Name comparison is case-insensitive.
2537 * @param pattern regular expression for matching object name
2538 * @return object with matching name or null
2540 public AbstractObject
findObjectByNamePattern(final String pattern
)
2542 AbstractObject result
= null;
2543 Matcher matcher
= Pattern
.compile(pattern
).matcher("");
2544 synchronized(objectList
)
2546 for(AbstractObject object
: objectList
.values())
2548 matcher
.reset(object
.getObjectName());
2549 if (matcher
.matches())
2560 * Generic object find using filter. WIll return first object matching given filter.
2563 * @return first matching object or null
2565 public AbstractObject
findObject(ObjectFilter filter
)
2567 AbstractObject result
= null;
2568 synchronized(objectList
)
2570 for(AbstractObject object
: objectList
.values())
2572 if (filter
.filter(object
))
2583 * Find all objects matching given filter.
2586 * @return list of matching objects (empty list if nothing found)
2588 public List
<AbstractObject
> filterObjects(ObjectFilter filter
)
2590 List
<AbstractObject
> result
= new ArrayList
<AbstractObject
>();
2591 synchronized(objectList
)
2593 for(AbstractObject object
: objectList
.values())
2595 if (filter
.filter(object
))
2605 * Get list of top-level objects matching given class filter. Class filter
2606 * may be null to ignore object class.
2608 * @return List of all top matching level objects (either without parents or with
2609 * inaccessible parents)
2611 public AbstractObject
[] getTopLevelObjects(Set
<Integer
> classFilter
)
2613 HashSet
<AbstractObject
> list
= new HashSet
<AbstractObject
>();
2614 synchronized(objectList
)
2616 for(AbstractObject object
: objectList
.values())
2618 if ((classFilter
!= null) && !classFilter
.contains(object
.getObjectClass())) continue;
2620 if (!object
.hasParents())
2626 boolean hasParents
= false;
2627 Iterator
<Long
> it
= object
.getParents();
2630 Long parent
= it
.next();
2631 if (classFilter
!= null)
2633 AbstractObject p
= objectList
.get(parent
);
2634 if ((p
!= null) && classFilter
.contains(p
.getObjectClass()))
2642 if (objectList
.containsKey(parent
))
2649 if (!hasParents
) list
.add(object
);
2653 return list
.toArray(new AbstractObject
[list
.size()]);
2657 * Get list of top-level objects.
2659 * @return List of all top level objects (either without parents or with
2660 * inaccessible parents)
2662 public AbstractObject
[] getTopLevelObjects()
2664 return getTopLevelObjects(null);
2668 * Get list of all objects
2670 * @return List of all objects
2672 public AbstractObject
[] getAllObjects()
2674 AbstractObject
[] list
;
2676 synchronized(objectList
)
2678 list
= objectList
.values().toArray(new AbstractObject
[objectList
.size()]);
2684 * Get object name by ID.
2686 * @param objectId object ID
2687 * @return object name if object is known, or string in form [<object_id>] for unknown objects
2689 public String
getObjectName(long objectId
)
2691 AbstractObject object
= findObjectById(objectId
);
2692 return (object
!= null) ? object
.getObjectName() : ("[" + Long
.toString(objectId
) + "]");
2696 * Get list of active alarms. For accessing terminated alarms log view API should be used.
2698 * @return Hash map containing alarms
2699 * @throws IOException if socket I/O error occurs
2700 * @throws NXCException if NetXMS server returns an error or operation was timed out
2702 public HashMap
<Long
, Alarm
> getAlarms() throws IOException
, NXCException
2704 NXCPMessage msg
= newMessage(NXCPCodes
.CMD_GET_ALL_ALARMS
);
2705 final long rqId
= msg
.getMessageId();
2708 final HashMap
<Long
, Alarm
> alarmList
= new HashMap
<Long
, Alarm
>(0);
2711 msg
= waitForMessage(NXCPCodes
.CMD_ALARM_DATA
, rqId
);
2712 long alarmId
= msg
.getFieldAsInt32(NXCPCodes
.VID_ALARM_ID
);
2714 break; // ALARM_ID == 0 indicates end of list
2715 alarmList
.put(alarmId
, new Alarm(msg
));
2722 * Get information about single active alarm. Terminated alarms cannot be accessed with this call.
2724 * @param alarmId alarm ID
2725 * @return alarm object
2726 * @throws IOException if socket I/O error occurs
2727 * @throws NXCException if NetXMS server returns an error or operation was timed out
2729 public Alarm
getAlarm(long alarmId
) throws IOException
, NXCException
2731 NXCPMessage msg
= newMessage(NXCPCodes
.CMD_GET_ALARM
);
2732 msg
.setFieldInt32(NXCPCodes
.VID_ALARM_ID
, (int) alarmId
);
2734 final NXCPMessage response
= waitForRCC(msg
.getMessageId());
2735 return new Alarm(response
);
2739 * Get information about events related to single active alarm. Information for terminated alarms cannot be accessed with this call.
2740 * User must have "view alarms" permission on alarm's source node and "view event log" system-wide access.
2742 * @param alarmId alarm ID
2743 * @return list of related events
2744 * @throws IOException if socket I/O error occurs
2745 * @throws NXCException if NetXMS server returns an error or operation was timed out
2747 public List
<EventInfo
> getAlarmEvents(long alarmId
) throws IOException
, NXCException
2749 NXCPMessage msg
= newMessage(NXCPCodes
.CMD_GET_ALARM_EVENTS
);
2750 msg
.setFieldInt32(NXCPCodes
.VID_ALARM_ID
, (int) alarmId
);
2752 final NXCPMessage response
= waitForRCC(msg
.getMessageId());
2754 int count
= response
.getFieldAsInt32(NXCPCodes
.VID_NUM_ELEMENTS
);
2755 List
<EventInfo
> list
= new ArrayList
<EventInfo
>(count
);
2756 long varId
= NXCPCodes
.VID_ELEMENT_LIST_BASE
;
2757 for(int i
= 0; i
< count
; i
++)
2759 EventInfo parent
= null;
2760 long rootId
= response
.getFieldAsInt64(varId
+ 1);
2763 for(EventInfo e
: list
)
2765 if (e
.getId() == rootId
)
2772 list
.add(new EventInfo(response
, varId
, parent
));
2779 * Acknowledge alarm.
2781 * @param alarmId Identifier of alarm to be acknowledged.
2782 * @param sticky if set to true, acknowledged state will be made "sticky" (duplicate alarms with same key will not revert it back to outstanding)
2783 * @param time timeout for sticky acknowledge in seconds (0 for infinite)
2784 * @throws IOException if socket I/O error occurs
2785 * @throws NXCException if NetXMS server returns an error or operation was timed out
2787 public void acknowledgeAlarm(final long alarmId
, boolean sticky
, int time
) throws IOException
, NXCException
2789 NXCPMessage msg
= newMessage(NXCPCodes
.CMD_ACK_ALARM
);
2790 msg
.setFieldInt32(NXCPCodes
.VID_ALARM_ID
, (int) alarmId
);
2791 msg
.setFieldInt16(NXCPCodes
.VID_STICKY_FLAG
, sticky ?
1 : 0);
2792 msg
.setFieldInt32(NXCPCodes
.VID_TIMESTAMP
, time
);
2794 waitForRCC(msg
.getMessageId());
2798 * Acknowledge alarm.
2800 * @param alarmId Identifier of alarm to be acknowledged.
2801 * @throws IOException if socket I/O error occurs
2802 * @throws NXCException if NetXMS server returns an error or operation was timed out
2804 public void acknowledgeAlarm(final long alarmId
) throws IOException
, NXCException
2806 acknowledgeAlarm(alarmId
, false, 0);
2810 * Acknowledge alarm by helpdesk reference.
2812 * @param helpdeskReference Helpdesk issue reference (e.g. JIRA issue key)
2813 * @throws IOException if socket I/O error occurs
2814 * @throws NXCException if NetXMS server returns an error or operation was timed out
2816 public void acknowledgeAlarm(String helpdeskReference
) throws IOException
, NXCException
2818 NXCPMessage msg
= newMessage(NXCPCodes
.CMD_ACK_ALARM
);
2819 msg
.setField(NXCPCodes
.VID_HELPDESK_REF
, helpdeskReference
);
2821 waitForRCC(msg
.getMessageId());
2827 * @param alarmId Identifier of alarm to be resolved.
2828 * @throws IOException if socket I/O error occurs
2829 * @throws NXCException if NetXMS server returns an error or operation was timed out
2831 public void resolveAlarm(final long alarmId
) throws IOException
, NXCException
2833 NXCPMessage msg
= newMessage(NXCPCodes
.CMD_RESOLVE_ALARM
);
2834 msg
.setFieldInt32(NXCPCodes
.VID_ALARM_ID
, (int) alarmId
);
2836 waitForRCC(msg
.getMessageId());
2840 * Resolve alarm by helpdesk reference.
2842 * @param helpdeskReference Identifier of alarm to be resolved.
2843 * @throws IOException if socket I/O error occurs
2844 * @throws NXCException if NetXMS server returns an error or operation was timed out
2846 public void resolveAlarm(final String helpdeskReference
) throws IOException
, NXCException
2848 NXCPMessage msg
= newMessage(NXCPCodes
.CMD_RESOLVE_ALARM
);
2849 msg
.setField(NXCPCodes
.VID_HELPDESK_REF
, helpdeskReference
);
2851 waitForRCC(msg
.getMessageId());
2857 * @param alarmId Identifier of alarm to be terminated.
2858 * @throws IOException if socket I/O error occurs
2859 * @throws NXCException if NetXMS server returns an error or operation was timed out
2861 public void terminateAlarm(final long alarmId
) throws IOException
, NXCException
2863 NXCPMessage msg
= newMessage(NXCPCodes
.CMD_TERMINATE_ALARM
);
2864 msg
.setFieldInt32(NXCPCodes
.VID_ALARM_ID
, (int) alarmId
);
2866 waitForRCC(msg
.getMessageId());
2870 * Terminate alarm by helpdesk reference.
2872 * @param helpdeskReference Identifier of alarm to be resolved.
2873 * @throws IOException if socket I/O error occurs
2874 * @throws NXCException if NetXMS server returns an error or operation was timed out
2876 public void terminateAlarm(final String helpdeskReference
) throws IOException
, NXCException
2878 NXCPMessage msg
= newMessage(NXCPCodes
.CMD_TERMINATE_ALARM
);
2879 msg
.setField(NXCPCodes
.VID_HELPDESK_REF
, helpdeskReference
);
2881 waitForRCC(msg
.getMessageId());
2887 * @param alarmId Identifier of alarm to be deleted.
2888 * @throws IOException if socket I/O error occurs
2889 * @throws NXCException if NetXMS server returns an error or operation was timed out
2891 public void deleteAlarm(final long alarmId
) throws IOException
, NXCException
2893 NXCPMessage msg
= newMessage(NXCPCodes
.CMD_DELETE_ALARM
);
2894 msg
.setFieldInt32(NXCPCodes
.VID_ALARM_ID
, (int) alarmId
);
2896 waitForRCC(msg
.getMessageId());
2900 * Open issue in helpdesk system from given alarm
2902 * @param alarmId alarm identifier
2903 * @return helpdesk issue identifier
2904 * @throws IOException if socket I/O error occurs
2905 * @throws NXCException if NetXMS server returns an error or operation was timed out
2907 public String
openHelpdeskIssue(long alarmId
) throws IOException
, NXCException
2909 NXCPMessage msg
= newMessage(NXCPCodes
.CMD_OPEN_HELPDESK_ISSUE
);
2910 msg
.setFieldInt32(NXCPCodes
.VID_ALARM_ID
, (int)alarmId
);
2912 return waitForRCC(msg
.getMessageId()).getFieldAsString(NXCPCodes
.VID_HELPDESK_REF
);
2916 * Get URL for helpdesk issue associated with given alarm
2920 * @throws IOException if socket I/O error occurs
2921 * @throws NXCException if NetXMS server returns an error or operation was timed out
2923 public String
getHelpdeskIssueUrl(long alarmId
) throws IOException
, NXCException
2925 NXCPMessage msg
= newMessage(NXCPCodes
.CMD_GET_HELPDESK_URL
);
2926 msg
.setFieldInt32(NXCPCodes
.VID_ALARM_ID
, (int)alarmId
);
2928 return waitForRCC(msg
.getMessageId()).getFieldAsString(NXCPCodes
.VID_URL
);
2932 * Unlink helpdesk issue from alarm. User must have OBJECT_ACCESS_UPDATE_ALARMS access right
2933 * on alarm's source object and SYSTEM_ACCESS_UNLINK_ISSUES system wide access right.
2935 * @param helpdeskReference
2936 * @throws IOException if socket I/O error occurs
2937 * @throws NXCException if NetXMS server returns an error or operation was timed out
2939 public void unlinkHelpdeskIssue(String helpdeskReference
) throws IOException
, NXCException
2941 NXCPMessage msg
= newMessage(NXCPCodes
.CMD_UNLINK_HELPDESK_ISSUE
);
2942 msg
.setField(NXCPCodes
.VID_HELPDESK_REF
, helpdeskReference
);
2944 waitForRCC(msg
.getMessageId());
2948 * Unlink helpdesk issue from alarm. User must have OBJECT_ACCESS_UPDATE_ALARMS access right
2949 * on alarm's source object and SYSTEM_ACCESS_UNLINK_ISSUES system wide access right.
2951 * @param helpdeskReference
2952 * @throws IOException if socket I/O error occurs
2953 * @throws NXCException if NetXMS server returns an error or operation was timed out
2955 public void unlinkHelpdeskIssue(long alarmId
) throws IOException
, NXCException
2957 NXCPMessage msg
= newMessage(NXCPCodes
.CMD_UNLINK_HELPDESK_ISSUE
);
2958 msg
.setFieldInt32(NXCPCodes
.VID_ALARM_ID
, (int)alarmId
);
2960 waitForRCC(msg
.getMessageId());
2964 * Get list of comments for given alarm.
2966 * @param alarmId alarm ID
2967 * @return list of alarm comments
2968 * @throws IOException if socket I/O error occurs
2969 * @throws NXCException if NetXMS server returns an error or operation was timed out
2971 public List
<AlarmComment
> getAlarmComments(long alarmId
) throws IOException
, NXCException
2973 NXCPMessage msg
= newMessage(NXCPCodes
.CMD_GET_ALARM_COMMENTS
);
2974 msg
.setFieldInt32(NXCPCodes
.VID_ALARM_ID
, (int) alarmId
);
2977 final NXCPMessage response
= waitForRCC(msg
.getMessageId());
2978 int count
= response
.getFieldAsInt32(NXCPCodes
.VID_NUM_ELEMENTS
);
2979 final List
<AlarmComment
> comments
= new ArrayList
<AlarmComment
>(count
);
2980 long varId
= NXCPCodes
.VID_ELEMENT_LIST_BASE
;
2981 for(int i
= 0; i
< count
; i
++)
2983 comments
.add(new AlarmComment(response
, varId
));
2990 * Delete alarm comment.
2992 * @param alarmId alarm ID
2993 * @param commentId comment ID
2994 * @throws IOException if socket I/O error occurs
2995 * @throws NXCException if NetXMS server returns an error or operation was timed out
2997 public void deleteAlarmComment(long alarmId
, long commentId
) throws IOException
, NXCException
2999 NXCPMessage msg
= newMessage(NXCPCodes
.CMD_DELETE_ALARM_COMMENT
);
3000 msg
.setFieldInt32(NXCPCodes
.VID_ALARM_ID
, (int) alarmId
);
3001 msg
.setFieldInt32(NXCPCodes
.VID_COMMENT_ID
, (int) commentId
);
3003 waitForRCC(msg
.getMessageId());
3007 * Create alarm comment.
3011 * @throws IOException
3012 * @throws NXCException
3014 public void createAlarmComment(long alarmId
, String text
) throws IOException
, NXCException
3016 updateAlarmComment(alarmId
, 0, text
);
3020 * Create alarm comment by helpdesk reference.
3022 * @param helpdeskReference
3024 * @throws IOException
3025 * @throws NXCException
3027 public void createAlarmComment(final String helpdeskReference
, String text
) throws IOException
, NXCException
3029 NXCPMessage msg
= newMessage(NXCPCodes
.CMD_UPDATE_ALARM_COMMENT
);
3030 msg
.setFieldInt32(NXCPCodes
.VID_ALARM_ID
, 0);
3031 msg
.setField(NXCPCodes
.VID_HELPDESK_REF
, helpdeskReference
);
3032 msg
.setField(NXCPCodes
.VID_COMMENTS
, text
);
3034 waitForRCC(msg
.getMessageId());
3038 * Update alarm comment.
3039 * If alarmId == 0 — new comment will be created.
3041 * @param alarmId alarm ID
3042 * @param commentId comment ID or 0 for creating new comment
3043 * @param text message text
3044 * @throws IOException if socket I/O error occurs
3045 * @throws NXCException if NetXMS server returns an error or operation was timed out
3047 public void updateAlarmComment(long alarmId
, long commentId
, String text
) throws IOException
, NXCException
3049 NXCPMessage msg
= newMessage(NXCPCodes
.CMD_UPDATE_ALARM_COMMENT
);
3050 msg
.setFieldInt32(NXCPCodes
.VID_ALARM_ID
, (int) alarmId
);
3051 msg
.setFieldInt32(NXCPCodes
.VID_COMMENT_ID
, (int) commentId
);
3052 msg
.setField(NXCPCodes
.VID_COMMENTS
, text
);
3054 waitForRCC(msg
.getMessageId());
3058 * Changes state of alarm status flow. Strict or not - terminate state can be set only after
3059 * resolve state or after any state.
3061 * @param state state of alarm status flow - strict or not (1 or 0)
3062 * @throws IOException if socket I/O error occurs
3063 * @throws NXCException if NetXMS server returns an error or operation was timed out
3065 public void setAlarmFlowState(int state
) throws IOException
, NXCException
3067 NXCPMessage msg
= newMessage(NXCPCodes
.CMD_SET_ALARM_STATUS_FLOW
);
3068 msg
.setFieldInt32(NXCPCodes
.VID_ALARM_STATUS_FLOW_STATE
, state
);
3070 waitForRCC(msg
.getMessageId());
3074 * Get server configuration variables
3077 * @throws IOException if socket I/O error occurs
3078 * @throws NXCException if NetXMS server returns an error or operation was timed out
3080 public Map
<String
, ServerVariable
> getServerVariables() throws IOException
, NXCException
3082 NXCPMessage request
= newMessage(NXCPCodes
.CMD_GET_CONFIG_VARLIST
);
3083 sendMessage(request
);
3085 final NXCPMessage response
= waitForRCC(request
.getMessageId());
3088 int i
, count
= response
.getFieldAsInt32(NXCPCodes
.VID_NUM_VARIABLES
);
3089 final HashMap
<String
, ServerVariable
> varList
= new HashMap
<String
, ServerVariable
>(count
);
3090 for(i
= 0, id
= NXCPCodes
.VID_VARLIST_BASE
; i
< count
; i
++, id
+= 3)
3092 String name
= response
.getFieldAsString(id
);
3094 new ServerVariable(name
, response
.getFieldAsString(id
+ 1), response
.getFieldAsBoolean(id
+ 2)));
3101 * Get server public configuration variable
3103 * @param name configuration variable name
3104 * @return value of requested configuration variable
3105 * @throws IOException if socket I/O error occurs
3106 * @throws NXCException if NetXMS server returns an error or operation was timed out
3108 public String
getPublicServerVariable(String name
) throws IOException
, NXCException
3110 NXCPMessage msg
= newMessage(NXCPCodes
.CMD_GET_PUBLIC_CONFIG_VAR
);
3111 msg
.setField(NXCPCodes
.VID_NAME
, name
);
3113 NXCPMessage response
= waitForRCC(msg
.getMessageId());
3114 return response
.getFieldAsString(NXCPCodes
.VID_VALUE
);
3118 * Get server public configuration variable as boolen value
3120 * @param name configuration variable name
3121 * @return value of requested configuration variable
3122 * @throws IOException if socket I/O error occurs
3123 * @throws NXCException if NetXMS server returns an error or operation was timed out
3125 public boolean getPublicServerVariableAsBoolean(String name
) throws IOException
, NXCException
3127 String value
= getPublicServerVariable(name
);
3128 if ((value
.equalsIgnoreCase("true")) || (value
.equalsIgnoreCase("yes")))
3130 if ((value
.equalsIgnoreCase("false")) || (value
.equalsIgnoreCase("no")))
3134 int n
= Integer
.parseInt(value
);
3137 catch(NumberFormatException e
)
3144 * Set server configuration variable
3148 * @throws IOException if socket I/O error occurs
3149 * @throws NXCException if NetXMS server returns an error or operation was timed out
3151 public void setServerVariable(final String name
, final String value
) throws IOException
, NXCException
3153 NXCPMessage msg
= newMessage(NXCPCodes
.CMD_SET_CONFIG_VARIABLE
);
3154 msg
.setField(NXCPCodes
.VID_NAME
, name
);
3155 msg
.setField(NXCPCodes
.VID_VALUE
, value
);
3157 waitForRCC(msg
.getMessageId());
3161 * Delete server configuration variable
3164 * @throws IOException if socket I/O error occurs
3165 * @throws NXCException if NetXMS server returns an error or operation was timed out
3167 public void deleteServerVariable(final String name
) throws IOException
, NXCException
3169 NXCPMessage msg
= newMessage(NXCPCodes
.CMD_DELETE_CONFIG_VARIABLE
);
3170 msg
.setField(NXCPCodes
.VID_NAME
, name
);
3172 waitForRCC(msg
.getMessageId());
3176 * Get server config CLOB
3180 * @throws IOException if socket I/O error occurs
3181 * @throws NXCException if NetXMS server returns an error or operation was timed out
3183 public String
getServerConfigClob(final String name
) throws IOException
, NXCException
3185 final NXCPMessage msg
= newMessage(NXCPCodes
.CMD_CONFIG_GET_CLOB
);
3186 msg
.setField(NXCPCodes
.VID_NAME
, name
);
3188 final NXCPMessage response
= waitForRCC(msg
.getMessageId());
3189 return response
.getFieldAsString(NXCPCodes
.VID_VALUE
);
3193 * Set server config CLOB
3197 * @throws IOException if socket I/O error occurs