001/*
002 * JPPF.
003 * Copyright (C) 2005-2018 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   */
068  public static final int DOTNET = 0x0008_0000;
069  /**
070   * Information that the node is an Android node.
071   * @since 5.1
072   */
073  public static final int ANDROID = 0x0010_0000;
074  /**
075   * Mask for elimination extended type attributes (bits 16-31).
076   */
077  protected static final int TYPE_MASK = 0xFFFF;
078  /**
079   * Maps type values to readable strings.
080   */
081  private static final Map<Integer, String> typeMap = new HashMap<>();
082  static {
083    typeMap.put(DRIVER, "driver");
084    typeMap.put(NODE, "node");
085    typeMap.put(PEER, "peer");
086  }
087  /**
088   * The name of the host on which the node or driver is running.
089   */
090  private final String host;
091  /**
092   * The ip address of the host on which the node or driver is running.
093   * @since 5.0
094   */
095  private final String ipAddress;
096  /**
097   * The port on which the node's JMX server is listening.
098   */
099  private final int port;
100  /**
101   * Unique id for the node.
102   */
103  private final String uuid;
104  /**
105   * The type of component this info is for, must be one of {@link #NODE} or {@link #DRIVER}.
106   */
107  private final int type;
108  /**
109   * Determines whether communication with the node or driver should be secure, i.e. via SSL/TLS.
110   */
111  private final boolean secure;
112  /**
113   * The system information associated with the node at the time of the initial connection.
114   */
115  private transient JPPFSystemInformation systemInfo = null;
116  /**
117   * Determines whether the node is active or inactive.
118   */
119  private boolean active = true;
120  /**
121   * The uuid of the node of which this node is a slave, if any.
122   */
123  private final String masterUuid;
124
125  /**
126   * Initialize this information with the specified parameters.
127   * @param host the name of the host on which the node or driver is running.
128   * @param ip the ip address of the host on which the node is running.
129   * @param port the port on which the node's or driver's JMX server is listening.
130   * @param uuid unique id of the node or driver.
131   * @param type the type of component this info is for, must be one of {@link #NODE NODE} or {@link #DRIVER DRIVER}.
132   * @param secure specifies whether communication with the node or driver should be secure, i.e. via SSL/TLS.
133   * @since 5.0
134   * @exclude
135   */
136  public JPPFManagementInfo(final String host, final String ip, final int port, final String uuid, final int type, final boolean secure) {
137    this(host, ip, port, uuid, type, secure, null);
138  }
139
140  /**
141   * Initialize this information with the specified parameters.
142   * @param host the name of the host on which the node or driver is running.
143   * @param ip the ip address of the host on which the node is running.
144   * @param port the port on which the node's or driver's JMX server is listening.
145   * @param uuid unique id of the node or driver.
146   * @param type the type of component this info is for, must be one of {@link #NODE NODE} or {@link #DRIVER DRIVER}.
147   * @param secure specifies whether communication with the node or driver should be secure, i.e. via SSL/TLS.
148   * @param masterUuid uuid of the node of which this node is a slave, if any.
149   * @since 5.0
150   * @exclude
151   */
152  public JPPFManagementInfo(final String host, final String ip, final int port, final String uuid, final int type, final boolean secure, final String masterUuid) {
153    this.host = host;
154    this.ipAddress = ip;
155    this.port = port;
156    this.uuid = uuid;
157    this.type = type;
158    this.secure = secure;
159    this.masterUuid = masterUuid;
160  }
161
162  /**
163   * Get the host on which the node is running.
164   * @return the host as a string.
165   */
166  public synchronized String getHost() {
167    return host;
168  }
169
170  /**
171   * Get the port on which the node's JMX server is listening.
172   * @return the port as an int.
173   */
174  public synchronized int getPort() {
175    return port;
176  }
177
178  @Override
179  public int hashCode() {
180    return (uuid == null) ? 0 : uuid.hashCode();
181  }
182
183  @Override
184  public boolean equals(final Object obj) {
185    if (this == obj) return true;
186    if (obj == null) return false;
187    if (getClass() != obj.getClass()) return false;
188    final JPPFManagementInfo other = (JPPFManagementInfo) obj;
189    if (other.uuid == null) return uuid == null;
190    return (uuid != null) && uuid.equals(other.uuid);
191  }
192
193  @Override
194  public int compareTo(final JPPFManagementInfo o) {
195    if (o == null) return 1;
196    if (this.equals(o)) return 0;
197    // we want ascending alphabetical order
198    final int n = -1 * host.compareTo(o.getHost());
199    if (n != 0) return n;
200    return port - o.getPort();
201  }
202
203  @Override
204  public String toString() {
205    final StringBuilder sb = new StringBuilder(getClass().getSimpleName()).append('[');
206    sb.append(host).append(':').append(port);
207    sb.append(", type=").append(typeToString());
208    sb.append(", local=").append(isLocal());
209    sb.append(", secure=").append(secure);
210    sb.append(", active=").append(active);
211    sb.append(", uuid=").append(uuid);
212    sb.append(']');
213    return sb.toString();
214  }
215
216  /**
217   * Get a string displayed in the console.
218   * @return .
219   * @exclude
220   */
221  public String toDisplayString() {
222    return host + ':' + port;
223  }
224
225  /**
226   * Get the system information associated with the node at the time of the initial connection.
227   * 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. 
228   * @return a {@link JPPFSystemInformation} instance.
229   */
230  public synchronized JPPFSystemInformation getSystemInfo() {
231    return systemInfo;
232  }
233
234  /**
235   * Set the system information associated with the node at the time of the initial connection.
236   * @param systemInfo a {@link JPPFSystemInformation} instance.
237   * @exclude
238   */
239  public synchronized void setSystemInfo(final JPPFSystemInformation systemInfo) {
240    this.systemInfo = systemInfo;
241  }
242
243  /**
244   * Get the unique id for the node's mbean server.
245   * @return the id as a string.
246   */
247  public String getUuid() {
248    return uuid;
249  }
250
251  /**
252   * Determine whether this information represents a connection to peer driver.
253   * @return {@code true} if this information represents a peer driver, {@code false} otherwise.
254   */
255  public boolean isPeer() {
256    return (type & TYPE_MASK) == PEER;
257  }
258
259  /**
260   * Determine whether this information represents a real node.
261   * @return {@code true} if this information represents a node, {@code false} otherwise.
262   */
263  public boolean isNode() {
264    return (type & TYPE_MASK) == NODE;
265  }
266
267  /**
268   * Determine whether this information represents a driver, connected as a peer to the
269   * driver from which this information is obtained.
270   * @return {@code true} if this information represents a driver, {@code false} otherwise.
271   */
272  public boolean isDriver() {
273    return (type & TYPE_MASK) == DRIVER;
274  }
275
276  /**
277   * Determine whether communication with the node or driver is be secure, i.e. via SSL/TLS.
278   * @return {@code true} if the connection is secure, {@code false} otherwise.
279   */
280  public boolean isSecure() {
281    return secure;
282  }
283
284  /**
285   * Determine whether this information represents a master node for provisioning.
286   * @return {@code true} if the node is a master node, {@code false} otherwise.
287   */
288  public boolean isMasterNode() {
289    return (type & MASTER) == MASTER;
290  }
291
292  /**
293   * Determine whether this information represents a slave node for provisioning.
294   * @return {@code true} if the node is a master node, {@code false} otherwise.
295   */
296  public boolean isSlaveNode() {
297    return (type & SLAVE) == SLAVE;
298  }
299
300  /**
301   * Determine whether this information represents a local node on client or driver.
302   * @return {@code true} if the node is local to a driver, {@code false} otherwise
303   */
304  public boolean isLocal() {
305    return (type & LOCAL) == LOCAL;
306  }
307
308  /**
309   * Determine whether this information represents a node than can execute .Net tasks.
310   * @return {@code true} if the node is .Net-capable, {@code false} otherwise.
311   * @since 5.0
312   */
313  public boolean isDotnetCapable() {
314    return (type & DOTNET) == DOTNET;
315  }
316
317  /**
318   * Determine whether this information represents an Android node.
319   * @return {@code true} if the node an Android node, {@code false} otherwise.
320   * @since 5.1
321   */
322  public boolean isAndroidNode() {
323    return (type & ANDROID) == ANDROID;
324  }
325
326  /**
327   * Determine whether the node is active or inactive.
328   * @return {@code true} if the node is active, {@code false} if it is inactve.
329   */
330  public boolean isActive() {
331    return active;
332  }
333
334  /**
335   * Specify whether the node is active or inactive.
336   * @param active {@code true} if the node is active, {@code false} if it is inactve.
337   * @exclude
338   */
339  public void setIsActive(final boolean active) {
340    this.active = active;
341  }
342
343  /**
344   * Get a string representation of the type.
345   * @return a string representing the type.
346   */
347  private String typeToString() {
348    final int b = (type & TYPE_MASK);
349    final StringBuilder sb = new StringBuilder();
350    final String s = typeMap.get(b);
351    sb.append(s == null ? "?" : s);
352    if (isMasterNode()) sb.append("|MASTER");
353    if (isSlaveNode()) sb.append("|SLAVE");
354    if (isLocal()) sb.append("|LOCAL");
355    if (isDotnetCapable()) sb.append("|DOTNET");
356    if (isAndroidNode()) sb.append("|ANDROID");
357    return sb.toString();
358  }
359
360  /**
361   * Get the ip address of the host on which the node or driver is running.
362   * @return the ip address as a string.
363   * @since 5.0
364   */
365  public String getIpAddress() {
366    return ipAddress;
367  }
368
369  /**
370   * Get the uuid of the master node that providioned this node.
371   * @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.
372   */
373  public String getMasterUuid() {
374    return masterUuid;
375  }
376}