@Override
  public JSONObject getSnapshot() {
    JSONObject snapshot = new JSONObject();
    snapshot.put(DATA_NODE_HOSTNAME, getHostname());
    snapshot.put(DATA_NODE_DATACENTER, getDatacenterName());
    snapshot.put(DATA_NODE_SSL_ENABLED_DATACENTERS, new JSONArray(sslEnabledDataCenters));
    JSONObject portsJson = new JSONObject();
    ports.forEach((portType, port) -> portsJson.put(port.getPortType().name(), port.getPort()));
    portsJson.put(DATA_NODE_PORT_CONNECT_TO, getPortToConnectTo().getPort());
    snapshot.put(DATA_NODE_PORTS, portsJson);
    snapshot.put(DATA_NODE_RACK_ID, getRackId());
    snapshot.put(DATA_NODE_XID, getXid());
    String liveness = UP;
    if (dataNodeStatePolicy.isHardDown()) {
      liveness = NODE_DOWN;
    } else if (dataNodeStatePolicy.isDown()) {
      liveness = SOFT_DOWN;
    }
    snapshot.put(LIVENESS, liveness);
    JSONArray disksJson = new JSONArray();
    disks.forEach(disk -> disksJson.put(disk.getSnapshot()));
    snapshot.put(DATA_NODE_DISKS, disksJson);
    return snapshot;
  }
Returns the {@link Port} of this node to connect to. A {@link Port} will be automatically selected based on if
there is a need of establishing an SSL connection.

@return {@link Port} to which the caller can connect to.
@throws IllegalStateException Thrown if an SSL connection is needed but no SSL port exists.
ambry-clustermap/src/main/java/com/github/ambry/clustermap/DataNode.java