/* * Copyright 2016 Intel Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package com.emc.storageos.db.client.upgrade.callbacks; import java.net.URI; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import com.emc.storageos.svcs.errorhandling.resources.MigrationCallbackException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.emc.storageos.db.client.DbClient; import com.emc.storageos.db.client.URIUtil; import com.emc.storageos.db.client.model.QosSpecification; import com.emc.storageos.db.client.model.StringMap; import com.emc.storageos.db.client.model.VirtualPool; import com.emc.storageos.db.client.upgrade.BaseCustomMigrationCallback; /** * DB Migration callback to populate Quality of Service objects for * pre-existing Virtual Pools. * */ public class QualityOfServiceMigration extends BaseCustomMigrationCallback{ private static final Logger _log = LoggerFactory.getLogger(QualityOfServiceMigration.class); private static final String SYSTEM_TYPE = "system_type"; private static final String RAID_LEVEL = "raid_level"; private static final Integer UNLIMITED_SNAPSHOTS = -1; private static final Integer DISABLED_SNAPSHOTS = 0; private static final String QOS_CONSUMER = "back-end"; private static final String QOS_NAME = "specs-"; // with appended Virtual Pool label // QoS spec labels private static final String SPEC_PROVISIONING_TYPE = "Provisioning Type"; private static final String SPEC_PROTOCOL = "Protocol"; private static final String SPEC_DRIVE_TYPE = "Drive Type"; private static final String SPEC_SYSTEM_TYPE = "System Type"; private static final String SPEC_MULTI_VOL_CONSISTENCY = "Multi-Volume Consistency"; private static final String SPEC_RAID_LEVEL = "RAID Level"; private static final String SPEC_EXPENDABLE = "Expendable"; private static final String SPEC_MAX_SAN_PATHS = "Maximum SAN paths"; private static final String SPEC_MIN_SAN_PATHS = "Minimum SAN paths"; private static final String SPEC_MAX_BLOCK_MIRRORS = "Maximum block mirrors"; private static final String SPEC_PATHS_PER_INITIATOR = "Paths per Initiator"; private static final String SPEC_HIGH_AVAILABILITY = "High Availability"; private static final String SPEC_MAX_SNAPSHOTS = "Maximum Snapshots"; private static final String LABEL_DISABLED_SNAPSHOTS = "disabled"; private static final String LABEL_UNLIMITED_SNAPSHOTS = "unlimited"; @Override public void process() throws MigrationCallbackException { _log.debug("START - QualityOfServiceMigration callback"); DbClient _dbClient = getDbClient(); List<QosSpecification> qosSpecifications = new ArrayList<>(); List<URI> virtualPoolURIs = _dbClient.queryByType(VirtualPool.class, true); Iterator<VirtualPool> vpIter = _dbClient.queryIterativeObjects(VirtualPool.class, virtualPoolURIs); while (vpIter.hasNext()) { VirtualPool virtualPool = vpIter.next(); if(virtualPool != null){ _log.info("Virtual Pool found, id: {}", virtualPool.getId()); QosSpecification qosSpecification = getDataFromVirtualPool(virtualPool); qosSpecifications.add(qosSpecification); } } if(!qosSpecifications.isEmpty()){ _dbClient.createObject(qosSpecifications); } _log.debug("END - QualityOfServiceMigration callback"); } /** * Retrieves information from given Virtual Pool * * @param virtualPool Virtual Pool * @return QosSpecification filled with information from Virtual Pool */ private QosSpecification getDataFromVirtualPool(VirtualPool virtualPool) throws MigrationCallbackException { _log.debug("Fetching data from Virtual Pool, id: {}", virtualPool.getId()); QosSpecification qos = null; try { qos = new QosSpecification(); StringMap specs = new StringMap(); qos.setName(QOS_NAME + virtualPool.getLabel()); qos.setConsumer(QOS_CONSUMER); qos.setLabel(virtualPool.getLabel()); qos.setId(URIUtil.createId(QosSpecification.class)); qos.setVirtualPoolId(virtualPool.getId()); String protocols = null; if (virtualPool.getProtocols() != null) { protocols = virtualPool.getProtocols().toString(); } if (protocols != null) { specs.put(SPEC_PROTOCOL, protocols.substring(1, protocols.length() - 1)); } if (virtualPool.getSupportedProvisioningType() != null) { specs.put(SPEC_PROVISIONING_TYPE, virtualPool.getSupportedProvisioningType()); } if (virtualPool.getDriveType() != null) { specs.put(SPEC_DRIVE_TYPE, virtualPool.getDriveType()); } String systemType = getSystemType(virtualPool); if (systemType != null) { specs.put(SPEC_SYSTEM_TYPE, systemType); } if (virtualPool.getMultivolumeConsistency() != null) { specs.put(SPEC_MULTI_VOL_CONSISTENCY, Boolean.toString(virtualPool.getMultivolumeConsistency())); } if (virtualPool.getArrayInfo() != null && virtualPool.getArrayInfo().get(RAID_LEVEL) != null) { specs.put(SPEC_RAID_LEVEL, virtualPool.getArrayInfo().get(RAID_LEVEL).toString()); } if (virtualPool.getExpandable() != null) { specs.put(SPEC_EXPENDABLE, Boolean.toString(virtualPool.getExpandable())); } if (virtualPool.getNumPaths() != null) { specs.put(SPEC_MAX_SAN_PATHS, Integer.toString(virtualPool.getNumPaths())); } if (virtualPool.getMinPaths() != null) { specs.put(SPEC_MIN_SAN_PATHS, Integer.toString(virtualPool.getMinPaths())); } if (virtualPool.getMaxNativeContinuousCopies() != null) { specs.put(SPEC_MAX_BLOCK_MIRRORS, Integer.toString(virtualPool.getMaxNativeContinuousCopies())); } if (virtualPool.getPathsPerInitiator() != null) { specs.put(SPEC_PATHS_PER_INITIATOR, Integer.toString(virtualPool.getPathsPerInitiator())); } if (virtualPool.getHighAvailability() != null) { specs.put(SPEC_HIGH_AVAILABILITY, virtualPool.getHighAvailability()); } if (virtualPool.getMaxNativeSnapshots() != null) { if (virtualPool.getMaxNativeSnapshots().equals(UNLIMITED_SNAPSHOTS)) { specs.put(SPEC_MAX_SNAPSHOTS, LABEL_UNLIMITED_SNAPSHOTS); }else if(virtualPool.getMaxNativeSnapshots().equals(DISABLED_SNAPSHOTS)){ specs.put(SPEC_MAX_SNAPSHOTS, LABEL_DISABLED_SNAPSHOTS); }else{ specs.put(SPEC_MAX_SNAPSHOTS, Integer.toString(virtualPool.getMaxNativeSnapshots())); } } qos.setSpecs(specs); } catch (Exception e) { String errorMsg = String.format("%s encounter unexpected error %s", getName(), e.getMessage()); _log.error(errorMsg); throw new MigrationCallbackException(errorMsg, e); } return qos; } /** * Gives systemType of the given vPool * * @param virtualPool * @return {@link String} vpool's systemType */ private String getSystemType(VirtualPool virtualPool) { String systemType = null; if (virtualPool != null && virtualPool.getArrayInfo() != null && virtualPool.getArrayInfo().containsKey(SYSTEM_TYPE)) { for (String sysType : virtualPool.getArrayInfo().get(SYSTEM_TYPE)) { systemType = sysType; break; } } return systemType; } }