JsonValue performDynamicClientRegistration(
      final Context context,
      final JsonValue clientRegistrationConfiguration,
      final URI registrationEndpoint)
      throws RegistrationException {
    final Request request = new Request();
    request.setMethod("POST");
    request.setUri(registrationEndpoint);
    request.setEntity(clientRegistrationConfiguration.asMap());

    final Response response;
    try {
      response = blockingCall(registrationHandler, context, request);
    } catch (InterruptedException e) {
      throw new RegistrationException(
          format("Interrupted while waiting for '%s' response", request.getUri()), e);
    }
    if (!CREATED.equals(response.getStatus())) {
      throw new RegistrationException(
          "Cannot perform dynamic registration: this can be caused "
              + "by the distant server(busy, offline...) "
              + "or a malformed registration response.");
    }
    try {
      return getJsonContent(response);
    } catch (OAuth2ErrorException e) {
      throw new RegistrationException(
          "Cannot perform dynamic registration: invalid response JSON content.");
    }
  }
  /**
   * Retrieves all server info set on the server.
   *
   * @param context Current Server Context.
   * @param realm realm in whose security context we use.
   */
  private Promise<ResourceResponse, ResourceException> getAllServerInfo(
      Context context, String realm) {
    JsonValue result = new JsonValue(new LinkedHashMap<String, Object>(1));
    Set<String> cookieDomains;
    ResourceResponse resource;

    // added for the XUI to be able to understand its locale to request the appropriate translations
    // to cache
    ISLocaleContext localeContext = new ISLocaleContext();
    HttpContext httpContext = context.asContext(HttpContext.class);
    localeContext.setLocale(
        httpContext); // we have nothing else to go on at this point other than their request

    SelfServiceInfo selfServiceInfo = configHandler.getConfig(realm, SelfServiceInfoBuilder.class);
    RestSecurity restSecurity = restSecurityProvider.get(realm);
    Set<String> protectedUserAttributes = new HashSet<>();
    protectedUserAttributes.addAll(selfServiceInfo.getProtectedUserAttributes());
    protectedUserAttributes.addAll(restSecurity.getProtectedUserAttributes());

    try {
      cookieDomains = AuthClientUtils.getCookieDomains();
      result.put("domains", cookieDomains);
      result.put("protectedUserAttributes", protectedUserAttributes);
      result.put(
          "cookieName", SystemProperties.get(Constants.AM_COOKIE_NAME, "iPlanetDirectoryPro"));
      result.put("secureCookie", CookieUtils.isCookieSecure());
      result.put("forgotPassword", String.valueOf(selfServiceInfo.isForgottenPasswordEnabled()));
      result.put("forgotUsername", String.valueOf(selfServiceInfo.isForgottenUsernameEnabled()));
      result.put("kbaEnabled", String.valueOf(selfServiceInfo.isKbaEnabled()));
      result.put("selfRegistration", String.valueOf(selfServiceInfo.isUserRegistrationEnabled()));
      result.put("lang", getJsLocale(localeContext.getLocale()));
      result.put("successfulUserRegistrationDestination", "default");
      result.put("socialImplementations", getSocialAuthnImplementations(realm));
      result.put("referralsEnabled", Boolean.FALSE.toString());
      result.put("zeroPageLogin", AuthUtils.getZeroPageLoginConfig(realm));
      result.put("realm", realm);
      result.put(
          "xuiUserSessionValidationEnabled",
          SystemProperties.getAsBoolean(Constants.XUI_USER_SESSION_VALIDATION_ENABLED, true));

      if (debug.messageEnabled()) {
        debug.message(
            "ServerInfoResource.getAllServerInfo ::"
                + " Added resource to response: "
                + ALL_SERVER_INFO);
      }

      resource =
          newResourceResponse(ALL_SERVER_INFO, Integer.toString(result.asMap().hashCode()), result);

      return newResultPromise(resource);
    } catch (Exception e) {
      debug.error(
          "ServerInfoResource.getAllServerInfo : Cannot retrieve all server info domains.", e);
      return new NotFoundException(e.getMessage()).asPromise();
    }
  }
  @Test
  public void testReadSchedule() throws Exception {
    // given
    final ReadRequest readRequest = Requests.newReadRequest("test1");

    // when
    Promise<ResourceResponse, ResourceException> promise =
        schedulerService.handleRead(new RootContext(), readRequest);

    // then
    AssertJPromiseAssert.assertThat(promise).isNotNull().succeeded();
    ResourceResponse resourceResponse = promise.getOrThrow();
    assertThat(resourceResponse.getContent().asMap()).isEqualTo(testScheduleConfig.asMap());
  }
  /**
   * Will validate the Json representation of the service configuration against the serviceSchema
   * for a realm, and return a corresponding Map representation.
   *
   * @param jsonValue The request body.
   * @param realm The realm, or null if global.
   * @return Map representation of jsonValue
   */
  public Map<String, Set<String>> fromJson(String realm, JsonValue jsonValue)
      throws JsonException, BadRequestException {
    if (!initialised) {
      init();
    }

    Map<String, Set<String>> result = new HashMap<>();
    if (jsonValue == null || jsonValue.isNull()) {
      return result;
    }
    Map<String, Object> translatedAttributeValuePairs =
        getTranslatedAttributeValuePairs(jsonValue.asMap());

    for (String attributeName : translatedAttributeValuePairs.keySet()) {

      // Ignore _id field used to name resource when creating
      if (ResourceResponse.FIELD_CONTENT_ID.equals(attributeName)) {
        continue;
      }

      if (shouldNotBeUpdated(attributeName)) {
        throw new BadRequestException("Invalid attribute, '" + attributeName + "', specified");
      }

      if (shouldBeIgnored(attributeName)) {
        continue;
      }

      final Object attributeValue = translatedAttributeValuePairs.get(attributeName);
      Set<String> value = new HashSet<>();

      if (attributeValue instanceof HashMap) {
        final HashMap<String, Object> attributeMap = (HashMap<String, Object>) attributeValue;
        for (String name : attributeMap.keySet()) {
          value.add("[" + name + "]=" + convertJsonToString(attributeName, attributeMap.get(name)));
        }
      } else if (attributeValue instanceof List) {
        List<Object> attributeArray = (ArrayList<Object>) attributeValue;
        for (Object val : attributeArray) {
          value.add(convertJsonToString(attributeName, val));
        }
      } else {
        value.add(convertJsonToString(attributeName, attributeValue));
      }
      result.put(attributeName, value);
    }

    try {
      if (result.isEmpty()
          || (realm == null && schema.validateAttributes(result))
          || (realm != null && schema.validateAttributes(result, realm))) {
        return result;
      } else {
        throw new JsonException("Invalid attributes");
      }
    } catch (InvalidAttributeValueException e) {
      throw new BadRequestException(e.getLocalizedMessage(), e);
    } catch (SMSException e) {
      throw new JsonException("Unable to validate attributes", e);
    }
  }