/**
  * If any endpoint is used in an active File Export, throws an exception
  *
  * @param endpoints endpoints being added
  * @param varrays endpoints belong to
  *     <p>Assumes endpoint formats have been validated.
  */
 public static void checkNotUsedByActiveFileExport(String endpoint, DbClient dbClient) {
   Network network = NetworkUtil.getEndpointNetwork(endpoint, dbClient);
   if (network != null) {
     Set<String> netVArrayIds = network.getConnectedVirtualArrays();
     if ((netVArrayIds != null) && (!netVArrayIds.isEmpty())) {
       Iterator<String> netVArrayIdsIter = netVArrayIds.iterator();
       while (netVArrayIdsIter.hasNext()) {
         String varrayId = netVArrayIdsIter.next();
         List<FileShare> fileShares =
             CustomQueryUtility.queryActiveResourcesByConstraint(
                 dbClient,
                 FileShare.class,
                 AlternateIdConstraint.Factory.getConstraint(FileShare.class, "varray", varrayId));
         for (FileShare fileShare : fileShares) {
           FSExportMap fsExports = fileShare.getFsExports();
           if (fsExports != null) {
             Iterator<FileExport> it = fsExports.values().iterator();
             while (it.hasNext()) {
               FileExport fileExport = it.next();
               if (fileExport.getClients().contains(endpoint)
                   || fileExport.getStoragePort().contains(endpoint)) {
                 throw APIException.badRequests.endpointsCannotBeUpdatedActiveExport(endpoint);
               }
             }
           }
         }
       }
     }
   }
 }
  /**
   * If the endpoint is used in an active Export Group, throws an exception
   *
   * @param endpoint endpoint being added
   * @param dbClient Assumes endpoint formats have been validated.
   */
  public static void checkNotUsedByActiveExportGroup(String endpoint, DbClient dbClient) {

    if (endpoint != null && !"".equals(endpoint)) {

      Initiator initiator = getInitiator(endpoint, dbClient);

      if (initiator != null && initiator.getId() != null) {
        if (NetworkUtil.isInitiatorInUse(initiator.getId(), dbClient)) {
          throw APIException.badRequests.endpointsCannotBeUpdatedActiveExport(endpoint);
        }
      }

      List<StoragePort> ports = findStoragePortsInDB(endpoint, dbClient);
      for (StoragePort port : ports) {
        if (port != null && port.getId() != null) {
          if (NetworkUtil.isBlockStoragePortInUse(port.getId(), dbClient)) {
            throw APIException.badRequests.endpointsCannotBeUpdatedActiveExport(endpoint);
          }
        }
      }
    }
  }
 /**
  * Creates a map of initiators grouped and keyed by their network. Initiators which are not in any
  * network are not returned.
  *
  * @param initiators the initiators
  * @param client
  * @return a map of network-to-initiators
  */
 public static Map<NetworkLite, List<Initiator>> getInitiatorsByNetwork(
     Collection<Initiator> initiators, DbClient dbClient) {
   Map<NetworkLite, List<Initiator>> map = new HashMap<NetworkLite, List<Initiator>>();
   NetworkLite network = null;
   List<Initiator> netInitiators = null;
   for (Initiator initiator : initiators) {
     network = NetworkUtil.getEndpointNetworkLite(initiator.getInitiatorPort(), dbClient);
     if (network != null) {
       netInitiators = map.get(network);
       if (netInitiators == null) {
         netInitiators = new ArrayList<Initiator>();
         map.put(network, netInitiators);
       }
       netInitiators.add(initiator);
     }
   }
   return map;
 }
  /**
   * Looks in the topology view for endpoints that accessible by routing
   *
   * @param networkSystem the network system being refreshed
   * @param updatedNetworks the networks that require updating
   * @param routedEndpoints the routed endpoints map of Fabric-WWN-to-endpoints-WWN
   * @throws Exception
   */
  private void updateRoutedNetworks(
      NetworkSystem networkSystem,
      List<Network> updatedNetworks,
      Map<String, Set<String>> routedEndpoints)
      throws Exception {
    // for each network, get the list of routed ports and locate them in other networks
    StringSet routedNetworks = null;
    Network routedNetwork = null;

    // get the current networks from the database
    Map<URI, Network> allNetworks = DataObjectUtils.toMap(getCurrentTransportZones());
    for (Network network : updatedNetworks) {
      // if this network has any routed endpoints
      Set<String> netRoutedEndpoints = routedEndpoints.get(NetworkUtil.getNetworkWwn(network));
      if (netRoutedEndpoints == null || netRoutedEndpoints.isEmpty()) {
        _log.debug("No routed endpoint in network {}", network.getNativeGuid());
        network.setRoutedNetworks(null);
      } else {
        _log.info(
            "Found {} routed endpoint in network {}", netRoutedEndpoints, network.getNativeGuid());
        routedNetworks = new StringSet();
        for (String endpoint : netRoutedEndpoints) {
          // find the source network of the routed endpoint
          routedNetwork = findNetworkForDiscoveredEndPoint(allNetworks.values(), endpoint, network);
          if (routedNetwork != null) { // it is possible we did not discover the source
            routedNetworks.add(routedNetwork.getId().toString());
          }
        }
        network.setRoutedNetworks(routedNetworks);
      }
      dbClient.updateAndReindexObject(network);
      _log.info("Updated routed networks for {} to {}", network.getNativeGuid(), routedNetworks);
    }
    // clean up transit networks from any one-way associations.
    // Transit networks will show any endpoints routed thru them
    // which may cause one-way associations in the routedNetworks.
    // For example if network A has ep1 and B has ep2 and there is
    // a routed zone between A and B, the transit network C will
    // reports ep1 and ep2 but there is not actual routing between
    // C and A or C and B, so we want to remove these associations.
    for (URI id : allNetworks.keySet()) {
      Network net = allNetworks.get(id);
      boolean updated = false;
      if (net.getRoutedNetworks() != null) {
        routedNetworks = new StringSet(net.getRoutedNetworks());
        // for each network this network is pointing to
        for (String strUri : net.getRoutedNetworks()) {
          // get the opposite network
          Network opNet = allNetworks.get(URI.create(strUri));
          if (opNet != null // it is possible this network is getting removed - the next discovery
              // cleans up
              && opNet.getRoutedNetworks()
                  != null // check for null in case the other network routed eps are not yet visible
              && !opNet
                  .getRoutedNetworks()
                  .contains(net.getId().toString())) { // if the opposite network is not seeing this
            // one
            // remove this association because the opposite network is does not have the matching
            // association
            routedNetworks.remove(opNet.getId().toString());
            updated = true;
          }
        }
        if (updated) {
          _log.info("Reconciled routed networks for {} to {}", net.getNativeGuid(), routedNetworks);
          net.setRoutedNetworks(routedNetworks);
          dbClient.updateAndReindexObject(net);
        }
      }
    }
    for (Network network : allNetworks.values()) {
      NetworkAssociationHelper.setNetworkConnectedVirtualArrays(network, false, dbClient);
    }
    /*
     * COP-23266, COP-20698: Fix the problem that ViPR could not create IVR zone between VSANs routed by
     * transit VSAN(network), the "routedNetwork" field of "Network" data object should be updated based
     * on the transit network(s) if there is.
     */
    this.updateTransitRoutedNetworks(networkSystem);
  }