keycloak-memoizeit

Added performance-web module

6/24/2014 6:44:34 PM

Details

pom.xml 2(+1 -1)

diff --git a/pom.xml b/pom.xml
index 9d6f311..1383a9e 100755
--- a/pom.xml
+++ b/pom.xml
@@ -174,7 +174,7 @@
             <dependency>
                 <groupId>org.jboss.resteasy</groupId>
                 <artifactId>resteasy-undertow</artifactId>
-                <version>${resteasy.version}</version>
+                <version>${resteasy.version.latest}</version>
             </dependency>
             <dependency>
                 <groupId>io.undertow</groupId>
diff --git a/testsuite/integration/src/main/java/org/keycloak/testutils/KeycloakServer.java b/testsuite/integration/src/main/java/org/keycloak/testutils/KeycloakServer.java
index e867087..6f2aaf9 100755
--- a/testsuite/integration/src/main/java/org/keycloak/testutils/KeycloakServer.java
+++ b/testsuite/integration/src/main/java/org/keycloak/testutils/KeycloakServer.java
@@ -95,6 +95,10 @@ public class KeycloakServer {
     }
 
     public static void main(String[] args) throws Throwable {
+        bootstrapKeycloakServer(args);
+    }
+
+    public static KeycloakServer bootstrapKeycloakServer(String[] args) throws Throwable {
         KeycloakServerConfig config = new KeycloakServerConfig();
 
         for (int i = 0; i < args.length; i++) {
@@ -158,6 +162,8 @@ public class KeycloakServer {
                 keycloak.stop();
             }
         });
+
+        return keycloak;
     }
 
     private KeycloakServerConfig config;
diff --git a/testsuite/performance-web/pom.xml b/testsuite/performance-web/pom.xml
new file mode 100644
index 0000000..7ca6bac
--- /dev/null
+++ b/testsuite/performance-web/pom.xml
@@ -0,0 +1,106 @@
+<?xml version="1.0"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <parent>
+        <artifactId>keycloak-testsuite-pom</artifactId>
+        <groupId>org.keycloak</groupId>
+        <version>1.0-beta-4-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>keycloak-testsuite-performance-web</artifactId>
+    <name>Keycloak TestSuite for Web Performance</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-testsuite-integration</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-testsuite-tools</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <!-- Resteasy deps specified here as we want latest version of them -->
+        <dependency>
+            <groupId>org.jboss.resteasy</groupId>
+            <artifactId>jaxrs-api</artifactId>
+            <version>${resteasy.version.latest}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.jboss.resteasy</groupId>
+            <artifactId>resteasy-jaxrs</artifactId>
+            <version>${resteasy.version.latest}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>log4j</groupId>
+                    <artifactId>log4j</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.slf4j</groupId>
+                    <artifactId>slf4j-api</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.slf4j</groupId>
+                    <artifactId>slf4j-simple</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.jboss.resteasy</groupId>
+            <artifactId>resteasy-client</artifactId>
+            <version>${resteasy.version.latest}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.jboss.resteasy</groupId>
+            <artifactId>resteasy-crypto</artifactId>
+            <version>${resteasy.version.latest}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.jboss.resteasy</groupId>
+            <artifactId>resteasy-multipart-provider</artifactId>
+            <version>${resteasy.version.latest}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.jboss.resteasy</groupId>
+            <artifactId>resteasy-jackson-provider</artifactId>
+            <version>${resteasy.version.latest}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.jboss.resteasy</groupId>
+            <artifactId>resteasy-undertow</artifactId>
+            <version>${resteasy.version.latest}</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-deploy-plugin</artifactId>
+                <configuration>
+                    <skip>true</skip>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>${maven.compiler.source}</source>
+                    <target>${maven.compiler.target}</target>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>exec-maven-plugin</artifactId>
+                <configuration>
+                    <workingDirectory>${project.basedir}</workingDirectory>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
diff --git a/testsuite/performance-web/src/main/java/org/keycloak/testsuite/performance/web/KeycloakPerfServer.java b/testsuite/performance-web/src/main/java/org/keycloak/testsuite/performance/web/KeycloakPerfServer.java
new file mode 100644
index 0000000..55cc44f
--- /dev/null
+++ b/testsuite/performance-web/src/main/java/org/keycloak/testsuite/performance/web/KeycloakPerfServer.java
@@ -0,0 +1,87 @@
+package org.keycloak.testsuite.performance.web;
+
+import java.io.InputStream;
+
+import javax.servlet.DispatcherType;
+
+import io.undertow.servlet.Servlets;
+import io.undertow.servlet.api.DeploymentInfo;
+import io.undertow.servlet.api.FilterInfo;
+import io.undertow.servlet.api.ServletInfo;
+import org.jboss.resteasy.plugins.server.undertow.UndertowJaxrsServer;
+import org.jboss.resteasy.spi.ResteasyDeployment;
+import org.keycloak.services.filters.ClientConnectionFilter;
+import org.keycloak.services.filters.KeycloakSessionServletFilter;
+import org.keycloak.test.tools.KeycloakTestApplication;
+import org.keycloak.testutils.KeycloakServer;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class KeycloakPerfServer {
+
+    private KeycloakServer keycloakServer;
+
+    public static void main(String[] args) throws Throwable {
+        KeycloakServer keycloakServer = KeycloakServer.bootstrapKeycloakServer(args);
+        System.out.println("Keycloak server bootstrapped");
+
+        ProviderSessionFactoryHolder.setProviderSessionFactory(keycloakServer.getProviderSessionFactory());
+        new KeycloakPerfServer(keycloakServer).start();
+    }
+
+    public KeycloakPerfServer(KeycloakServer keycloakServer) {
+        this.keycloakServer = keycloakServer;
+    }
+
+    public void start() {
+        importPerfRealm();
+        deployPerfTools();
+        deployPerfApp();
+    }
+
+    protected void importPerfRealm() {
+        InputStream perfRealmStream = KeycloakPerfServer.class.getClassLoader().getResourceAsStream("perfrealm.json");
+        keycloakServer.importRealm(perfRealmStream);
+    }
+
+    protected void deployPerfTools() {
+        ResteasyDeployment deployment = new ResteasyDeployment();
+        deployment.setApplicationClass(KeycloakToolsApplication.class.getName());
+
+        UndertowJaxrsServer server = keycloakServer.getServer();
+
+        DeploymentInfo di = server.undertowDeployment(deployment, "");
+        di.setClassLoader(KeycloakTestApplication.class.getClassLoader());
+        di.setContextPath("/keycloak-tools");
+        di.setDeploymentName("KeycloakTools");
+
+        FilterInfo filter = Servlets.filter("SessionFilter", KeycloakSessionServletFilter.class);
+        di.addFilter(filter);
+        di.addFilterUrlMapping("SessionFilter", "/perf/*", DispatcherType.REQUEST);
+
+        FilterInfo connectionFilter = Servlets.filter("ClientConnectionFilter", ClientConnectionFilter.class);
+        di.addFilter(connectionFilter);
+        di.addFilterUrlMapping("ClientConnectionFilter", "/perf/*", DispatcherType.REQUEST);
+
+        server.deploy(di);
+
+        System.out.println("Keycloak tools deployed");
+    }
+
+    protected void deployPerfApp() {
+        DeploymentInfo deploymentInfo = new DeploymentInfo();
+        deploymentInfo.setClassLoader(getClass().getClassLoader());
+        deploymentInfo.setDeploymentName("PerfApp");
+        deploymentInfo.setContextPath("/perf-app");
+
+        ServletInfo servlet = new ServletInfo("PerfAppServlet", PerfAppServlet.class);
+        servlet.addMapping("/*");
+
+        deploymentInfo.addServlet(servlet);
+
+        keycloakServer.getServer().deploy(deploymentInfo);
+
+        System.out.println("PerfApp deployed");
+    }
+}
diff --git a/testsuite/performance-web/src/main/java/org/keycloak/testsuite/performance/web/KeycloakToolsApplication.java b/testsuite/performance-web/src/main/java/org/keycloak/testsuite/performance/web/KeycloakToolsApplication.java
new file mode 100644
index 0000000..94798d9
--- /dev/null
+++ b/testsuite/performance-web/src/main/java/org/keycloak/testsuite/performance/web/KeycloakToolsApplication.java
@@ -0,0 +1,42 @@
+package org.keycloak.testsuite.performance.web;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.servlet.ServletContext;
+import javax.ws.rs.core.Application;
+import javax.ws.rs.core.Context;
+
+import org.jboss.resteasy.core.Dispatcher;
+import org.keycloak.provider.ProviderSessionFactory;
+import org.keycloak.test.tools.PerfTools;
+
+/**
+ * Modified version of {@link org.keycloak.test.tools.KeycloakTestApplication}, which shares ProviderSessionFactory with KeycloakApplication
+ *
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class KeycloakToolsApplication extends Application {
+
+    protected ProviderSessionFactory providerSessionFactory;
+    protected Set<Class<?>> classes = new HashSet<Class<?>>();
+    protected Set<Object> singletons = new HashSet<Object>();
+
+    public KeycloakToolsApplication(@Context ServletContext context, @Context Dispatcher dispatcher) {
+        this.providerSessionFactory = ProviderSessionFactoryHolder.getProviderSessionFactory();
+        context.setAttribute(ProviderSessionFactory.class.getName(), this.providerSessionFactory);
+        singletons.add(new PerfTools(providerSessionFactory));
+    }
+
+    @Override
+    public Set<Class<?>> getClasses() {
+        return classes;
+    }
+
+    @Override
+    public Set<Object> getSingletons() {
+        return singletons;
+    }
+
+
+}
diff --git a/testsuite/performance-web/src/main/java/org/keycloak/testsuite/performance/web/PerfAppServlet.java b/testsuite/performance-web/src/main/java/org/keycloak/testsuite/performance/web/PerfAppServlet.java
new file mode 100644
index 0000000..cc38ae6
--- /dev/null
+++ b/testsuite/performance-web/src/main/java/org/keycloak/testsuite/performance/web/PerfAppServlet.java
@@ -0,0 +1,39 @@
+package org.keycloak.testsuite.performance.web;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class PerfAppServlet extends HttpServlet {
+
+    @Override
+    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+        String resourcePath = "perf-app-resources" + req.getPathInfo();
+        System.out.println("Resource path: " + resourcePath);
+
+        InputStream inputStream = getClass().getClassLoader().getResourceAsStream(resourcePath);
+        if (inputStream == null) {
+            resp.getWriter().println("Not found: " + resourcePath);
+        } else {
+            OutputStream servletOutputStream = resp.getOutputStream();
+
+            byte[] buf = new byte[1024];
+            int bytesRead = 0;
+            while (bytesRead != -1) {
+                bytesRead = inputStream.read(buf);
+                if (bytesRead != -1) {
+                    servletOutputStream.write(buf, 0, bytesRead);
+                }
+            }
+            servletOutputStream.flush();
+        }
+    }
+}
diff --git a/testsuite/performance-web/src/main/java/org/keycloak/testsuite/performance/web/ProviderSessionFactoryHolder.java b/testsuite/performance-web/src/main/java/org/keycloak/testsuite/performance/web/ProviderSessionFactoryHolder.java
new file mode 100644
index 0000000..ea1420b
--- /dev/null
+++ b/testsuite/performance-web/src/main/java/org/keycloak/testsuite/performance/web/ProviderSessionFactoryHolder.java
@@ -0,0 +1,21 @@
+package org.keycloak.testsuite.performance.web;
+
+import org.keycloak.provider.ProviderSessionFactory;
+
+/**
+ * Static holder to allow sharing ProviderSessionFactory among different JAX-RS applications
+ *
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class ProviderSessionFactoryHolder {
+
+    private static ProviderSessionFactory providerSessionFactory;
+
+    public static ProviderSessionFactory getProviderSessionFactory() {
+        return providerSessionFactory;
+    }
+
+    public static void setProviderSessionFactory(ProviderSessionFactory providerSessionFactory) {
+        ProviderSessionFactoryHolder.providerSessionFactory = providerSessionFactory;
+    }
+}
diff --git a/testsuite/performance-web/src/main/resources/perf-app-resources/index.html b/testsuite/performance-web/src/main/resources/perf-app-resources/index.html
new file mode 100644
index 0000000..c5b7c53
--- /dev/null
+++ b/testsuite/performance-web/src/main/resources/perf-app-resources/index.html
@@ -0,0 +1,110 @@
+<html>
+<head>
+    <script src="/auth/js/keycloak.js"></script>
+</head>
+<body>
+
+<div>
+    <button onclick="keycloak.login()">Login</button>
+    <button onclick="keycloak.logout()">Logout</button>
+    <button onclick="refreshToken(9999)">Refresh Token</button>
+    <button onclick="refreshToken(30)">Refresh Token (if <30s validity)</button>
+    <button onclick="loadProfile()">Get Profile</button>
+    <button onclick="output(keycloak.tokenParsed)">Show Token</button>
+    <button onclick="output(keycloak.refreshTokenParsed)">Show Refresh Token</button>
+    <button onclick="showExpires()">Show Expires</button>
+    <button onclick="output(keycloak.idToken)">Show ID Token</button>
+    <button onclick="output(keycloak)">Show Details</button>
+    <button onclick="output(keycloak.createLoginUrl())">Show Login URL</button>
+    <button onclick="output(keycloak.createLogoutUrl())">Show Logout URL</button>
+</div>
+
+<h2>Result</h2>
+<pre style="background-color: #ddd; border: 1px solid #ccc; padding: 10px;" id="output"></pre>
+
+<h2>Events</h2>
+<pre style="background-color: #ddd; border: 1px solid #ccc; padding: 10px;" id="events"></pre>
+
+
+<script>
+    function loadProfile() {
+        keycloak.loadUserProfile().success(function(profile) {
+            output(profile);
+        }).error(function() {
+            output('Failed to load profile');
+        });
+    }
+
+    function refreshToken(minValidity) {
+        keycloak.updateToken(minValidity).success(function(refreshed) {
+            if (refreshed) {
+                output(keycloak.tokenParsed);
+            } else {
+                output('Token not refreshed, valid for ' + Math.round(keycloak.tokenParsed.exp - new Date().getTime() / 1000) + ' seconds');
+            }
+        }).error(function() {
+            output('Failed to refresh token');
+        });
+    }
+
+    function showExpires() {
+        if (!keycloak.tokenParsed) {
+            output("Not authenticated");
+            return;
+        }
+
+        var o = 'Token Expires:\t\t' + new Date(keycloak.tokenParsed.exp * 1000).toLocaleString() + '\n';
+        o += 'Token Expires in:\t' + Math.round(keycloak.tokenParsed.exp - new Date().getTime() / 1000) + ' seconds\n';
+
+        o += 'Refresh Token Expires:\t' + new Date(keycloak.refreshTokenParsed.exp * 1000).toLocaleString() + '\n';
+        o += 'Refresh Expires in:\t' + Math.round(keycloak.refreshTokenParsed.exp - new Date().getTime() / 1000) + ' seconds';
+        output(o);
+    }
+
+    function output(data) {
+        if (typeof data === 'object') {
+            data = JSON.stringify(data, null, '  ');
+        }
+        document.getElementById('output').innerHTML = data;
+    }
+
+    function event(event) {
+        var e = document.getElementById('events').innerHTML;
+        document.getElementById('events').innerHTML = new Date().toLocaleString() + "\t" + event + "\n" + e;
+    }
+
+    var keycloak = Keycloak({
+        url: "/auth",
+        realm: "perf-realm",
+        clientId: "perf-app"
+    });
+
+    keycloak.onAuthSuccess = function () {
+        event('Auth Success');
+    };
+
+    keycloak.onAuthError = function () {
+        event('Auth Error');
+    };
+
+    keycloak.onAuthRefreshSuccess = function () {
+        event('Auth Refresh Success');
+    };
+
+    keycloak.onAuthRefreshError = function () {
+        event('Auth Refresh Error');
+    };
+
+    keycloak.onAuthLogout = function () {
+        event('Auth Logout');
+    };
+
+    keycloak.init().success(function(authenticated) {
+        output('Init Success (' + (authenticated ? 'Authenticated' : 'Not Authenticated') + ')');
+    }).error(function() {
+        output('Init Error');
+    });
+
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/testsuite/performance-web/src/main/resources/perfrealm.json b/testsuite/performance-web/src/main/resources/perfrealm.json
new file mode 100644
index 0000000..aaa7fc4
--- /dev/null
+++ b/testsuite/performance-web/src/main/resources/perfrealm.json
@@ -0,0 +1,108 @@
+{
+    "id": "perf-realm",
+    "realm": "perf-realm",
+    "enabled": true,
+    "sslNotRequired": true,
+    "registrationAllowed": true,
+    "resetPasswordAllowed": true,
+    "privateKey": "MIICXAIBAAKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQABAoGAfmO8gVhyBxdqlxmIuglbz8bcjQbhXJLR2EoS8ngTXmN1bo2L90M0mUKSdc7qF10LgETBzqL8jYlQIbt+e6TH8fcEpKCjUlyq0Mf/vVbfZSNaVycY13nTzo27iPyWQHK5NLuJzn1xvxxrUeXI6A2WFpGEBLbHjwpx5WQG9A+2scECQQDvdn9NE75HPTVPxBqsEd2z10TKkl9CZxu10Qby3iQQmWLEJ9LNmy3acvKrE3gMiYNWb6xHPKiIqOR1as7L24aTAkEAtyvQOlCvr5kAjVqrEKXalj0Tzewjweuxc0pskvArTI2Oo070h65GpoIKLc9jf+UA69cRtquwP93aZKtW06U8dQJAF2Y44ks/mK5+eyDqik3koCI08qaC8HYq2wVl7G2QkJ6sbAaILtcvD92ToOvyGyeE0flvmDZxMYlvaZnaQ0lcSQJBAKZU6umJi3/xeEbkJqMfeLclD27XGEFoPeNrmdx0q10Azp4NfJAY+Z8KRyQCR2BEG+oNitBOZ+YXF9KCpH3cdmECQHEigJhYg+ykOvr1aiZUMFT72HU0jnmQe2FVekuG+LJUt2Tm7GtMjTFoGpf0JwrVuZN39fOYAlo+nTixgeW7X8Y=",
+    "publicKey": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
+    "requiredCredentials": [ "password" ],
+    "defaultRoles": [ "user" ],
+    "smtpServer": {
+        "from": "auto@keycloak.org",
+        "host": "localhost",
+        "port":"3025"
+    },
+    "users" : [
+        {
+            "username" : "test-user@localhost",
+            "enabled": true,
+            "email" : "test-user@localhost",
+            "credentials" : [
+                { "type" : "password",
+                  "value" : "password" }
+            ]
+        }
+    ],
+    "oauthClients" : [
+        {
+            "name" : "third-party",
+            "enabled": true,
+            "redirectUris": [
+                "http://localhost:8081/app/*"
+            ],
+            "secret": "password"
+        }
+    ],
+    "roleMappings": [
+        {
+            "username": "test-user@localhost",
+            "roles": ["user"]
+        }
+    ],
+    "scopeMappings": [
+        {
+            "client": "third-party",
+            "roles": ["user"]
+        },
+        {
+            "client": "perf-app",
+            "roles": ["user"]
+        }
+    ],
+    "applications": [
+        {
+            "name": "perf-app",
+            "enabled": true,
+            "baseUrl": "http://localhost:8081/perf-app",
+            "redirectUris": [
+                "http://localhost:8081/perf-app/*"
+            ],
+            "adminUrl": "http://localhost:8081/perf-app/logout",
+            "secret": "password"
+         }
+    ],
+    "roles" : {
+        "realm" : [
+            {
+                "name": "user",
+                "description": "Have User privileges"
+            },
+            {
+                "name": "admin",
+                "description": "Have Administrator privileges"
+            }
+        ],
+        "application" : {
+            "perf-app" : [
+                {
+                    "name": "customer-user",
+                    "description": "Have Customer User privileges"
+                },
+                {
+                    "name": "customer-admin",
+                    "description": "Have Customer Admin privileges"
+                }
+            ]
+        }
+
+    },
+
+    "applicationRoleMappings": {
+        "perf-app": [
+            {
+                "username": "test-user@localhost",
+                "roles": ["customer-user"]
+            }
+        ]
+    },
+    "applicationScopeMappings": {
+        "perf-app": [
+            {
+                "client": "third-party",
+                "roles": ["customer-user"]
+            }
+        ]
+    }
+}
\ No newline at end of file
diff --git a/testsuite/pom.xml b/testsuite/pom.xml
index 36085e7..7961ca5 100755
--- a/testsuite/pom.xml
+++ b/testsuite/pom.xml
@@ -28,6 +28,7 @@
         <module>integration</module>
         <module>performance</module>
         <module>tools</module>
+        <module>performance-web</module>
     </modules>
 
 </project>