Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions testsuite/tools/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,19 @@
<description/>

<dependencies>

<dependency>
<groupId>com.icegreen</groupId>
<artifactId>greenmail</artifactId>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>


<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-core</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package org.keycloak.test.tools;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

/**
* @author <a href="mailto:[email protected]">Stian Thorgersen</a>
*/
public class DestroyListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {

}

@Override
public void contextDestroyed(ServletContextEvent sce) {
if (KeycloakTestApplication.mail != null) {
KeycloakTestApplication.mail.stop();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import org.keycloak.services.resources.KeycloakApplication;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.Context;
import java.util.HashSet;
Expand All @@ -19,6 +21,8 @@ public class KeycloakTestApplication extends Application {
protected Set<Class<?>> classes = new HashSet<Class<?>>();
protected Set<Object> singletons = new HashSet<Object>();

static Mail mail = new Mail();

public KeycloakTestApplication(@Context ServletContext context, @Context Dispatcher dispatcher) {
KeycloakApplication.loadConfig();

Expand All @@ -27,6 +31,7 @@ public KeycloakTestApplication(@Context ServletContext context, @Context Dispatc
context.setAttribute(KeycloakSessionFactory.class.getName(), this.sessionFactory);

singletons.add(new PerfTools(sessionFactory));
singletons.add(mail);
}

@Override
Expand Down
131 changes: 131 additions & 0 deletions testsuite/tools/src/main/java/org/keycloak/test/tools/Mail.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
package org.keycloak.test.tools;

import com.icegreen.greenmail.util.GreenMail;
import com.icegreen.greenmail.util.ServerSetup;

import javax.mail.internet.MimeMessage;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import java.util.LinkedList;
import java.util.List;

/**
* @author <a href="mailto:[email protected]">Stian Thorgersen</a>
*/
@Path("mail")
public class Mail {

private GreenMail greenMail;

@GET
@Path("status")
@Produces("application/json")
public synchronized Status status() {
return new Status(greenMail != null);
}

@GET
@Path("start")
@Produces("application/json")
public synchronized Status start() {
if (greenMail == null) {
ServerSetup setup = new ServerSetup(3025, "localhost", "smtp");

greenMail = new GreenMail(setup);
try {
greenMail.start();
} catch (Throwable t) {
greenMail = null;
return new Status(false);
}
}

return new Status(true);
}

@GET
@Path("stop")
@Produces("application/json")
public synchronized Status stop() {
if (greenMail != null) {
greenMail.stop();
greenMail = null;
}

return new Status(false);
}

@GET
@Path("messages")
@Produces("application/json")
public synchronized List<Message> getMessages() throws Exception {
List<Message> messages = new LinkedList<Message>();
if (greenMail != null) {
for (MimeMessage m : greenMail.getReceivedMessages()) {
messages.add(new Message(m));
}
}
return messages;
}

@Override
protected void finalize() throws Throwable {
if (greenMail != null) {
greenMail.stop();
}
}

public static class Status {

private boolean started;

public Status(boolean started) {
this.started = started;
}

public boolean isStarted() {
return started;
}

}

public static class Message {

private String from;
private String to;
private String subject;
private String body;
private Long date;

public Message(MimeMessage m) throws Exception {
from = m.getFrom()[0].toString();
to = m.getRecipients(MimeMessage.RecipientType.TO)[0].toString();
subject = m.getSubject();
body = m.getContent().toString();
date = m.getSentDate() != null ? m.getSentDate().getTime() : null;
}

public String getFrom() {
return from;
}

public String getTo() {
return to;
}

public String getSubject() {
return subject;
}

public String getBody() {
return body;
}

public Long getDate() {
return date;
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public void deleteJobs() {

@GET
@Path("{realm}/create-users")
public Response createUsers(@PathParam("realm") String realmName, @QueryParam("count") Integer count, @QueryParam("batch") Integer batch, @QueryParam("start") Integer start, @QueryParam("prefix") String prefix, @QueryParam("roles") String roles) throws InterruptedException {
public void createUsers(@PathParam("realm") String realmName, @QueryParam("count") Integer count, @QueryParam("batch") Integer batch, @QueryParam("start") Integer start, @QueryParam("prefix") String prefix, @QueryParam("roles") String roles) throws InterruptedException {
if (count == null) {
count = 1;
}
Expand All @@ -88,8 +88,6 @@ public Response createUsers(@PathParam("realm") String realmName, @QueryParam("c
int c = s + batch <= (start + count) ? batch : (start + count) - s;
executor.submit(new CreateUsers(job, sessionFactory, realmName, s, c, prefix, rolesArray));
}

return Response.noContent().build();
}

@GET
Expand Down
7 changes: 6 additions & 1 deletion testsuite/tools/src/main/webapp/WEB-INF/web.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
</welcome-file-list>

<listener>
<listener-class>org.keycloak.services.listeners.KeycloakSessionDestroyListener</listener-class>
<listener-class>org.keycloak.test.tools.DestroyListener</listener-class>
</listener>

<filter>
Expand Down Expand Up @@ -54,6 +54,11 @@
<url-pattern>/perf/*</url-pattern>
</servlet-mapping>

<servlet-mapping>
<servlet-name>Keycloak REST Interface</servlet-name>
<url-pattern>/mail/*</url-pattern>
</servlet-mapping>

<!--

<security-constraint>
Expand Down
1 change: 1 addition & 0 deletions testsuite/tools/src/main/webapp/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
<ul class="nav navbar-nav navbar-primary persistent-secondary ng-scope">
<li><a href="#/">Home</a></li>
<li><a href="#/perf">Perf</a></li>
<li><a href="#/mail">Mail</a></li>
</ul>
</header>

Expand Down
25 changes: 25 additions & 0 deletions testsuite/tools/src/main/webapp/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ module.config([ '$routeProvider', function ($routeProvider) {
templateUrl: 'pages/perf.html',
controller: 'PerfCtrl'
})
.when('/mail', {
templateUrl: 'pages/mail.html',
controller: 'MailCtrl'
})
.otherwise({
templateUrl: 'pages/home.html'
});
Expand Down Expand Up @@ -47,3 +51,24 @@ module.controller('PerfCtrl', function ($scope, $resource) {
$scope.loadJobs();

});

module.controller('MailCtrl', function ($scope, $resource) {

$scope.start = function() {
$resource('/keycloak-tools/mail/start').get({}, function(status) {
$scope.status = status;
});
}

$scope.stop = function() {
$resource('/keycloak-tools/mail/stop').get({}, function(status) {
$scope.status = status;
});
}
$scope.loadMessages = function() {
$scope.messages = $resource('/keycloak-tools/mail/messages').query();
}

$scope.status = $resource('/keycloak-tools/mail/status').get();

});
23 changes: 23 additions & 0 deletions testsuite/tools/src/main/webapp/pages/mail.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<h1>Mail</h1>

<button data-ng-click="start()" class="btn btn-default" data-ng-show="!status.started">Start</button>
<button data-ng-click="stop()" class="btn btn-default" data-ng-show="status.started">Stop</button>
<button data-ng-click="loadMessages()" class="btn btn-default" data-ng-show="status.started">Refresh</button>

<table class="table table-striped table-bordered">
<thead>
<tr>
<th>From</th>
<th>To</th>
<th>Subject</th>
<th>Body</th>
</tr>
</thead>
<tr data-ng-repeat="m in messages|reverse">
<td>{{m.from}}</td>
<td>{{m.to}}</td>
<td>{{m.subject}}</td>
<td><pre>{{m.body}}</pre></td>
<td>{{m.date|date:'medium'}}</td>
</tr>
</table>