@Override
  public Promise<ResourceResponse, ResourceException> createInstance(
      Context context, CreateRequest request) {
    TokenGenerationServiceInvocationState invocationState;
    try {
      invocationState = TokenGenerationServiceInvocationState.fromJson(request.getContent());
    } catch (Exception e) {
      logger.error(
          "Exception caught marshalling json into TokenGenerationServiceInvocationState instance: "
              + e);
      return new BadRequestException(e.getMessage(), e).asPromise();
    }
    SSOToken subjectToken;
    try {
      subjectToken = validateAssertionSubjectSession(invocationState);
    } catch (ForbiddenException e) {
      return e.asPromise();
    }

    STSInstanceState stsInstanceState;
    try {
      stsInstanceState = getSTSInstanceState(invocationState);
    } catch (ResourceException e) {
      return e.asPromise();
    }

    if (TokenType.SAML2.equals(invocationState.getTokenType())) {
      try {
        final String assertion =
            saml2TokenGeneration.generate(subjectToken, stsInstanceState, invocationState);
        return newResultPromise(issuedTokenResource(assertion));
      } catch (TokenCreationException e) {
        logger.error("Exception caught generating saml2 token: " + e, e);
        return e.asPromise();
      } catch (Exception e) {
        logger.error("Exception caught generating saml2 token: " + e, e);
        return new InternalServerErrorException(e.toString(), e).asPromise();
      }
    } else if (TokenType.OPENIDCONNECT.equals(invocationState.getTokenType())) {
      try {
        final String assertion =
            openIdConnectTokenGeneration.generate(subjectToken, stsInstanceState, invocationState);
        return newResultPromise(issuedTokenResource(assertion));
      } catch (TokenCreationException e) {
        logger.error("Exception caught generating OpenIdConnect token: " + e, e);
        return e.asPromise();
      } catch (Exception e) {
        logger.error("Exception caught generating OpenIdConnect token: " + e, e);
        return new InternalServerErrorException(e.toString(), e).asPromise();
      }
    } else {
      String message = "Bad request: unexpected token type:" + invocationState.getTokenType();
      logger.error(message);
      return new BadRequestException(message).asPromise();
    }
  }
 private STSInstanceState getSTSInstanceState(
     TokenGenerationServiceInvocationState invocationState) throws ResourceException {
   STSInstanceState stsInstanceState;
   try {
     if (AMSTSConstants.STSType.REST.equals(invocationState.getStsType())) {
       stsInstanceState =
           restSTSInstanceStateProvider.getSTSInstanceState(
               invocationState.getStsInstanceId(), invocationState.getRealm());
     } else if (AMSTSConstants.STSType.SOAP.equals(invocationState.getStsType())) {
       stsInstanceState =
           soapSTSInstanceStateProvider.getSTSInstanceState(
               invocationState.getStsInstanceId(), invocationState.getRealm());
     } else {
       String message =
           "Illegal STSType specified in TokenGenerationService invocation: "
               + invocationState.getStsType();
       logger.error(message);
       throw new BadRequestException(message);
     }
   } catch (TokenCreationException | STSPublishException e) {
     logger.error(
         "Exception caught obtaining the sts instance state necessary to generate a saml2 assertion: "
             + e,
         e);
     throw e;
   } catch (Exception e) {
     logger.error(
         "Exception caught obtaining the sts instance state necessary to generate a saml2 assertion: "
             + e,
         e);
     throw new InternalServerErrorException(e);
   }
   return stsInstanceState;
 }
 private SSOToken validateAssertionSubjectSession(
     TokenGenerationServiceInvocationState invocationState) throws ForbiddenException {
   SSOToken subjectToken;
   SSOTokenManager tokenManager;
   try {
     tokenManager = SSOTokenManager.getInstance();
     subjectToken = tokenManager.createSSOToken(invocationState.getSsoTokenString());
   } catch (SSOException e) {
     logger.debug(
         "Exception caught creating the SSO token from the token string, almost certainly "
             + "because token string does not correspond to a valid session: "
             + e);
     throw new ForbiddenException(e.toString(), e);
   }
   if (!tokenManager.isValidToken(subjectToken)) {
     throw new ForbiddenException("SSO token string does not correspond to a valid SSOToken");
   }
   try {
     AMIdentity subjectIdentity = IdUtils.getIdentity(subjectToken);
     String invocationRealm = invocationState.getRealm();
     String subjectSessionRealm = DNMapper.orgNameToRealmName(subjectIdentity.getRealm());
     logger.debug(
         "TokenGenerationService:validateAssertionSubjectSession subjectRealm "
             + subjectSessionRealm
             + " invocation realm: "
             + invocationRealm);
     if (!invocationRealm.equalsIgnoreCase(subjectSessionRealm)) {
       logger.error(
           "TokenGenerationService:validateAssertionSubjectSession realms do not match: Subject realm : "
               + subjectSessionRealm
               + " invocation realm: "
               + invocationRealm);
       throw new ForbiddenException("SSO token subject realm does not match invocation realm");
     }
   } catch (SSOException | IdRepoException e) {
     logger.error(
         "TokenGenerationService:validateAssertionSubjectSession error while validating identity : "
             + e);
     throw new ForbiddenException(e.toString(), e);
   }
   return subjectToken;
 }