@Test
  public void testAddUserDuplicateByAdmin() throws Exception {

    String testUser = "******";
    String testPassword = "******";
    IRODSAccount irodsAccount =
        testingPropertiesHelper.buildIRODSAccountFromTestProperties(testingProperties);

    IRODSAccessObjectFactory accessObjectFactory = irodsFileSystem.getIRODSAccessObjectFactory();

    UserAO userAO = accessObjectFactory.getUserAO(irodsAccount);
    userAO.deleteUser(testUser);
    User user = new User();
    user.setName(testUser);
    user.setUserType(UserTypeEnum.RODS_USER);
    userAO.addUser(user);

    StringBuilder sb = new StringBuilder();
    sb.append("http://localhost:");
    sb.append(
        testingPropertiesHelper.getPropertyValueAsInt(
            testingProperties, RestTestingProperties.REST_PORT_PROPERTY));
    sb.append("/user/");

    DefaultHttpClientAndContext clientAndContext =
        RestAuthUtils.httpClientSetup(irodsAccount, testingProperties);
    try {

      HttpPut httpPut = new HttpPut(sb.toString());
      httpPut.addHeader("accept", "application/json");
      httpPut.addHeader("Content-Type", "application/json");

      ObjectMapper mapper = new ObjectMapper();
      UserAddByAdminRequest addRequest = new UserAddByAdminRequest();
      addRequest.setDistinguishedName("dn here");
      addRequest.setTempPassword(testPassword);
      addRequest.setUserName(testUser);
      String body = mapper.writeValueAsString(addRequest);

      System.out.println(body);

      httpPut.setEntity(new StringEntity(body));

      HttpResponse response =
          clientAndContext.getHttpClient().execute(httpPut, clientAndContext.getHttpContext());
      HttpEntity entity = response.getEntity();
      Assert.assertEquals(200, response.getStatusLine().getStatusCode());
      String entityData = EntityUtils.toString(entity);

      System.out.println(entityData);

      UserAddActionResponse actual = mapper.readValue(entityData, UserAddActionResponse.class);
      Assert.assertEquals(testUser, actual.getUserName());
      Assert.assertEquals(
          UserAddActionResponse.UserAddActionResponseCode.USER_NAME_IS_TAKEN,
          actual.getUserAddActionResponse());
      Assert.assertEquals(
          UserAddActionResponse.UserAddActionResponseCode.USER_NAME_IS_TAKEN.ordinal(),
          actual.getUserAddActionResponseNumericCode());

    } finally {
      // When HttpClient instance is no longer needed,
      // shut down the connection manager to ensure
      // immediate deallocation of all system resources
      clientAndContext.getHttpClient().getConnectionManager().shutdown();
    }
  }
  /**
   * Add a user and set the password based on a {@link UserAddByAdminRequest}, which is expected as
   * a JSON structure in the PUT message body. This method will return a JSON structure reflecting
   * {@link UserAddActionResponse} with error or success details.
   *
   * <p>In iRODS, this method will add the user and set a temporary password as described in the
   * JSON request.
   *
   * <p>Note that any Jargon or other exceptions are trapped and returned to the caller in the
   * response.
   *
   * @param authorization BasicAuth info
   * @param userAddByAdminRequest {@link UserAddByAdminRequest}
   * @return {@link UserAddActionResponse}
   */
  @PUT
  @Consumes("application/json")
  @Mapped(
      namespaceMap = {
        @XmlNsMap(namespace = "http://irods.org/irods-rest", jsonName = "irods-rest")
      })
  public UserAddActionResponse addUser(
      @HeaderParam("Authorization") final String authorization,
      final UserAddByAdminRequest userAddByAdminRequest) {
    log.info("addUser()");
    UserAddActionResponse response = new UserAddActionResponse();

    if (userAddByAdminRequest == null) {
      log.error("request not found");
      response.setUserAddActionResponse(UserAddActionResponseCode.ATTRIBUTES_MISSING);
      response.setMessage("null userAddByAdminRequest");
      return response;
    }

    log.info("userAddByAdminRequest:{}", userAddByAdminRequest);

    if (userAddByAdminRequest.getUserName() == null
        || userAddByAdminRequest.getUserName().isEmpty()) {
      log.error("user name missing");
      response.setMessage("User name is missing in the request");
      response.setUserAddActionResponse(UserAddActionResponseCode.ATTRIBUTES_MISSING);
      return response;
    }

    if (userAddByAdminRequest.getTempPassword() == null
        || userAddByAdminRequest.getTempPassword().isEmpty()) {
      log.error("temp password is missing");
      response.setMessage("temp password is missing in the request");
      response.setUserName(userAddByAdminRequest.getUserName());
      response.setUserAddActionResponse(UserAddActionResponseCode.ATTRIBUTES_MISSING);
      return response;
    }

    try {
      IRODSAccount irodsAccount =
          RestAuthUtils.getIRODSAccountFromBasicAuthValues(authorization, getRestConfiguration());

      UserAO userAO = getIrodsAccessObjectFactory().getUserAO(irodsAccount);

      log.info("adding user based on:{}", userAddByAdminRequest);
      User user = new User();
      user.setName(userAddByAdminRequest.getUserName());
      user.setUserDN(userAddByAdminRequest.getDistinguishedName());
      user.setUserType(UserTypeEnum.RODS_USER);
      userAO.addUser(user);
      log.info("user added... set the password");

      userAO.changeAUserPasswordByAnAdmin(user.getName(), userAddByAdminRequest.getTempPassword());
      log.info("password was set to requested value");

      response.setMessage("success");
      response.setUserName(userAddByAdminRequest.getUserName());
      response.setUserAddActionResponse(UserAddActionResponseCode.SUCCESS);
      response.setIrodsEnv(
          ConfigurationUtils.buildIrodsEnvForConfigAndUser(
              getRestConfiguration(), user.getNameWithZone()));
      response.setWebAccessURL(getRestConfiguration().getWebInterfaceURL());
      return response;
    } catch (DuplicateDataException dde) {
      log.error("duplicate data for user add", dde);
      response.setMessage(dde.getMessage());
      response.setUserName(userAddByAdminRequest.getUserName());
      response.setUserAddActionResponse(UserAddActionResponseCode.USER_NAME_IS_TAKEN);
      return response;
    } catch (JargonException je) {
      log.error("Jargon exception in user add", je);
      response.setMessage(je.getMessage());
      response.setUserName(userAddByAdminRequest.getUserName());
      response.setUserAddActionResponse(UserAddActionResponseCode.INTERNAL_ERROR);
      return response;
    } finally {
      getIrodsAccessObjectFactory().closeSessionAndEatExceptions();
    }
  }
  @Test
  public void testAddUserByAdminLongDn() throws Exception {

    String testUser = "******";
    String testPassword = "******";
    String testDN =
        "/CN=xxxxxyyxx-64f0-4d49-a0a9-508a8a5328cd/emailAddress=xxxxxxxxxxthismaynotshowup";
    IRODSAccount irodsAccount =
        testingPropertiesHelper.buildIRODSAccountFromTestProperties(testingProperties);

    IRODSAccount userAccount =
        testingPropertiesHelper.buildIRODSAccountForIRODSUserFromTestPropertiesForGivenUser(
            testingProperties, testUser, testPassword);

    IRODSAccessObjectFactory accessObjectFactory = irodsFileSystem.getIRODSAccessObjectFactory();

    UserAO userAO = accessObjectFactory.getUserAO(irodsAccount);

    try {
      userAO.findByName(testUser);
      String homeDir = MiscIRODSUtils.computeHomeDirectoryForIRODSAccount(userAccount);
      IRODSFile userHomeDir =
          irodsFileSystem.getIRODSFileFactory(userAccount).instanceIRODSFile(homeDir);

      for (File homeDirFile : userHomeDir.listFiles()) {
        homeDirFile.delete();
      }
      userAO.deleteUser(testUser);

    } catch (DataNotFoundException dnf) {
      // OK
    }

    StringBuilder sb = new StringBuilder();
    sb.append("http://localhost:");
    sb.append(
        testingPropertiesHelper.getPropertyValueAsInt(
            testingProperties, RestTestingProperties.REST_PORT_PROPERTY));
    sb.append("/user/");

    DefaultHttpClientAndContext clientAndContext =
        RestAuthUtils.httpClientSetup(irodsAccount, testingProperties);
    try {

      HttpPut httpPut = new HttpPut(sb.toString());
      httpPut.addHeader("accept", "application/json");
      httpPut.addHeader("Content-Type", "application/json");

      ObjectMapper mapper = new ObjectMapper();
      UserAddByAdminRequest addRequest = new UserAddByAdminRequest();
      addRequest.setDistinguishedName(testDN);
      addRequest.setTempPassword(testPassword);
      addRequest.setUserName(testUser);
      String body = mapper.writeValueAsString(addRequest);

      System.out.println(body);

      httpPut.setEntity(new StringEntity(body));

      HttpResponse response =
          clientAndContext.getHttpClient().execute(httpPut, clientAndContext.getHttpContext());
      HttpEntity entity = response.getEntity();
      Assert.assertEquals(200, response.getStatusLine().getStatusCode());
      String entityData = EntityUtils.toString(entity);

      System.out.println(entityData);

      UserAddActionResponse actual = mapper.readValue(entityData, UserAddActionResponse.class);
      Assert.assertEquals(testUser, actual.getUserName());
      Assert.assertEquals(
          UserAddActionResponse.UserAddActionResponseCode.SUCCESS,
          actual.getUserAddActionResponse());
      Assert.assertEquals(
          UserAddActionResponse.UserAddActionResponseCode.SUCCESS.ordinal(),
          actual.getUserAddActionResponseNumericCode());

    } finally {
      // When HttpClient instance is no longer needed,
      // shut down the connection manager to ensure
      // immediate deallocation of all system resources
      clientAndContext.getHttpClient().getConnectionManager().shutdown();
    }

    User user = userAO.findByName(testUser);
    Assert.assertNotNull("user not added", user);
    Assert.assertEquals("dn not set", testDN, user.getUserDN());
  }