KEYCLOAK-2755 Refactor testsuite events provider
This commit is contained in:
parent
8efbdce810
commit
b8832d2d71
21 changed files with 295 additions and 326 deletions
|
@ -29,7 +29,7 @@
|
|||
|
||||
// inject provider
|
||||
providers = root.withArray("providers");
|
||||
providers.add("module:org.keycloak.testsuite.integration-arquillian-event-queue");
|
||||
providers.add("module:org.keycloak.testsuite.integration-arquillian-testsuite-providers");
|
||||
|
||||
// save file
|
||||
JsonSerialization.prettyMapper.writeValue(file, root);
|
||||
|
|
|
@ -101,7 +101,7 @@
|
|||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>copy-event-queue-provider</id>
|
||||
<id>copy-testsuite-providers</id>
|
||||
<phase>generate-resources</phase>
|
||||
<goals>
|
||||
<goal>copy</goal>
|
||||
|
@ -110,17 +110,17 @@
|
|||
<artifactItems>
|
||||
<artifactItem>
|
||||
<groupId>org.keycloak.testsuite</groupId>
|
||||
<artifactId>integration-arquillian-event-queue</artifactId>
|
||||
<artifactId>integration-arquillian-testsuite-providers</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<type>jar</type>
|
||||
<overWrite>false</overWrite>
|
||||
<outputDirectory>${auth.server.home}/modules/org/keycloak/testsuite/integration-arquillian-event-queue/main</outputDirectory>
|
||||
<outputDirectory>${auth.server.home}/modules/org/keycloak/testsuite/integration-arquillian-testsuite-providers/main</outputDirectory>
|
||||
</artifactItem>
|
||||
</artifactItems>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>install-event-queue-module</id>
|
||||
<id>install-testsuite-providers-module</id>
|
||||
<phase>generate-resources</phase>
|
||||
<goals>
|
||||
<goal>unpack</goal>
|
||||
|
@ -129,7 +129,7 @@
|
|||
<artifactItems>
|
||||
<artifactItem>
|
||||
<groupId>org.keycloak.testsuite</groupId>
|
||||
<artifactId>integration-arquillian-event-queue</artifactId>
|
||||
<artifactId>integration-arquillian-testsuite-providers</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<type>jar</type>
|
||||
<outputDirectory>${auth.server.home}/modules</outputDirectory>
|
||||
|
|
|
@ -1,71 +0,0 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package org.keycloak.testsuite.events;
|
||||
|
||||
import org.keycloak.events.Event;
|
||||
import org.keycloak.util.JsonSerialization;
|
||||
|
||||
import javax.servlet.Filter;
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.FilterConfig;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mstrukel@redhat.com">Marko Strukelj</a>
|
||||
*/
|
||||
public class AssertEventsServletFilter implements Filter {
|
||||
|
||||
@Override
|
||||
public void init(FilterConfig filterConfig) throws ServletException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
|
||||
HttpServletRequest req = (HttpServletRequest) servletRequest;
|
||||
|
||||
if ("/clear-event-queue".equals(req.getRequestURI().substring(req.getContextPath().length()))) {
|
||||
EventsListenerProvider.getInstance().clear();
|
||||
return;
|
||||
}
|
||||
|
||||
if ("/event-queue".equals(req.getRequestURI().substring(req.getContextPath().length()))) {
|
||||
BlockingQueue<Event> events = EventsListenerProvider.getInstance();
|
||||
HttpServletResponse resp = (HttpServletResponse) servletResponse;
|
||||
resp.setContentType("application/json");
|
||||
|
||||
Event event = events.poll();
|
||||
if (event != null) {
|
||||
JsonSerialization.writeValueToStream(servletResponse.getOutputStream(), event);
|
||||
} else {
|
||||
resp.setStatus(204);
|
||||
}
|
||||
} else {
|
||||
filterChain.doFilter(servletRequest, servletResponse);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
}
|
||||
}
|
|
@ -1,96 +0,0 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package org.keycloak.testsuite.events;
|
||||
|
||||
import io.undertow.Undertow;
|
||||
import io.undertow.server.handlers.PathHandler;
|
||||
import io.undertow.servlet.Servlets;
|
||||
import io.undertow.servlet.api.DeploymentInfo;
|
||||
import io.undertow.servlet.api.DeploymentManager;
|
||||
import io.undertow.servlet.api.FilterInfo;
|
||||
import io.undertow.servlet.api.ServletContainer;
|
||||
import io.undertow.servlet.api.ServletContainer.Factory;
|
||||
|
||||
import javax.servlet.DispatcherType;
|
||||
import javax.servlet.ServletException;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mstrukel@redhat.com">Marko Strukelj</a>
|
||||
*/
|
||||
public class EventsServer {
|
||||
|
||||
private static final Logger log = Logger.getLogger(EventsServer.class.getName());
|
||||
|
||||
private String rootPath = "/";
|
||||
private int port;
|
||||
private Undertow server;
|
||||
|
||||
public EventsServer() {
|
||||
int eventsPort = Integer.parseInt(System.getProperty("auth.server.events.http.port", "8089"));
|
||||
int portOffset = Integer.parseInt(System.getProperty("auth.server.port.offset", "0"));
|
||||
int jbossPortOffset = Integer.parseInt(System.getProperty("jboss.socket.binding.port-offset", "-1"));
|
||||
|
||||
log.fine("Configuration:");
|
||||
log.fine(" auth.server.events.http.port: " + eventsPort);
|
||||
log.fine(" auth.server.port.offset: " + portOffset);
|
||||
log.fine(" jboss.socket.binding.port-offset: " + jbossPortOffset);
|
||||
port = eventsPort + (jbossPortOffset != -1 ? jbossPortOffset : portOffset);
|
||||
}
|
||||
|
||||
public void start() {
|
||||
|
||||
PathHandler root = new PathHandler();
|
||||
this.server = Undertow.builder().addHttpListener(port, "localhost").setHandler(root).build();
|
||||
this.server.start();
|
||||
|
||||
ServletContainer container = Factory.newInstance();
|
||||
|
||||
DeploymentInfo di = new DeploymentInfo();
|
||||
di.setClassLoader(getClass().getClassLoader());
|
||||
di.setContextPath(rootPath);
|
||||
di.setDeploymentName("testing-event-queue");
|
||||
|
||||
FilterInfo filter = Servlets.filter("EventsFilter", AssertEventsServletFilter.class);
|
||||
di.addFilter(filter);
|
||||
di.addFilterUrlMapping("EventsFilter", "/event-queue", DispatcherType.REQUEST);
|
||||
di.addFilterUrlMapping("EventsFilter", "/clear-event-queue", DispatcherType.REQUEST);
|
||||
|
||||
DeploymentManager manager = container.addDeployment(di);
|
||||
manager.deploy();
|
||||
|
||||
try {
|
||||
root.addPrefixPath(rootPath, manager.start());
|
||||
} catch (ServletException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
log.info("Started EventsServer on port: " + port);
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
this.server.stop();
|
||||
}
|
||||
|
||||
public void setRootPath(String rootPath) {
|
||||
this.rootPath = rootPath;
|
||||
}
|
||||
|
||||
public void setPort(int port) {
|
||||
this.port = port;
|
||||
}
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package org.keycloak.testsuite.rest;
|
||||
|
||||
import org.keycloak.common.util.Time;
|
||||
import org.keycloak.services.resource.RealmResourceProvider;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.PUT;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public class TimeOffsetResourceProvider implements RealmResourceProvider {
|
||||
|
||||
@Override
|
||||
public Object getResource() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public Map<String, String> get() {
|
||||
Map<String, String> response = new HashMap<>();
|
||||
response.put("currentTime", String.valueOf(Time.currentTime()));
|
||||
response.put("offset", String.valueOf(Time.getOffset()));
|
||||
return response;
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public Map<String, String> put(Map<String, String> time) {
|
||||
int offset = Integer.parseInt(time.get("offset"));
|
||||
Time.setOffset(offset);
|
||||
return get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
}
|
||||
|
||||
}
|
|
@ -30,7 +30,7 @@
|
|||
<name>Auth Server Services</name>
|
||||
|
||||
<modules>
|
||||
<module>event-queue</module>
|
||||
<module>testsuite-providers</module>
|
||||
</modules>
|
||||
|
||||
</project>
|
||||
|
|
|
@ -27,8 +27,8 @@
|
|||
<version>2.0.0.CR1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>integration-arquillian-event-queue</artifactId>
|
||||
<name>Auth Server Services - Event Queue</name>
|
||||
<artifactId>integration-arquillian-testsuite-providers</artifactId>
|
||||
<name>Auth Server Services - Testsuite Providers</name>
|
||||
|
||||
<dependencies>
|
||||
|
|
@ -30,8 +30,6 @@ public class EventsListenerProviderFactory implements EventListenerProviderFacto
|
|||
|
||||
private static final EventsListenerProvider INSTANCE = new EventsListenerProvider();
|
||||
|
||||
private EventsServer server = new EventsServer();
|
||||
|
||||
@Override
|
||||
public EventListenerProvider create(KeycloakSession session) {
|
||||
return INSTANCE;
|
||||
|
@ -43,12 +41,10 @@ public class EventsListenerProviderFactory implements EventListenerProviderFacto
|
|||
|
||||
@Override
|
||||
public void postInit(KeycloakSessionFactory factory) {
|
||||
server.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
server.stop();
|
||||
}
|
||||
|
||||
@Override
|
|
@ -0,0 +1,137 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package org.keycloak.testsuite.rest;
|
||||
|
||||
import org.keycloak.common.util.Time;
|
||||
import org.keycloak.events.Event;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.UserSessionModel;
|
||||
import org.keycloak.models.utils.ModelToRepresentation;
|
||||
import org.keycloak.representations.idm.EventRepresentation;
|
||||
import org.keycloak.services.managers.RealmManager;
|
||||
import org.keycloak.services.resource.RealmResourceProvider;
|
||||
import org.keycloak.testsuite.events.EventsListenerProvider;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.NotFoundException;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.PUT;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public class TestingResourceProvider implements RealmResourceProvider {
|
||||
|
||||
private KeycloakSession session;
|
||||
|
||||
@Override
|
||||
public Object getResource() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public TestingResourceProvider(KeycloakSession session) {
|
||||
this.session = session;
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("/remove-user-session")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public Response removeUserSession(@QueryParam("realm") final String name, @QueryParam("session") final String sessionId) {
|
||||
RealmManager realmManager = new RealmManager(session);
|
||||
RealmModel realm = realmManager.getRealmByName(name);
|
||||
if (realm == null) {
|
||||
throw new NotFoundException("Realm not found");
|
||||
}
|
||||
|
||||
UserSessionModel sessionModel = session.sessions().getUserSession(realm, sessionId);
|
||||
if (sessionModel == null) {
|
||||
throw new NotFoundException("Session not found");
|
||||
}
|
||||
|
||||
session.sessions().removeUserSession(realm, sessionModel);
|
||||
return Response.ok().build();
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("/remove-expired")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public Response removeExpired(@QueryParam("realm") final String name) {
|
||||
RealmManager realmManager = new RealmManager(session);
|
||||
RealmModel realm = realmManager.getRealmByName(name);
|
||||
if (realm == null) {
|
||||
throw new NotFoundException("Realm not found");
|
||||
}
|
||||
|
||||
session.sessions().removeExpired(realm);
|
||||
return Response.ok().build();
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/time-offset")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public Map<String, String> getTimeOffset() {
|
||||
Map<String, String> response = new HashMap<>();
|
||||
response.put("currentTime", String.valueOf(Time.currentTime()));
|
||||
response.put("offset", String.valueOf(Time.getOffset()));
|
||||
return response;
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Path("/time-offset")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public Map<String, String> setTimeOffset(Map<String, String> time) {
|
||||
int offset = Integer.parseInt(time.get("offset"));
|
||||
Time.setOffset(offset);
|
||||
return getTimeOffset();
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("/poll-event-queue")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public EventRepresentation getEvent() {
|
||||
Event event = EventsListenerProvider.getInstance().poll();
|
||||
if (event != null) {
|
||||
return ModelToRepresentation.toRepresentation(event);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("/clear-event-queue")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public Response clearQueue() {
|
||||
EventsListenerProvider.getInstance().clear();
|
||||
return Response.ok().build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
}
|
||||
|
||||
}
|
|
@ -26,11 +26,11 @@ import org.keycloak.services.resource.RealmResourceProviderFactory;
|
|||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public class TimeOffsetResourceProviderFactory implements RealmResourceProviderFactory {
|
||||
public class TestingResourceProviderFactory implements RealmResourceProviderFactory {
|
||||
|
||||
@Override
|
||||
public RealmResourceProvider create(KeycloakSession session) {
|
||||
return new TimeOffsetResourceProvider();
|
||||
return new TestingResourceProvider(session);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -47,7 +47,7 @@ public class TimeOffsetResourceProviderFactory implements RealmResourceProviderF
|
|||
|
||||
@Override
|
||||
public String getId() {
|
||||
return "time-offset";
|
||||
return "testing";
|
||||
}
|
||||
|
||||
}
|
|
@ -15,5 +15,5 @@
|
|||
# limitations under the License.
|
||||
#
|
||||
|
||||
org.keycloak.testsuite.rest.TimeOffsetResourceProviderFactory
|
||||
org.keycloak.testsuite.rest.TestingResourceProviderFactory
|
||||
org.keycloak.testsuite.rest.TestApplicationResourceProviderFactory
|
|
@ -15,9 +15,9 @@
|
|||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<module xmlns="urn:jboss:module:1.1" name="org.keycloak.testsuite.integration-arquillian-event-queue">
|
||||
<module xmlns="urn:jboss:module:1.1" name="org.keycloak.testsuite.integration-arquillian-testsuite-providers">
|
||||
<resources>
|
||||
<resource-root path="integration-arquillian-event-queue-${project.version}.jar"/>
|
||||
<resource-root path="integration-arquillian-testsuite-providers-${project.version}.jar"/>
|
||||
</resources>
|
||||
<dependencies>
|
||||
<module name="javax.api"/>
|
||||
|
@ -28,5 +28,6 @@
|
|||
<module name="org.keycloak.keycloak-common"/>
|
||||
<module name="org.keycloak.keycloak-core"/>
|
||||
<module name="org.keycloak.keycloak-server-spi"/>
|
||||
<module name="org.keycloak.keycloak-services"/>
|
||||
</dependencies>
|
||||
</module>
|
|
@ -59,7 +59,7 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak.testsuite</groupId>
|
||||
<artifactId>integration-arquillian-event-queue</artifactId>
|
||||
<artifactId>integration-arquillian-testsuite-providers</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package org.keycloak.testsuite.client;
|
||||
|
||||
import org.jboss.resteasy.client.jaxrs.ResteasyClient;
|
||||
import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
|
||||
import org.jboss.resteasy.client.jaxrs.ResteasyWebTarget;
|
||||
import org.keycloak.testsuite.client.resources.TestingResource;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mstrukel@redhat.com">Marko Strukelj</a>
|
||||
*/
|
||||
public class KeycloakTestingClient {
|
||||
private final ResteasyWebTarget target;
|
||||
private final ResteasyClient client;
|
||||
|
||||
KeycloakTestingClient(String serverUrl, ResteasyClient resteasyClient) {
|
||||
client = resteasyClient != null ? resteasyClient : new ResteasyClientBuilder().connectionPoolSize(10).build();
|
||||
target = client.target(serverUrl);
|
||||
}
|
||||
|
||||
public static KeycloakTestingClient getInstance(String serverUrl) {
|
||||
return new KeycloakTestingClient(serverUrl, null);
|
||||
}
|
||||
|
||||
public TestingResource testing() {
|
||||
return target.proxy(TestingResource.class);
|
||||
}
|
||||
|
||||
public void close() {
|
||||
client.close();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package org.keycloak.testsuite.client.resources;
|
||||
|
||||
import org.keycloak.representations.idm.EventRepresentation;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.PUT;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mstrukel@redhat.com">Marko Strukelj</a>
|
||||
*/
|
||||
|
||||
@Path("/realms/master/testing")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public interface TestingResource {
|
||||
|
||||
@GET
|
||||
@Path("/time-offset")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
Map<String, String> getTimeOffset() ;
|
||||
|
||||
@PUT
|
||||
@Path("/time-offset")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
Map<String, String> setTimeOffset(Map<String, String> time);
|
||||
|
||||
@POST
|
||||
@Path("/poll-event-queue")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
EventRepresentation pollEvent();
|
||||
|
||||
@POST
|
||||
@Path("/clear-event-queue")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
Response clearQueue();
|
||||
|
||||
@POST
|
||||
@Path("/remove-user-session")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
Response removeUserSession(@QueryParam("realm") final String name, @QueryParam("session") final String sessionId);
|
||||
|
||||
@POST
|
||||
@Path("/remove-expired")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
Response removeExpired(@QueryParam("realm") final String name);
|
||||
}
|
|
@ -18,19 +18,16 @@ package org.keycloak.testsuite;
|
|||
|
||||
import org.apache.commons.configuration.ConfigurationException;
|
||||
import org.apache.commons.configuration.PropertiesConfiguration;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.keycloak.common.util.KeycloakUriBuilder;
|
||||
import org.keycloak.testsuite.arquillian.TestContext;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import javax.ws.rs.NotFoundException;
|
||||
import org.jboss.arquillian.container.test.api.RunAsClient;
|
||||
|
@ -56,9 +53,9 @@ import org.keycloak.testsuite.admin.ApiUtil;
|
|||
import org.keycloak.testsuite.arquillian.AuthServerTestEnricher;
|
||||
import org.keycloak.testsuite.arquillian.SuiteContext;
|
||||
import org.keycloak.testsuite.auth.page.WelcomePage;
|
||||
import org.keycloak.testsuite.client.KeycloakTestingClient;
|
||||
import org.keycloak.testsuite.util.DeleteMeOAuthClient;
|
||||
import org.keycloak.testsuite.util.OAuthClient;
|
||||
import org.keycloak.util.JsonSerialization;
|
||||
import org.openqa.selenium.WebDriver;
|
||||
import org.keycloak.testsuite.auth.page.AuthServer;
|
||||
import org.keycloak.testsuite.auth.page.AuthServerContextRoot;
|
||||
|
@ -94,6 +91,8 @@ public abstract class AbstractKeycloakTest {
|
|||
|
||||
protected Keycloak adminClient;
|
||||
|
||||
protected KeycloakTestingClient testingClient;
|
||||
|
||||
@ArquillianResource
|
||||
protected OAuthClient oauthClient;
|
||||
|
||||
|
@ -134,6 +133,7 @@ public abstract class AbstractKeycloakTest {
|
|||
MASTER, ADMIN, ADMIN, Constants.ADMIN_CLI_CLIENT_ID);
|
||||
deleteMeOAuthClient = new DeleteMeOAuthClient(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth");
|
||||
|
||||
testingClient = KeycloakTestingClient.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth");
|
||||
|
||||
adminUser = createAdminUserRepresentation();
|
||||
|
||||
|
@ -302,7 +302,7 @@ public abstract class AbstractKeycloakTest {
|
|||
userResource.update(userRepresentation);
|
||||
}
|
||||
|
||||
public void setTimeOffset(int offset) {invokeTimeOffset(offset);
|
||||
public void setTimeOffset(int offset) {
|
||||
String response = invokeTimeOffset(offset);
|
||||
resetTimeOffset = offset != 0;
|
||||
log.debugv("Set time offset, response {0}", response);
|
||||
|
@ -315,26 +315,8 @@ public abstract class AbstractKeycloakTest {
|
|||
}
|
||||
|
||||
private String invokeTimeOffset(int offset) {
|
||||
try {
|
||||
String data = JsonSerialization.writeValueAsString(Collections.singletonMap("offset", String.valueOf(offset)));
|
||||
URI uri = KeycloakUriBuilder.fromUri(suiteContext.getAuthServerInfo().getContextRoot().toURI()).path("/auth/realms/master/time-offset").build();
|
||||
HttpURLConnection connection = (HttpURLConnection) uri.toURL().openConnection();
|
||||
connection.setDoOutput(true);
|
||||
connection.setRequestMethod("PUT");
|
||||
connection.setRequestProperty("Content-Type", "application/json");
|
||||
connection.setRequestProperty("Content-Length", String.valueOf(data.length()));
|
||||
|
||||
OutputStream os = connection.getOutputStream();
|
||||
os.write(data.getBytes());
|
||||
os.close();
|
||||
|
||||
InputStream is = connection.getInputStream();
|
||||
String response = IOUtils.toString(is);
|
||||
is.close();
|
||||
return response;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
Map result = testingClient.testing().setTimeOffset(Collections.singletonMap("offset", String.valueOf(offset)));
|
||||
return String.valueOf(result);
|
||||
}
|
||||
|
||||
private void loadConstantsProperties() throws ConfigurationException {
|
||||
|
|
|
@ -17,11 +17,6 @@
|
|||
|
||||
package org.keycloak.testsuite;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.hamcrest.Description;
|
||||
import org.hamcrest.Matcher;
|
||||
|
@ -38,10 +33,10 @@ import org.keycloak.representations.idm.EventRepresentation;
|
|||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.representations.idm.UserRepresentation;
|
||||
import org.keycloak.representations.idm.UserSessionRepresentation;
|
||||
import org.keycloak.util.JsonSerialization;
|
||||
import org.keycloak.testsuite.client.resources.TestingResource;
|
||||
import org.keycloak.util.TokenUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.security.PublicKey;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
@ -58,9 +53,9 @@ public class AssertEvents {
|
|||
public static final String DEFAULT_USERNAME = "test-user@localhost";
|
||||
|
||||
String defaultRedirectUri = "http://localhost:8180/auth/realms/master/app/auth";
|
||||
String defaultEventsQueueUri = "http://localhost:8092";
|
||||
|
||||
private RealmResource realmResource;
|
||||
private TestingResource testingResource;
|
||||
private RealmRepresentation realmRep;
|
||||
private AbstractKeycloakTest context;
|
||||
private PublicKey realmPublicKey;
|
||||
|
@ -73,13 +68,11 @@ public class AssertEvents {
|
|||
String pubKeyString = realmRep.getPublicKey();
|
||||
realmPublicKey = PemUtils.decodePublicKey(pubKeyString);
|
||||
|
||||
defaultEventsQueueUri = getAuthServerEventsQueueUri();
|
||||
UserRepresentation defaultUser = getUser(DEFAULT_USERNAME);
|
||||
if (defaultUser == null) {
|
||||
throw new RuntimeException("Default user does not exist: " + DEFAULT_USERNAME + ". Make sure to add it to your test realm.");
|
||||
}
|
||||
|
||||
String getAuthServerEventsQueueUri() {
|
||||
int httpPort = Integer.parseInt(System.getProperty("auth.server.event.http.port", "8089"));
|
||||
int portOffset = Integer.parseInt(System.getProperty("auth.server.port.offset", "0"));
|
||||
return "http://localhost:" + (httpPort + portOffset);
|
||||
testingResource = context.testingClient.testing();
|
||||
}
|
||||
|
||||
public EventRepresentation poll() {
|
||||
|
@ -90,22 +83,11 @@ public class AssertEvents {
|
|||
}
|
||||
|
||||
public void clear() {
|
||||
CloseableHttpClient httpclient = HttpClients.createDefault();
|
||||
Response res = testingResource.clearQueue();
|
||||
try {
|
||||
HttpPost post = new HttpPost(defaultEventsQueueUri + "/clear-event-queue");
|
||||
CloseableHttpResponse response = httpclient.execute(post);
|
||||
if (response.getStatusLine().getStatusCode() != 200) {
|
||||
throw new RuntimeException("Failed to clear events from " + post.getURI() + ": " + response.getStatusLine().toString());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
httpclient.close();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
Assert.assertEquals("clear-event-queue success", res.getStatus(), 200);
|
||||
} finally {
|
||||
res.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -380,24 +362,6 @@ public class AssertEvents {
|
|||
}
|
||||
|
||||
private EventRepresentation fetchNextEvent() {
|
||||
CloseableHttpClient httpclient = HttpClients.createDefault();
|
||||
try {
|
||||
HttpPost post = new HttpPost(defaultEventsQueueUri + "/event-queue");
|
||||
CloseableHttpResponse response = httpclient.execute(post);
|
||||
if (response.getStatusLine().getStatusCode() != 200) {
|
||||
throw new RuntimeException("Failed to retrieve event from " + post.getURI() + ": " + response.getStatusLine().toString() + " / " + IOUtils.toString(response.getEntity().getContent()));
|
||||
}
|
||||
|
||||
return JsonSerialization.readValue(response.getEntity().getContent(), EventRepresentation.class);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
httpclient.close();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
return testingResource.pollEvent();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue