Merge pull request #485 from stianst/master

Added mail server to test tools
This commit is contained in:
Stian Thorgersen 2014-06-27 11:11:52 +01:00
commit 6b29202f1f
9 changed files with 226 additions and 4 deletions

View file

@ -15,6 +15,19 @@
<description/> <description/>
<dependencies> <dependencies>
<dependency>
<groupId>com.icegreen</groupId>
<artifactId>greenmail</artifactId>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency> <dependency>
<groupId>org.keycloak</groupId> <groupId>org.keycloak</groupId>
<artifactId>keycloak-core</artifactId> <artifactId>keycloak-core</artifactId>

View file

@ -0,0 +1,21 @@
package org.keycloak.test.tools;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
/**
* @author <a href="mailto:sthorger@redhat.com">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();
}
}
}

View file

@ -5,6 +5,8 @@ import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.services.resources.KeycloakApplication; import org.keycloak.services.resources.KeycloakApplication;
import javax.servlet.ServletContext; import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.ws.rs.core.Application; import javax.ws.rs.core.Application;
import javax.ws.rs.core.Context; import javax.ws.rs.core.Context;
import java.util.HashSet; import java.util.HashSet;
@ -19,6 +21,8 @@ public class KeycloakTestApplication extends Application {
protected Set<Class<?>> classes = new HashSet<Class<?>>(); protected Set<Class<?>> classes = new HashSet<Class<?>>();
protected Set<Object> singletons = new HashSet<Object>(); protected Set<Object> singletons = new HashSet<Object>();
static Mail mail = new Mail();
public KeycloakTestApplication(@Context ServletContext context, @Context Dispatcher dispatcher) { public KeycloakTestApplication(@Context ServletContext context, @Context Dispatcher dispatcher) {
KeycloakApplication.loadConfig(); KeycloakApplication.loadConfig();
@ -27,6 +31,7 @@ public class KeycloakTestApplication extends Application {
context.setAttribute(KeycloakSessionFactory.class.getName(), this.sessionFactory); context.setAttribute(KeycloakSessionFactory.class.getName(), this.sessionFactory);
singletons.add(new PerfTools(sessionFactory)); singletons.add(new PerfTools(sessionFactory));
singletons.add(mail);
} }
@Override @Override

View file

@ -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:sthorger@redhat.com">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;
}
}
}

View file

@ -65,7 +65,7 @@ public class PerfTools {
@GET @GET
@Path("{realm}/create-users") @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) { if (count == null) {
count = 1; count = 1;
} }
@ -88,8 +88,6 @@ public class PerfTools {
int c = s + batch <= (start + count) ? batch : (start + count) - s; int c = s + batch <= (start + count) ? batch : (start + count) - s;
executor.submit(new CreateUsers(job, sessionFactory, realmName, s, c, prefix, rolesArray)); executor.submit(new CreateUsers(job, sessionFactory, realmName, s, c, prefix, rolesArray));
} }
return Response.noContent().build();
} }
@GET @GET

View file

@ -26,7 +26,7 @@
</welcome-file-list> </welcome-file-list>
<listener> <listener>
<listener-class>org.keycloak.services.listeners.KeycloakSessionDestroyListener</listener-class> <listener-class>org.keycloak.test.tools.DestroyListener</listener-class>
</listener> </listener>
<filter> <filter>
@ -54,6 +54,11 @@
<url-pattern>/perf/*</url-pattern> <url-pattern>/perf/*</url-pattern>
</servlet-mapping> </servlet-mapping>
<servlet-mapping>
<servlet-name>Keycloak REST Interface</servlet-name>
<url-pattern>/mail/*</url-pattern>
</servlet-mapping>
<!-- <!--
<security-constraint> <security-constraint>

View file

@ -21,6 +21,7 @@
<ul class="nav navbar-nav navbar-primary persistent-secondary ng-scope"> <ul class="nav navbar-nav navbar-primary persistent-secondary ng-scope">
<li><a href="#/">Home</a></li> <li><a href="#/">Home</a></li>
<li><a href="#/perf">Perf</a></li> <li><a href="#/perf">Perf</a></li>
<li><a href="#/mail">Mail</a></li>
</ul> </ul>
</header> </header>

View file

@ -7,6 +7,10 @@ module.config([ '$routeProvider', function ($routeProvider) {
templateUrl: 'pages/perf.html', templateUrl: 'pages/perf.html',
controller: 'PerfCtrl' controller: 'PerfCtrl'
}) })
.when('/mail', {
templateUrl: 'pages/mail.html',
controller: 'MailCtrl'
})
.otherwise({ .otherwise({
templateUrl: 'pages/home.html' templateUrl: 'pages/home.html'
}); });
@ -47,3 +51,24 @@ module.controller('PerfCtrl', function ($scope, $resource) {
$scope.loadJobs(); $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();
});

View file

@ -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>