001/*
002 * JPPF.
003 * Copyright (C) 2005-2019 JPPF Team.
004 * http://www.jppf.org
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License");
007 * you may not use this file except in compliance with the License.
008 * You may obtain a copy of the License at
009 *
010 *   http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019package org.jppf.management;
020
021import java.io.Serializable;
022import java.util.*;
023
024
025/**
026 * Instances of this class encapsulate the information required to access the JMX server of a node or a driver.
027 * @author Laurent Cohen
028 */
029public class JPPFManagementInfo implements Serializable, Comparable<JPPFManagementInfo> {
030  /**
031   * Explicit serialVersionUID.
032   */
033  private static final long serialVersionUID = 1L;
034  /**
035   * DRIVER information type.
036   * @exclude
037   */
038  public static final int DRIVER = 0;
039  /**
040   * Node information type.
041   * @exclude
042   */
043  public static final int NODE = 1;
044  /**
045   * Peer driver information type.
046   * @exclude
047   */
048  public static final int PEER = 2;
049  /*
050   * Extended attributes must have their 0-15 bits set to 0.
051   */
052  /**
053   * Information that the node is a master node for the provisioning feature.
054   */
055  public static final int MASTER = 0x0001_0000;
056  /**
057   * Information that the node is a slave node for the provisioning feature.
058   */
059  public static final int SLAVE = 0x0002_0000;
060  /**
061   * Information that node is local on DRIVER or CLIENT. Value of this constant can be changed in future!
062   */
063  public static final int LOCAL = 0x0004_0000;
064  /**
065   * Information that the node is initialized with a .Net bridge and can execute .Net tasks. Value of this constant can be changed in future!
066   * @since 5.0
067   * @deprecated the .Net bridge feature is no longer part of JPPF
068   * @exclude
069   */
070  public static final int DOTNET = 0x0008_0000;
071  /**
072   * Information that the node is an Android node.
073   * @since 5.1
074   * @deprecated the Android node feature is no longer part of JPPF
075   * @exclude
076   */
077  public static final int ANDROID = 0x0010_0000;
078  /**
079   * Mask for elimination extended type attributes (bits 16-31).
080   */
081  protected static final int TYPE_MASK = 0xFFFF;
082  /**
083   * Maps type values to readable strings.
084   */
085  private static final Map<Integer, String> typeMap = new HashMap<>();
086  static {
087    typeMap.put(DRIVER, "driver");
088    typeMap.put(NODE, "node");
089    typeMap.put(PEER, "peer");
090  }
091  /**
092   * The name of the host on which the node or driver is running.
093   */
094  private final String host;
095  /**
096   * The ip address of the host on which the node or driver is running.
097   * @since 5.0
098   */
099  private final String ipAddress;
100  /**
101   * The port on which the node's JMX server is listening.
102   */
103  private final int port;
104  /**
105   * Unique id for the node.
106   */
107  private final String uuid;
108  /**
109   * The type of component this info is for, must be one of {@link #NODE} or {@link #DRIVER}.
110   */
111  private final int type;
112  /**
113   * Determines whether communication with the node or driver should be secure, i.e. via SSL/TLS.
114   */
115  private final boolean secure;
116  /**
117   * The system information associated with the node at the time of the initial connection.
118   */
119  private transient JPPFSystemInformation systemInfo;
120  /**
121   * Determines whether the node is active or inactive.
122   */
123  private boolean active = true;
124  /**
125   * The uuid of the node of which this node is a slave, if any.
126   */
127  private final String masterUuid;
128
129  /**
130   * Initialize this information with the specified parameters.
131   * @param host the name of the host on which the node or driver is running.
132   * @param ip the ip address of the host on which the node is running.
133   * @param port the port on which the node's or driver's JMX server is listening.
134   * @param uuid unique id of the node or driver.
135   * @param type the type of component this info is for, must be one of {@link #NODE NODE} or {@link #DRIVER DRIVER}.
136   * @param secure specifies whether communication with the node or driver should be secure, i.e. via SSL/TLS.
137   * @since 5.0
138   * @exclude
139   */
140  public JPPFManagementInfo(final String host, final String ip, final int port, final String uuid, final int type, final boolean secure) {
141    this(host, ip, port, uuid, type, secure, null);
142  }
143
144  /**
145   * Initialize this information with the specified parameters.
146   * @param host the name of the host on which the node or driver is running.
147   * @param ip the ip address of the host on which the node is running.
148   * @param port the port on which the node's or driver's JMX server is listening.
149   * @param uuid unique id of the node or driver.
150   * @param type the type of component this info is for, must be one of {@link #NODE NODE} or {@link #DRIVER DRIVER}.
151   * @param secure specifies whether communication with the node or driver should be secure, i.e. via SSL/TLS.
152   * @param masterUuid uuid of the node of which this node is a slave, if any.
153   * @since 5.0
154   * @exclude
155   */
156  public JPPFManagementInfo(final String host, final String ip, final int port, final String uuid, final int type, final boolean secure, final String masterUuid) {
157    this.host = host;
158    this.ipAddress = ip;
159    this.port = port;
160    this.uuid = uuid;
161    this.type = type;
162    this.secure = secure;
163    this.masterUuid = masterUuid;
164  }
165
166  /**
167   * Get the host on which the node is running.
168   * @return the host as a string.
169   */
170  public synchronized String getHost() {
171    return host;
172  }
173
174  /**
175   * Get the port on which the node's JMX server is listening.
176   * @return the port as an int.
177   */
178  public synchronized int getPort() {
179    return port;
180  }
181
182  @Override
183  public int hashCode() {
184    return (uuid == null) ? 0 : uuid.hashCode();
185  }
186
187  @Override
188  public boolean equals(final Object obj) {
189    if (this == obj) return true;
190    if (obj == null) return false;
191    if (getClass() != obj.getClass()) return false;
192    final JPPFManagementInfo other = (JPPFManagementInfo) obj;
193    if (other.uuid == null) return uuid == null;
194    return (uuid != null) && uuid.equals(other.uuid);
195  }
196
197  @Override
198  public int compareTo(final JPPFManagementInfo o) {
199    if (o == null) return 1;
200    if (this.equals(o)) return 0;
201    // we want ascending alphabetical order
202    final int n = -1 * host.compareTo(o.getHost());
203    if (n != 0) return n;
204    return port - o.getPort();
205  }
206
207  @Override
208  public String toString() {
209    final StringBuilder sb = new StringBuilder(getClass().getSimpleName()).append('[');
210    sb.append(host).append(':').append(port);
211    sb.append(", type=").append(typeToString());
212    sb.append(", local=").append(isLocal());
213    sb.append(", secure=").append(secure);
214    sb.append(", active=").append(active);
215    sb.append(", uuid=").append(uuid);
216    sb.append(']');
217    return sb.toString();
218  }
219
220  /**
221   * Get a string displayed in the console.
222   * @return .
223   * @exclude
224   */
225  public String toDisplayString() {
226    return host + ':' + port;
227  }
228
229  /**
230   * Get the system information associated with the node at the time of the initial connection.
231   * Please note that this atrribute is <i>transient</i> and will always be null immediately after the {@code JPPFManagementInfo} object is retrieved from a remote server. 
232   * @return a {@link JPPFSystemInformation} instance.
233   */
234  public synchronized JPPFSystemInformation getSystemInfo() {
235    return systemInfo;
236  }
237
238  /**
239   * Set the system information associated with the node at the time of the initial connection.
240   * @param systemInfo a {@link JPPFSystemInformation} instance.
241   * @exclude
242   */
243  public synchronized void setSystemInfo(final JPPFSystemInformation systemInfo) {
244    this.systemInfo = systemInfo;
245  }
246
247  /**
248   * Get the unique id for the node's mbean server.
249   * @return the id as a string.
250   */
251  public String getUuid() {
252    return uuid;
253  }
254
255  /**
256   * Determine whether this information represents a connection to peer driver.
257   * @return {@code true} if this information represents a peer driver, {@code false} otherwise.
258   */
259  public boolean isPeer() {
260    return (type & TYPE_MASK) == PEER;
261  }
262
263  /**
264   * Determine whether this information represents a real node.
265   * @return {@code true} if this information represents a node, {@code false} otherwise.
266   */
267  public boolean isNode() {
268    return (type & TYPE_MASK) == NODE;
269  }
270
271  /**
272   * Determine whether this information represents a driver, connected as a peer to the
273   * driver from which this information is obtained.
274   * @return {@code true} if this information represents a driver, {@code false} otherwise.
275   */
276  public boolean isDriver() {
277    return (type & TYPE_MASK) == DRIVER;
278  }
279
280  /**
281   * Determine whether communication with the node or driver is be secure, i.e. via SSL/TLS.
282   * @return {@code true} if the connection is secure, {@code false} otherwise.
283   */
284  public boolean isSecure() {
285    return secure;
286  }
287
288  /**
289   * Determine whether this information represents a master node for provisioning.
290   * @return {@code true} if the node is a master node, {@code false} otherwise.
291   */
292  public boolean isMasterNode() {
293    return (type & MASTER) == MASTER;
294  }
295
296  /**
297   * Determine whether this information represents a slave node for provisioning.
298   * @return {@code true} if the node is a master node, {@code false} otherwise.
299   */
300  public boolean isSlaveNode() {
301    return (type & SLAVE) == SLAVE;
302  }
303
304  /**
305   * Determine whether this information represents a local node on client or driver.
306   * @return {@code true} if the node is local to a driver, {@code false} otherwise
307   */
308  public boolean isLocal() {
309    return (type & LOCAL) == LOCAL;
310  }
311
312  /**
313   * Determine whether this information represents a node than can execute .Net tasks.
314   * @return {@code true} if the node is .Net-capable, {@code false} otherwise.
315   * @since 5.0
316   * @deprecated the .Net bridge feature is no longer part of JPPF
317   * @exclude
318   */
319  public boolean isDotnetCapable() {
320    return (type & DOTNET) == DOTNET;
321  }
322
323  /**
324   * Determine whether this information represents an Android node.
325   * @return {@code true} if the node an Android node, {@code false} otherwise.
326   * @since 5.1
327   * @deprecated the Android node feature is no longer part of JPPF
328   * @exclude
329   */
330  public boolean isAndroidNode() {
331    return (type & ANDROID) == ANDROID;
332  }
333
334  /**
335   * Determine whether the node is active or inactive.
336   * @return {@code true} if the node is active, {@code false} if it is inactve.
337   */
338  public boolean isActive() {
339    return active;
340  }
341
342  /**
343   * Specify whether the node is active or inactive.
344   * @param active {@code true} if the node is active, {@code false} if it is inactve.
345   * @exclude
346   */
347  public void setIsActive(final boolean active) {
348    this.active = active;
349  }
350
351  /**
352   * Get a string representation of the type.
353   * @return a string representing the type.
354   */
355  private String typeToString() {
356    final int b = (type & TYPE_MASK);
357    final StringBuilder sb = new StringBuilder();
358    final String s = typeMap.get(b);
359    sb.append(s == null ? "?" : s);
360    if (isMasterNode()) sb.append("|MASTER");
361    if (isSlaveNode()) sb.append("|SLAVE");
362    if (isLocal()) sb.append("|LOCAL");
363    if (isDotnetCapable()) sb.append("|DOTNET");
364    if (isAndroidNode()) sb.append("|ANDROID");
365    return sb.toString();
366  }
367
368  /**
369   * Get the ip address of the host on which the node or driver is running.
370   * @return the ip address as a string.
371   * @since 5.0
372   */
373  public String getIpAddress() {
374    return ipAddress;
375  }
376
377  /**
378   * Get the uuid of the master node that providioned this node.
379   * @return the uuid of the node of which this node is a slave, if any, or {@code null} if this object doesn't represent a node, or if it represents a node that is not a slave.
380   */
381  public String getMasterUuid() {
382    return masterUuid;
383  }
384}