diff --git a/modules/module-list.nix b/modules/module-list.nix
index 208abb4ffaf3..35da89c8df97 100644
--- a/modules/module-list.nix
+++ b/modules/module-list.nix
@@ -54,6 +54,7 @@
./security/rtkit.nix
./security/setuid-wrappers.nix
./security/sudo.nix
+ ./services/amqp/activemq/default.nix
./services/amqp/rabbitmq.nix
./services/audio/alsa.nix
./services/audio/fuppes.nix
diff --git a/modules/services/amqp/activemq/ActiveMQBroker.java b/modules/services/amqp/activemq/ActiveMQBroker.java
new file mode 100644
index 000000000000..c0f5d16ea11a
--- /dev/null
+++ b/modules/services/amqp/activemq/ActiveMQBroker.java
@@ -0,0 +1,19 @@
+import org.apache.activemq.broker.BrokerService;
+import org.apache.activemq.broker.BrokerFactory;
+import java.net.URI;
+
+public class ActiveMQBroker {
+
+ public static void main(String[] args) throws Throwable {
+ URI uri = new URI((args.length > 0) ? args[0] : "xbean:activemq.xml");
+ BrokerService broker = BrokerFactory.createBroker(uri);
+ broker.start();
+ if (broker.waitUntilStarted()) {
+ broker.waitUntilStopped();
+ } else {
+ System.out.println("Failed starting broker");
+ System.exit(-1);
+ };
+ }
+
+}
diff --git a/modules/services/amqp/activemq/default.nix b/modules/services/amqp/activemq/default.nix
new file mode 100644
index 000000000000..0df79205d5a9
--- /dev/null
+++ b/modules/services/amqp/activemq/default.nix
@@ -0,0 +1,146 @@
+{ config, pkgs, ... }:
+
+with pkgs.lib;
+with pkgs;
+
+let
+
+ cfg = config.services.activemq;
+
+ activemqBroker = stdenv.mkDerivation {
+ name = "activemq-broker";
+ phases = [ "installPhase" ];
+ buildInputs = [ jdk ];
+ installPhase = ''
+ ensureDir $out/lib
+ source ${activemq}/lib/classpath.env
+ export CLASSPATH
+ ln -s "${./ActiveMQBroker.java}" ActiveMQBroker.java
+ javac -d $out/lib ActiveMQBroker.java
+ '';
+ };
+
+in {
+
+ options = {
+ services.activemq = {
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Enable the Apache ActiveMQ message broker service.
+ '';
+ };
+ configurationDir = mkOption {
+ default = "${activemq}/conf";
+ description = ''
+ The base directory for ActiveMQ's configuration.
+ By default, this directory is searched for a file named activemq.xml,
+ which should contain the configuration for the broker service.
+ '';
+ };
+ configurationURI = mkOption {
+ type = types.string;
+ default = "xbean:activemq.xml";
+ description = ''
+ The URI that is passed along to the BrokerFactory to
+ set up the configuration of the ActiveMQ broker service.
+ You should not need to change this. For custom configuration,
+ set the configurationDir instead, and create
+ an activemq.xml configuration file in it.
+ '';
+ };
+ baseDir = mkOption {
+ type = types.string;
+ default = "/var/activemq";
+ description = ''
+ The base directory where ActiveMQ stores its persistent data and logs.
+ This will be overriden if you set "activemq.base" and "activemq.data"
+ in the javaProperties option. You can also override
+ this in activemq.xml.
+ '';
+ };
+ javaProperties = mkOption {
+ type = types.attrs;
+ default = { };
+ example = {
+ "java.net.preferIPv4Stack" = "true";
+ };
+ apply = attrs: {
+ "activemq.base" = "${cfg.baseDir}";
+ "activemq.data" = "${cfg.baseDir}/data";
+ "activemq.conf" = "${cfg.configurationDir}";
+ "activemq.home" = "${activemq}";
+ } // attrs;
+ description = ''
+ Specifies Java properties that are sent to the ActiveMQ
+ broker service with the "-D" option. You can set properties
+ here to change the behaviour and configuration of the broker.
+ All essential properties that are not set here are automatically
+ given reasonable defaults.
+ '';
+ };
+ extraJavaOptions = mkOption {
+ type = types.string;
+ default = "";
+ example = "-Xmx2G -Xms2G -XX:MaxPermSize=512M";
+ description = ''
+ Add extra options here that you want to be sent to the
+ Java runtime when the broker service is started.
+ '';
+ };
+ user = {
+ create = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ If true, the a system user with the specified name will be added
+ to the system configuration. If false, a user with the specified
+ name is expected to exist.
+ '';
+ };
+ name = mkOption {
+ type = types.string;
+ default = "activemq";
+ description = ''
+ The name of the user that should run the ActiveMQ process.
+ '';
+ };
+ };
+ };
+ };
+
+ config = mkIf cfg.enable {
+ users.extraUsers = mkIf cfg.user.create (singleton {
+ inherit (cfg.user) name;
+ description = "ActiveMQ server user";
+ });
+
+ systemd.services.activemq_init = {
+ wantedBy = [ "activemq.service" ];
+ partOf = [ "activemq.service" ];
+ before = [ "activemq.service" ];
+ serviceConfig.Type = "oneshot";
+ script = ''
+ mkdir -p "${cfg.javaProperties."activemq.data"}"
+ chown -R activemq "${cfg.javaProperties."activemq.data"}"
+ '';
+ };
+
+ systemd.services.activemq = {
+ wantedBy = [ "multi-user.target" ];
+ after = [ "network.target" ];
+ path = [ jre ];
+ serviceConfig.User = "activemq";
+ script = ''
+ source ${activemq}/lib/classpath.env
+ export CLASSPATH=${activemqBroker}/lib:${cfg.configurationDir}:$CLASSPATH
+ exec java \
+ ${concatStringsSep " \\\n" (mapAttrsToList (name: value: "-D${name}=${value}") cfg.javaProperties)} \
+ ${cfg.extraJavaOptions} ActiveMQBroker "${cfg.configurationURI}"
+ '';
+ };
+
+ };
+
+}