@Override
  public String getSecurityGroupsNamesForVm(long vmId) {
    try {
      List<SecurityGroupVMMapVO> networkGroupsToVmMap =
          _securityGroupVMMapDao.listByInstanceId(vmId);
      int size = 0;
      int j = 0;
      StringBuilder networkGroupNames = new StringBuilder();

      if (networkGroupsToVmMap != null) {
        size = networkGroupsToVmMap.size();

        for (SecurityGroupVMMapVO nG : networkGroupsToVmMap) {
          // get the group id and look up for the group name
          SecurityGroupVO currentNetworkGroup = _securityGroupDao.findById(nG.getSecurityGroupId());
          networkGroupNames.append(currentNetworkGroup.getName());

          if (j < (size - 1)) {
            networkGroupNames.append(",");
            j++;
          }
        }
      }

      return networkGroupNames.toString();
    } catch (Exception e) {
      s_logger.warn("Error trying to get network groups for a vm: " + e);
      return null;
    }
  }
  @Override
  @DB
  public boolean addInstanceToGroups(final Long userVmId, final List<Long> groups) {
    if (!isVmSecurityGroupEnabled(userVmId)) {
      s_logger.warn(
          "User vm " + userVmId + " is not security group enabled, can't add it to security group");
      return false;
    }
    if (groups != null && !groups.isEmpty()) {

      final Transaction txn = Transaction.currentTxn();
      txn.start();
      UserVm userVm =
          _userVMDao.acquireInLockTable(
              userVmId); // ensures that duplicate entries are not created.
      List<SecurityGroupVO> sgs = new ArrayList<SecurityGroupVO>();
      for (Long sgId : groups) {
        sgs.add(_securityGroupDao.findById(sgId));
      }
      final Set<SecurityGroupVO> uniqueGroups =
          new TreeSet<SecurityGroupVO>(new SecurityGroupVOComparator());
      uniqueGroups.addAll(sgs);
      if (userVm == null) {
        s_logger.warn("Failed to acquire lock on user vm id=" + userVmId);
      }
      try {
        for (SecurityGroupVO securityGroup : uniqueGroups) {
          // don't let the group be deleted from under us.
          SecurityGroupVO ngrpLock = _securityGroupDao.lockRow(securityGroup.getId(), false);
          if (ngrpLock == null) {
            s_logger.warn(
                "Failed to acquire lock on network group id="
                    + securityGroup.getId()
                    + " name="
                    + securityGroup.getName());
            txn.rollback();
            return false;
          }
          if (_securityGroupVMMapDao.findByVmIdGroupId(userVmId, securityGroup.getId()) == null) {
            SecurityGroupVMMapVO groupVmMapVO =
                new SecurityGroupVMMapVO(securityGroup.getId(), userVmId);
            _securityGroupVMMapDao.persist(groupVmMapVO);
          }
        }
        txn.commit();
        return true;
      } finally {
        if (userVm != null) {
          _userVMDao.releaseFromLockTable(userVmId);
        }
      }
    }
    return false;
  }
  @DB
  @Override
  @ActionEvent(
      eventType = EventTypes.EVENT_SECURITY_GROUP_DELETE,
      eventDescription = "deleting security group")
  public boolean deleteSecurityGroup(DeleteSecurityGroupCmd cmd) throws ResourceInUseException {
    Long groupId = cmd.getId();
    Account caller = UserContext.current().getCaller();

    SecurityGroupVO group = _securityGroupDao.findById(groupId);
    if (group == null) {
      throw new InvalidParameterValueException(
          "Unable to find network group: " + groupId + "; failed to delete group.");
    }

    // check permissions
    _accountMgr.checkAccess(caller, null, group);

    final Transaction txn = Transaction.currentTxn();
    txn.start();

    group = _securityGroupDao.lockRow(groupId, true);
    if (group == null) {
      throw new InvalidParameterValueException("Unable to find security group by id " + groupId);
    }

    if (group.getName().equalsIgnoreCase(SecurityGroupManager.DEFAULT_GROUP_NAME)) {
      throw new InvalidParameterValueException("The network group default is reserved");
    }

    List<IngressRuleVO> allowingRules = _ingressRuleDao.listByAllowedSecurityGroupId(groupId);
    List<SecurityGroupVMMapVO> securityGroupVmMap =
        _securityGroupVMMapDao.listBySecurityGroup(groupId);
    if (!allowingRules.isEmpty()) {
      throw new ResourceInUseException(
          "Cannot delete group when there are ingress rules that allow this group");
    } else if (!securityGroupVmMap.isEmpty()) {
      throw new ResourceInUseException("Cannot delete group when it's in use by virtual machines");
    }

    _securityGroupDao.expunge(groupId);
    txn.commit();

    s_logger.debug("Deleted security group id=" + groupId);

    return true;
  }