/* * Copyright (c) 2012 EMC Corporation * All Rights Reserved */ package com.emc.storageos.db.client.model; import com.emc.storageos.db.client.util.EndpointUtility; import com.emc.storageos.db.client.util.WWNUtility; import com.emc.storageos.db.client.util.iSCSIUtility; /** * SCSI initiator in either a Fiber Channel or iSCSI SAN. */ @Cf("Initiator") public class Initiator extends HostInterface implements Comparable<Initiator> { private String _port; private String _node; // to do - This is temporary until initiator service is remove private String _hostName; // to do - This is temporary until initiator service is remove private String _clusterName; // Lazily initialized, cached hashCode private volatile int hashCode; // COP-18937: Initiator may be registered to multiple storage systems using different names. XIO Arrays // COP-18551: Initiator may be registered to multiple storage systems using different Aliases. VMAX Arrays private StringMap initiatorNames; /** * Default Constructor. This is the constructor used by the API. */ public Initiator() { setIsManualCreation(true); } /** * Constructor. * * @param protocol The initiator port protocol. * @param port The initiator port identifier. * @param node The initiator node identifier. * @param hostName The FQDN of the initiator host. * @param isManualCreation the flag that indicates if the initiator is user or system created */ public Initiator(String protocol, String port, String node, String hostName, boolean isManualCreation) { super(null, protocol); setInitiatorPort(port); setInitiatorNode(node == null ? "" : node); setHostName(hostName == null ? "" : hostName); setIsManualCreation(isManualCreation); } /** * Constructor supports setting of optional cluster name. * * @param protocol The initiator port protocol. * @param port The initiator port identifier. * @param node The initiator node identifier. * @param hostName The FQDN of the initiator host. * @param clusterName The FQDN of the cluster. * @param isManualCreation the flag that indicates if the initiator is user or system created */ public Initiator(String protocol, String port, String node, String hostName, String clusterName, boolean isManualCreation) { super(null, protocol); setInitiatorPort(port); setInitiatorNode(node == null ? "" : node); setHostName(hostName == null ? "" : hostName); setClusterName(clusterName == null ? "" : clusterName); setIsManualCreation(isManualCreation); } /** * Getter for the initiator port identifier. For FC, this is the port WWN. * For iSCSI, this is port name in IQN or EUI format. * * @return The initiator port identifier. */ @Name("iniport") @AlternateId("InitiatorPortIndex") public String getInitiatorPort() { return _port; } /** * Setter for the initiator port identifier. * * @param port The initiator port identifier. */ public void setInitiatorPort(String port) { _port = EndpointUtility.changeCase(port); setChanged("iniport"); } /** * Getter for the initiator node identifier. For FC, this is the node WWN. * For iSCSI, this field is optional. * * @return The initiator node identifier. */ @Name("ininode") public String getInitiatorNode() { return _node; } /** * Setter for the initiator node identifier. * * @param node The initiator node identifier. */ public void setInitiatorNode(String node) { _node = EndpointUtility.changeCase(node); setChanged("ininode"); } /** * Getter for the FQDN of the initiator host. * to do - This is temporary until initiator service is remove * * @return The FQDN of the initiator host. */ @AlternateId("AltIdIndex") @Name("hostname") public String getHostName() { return _hostName; } /** * Setter for the FQDN of the initiator host. * to do - This is temporary until initiator service is remove * * @param hostName The FQDN of the initiator host. */ public void setHostName(String hostName) { _hostName = hostName; setChanged("hostname"); } /** * Getter for the FQDN of the initiator cluster. * to do - This is temporary until initiator service is remove * * @return The FQDN of the initiator cluster or null if not applicable. */ @Name("clustername") public String getClusterName() { return _clusterName; } /** * Setter for the FQDN of the initiator cluster. * to do - This is temporary until initiator service is remove * * @param clusterName The FQDN of the initiator cluster. */ public void setClusterName(String clusterName) { _clusterName = clusterName; setChanged("clustername"); } /** * Getter for the initiator names * * @return Map of storage system serial number to initiator name */ @Name("initiatorNames") public StringMap getInitiatorNames() { if (initiatorNames == null) { initiatorNames = new StringMap(); } return initiatorNames; } /** * Setter for the initiatorNames * * @param initiatorNames - map of storage system to initiator name */ public void setInitiatorNames(StringMap initiatorNames) { this.initiatorNames = initiatorNames; } /** * Map the initiator name to the storage system * * @param storageSystemSerialNumber storage system serial number * @param initiatorName initiator name for the storage system */ public void mapInitiatorName(String storageSystemSerialNumber, String initiatorName) { if (storageSystemSerialNumber != null && initiatorName != null && !initiatorName.isEmpty()) { getInitiatorNames().put(storageSystemSerialNumber, initiatorName); } } /** * Unmap the initiator name for the storage system (remove it from initiator names). * * @param storageSystemSerialNumber storage system serial number */ public void unmapInitiatorName(String storageSystemSerialNumber) { if (storageSystemSerialNumber != null && !storageSystemSerialNumber.isEmpty()) { getInitiatorNames().remove(storageSystemSerialNumber); } } /** * Get the initiator name for the given storage system if present. * If there is no mapping for the storage system, return the initiator label. * * @param storageSystemSerialNumber * @return initiator name for the storage system if present or the label */ public String getMappedInitiatorName(String storageSystemSerialNumber) { String initiatorName = getInitiatorNames().get(storageSystemSerialNumber); return initiatorName != null ? initiatorName : getLabel(); } @Override public final String toString() { return String.format( "Initiator(Protocol:%s, Node:%s, Port:%s, Host Name: %s, Cluster Name: %s)", getProtocol(), getInitiatorNode(), getInitiatorPort(), getHostName(), getClusterName()); } static public String normalizePort(String port) { String normalizedPort = port; if (WWNUtility.isValidWWN(port)) { normalizedPort = WWNUtility.getUpperWWNWithNoColons(port); } else if (iSCSIUtility.isValidIQNPortName(port)) { normalizedPort = normalizedPort.toLowerCase(); } return normalizedPort; } static public String toPortNetworkId(String port) { String portNetworkId = port; if (port.startsWith("iqn")) { // iSCSI port may have some other values after the port name (e.g., // iqn.1992-04.com.emc:cx.apm00121500018.b9,t,0x0001). // Exclude the extraneous parts to arrive at // iqn.1992-04.com.emc:cx.apm00121500018.b9 int firstComma = port.indexOf(','); if (firstComma != -1) { portNetworkId = port.substring(0, firstComma).toLowerCase(); } } else if (!WWNUtility.isValidWWN(port)) { portNetworkId = WWNUtility.getWWNWithColons(port); } return portNetworkId; } @Override public Object[] auditParameters() { return new Object[] { getInitiatorPort(), getInitiatorNode(), getHost(), getId() }; } @Override public int compareTo(Initiator that) { if (this == that) { return 0; } if (this.equals(that)) { return 0; } return this.getInitiatorPort().compareTo(that.getInitiatorPort()); } @Override public boolean equals(Object object) { if (!(object instanceof Initiator)) { return false; } if (this == object) { return true; } Initiator that = (Initiator) object; if (!this._id.equals(that._id)) { return false; } String thisPort = this.getInitiatorPort(); String thatPort = that.getInitiatorPort(); return thisPort.equals(thatPort); } @Override public int hashCode() { int result = hashCode; if (result == 0) { result = 17; result = 31 * result + _id.hashCode(); result = 31 * result + this.getInitiatorPort().hashCode(); hashCode = result; } return result; } @Override public String forDisplay() { return this.toString(); } }