@TransactionAttribute(TransactionAttributeType.SUPPORTS)
  public Network verifyNetworkByKey(NullableWrapper<Network> network, AccessKey key) {
    Network stored;

    // case network is not defined
    if (network == null || network.getValue() == null) {
      return null;
    }

    Network update = network.getValue();

    if (update.getId() != null) {
      stored = networkDAO.getById(update.getId());
    } else {
      stored = networkDAO.findByName(update.getName());
    }
    if (stored != null) {
      if (stored.getKey() != null) {
        if (!stored.getKey().equals(update.getKey())) {
          throw new HiveException(Messages.INVALID_NETWORK_KEY, FORBIDDEN.getStatusCode());
        }
        if (!accessKeyService.hasAccessToNetwork(key, stored)) {
          throw new HiveException(Messages.NO_ACCESS_TO_NETWORK, FORBIDDEN.getStatusCode());
        }
      }
    }
    return stored;
  }
  @TransactionAttribute(TransactionAttributeType.SUPPORTS)
  public Network createOrVeriryNetwork(NullableWrapper<Network> network) {
    Network stored;
    // case network is not defined
    if (network == null || network.getValue() == null) {
      return null;
    }
    Network update = network.getValue();

    if (update.getId() != null) {
      stored = networkDAO.getById(update.getId());
    } else {
      stored = networkDAO.findByName(update.getName());
    }

    if (stored != null) {
      if (stored.getKey() != null) {
        if (!stored.getKey().equals(update.getKey())) {
          throw new HiveException(Messages.INVALID_NETWORK_KEY, FORBIDDEN.getStatusCode());
        }
      }
    } else {
      if (update.getId() != null) {
        throw new HiveException(Messages.INVALID_REQUEST_PARAMETERS, BAD_REQUEST.getStatusCode());
      }
      stored = networkDAO.createNetwork(update);
    }
    assert (stored != null);
    return stored;
  }
 public Network create(Network newNetwork) {
   if (newNetwork.getId() != null) {
     throw new HiveException(Messages.ID_NOT_ALLOWED, BAD_REQUEST.getStatusCode());
   }
   Network existing = networkDAO.findByName(newNetwork.getName());
   if (existing != null) {
     throw new HiveException(Messages.DUPLICATE_NETWORK, FORBIDDEN.getStatusCode());
   }
   return networkDAO.createNetwork(newNetwork);
 }
  @TransactionAttribute(TransactionAttributeType.SUPPORTS)
  public Network createOrUpdateNetworkByUser(NullableWrapper<Network> network, User user) {
    Network stored;

    // case network is not defined
    if (network == null || network.getValue() == null) {
      return null;
    }

    Network update = network.getValue();

    if (update.getId() != null) {
      stored = networkDAO.getWithDevicesAndDeviceClasses(update.getId());
    } else {
      stored = networkDAO.findByName(update.getName());
    }

    if (stored != null) {
      if (stored.getKey() != null) {
        if (!stored.getKey().equals(update.getKey())) {
          throw new HiveException(Messages.INVALID_NETWORK_KEY, FORBIDDEN.getStatusCode());
        }
      }
      if (!userService.hasAccessToNetwork(user, stored)) {
        throw new HiveException(Messages.NO_ACCESS_TO_NETWORK, FORBIDDEN.getStatusCode());
      }
    } else if (user.isAdmin()) {
      if (update.getId() != null) {
        throw new HiveException(Messages.INVALID_REQUEST_PARAMETERS, BAD_REQUEST.getStatusCode());
      }
      stored = networkDAO.createNetwork(update);

    } else {
      throw new HiveException(Messages.NETWORK_CREATION_NOT_ALLOWED, FORBIDDEN.getStatusCode());
    }
    return stored;
  }
  @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
  public User createUser(@NotNull User user, String password) {
    if (user.getId() != null) {
      throw new HiveException(Messages.ID_NOT_ALLOWED, BAD_REQUEST.getStatusCode());
    }
    user.setLogin(StringUtils.trim(user.getLogin()));
    User existing = userDAO.findByLogin(user.getLogin());
    if (existing != null) {
      throw new HiveException(Messages.DUPLICATE_LOGIN, FORBIDDEN.getStatusCode());
    }
    if (StringUtils.isEmpty(password)) {
      throw new HiveException(Messages.PASSWORD_REQUIRED, BAD_REQUEST.getStatusCode());
    }
    String salt = passwordService.generateSalt();
    String hash = passwordService.hashPassword(password, salt);
    user.setPasswordSalt(salt);
    user.setPasswordHash(hash);
    user.setLoginAttempts(Constants.INITIAL_LOGIN_ATTEMPTS);

    hiveValidator.validate(user);
    return userDAO.create(user);
  }
  @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
  public User updateUser(@NotNull Long id, UserUpdate userToUpdate) {
    User existing = userDAO.findById(id);

    if (existing == null) {
      throw new HiveException(
          String.format(Messages.USER_NOT_FOUND, id), NOT_FOUND.getStatusCode());
    }
    if (userToUpdate == null) {
      return existing;
    }
    if (userToUpdate.getLogin() != null) {
      String newLogin = StringUtils.trim(userToUpdate.getLogin().getValue());
      User withSuchLogin = userDAO.findByLogin(newLogin);
      if (withSuchLogin != null && !withSuchLogin.getId().equals(id)) {
        throw new HiveException(Messages.DUPLICATE_LOGIN, FORBIDDEN.getStatusCode());
      }
      existing.setLogin(newLogin);
    }
    if (userToUpdate.getPassword() != null) {
      if (StringUtils.isEmpty(userToUpdate.getPassword().getValue())) {
        throw new HiveException(Messages.PASSWORD_REQUIRED, BAD_REQUEST.getStatusCode());
      }
      String salt = passwordService.generateSalt();
      String hash = passwordService.hashPassword(userToUpdate.getPassword().getValue(), salt);
      existing.setPasswordSalt(salt);
      existing.setPasswordHash(hash);
    }
    if (userToUpdate.getRole() != null) {
      existing.setRole(userToUpdate.getRoleEnum());
    }
    if (userToUpdate.getStatus() != null) {
      existing.setStatus(userToUpdate.getStatusEnum());
    }

    hiveValidator.validate(existing);
    return userDAO.update(existing);
  }