KEYCLOAK-16113 Add JPA event test

This commit is contained in:
Hynek Mlnarik 2020-10-30 12:32:15 +01:00 committed by Hynek Mlnařík
parent 18c67f51ce
commit f0bdcdd204
3 changed files with 253 additions and 4 deletions

View file

@ -29,6 +29,18 @@
<name>Keycloak Model JPA</name>
<description/>
<properties>
<keycloak.connectionsJpa.driver>org.h2.Driver</keycloak.connectionsJpa.driver>
<keycloak.connectionsJpa.database>keycloak</keycloak.connectionsJpa.database>
<keycloak.connectionsJpa.user>sa</keycloak.connectionsJpa.user>
<keycloak.connectionsJpa.password></keycloak.connectionsJpa.password>
<keycloak.connectionsJpa.url>jdbc:h2:mem:test;MVCC=TRUE;DB_CLOSE_DELAY=-1</keycloak.connectionsJpa.url>
<jdbc.mvn.groupId>com.h2database</jdbc.mvn.groupId>
<jdbc.mvn.artifactId>h2</jdbc.mvn.artifactId>
<jdbc.mvn.version>${h2.version}</jdbc.mvn.version>
<log4j.configuration>file:${project.build.directory}/dependency/log4j.properties</log4j.configuration>
</properties>
<dependencies>
<dependency>
<groupId>org.bouncycastle</groupId>
@ -60,10 +72,6 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>jakarta.persistence</groupId>
<artifactId>jakarta.persistence-api</artifactId>
@ -92,6 +100,50 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-core</artifactId>
</dependency>
<dependency>
<groupId>${jdbc.mvn.groupId}</groupId>
<artifactId>${jdbc.mvn.artifactId}</artifactId>
<version>${jdbc.mvn.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<systemPropertyVariables>
<keycloak.connectionsJpa.default.driver>${keycloak.connectionsJpa.driver}</keycloak.connectionsJpa.default.driver>
<keycloak.connectionsJpa.default.database>${keycloak.connectionsJpa.database}</keycloak.connectionsJpa.default.database>
<keycloak.connectionsJpa.default.user>${keycloak.connectionsJpa.user}</keycloak.connectionsJpa.default.user>
<keycloak.connectionsJpa.default.password>${keycloak.connectionsJpa.password}</keycloak.connectionsJpa.default.password>
<keycloak.connectionsJpa.default.url>${keycloak.connectionsJpa.url}</keycloak.connectionsJpa.default.url>
<log4j.configuration>file:${project.build.directory}/test-classes/log4j.properties</log4j.configuration> <!-- for the logging to properly work with tests in the 'other' module -->
</systemPropertyVariables>
</configuration>
</plugin>
</plugins>
</build>
</project>

View file

@ -0,0 +1,155 @@
/*
* Copyright 2020 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.events.jpa;
import org.keycloak.Config.Scope;
import org.keycloak.common.ClientConnection;
import org.keycloak.connections.jpa.DefaultJpaConnectionProviderFactory;
import org.keycloak.connections.jpa.JpaConnectionSpi;
import org.keycloak.connections.jpa.updater.JpaUpdaterProviderFactory;
import org.keycloak.connections.jpa.updater.JpaUpdaterSpi;
import org.keycloak.connections.jpa.updater.liquibase.conn.LiquibaseConnectionProviderFactory;
import org.keycloak.connections.jpa.updater.liquibase.conn.LiquibaseConnectionSpi;
import org.keycloak.connections.jpa.updater.liquibase.lock.LiquibaseDBLockProviderFactory;
import org.keycloak.events.EventBuilder;
import org.keycloak.events.EventStoreProvider;
import org.keycloak.events.EventStoreProviderFactory;
import org.keycloak.events.EventStoreSpi;
import org.keycloak.events.EventType;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RealmSpi;
import org.keycloak.models.dblock.DBLockSpi;
import org.keycloak.models.jpa.JpaRealmProviderFactory;
import org.keycloak.provider.Provider;
import org.keycloak.provider.ProviderFactory;
import org.keycloak.provider.ProviderManager;
import org.keycloak.provider.Spi;
import org.keycloak.services.DefaultKeycloakSession;
import org.keycloak.services.DefaultKeycloakSessionFactory;
import com.google.common.collect.ImmutableSet;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
/**
*
* @author hmlnarik
*/
public class JpaAdminEventQueryTest {
private static final Set<Class<? extends Spi>> ALLOWED_SPIS = ImmutableSet.<Class<? extends Spi>>builder()
.add(DBLockSpi.class)
.add(EventStoreSpi.class)
.add(JpaConnectionSpi.class)
.add(JpaUpdaterSpi.class)
.add(LiquibaseConnectionSpi.class)
.add(RealmSpi.class)
.build();
private static final Set<Class<? extends ProviderFactory>> ALLOWED_FACTORIES = ImmutableSet.<Class<? extends ProviderFactory>>builder()
.add(DefaultJpaConnectionProviderFactory.class)
.add(EventStoreProviderFactory.class)
.add(JpaUpdaterProviderFactory.class)
.add(JpaRealmProviderFactory.class)
.add(LiquibaseConnectionProviderFactory.class)
.add(LiquibaseDBLockProviderFactory.class)
.build();
private static final DefaultKeycloakSessionFactory factory = new DefaultKeycloakSessionFactory() {
@Override
protected boolean isEnabled(ProviderFactory factory, Scope scope) {
return super.isEnabled(factory, scope) && ALLOWED_FACTORIES.stream().filter(c -> c.isAssignableFrom(factory.getClass())).findAny().isPresent();
}
@Override
protected Map<Class<? extends Provider>, Map<String, ProviderFactory>> loadFactories(ProviderManager pm) {
spis.removeIf(s -> ! ALLOWED_SPIS.contains(s.getClass()));
return super.loadFactories(pm);
}
};
static { factory.init(); }
private final KeycloakSession session = new DefaultKeycloakSession(factory);
private final EventStoreProvider eventStore = session.getProvider(EventStoreProvider.class);
@Before
public void startTransaction() {
session.getTransactionManager().begin();
}
@After
public void stopTransaction() {
session.getTransactionManager().rollback();
}
@Test
public void testClear() {
eventStore.clear();
}
@Test
public void testQuery() {
RealmModel realm = session.realms().createRealm("realm");
ClientConnection cc = new DummyClientConnection();
eventStore.onEvent(new EventBuilder(realm, null, cc).event(EventType.LOGIN).user("u1").getEvent());
eventStore.onEvent(new EventBuilder(realm, null, cc).event(EventType.LOGIN).user("u2").getEvent());
eventStore.onEvent(new EventBuilder(realm, null, cc).event(EventType.LOGIN).user("u3").getEvent());
eventStore.onEvent(new EventBuilder(realm, null, cc).event(EventType.LOGIN).user("u4").getEvent());
assertThat(eventStore.createQuery()
.firstResult(2)
.getResultStream()
.collect(Collectors.counting()),
is(2L)
);
}
private static class DummyClientConnection implements ClientConnection {
@Override
public String getRemoteAddr() {
return "remoteAddr";
}
@Override
public String getRemoteHost() {
return "remoteHost";
}
@Override
public int getRemotePort() {
return -1;
}
@Override
public String getLocalAddr() {
return "localAddr";
}
@Override
public int getLocalPort() {
return -2;
}
}
}

View file

@ -0,0 +1,42 @@
#
# Copyright 2016 Red Hat, Inc. and/or its affiliates
# and other contributors as indicated by the @author tags.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
log4j.rootLogger=info, keycloak
log4j.appender.keycloak=org.apache.log4j.ConsoleAppender
log4j.appender.keycloak.layout=org.apache.log4j.EnhancedPatternLayout
keycloak.testsuite.logging.pattern=%d{HH:mm:ss,SSS} %-5p [%c] %m%n
log4j.appender.keycloak.layout.ConversionPattern=${keycloak.testsuite.logging.pattern}
# Logging with "info" when running test from IDE, but disabled when running test with "mvn" . Both cases can be overriden by use system property "keycloak.logging.level" (eg. -Dkeycloak.logging.level=debug )
log4j.logger.org.keycloak=${keycloak.logging.level:debug}
keycloak.testsuite.logging.level=debug
log4j.logger.org.keycloak.testsuite=${keycloak.testsuite.logging.level}
# Enable to view loaded SPI and Providers
log4j.logger.org.keycloak.services.DefaultKeycloakSessionFactory=debug
log4j.logger.org.keycloak.provider.ProviderManager=debug
# log4j.logger.org.keycloak.provider.FileSystemProviderLoaderFactory=debug
# Liquibase updates logged with "info" by default. Logging level can be changed by system property "keycloak.liquibase.logging.level"
keycloak.liquibase.logging.level=info
log4j.logger.org.keycloak.connections.jpa.updater.liquibase=${keycloak.liquibase.logging.level}
log4j.logger.org.keycloak.connections.jpa.DefaultJpaConnectionProviderFactory=debug
# Enable to log short stack traces for log entries enabled with StackUtil.getShortStackTrace() calls
# log4j.logger.org.keycloak.STACK_TRACE=trace