Skip to content

Commit

Permalink
Review
Browse files Browse the repository at this point in the history
Signed-off-by: Alexander Schwartz <[email protected]>
  • Loading branch information
ahus1 committed May 21, 2024
1 parent 91f5727 commit 804bfa0
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,14 @@

import java.util.UUID;

import jakarta.ws.rs.DefaultValue;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.NotFoundException;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;

import jakarta.ws.rs.QueryParam;
import org.infinispan.Cache;
import org.infinispan.commons.CacheConfigurationException;
import org.jboss.logging.Logger;
Expand Down Expand Up @@ -85,6 +87,31 @@ public boolean contains(@PathParam("id") String id) {
}
}

@GET
@Path("/remove/{id}")
@NoCache
@Produces(MediaType.APPLICATION_JSON)
public boolean remove(@PathParam("id") String id, @QueryParam("skipListeners") @DefaultValue("false") boolean skipListeners) {
if (decorateCacheForRemovalAndSkipListenersIfTrue(skipListeners).remove(id) != null) {
return true;
} else if (id.length() == 36) {
try {
UUID uuid = UUID.fromString(id);
return decorateCacheForRemovalAndSkipListenersIfTrue(skipListeners).remove(uuid) != null;
} catch (IllegalArgumentException iae) {
logger.warnf("Given string %s not an UUID", id);
return false;
}
} else {
return false;
}
}

public Cache decorateCacheForRemovalAndSkipListenersIfTrue(boolean skipListeners) {
return skipListeners
? cache.getAdvancedCache().withFlags(org.infinispan.context.Flag.SKIP_CACHE_STORE)
: cache.getAdvancedCache();
}
@GET
@Path("/size")
@NoCache
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public abstract class AbstractCrossDCTest {
protected static HttpClient HTTP_CLIENT = HttpClientUtils.newHttpClient();
protected static final DatacenterInfo DC_1, DC_2;
protected static final KeycloakClient LOAD_BALANCER_KEYCLOAK;
public static String ISPN_USERNAME = System.getProperty("infinispan.username", "developer");;
public static String ISPN_USERNAME = System.getProperty("infinispan.username", "developer");
public static final String REALM_NAME = "cross-dc-test-realm";
public static final String CLIENTID = "cross-dc-test-client";
public static final String CLIENT_SECRET = "cross-dc-test-client-secret";
Expand Down Expand Up @@ -109,10 +109,23 @@ public void setUpTestEnvironment() throws UnknownHostException {

realmResource.users().create(user).close();

clearCache(DC_1, SESSIONS);
clearCache(DC_1, CLIENT_SESSIONS);
clearCache(DC_2, SESSIONS);
clearCache(DC_2, CLIENT_SESSIONS);
assertCacheSize(SESSIONS, 0);
assertCacheSize(CLIENT_SESSIONS, 0);
}

private void clearCache(DatacenterInfo dc, String cache) {
dc.kc().embeddedIspn().cache(cache).clear();
dc.ispn().cache(cache).clear();
if (cache.equals(SESSIONS) || cache.equals(CLIENT_SESSIONS)) {
// those sessions will have been invalidated
KeycloakClient.cleanAdminClients();
}
}

@AfterEach
public void tearDownTestEnvironment() throws URISyntaxException, IOException, InterruptedException {
Keycloak adminClient = DC_1.kc().adminClient();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.keycloak.benchmark.crossdc;

import org.jboss.logging.Logger;
import org.junit.jupiter.api.Test;
import org.keycloak.benchmark.crossdc.util.InfinispanUtils;

Expand All @@ -16,6 +17,9 @@


public class LoginLogoutTest extends AbstractCrossDCTest {

protected static final Logger LOG = Logger.getLogger(LoginLogoutTest.class);

@Test
public void loginLogoutTest() throws URISyntaxException, IOException, InterruptedException {
//Login and exchange code in DC1
Expand Down Expand Up @@ -127,7 +131,7 @@ public void testRemoteStoreDiscrepancyMissingSessionInBackupRemoteISPN() throws
assertTrue(DC_2.kc().embeddedIspn().cache(SESSIONS).contains((String) tokensMap.get("session_state")));
assertTrue(DC_2.ispn().cache(SESSIONS).contains((String) tokensMap.get("session_state")));

// Remove the session from the remote store in DC1 only
// Remove the session from the remote store in DC2 only
try (var close = InfinispanUtils.withBackupDisabled(DC_2.ispn().cache(SESSIONS), DC_1.ispn().siteName())) {
assertFalse(DC_2.ispn().cache(SESSIONS).isBackupOnline(DC_1.ispn().siteName()));
DC_2.ispn().cache(SESSIONS).remove((String) tokensMap.get("session_state"));
Expand All @@ -148,4 +152,47 @@ public void testRemoteStoreDiscrepancyMissingSessionInBackupRemoteISPN() throws
assertFalse(DC_2.kc().embeddedIspn().cache(SESSIONS).contains((String) tokensMap.get("session_state")));
assertFalse(DC_2.ispn().cache(SESSIONS).contains((String) tokensMap.get("session_state")));
}

@Test
public void testRemoteStoreDiscrepancyMissingSessionInAllRemoteISPN() throws URISyntaxException, IOException, InterruptedException {
// Create a new user session
Map<String, Object> tokensMap = LOAD_BALANCER_KEYCLOAK.passwordGrant(REALM_NAME, CLIENTID, USERNAME, MAIN_PASSWORD);
LOG.info("processing session " + tokensMap.get("session_state"));

// Make sure all ISPNs can see the entry in the cache
assertTrue(DC_1.kc().embeddedIspn().cache(SESSIONS).contains((String) tokensMap.get("session_state")));
assertTrue(DC_1.ispn().cache(SESSIONS).contains((String) tokensMap.get("session_state")));
assertTrue(DC_2.kc().embeddedIspn().cache(SESSIONS).contains((String) tokensMap.get("session_state")));
assertTrue(DC_2.ispn().cache(SESSIONS).contains((String) tokensMap.get("session_state")));

// Remove the session from the remote store in DC1 only
try (var close = InfinispanUtils.withBackupDisabled(DC_1.ispn().cache(SESSIONS), DC_2.ispn().siteName())) {
assertFalse(DC_1.ispn().cache(SESSIONS).isBackupOnline(DC_2.ispn().siteName()));
DC_1.ispn().cache(SESSIONS).remove((String) tokensMap.get("session_state"));
} catch (Exception e) {
throw new RuntimeException(e);
}
assertTrue(DC_1.ispn().cache(SESSIONS).isBackupOnline(DC_2.ispn().siteName()));

// Remove the session from the remote store in DC2 only
try (var close = InfinispanUtils.withBackupDisabled(DC_2.ispn().cache(SESSIONS), DC_1.ispn().siteName())) {
assertFalse(DC_2.ispn().cache(SESSIONS).isBackupOnline(DC_1.ispn().siteName()));
DC_2.ispn().cache(SESSIONS).remove((String) tokensMap.get("session_state"));
} catch (Exception e) {
throw new RuntimeException(e);
}
assertTrue(DC_2.ispn().cache(SESSIONS).isBackupOnline(DC_1.ispn().siteName()));

assertTrue(DC_1.kc().embeddedIspn().cache(SESSIONS).contains((String) tokensMap.get("session_state")));
assertFalse(DC_1.ispn().cache(SESSIONS).contains((String) tokensMap.get("session_state")));
assertTrue(DC_2.kc().embeddedIspn().cache(SESSIONS).contains((String) tokensMap.get("session_state")));
assertFalse(DC_2.ispn().cache(SESSIONS).contains((String) tokensMap.get("session_state")));

LOAD_BALANCER_KEYCLOAK.logout(REALM_NAME, (String) tokensMap.get("id_token"), CLIENTID);

assertFalse(DC_1.kc().embeddedIspn().cache(SESSIONS).contains((String) tokensMap.get("session_state")));
assertFalse(DC_1.ispn().cache(SESSIONS).contains((String) tokensMap.get("session_state")));
assertFalse(DC_2.kc().embeddedIspn().cache(SESSIONS).contains((String) tokensMap.get("session_state")));
assertFalse(DC_2.ispn().cache(SESSIONS).contains((String) tokensMap.get("session_state")));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -150,12 +150,13 @@ public boolean remove(String key) {
.build();


HttpResponse<String> response = null;
HttpResponse<String> response;
try {
response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
} catch (IOException | InterruptedException e) {
throw new RuntimeException(e);
}
assertEquals(200, response.statusCode());
return Boolean.parseBoolean(response.body());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,18 @@ public long size() {

@Override
public void clear() {
throw new NotImplementedYetException("This is not yet implemented :/");
try {
URI uri = new URIBuilder(testRealmUrl("master") + "/cache/" + name + "/clear").build();
HttpRequest request = HttpRequest.newBuilder()
.uri(uri)
.GET()
.build();

HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
assertEquals(200, response.statusCode());
} catch (URISyntaxException | IOException | InterruptedException e) {
throw new RuntimeException(e);
}
}

@Override
Expand All @@ -282,7 +293,27 @@ public boolean contains(String key) throws URISyntaxException, IOException, Inte

@Override
public boolean remove(String key) {
throw new NotImplementedYetException("This is not yet implemented :/");
URI uri = null;
try {
uri = new URIBuilder( testRealmUrl("master") + "/cache/" + name + "/remove/" + key + "?skipListeners=true").build();
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}

HttpRequest request = HttpRequest.newBuilder()
.uri(uri)
.GET()
.build();


HttpResponse<String> response;
try {
response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
} catch (IOException | InterruptedException e) {
throw new RuntimeException(e);
}
assertEquals(200, response.statusCode());
return Boolean.parseBoolean(response.body());
}

@Override
Expand Down

0 comments on commit 804bfa0

Please sign in to comment.