public Optional<Session> login(@Nullable String currentSessionId, String host,
                                   ActorAwareAuthenticationToken authToken) throws AuthenticationServiceUnavailableException {

        final String previousSessionId = StringUtils.defaultIfBlank(currentSessionId, null);
        final Subject subject = new Subject.Builder().sessionId(previousSessionId).host(host).buildSubject();

        ThreadContext.bind(subject);

        try {
            final Session session = subject.getSession();

            subject.login(authToken);

            return createSession(subject, session, host);
        } catch (AuthenticationServiceUnavailableException e) {
            log.info("Session creation failed due to authentication service being unavailable. Actor: \"{}\"",
                    authToken.getActor().urn());
            final Map<String, Object> auditEventContext = ImmutableMap.of(
                    "remote_address", host,
                    "message", "Authentication service unavailable: " + e.getMessage()
            );
            auditEventSender.failure(authToken.getActor(), SESSION_CREATE, auditEventContext);
            throw e;
        } catch (AuthenticationException e) {
            log.info("Invalid credentials in session create request. Actor: \"{}\"", authToken.getActor().urn());
            final Map<String, Object> auditEventContext = ImmutableMap.of(
                    "remote_address", host
            );
            auditEventSender.failure(authToken.getActor(), SESSION_CREATE, auditEventContext);
            return Optional.empty();
        }
    }
@Test
    public void serviceUnavailable() {
        setUpUserMock();

        assertFalse(SecurityUtils.getSubject().isAuthenticated());

        // First realm will throw, second realm will be unable to authenticate because user has no account
        securityManager.setRealms(ImmutableList.of(throwingRealm(), new SimpleAccountRealm()));

        assertThatThrownBy(() -> sessionCreator.login(null, "host", validToken)).isInstanceOf(
                AuthenticationServiceUnavailableException.class);
        assertThat(SecurityUtils.getSubject().isAuthenticated()).isFalse();
        verify(auditEventSender).failure(eq(AuditActor.user("username")), anyString(),
                argThat(map -> StringUtils.containsIgnoreCase((String) map.get("message"), "unavailable")));
    }