/** * Abiquo community edition * cloud management application for hybrid clouds * Copyright (C) 2008-2010 - Abiquo Holdings S.L. * * This application is free software; you can redistribute it and/or * modify it under the terms of the GNU LESSER GENERAL PUBLIC * LICENSE as published by the Free Software Foundation under * version 3 of the License * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * LESSER GENERAL PUBLIC LICENSE v.3 for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ package com.abiquo.model.util; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * utility methods to work with the iSCSI addressing model. * * @author ibarrera */ public class AddressingUtils { private static final String OCTET_PATTERN = "(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)"; private static final String IP_PATTERN = "(?:" + OCTET_PATTERN + "\\.){3}" + OCTET_PATTERN; private static final String PORT_PATTERN = "(?:6553[0-5]|655[0-2]\\d|65[0-4]\\d{2}|6[0-4]\\d{3}|[1-5]\\d{4}|[1-9]\\d{0,3})"; private static final String PORTAL_PATTERN = "(" + IP_PATTERN + "):(" + PORT_PATTERN + ")"; private static final String IQN_PATTERN = "iqn\\.\\d{4}-\\d{2}\\.[^:]+(?::.+)?"; private static final String LUN_PATTERN = "\\d+"; private static final String PARTITION_PATTERN = "\\d+"; private static final String PATH_PATTERN = "ip-(" + PORTAL_PATTERN + ")-iscsi-(" + IQN_PATTERN + ")-lun-(" + LUN_PATTERN + ")(?:-part(" + PARTITION_PATTERN + "))?"; private static final String DEVICE_ID_PATTERN = "[a-zA-Z0-9]{32}"; /** * Creates a new Path for the given parameters. * * @param ip The portal IP. * @param port The portal Port. * @param iqn The IQN. * @param lun The LUN. * @return The Path. * @throws IllegalArgumentException If any of the arguments has an invalid format. */ public static String toPath(final String ip, final int port, final String iqn, final int lun) { return toPath(ip + ":" + port, iqn, lun); } /** * Creates a new Path for the given parameters. * * @param portal The portal. * @param iqn The IQN. * @param lun The LUN. * @return The Path. * @throws IllegalArgumentException If any of the arguments has an invalid format. */ public static String toPath(final String portal, final String iqn, final int lun) { String path = String.format("ip-%s-iscsi-%s-lun-%d", portal, iqn, lun); if (!isValidPath(path)) { throw new IllegalArgumentException("The provided parameters do not have a valid format."); } return path; } /** * Checks if the provided IP is valid. * * @param ip The IP to check. * @return Boolean indicating if the specified IP is valid. */ public static boolean isValidIP(final String ip) { return ip.matches(IP_PATTERN); } /** * Checks if the provided Port is valid. * * @param port The Port to check. * @return Boolean indicating if the specified Port is valid. */ public static boolean isValidPort(final String port) { return port.matches(PORT_PATTERN); } /** * Checks if the provided IQN is valid. * * @param iqn The IQN to check. * @return Boolean indicating if the specified IQN is valid. */ public static boolean isValidIQN(final String iqn) { return iqn.matches(IQN_PATTERN); } /** * Checks if the provided Portal is valid. * * @param portal The Portal to check. * @return Boolean indicating if the specified Portal is valid. */ public static boolean isValidPortal(final String portal) { return portal.matches(PORTAL_PATTERN); } /** * Checks if the provided Device Path is valid. * * @param iscsiPath The Device Path to check. * @return Boolean indicating if the specified Device Path is valid. */ public static boolean isValidPath(final String path) { return path.matches(PATH_PATTERN); } /** * Checks if the provided Device Id is valid. * * @param deviceId The Device Id to check. * @return Boolean indicating if the specified Device Id is valid. */ public static boolean isValidDeviceId(final String deviceId) { return deviceId.matches(DEVICE_ID_PATTERN); } /** * Gets the IP from the specified path. * * @param path The path. * @return The IP. * @throws IllegalArgumentException If the provided path has not a valid format. */ public static String getIP(final String path) { return getPart(path, 2); } /** * Gets the Port from the specified path. * * @param path The path. * @return The Port. * @throws IllegalArgumentException If the provided path has not a valid format. */ public static String getPort(final String path) { return getPart(path, 3); } /** * Gets the Portal from the specified path. * * @param path The path. * @return The Portal. * @throws IllegalArgumentException If the provided path has not a valid format. */ public static String getPortal(final String path) { return getPart(path, 1); } /** * Gets the Portal from the specified url. * * @param url The url. * @return The Portal. */ public static String getPortalFromURL(final String url) { Pattern p = Pattern.compile(".*//(" + PORTAL_PATTERN + ").*"); Matcher m = p.matcher(url); if (!m.matches()) { throw new IllegalArgumentException("The url has an invalid format"); } return m.group(1); } /** * Gets the IQN from the specified path. * * @param path The path. * @return The IQN. * @throws IllegalArgumentException If the provided path has not a valid format. */ public static String getIQN(final String path) { return getPart(path, 4); } /** * TODO should return Integer (for ''toPath'' parameter type compatibility) * <p> * Gets the LUN from the specified path. * * @param path The path. * @return The LUN. * @throws IllegalArgumentException If the provided path has not a valid format. */ public static String getLUN(final String path) { return getPart(path, 5); } /** * Gets the Partition from the specified path. * * @param path The path. * @return The Partition. * @throws IllegalArgumentException If the provided path has not a valid format. */ public static String getPartition(final String path) { return getPart(path, 6); } /** * Gets the specified field of the provided path. * * @param path The path to parse. * @param part The field to get. * @return The value of the field. */ private static String getPart(final String path, final int part) { if (!isValidPath(path)) { throw new IllegalArgumentException("The path has an invalid format"); } Pattern p = Pattern.compile(PATH_PATTERN); Matcher m = p.matcher(path); if (!m.matches()) { throw new IllegalArgumentException("The path has an invalid format"); } return m.group(part); } /** Used to split the SSM response to obtain the target IQN and the visible LUN. */ private final static String LUN_SEPARATOR = "-lun-"; /** * Gets the IQN fragment of the SSM response. * * @param mapping, the the response of the SSM including the volume IQN and the LUN where the * initiator can reach the volume. * @return the IQN part of the mapping */ public static String getIqnFromSSMMappingResponse(final String mapping) { final Integer lunSeparator = mapping.indexOf(LUN_SEPARATOR); if (lunSeparator == -1) { final String cause = String.format("Malformed initiator mapping (expected {iqn}-lun-{lunid}) [%s]", mapping); throw new IllegalArgumentException(cause); } final String iqn = mapping.substring(0, lunSeparator); return iqn; } /** * Gets the LUN fragment of the SSM response. * * @param mapping, the the response of the SSM including the volume IQN and the LUN where the * initiator can reach the volume. * @return the LUN part of the mapping */ public static Integer getLunFromSSMMappingResponse(final String mapping) { final Integer lunSeparator = mapping.indexOf(LUN_SEPARATOR); if (lunSeparator == -1) { final String cause = String.format("Malformed initiator mapping (expected {iqn}-lun-{lunid}) [%s]", mapping); throw new IllegalArgumentException(cause); } String lun = mapping.substring(lunSeparator + LUN_SEPARATOR.length()); try { return Integer.parseInt(lun); } catch (Exception e) { final String cause = String.format("Malformed initiator mapping LUN (expected Integer lunid) [%s]", lun); throw new IllegalArgumentException(cause); } } }