private void validateRecoverPoint(String formName) {
    Validation.required(formName + ".rpJournalSize", rpJournalSize);
    if (!RPCopyForm.isValidJournalSize(rpJournalSize, rpJournalSizeUnit)) {
      Validation.addError(formName + ".rpJournalSize", "validation.invalid");
    }

    Set<String> varrayIds = Sets.newHashSet();
    Set<String> vpoolIds = Sets.newHashSet();

    boolean hasCopies = false;
    for (RPCopyForm rpCopy : rpCopies) {
      if (rpCopy != null && rpCopy.isEnabled()) {
        hasCopies = true;
        rpCopy.validate(formName + ".rpCopies");

        if (StringUtils.isNotBlank(rpCopy.virtualArray)) {
          if (!varrayIds.add(rpCopy.virtualArray)) {
            Validation.addError(formName + ".rpCopies", "rpCopy.virtualArray.error.duplicate");
          }
        }
        if (StringUtils.isNotBlank(rpCopy.virtualPool)) {
          vpoolIds.add(rpCopy.virtualPool);
        }
      }
    }
    if (!hasCopies) {
      Validation.required(formName + ".rpCopies", null);
    }

    // Extra validation when mixed with high availability
    if (HighAvailability.isHighAvailability(highAvailability)) {
      if (!Boolean.TRUE.equals(multiVolumeConsistency)) {
        Validation.addError(
            formName + ".multiVolumeConsistency", "vpool.rp.error.notMultiVolumeConsistent");
      }
    }
  }
  private BlockVirtualPoolUpdateBuilder apply(BlockVirtualPoolUpdateBuilder builder) {
    applyCommon(builder);
    builder.setSnapshots(defaultInt(maxSnapshots));
    builder.setContinuousCopies(maxContinuousCopies, uri(continuousCopyVirtualPool));

    // Only allow updating these fields if not locked
    if (!isLocked()) {
      builder.setMinPaths(defaultInt(minPaths, 1));
      builder.setMaxPaths(defaultInt(maxPaths, 1));
      builder.setPathsPerInitiator(defaultInt(initiatorPaths, 1));
      builder.setAutoTieringPolicyName(autoTierPolicy);
      builder.setDriveType(driveType);
      builder.setExpandable(defaultBoolean(expandable));
      builder.setFastExpansion(defaultBoolean(fastExpansion));
      builder.setThinVolumePreAllocationPercentage(thinPreAllocationPercent);
      builder.setUniquePolicyNames(defaultBoolean(uniqueAutoTierPolicyNames));
      builder.setMultiVolumeConsistency(defaultBoolean(multiVolumeConsistency));
      builder.setRaidLevels(defaultSet(raidLevels));
      builder.setHostIOLimitBandwidth(defaultInt(hostIOLimitBandwidth, 0));
      builder.setHostIOLimitIOPs(defaultInt(hostIOLimitIOPs, 0));

      if (ProtectionSystemTypes.isRecoverPoint(remoteProtection)) {
        builder.setRecoverPointJournalSize(
            RPCopyForm.formatJournalSize(rpJournalSize, rpJournalSizeUnit));
        builder.setRecoverPointRemoteCopyMode(rpRemoteCopyMode);
        builder.setRecoverPointRpo(rpRpoValue, rpRpoType);
        Set<VirtualPoolProtectionVirtualArraySettingsParam> copies = Sets.newLinkedHashSet();
        for (RPCopyForm rpCopy : rpCopies) {
          if (rpCopy != null && rpCopy.isEnabled()) {
            copies.add(rpCopy.write());
          }
        }
        builder.setRecoverPointCopies(copies);
        builder.setJournalVarrayAndVpool(uri(sourceJournalVArray), uri(sourceJournalVPool));
      } else {
        builder.disableRecoverPoint();
      }

      if (ProtectionSystemTypes.isSRDF(remoteProtection)) {
        Set<VirtualPoolRemoteProtectionVirtualArraySettingsParam> copies = Sets.newHashSet();
        for (SrdfCopyForm srdfCopyForm : srdfCopies) {
          if (srdfCopyForm != null && srdfCopyForm.isEnabled()) {
            copies.add(srdfCopyForm.write(srdfCopyMode));
          }
        }
        builder.setRemoteCopies(copies);
      } else {
        builder.disableRemoteCopies();
      }

      if (HighAvailability.isHighAvailability(highAvailability)) {
        boolean activeProtectionAtHASite = BooleanUtils.isTrue(protectHASite);
        boolean metroPoint = false;
        if (BooleanUtils.isTrue(protectSourceSite) && BooleanUtils.isTrue(protectHASite)) {
          metroPoint = true;
          activeProtectionAtHASite =
              StringUtils.equalsIgnoreCase(activeSite, HighAvailability.VPLEX_HA);
          builder.setJournalVarrayAndVpool(uri(sourceJournalVArray), uri(sourceJournalVPool));
          builder.setStandByJournalVArrayVpool(uri(haJournalVArray), uri(haJournalVPool));
        } else {
          if (activeProtectionAtHASite) {
            builder.setJournalVarrayAndVpool(uri(haJournalVArray), uri(haJournalVPool));
          } else {
            builder.setJournalVarrayAndVpool(uri(sourceJournalVArray), uri(sourceJournalVPool));
          }
        }
        builder.setHighAvailability(
            highAvailability,
            enableAutoCrossConnExport,
            uri(haVirtualArray),
            uri(haVirtualPool),
            activeProtectionAtHASite,
            metroPoint);
      } else {
        builder.disableHighAvailability();
      }
    }

    return builder;
  }
  protected void doLoad(BlockVirtualPoolRestRep virtualPool) {
    loadCommon(virtualPool);
    minPaths = virtualPool.getMinPaths();
    maxPaths = virtualPool.getMaxPaths();
    initiatorPaths = virtualPool.getPathsPerInitiator();
    driveType = virtualPool.getDriveType();
    autoTierPolicy = virtualPool.getAutoTieringPolicyName();
    expandable = virtualPool.getExpandable();
    fastExpansion = virtualPool.getFastExpansion();
    multiVolumeConsistency = virtualPool.getMultiVolumeConsistent();
    thinPreAllocationPercent = virtualPool.getThinVolumePreAllocationPercentage();
    uniqueAutoTierPolicyNames = virtualPool.getUniquePolicyNames();
    raidLevels = defaultSet(virtualPool.getRaidLevels());
    hostIOLimitBandwidth = virtualPool.getHostIOLimitBandwidth();
    hostIOLimitIOPs = virtualPool.getHostIOLimitIOPs();

    VirtualPoolHighAvailabilityParam highAvailabilityType = virtualPool.getHighAvailability();
    if (highAvailabilityType != null
        && HighAvailability.isHighAvailability(highAvailabilityType.getType())) {
      highAvailability = highAvailabilityType.getType();
      if (highAvailability.equals(HighAvailability.VPLEX_LOCAL)) {
        protectSourceSite = true;
      }
      enableAutoCrossConnExport = highAvailabilityType.getAutoCrossConnectExport();
      if (highAvailabilityType.getHaVirtualArrayVirtualPool() != null) {
        haVirtualArray =
            asString(highAvailabilityType.getHaVirtualArrayVirtualPool().getVirtualArray());
        haVirtualPool =
            asString(highAvailabilityType.getHaVirtualArrayVirtualPool().getVirtualPool());

        Boolean activeProtectionAtHASite =
            Boolean.TRUE.equals(
                highAvailabilityType.getHaVirtualArrayVirtualPool().getActiveProtectionAtHASite());
        Boolean metroPoint = Boolean.TRUE.equals(highAvailabilityType.getMetroPoint());
        if (metroPoint) {
          protectSourceSite = true;
          protectHASite = true;
          if (activeProtectionAtHASite) {
            activeSite = HighAvailability.VPLEX_HA.toString();
          } else {
            activeSite = HighAvailability.VPLEX_SOURCE.toString();
            protectSourceSite = true;
          }
        } else {
          protectHASite = activeProtectionAtHASite;
          protectSourceSite = !protectHASite;
        }
      } else {
        protectSourceSite = true;
      }
    } else {
      protectSourceSite = true;
    }

    BlockVirtualPoolProtectionParam protection = virtualPool.getProtection();
    if (protection != null) {
      if (protection.getSnapshots() != null) {
        maxSnapshots = protection.getSnapshots().getMaxSnapshots();
      }
      if (protection.getContinuousCopies() != null) {
        maxContinuousCopies = protection.getContinuousCopies().getMaxMirrors();
        continuousCopyVirtualPool = asString(protection.getContinuousCopies().getVpool());
      }

      VirtualPoolProtectionRPParam recoverPoint = protection.getRecoverPoint();
      if (recoverPoint != null) {
        remoteProtection = ProtectionSystemTypes.RECOVERPOINT;
        ProtectionSourcePolicy sourcePolicy = recoverPoint.getSourcePolicy();
        if (sourcePolicy != null) {
          String journalSize = sourcePolicy.getJournalSize();
          rpJournalSizeUnit = RPCopyForm.parseJournalSizeUnit(journalSize);
          rpJournalSize =
              StringUtils.defaultIfBlank(
                  RPCopyForm.parseJournalSize(journalSize, rpJournalSizeUnit),
                  RPCopyForm.JOURNAL_SIZE_MIN);
          rpRemoteCopyMode = sourcePolicy.getRemoteCopyMode();
          rpRpoValue = sourcePolicy.getRpoValue();
          rpRpoType = sourcePolicy.getRpoType();
          if (protectHASite != null
              && protectSourceSite != null
              && protectHASite
              && protectSourceSite) {
            // Backend will take care of swapping
            // if(activeSite.equalsIgnoreCase(HighAvailability.VPLEX_SOURCE)){
            sourceJournalVArray = asString(sourcePolicy.getJournalVarray());
            sourceJournalVPool = asString(sourcePolicy.getJournalVpool());
            haJournalVArray = asString(sourcePolicy.getStandbyJournalVarray());
            haJournalVPool = asString(sourcePolicy.getStandbyJournalVpool());
          } else {
            if (protectHASite != null && protectHASite) {
              haJournalVArray = asString(sourcePolicy.getJournalVarray());
              haJournalVPool = asString(sourcePolicy.getJournalVpool());
            } else if (protectSourceSite != null && protectSourceSite) {
              sourceJournalVArray = asString(sourcePolicy.getJournalVarray());
              sourceJournalVPool = asString(sourcePolicy.getJournalVpool());
            }
          }
        }

        List<RPCopyForm> rpCopyForms = Lists.newArrayList();
        for (VirtualPoolProtectionVirtualArraySettingsParam copy : recoverPoint.getCopies()) {
          RPCopyForm rpCopy = new RPCopyForm();
          rpCopy.load(copy);
          rpCopyForms.add(rpCopy);
        }
        rpCopies = rpCopyForms.toArray(new RPCopyForm[0]);
        rpCopiesJson = new Gson().toJson(rpCopies);
      }
      VirtualPoolRemoteMirrorProtectionParam srdf = protection.getRemoteCopies();
      if (srdf != null) {
        remoteProtection = ProtectionSystemTypes.SRDF;

        List<SrdfCopyForm> copyForms = Lists.newArrayList();
        for (VirtualPoolRemoteProtectionVirtualArraySettingsParam copy :
            srdf.getRemoteCopySettings()) {
          srdfCopyMode = copy.getRemoteCopyMode();

          SrdfCopyForm srdfCopyForm = new SrdfCopyForm();
          srdfCopyForm.load(copy);
          copyForms.add(srdfCopyForm);
        }
        srdfCopies = copyForms.toArray(new SrdfCopyForm[0]);
        Gson gson = new Gson();
        srdfCopiesJson = gson.toJson(srdfCopies);
      } else {
        srdfCopiesJson = "[]";
      }
    }
  }