commit
1835b641e6
33 changed files with 1824 additions and 4 deletions
|
|
@ -54,7 +54,8 @@ abstract class ActorSystemActivator extends BundleActivator {
|
|||
val logServiceListner = new ServiceListener {
|
||||
def serviceChanged(event: ServiceEvent) {
|
||||
event.getType match {
|
||||
case ServiceEvent.REGISTERED ⇒ system.eventStream.publish(serviceForReference[LogService](context, event.getServiceReference))
|
||||
case ServiceEvent.REGISTERED ⇒
|
||||
system.eventStream.publish(serviceForReference[LogService](context, event.getServiceReference))
|
||||
case ServiceEvent.UNREGISTERING ⇒ system.eventStream.publish(UnregisteringLogService)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
49
akka-samples/akka-sample-osgi-dining-hakkers/README.md
Normal file
49
akka-samples/akka-sample-osgi-dining-hakkers/README.md
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
akka-osgi-sample : Clustered DiningHakkers
|
||||
================
|
||||
This project may be used to test akka bundles in OSGi Frameworks. The build tool (sbt for the moment) provide scripts to run in an OSGi Framework (Karaf only for the moment) a version of the DiningHakkers that runs on several nodes using the akka-cluster module.
|
||||
|
||||
## Bundle overview
|
||||
|
||||
This project provides three Osgi Bundles
|
||||
- api providing an API for the Service exposed by the core and used by the command
|
||||
- core implementing the whole logic: clustered connections, Hakkers, ChopSticks. Finally it provides an ActorRef of one created Hakker
|
||||
- command use a service to get a Hakker (ActorRef) with its position around the table
|
||||
|
||||
An integration testing module is provided to verify OSGi functionality:
|
||||
- integration-test
|
||||
|
||||
Two modules that provision the project into the Karaf OSGi container for experimentation and integration testing:
|
||||
- assembly-features defines the karaf "feature" that allows Karaf to provision the bundles
|
||||
- assembly-dist creates a distribution tar.gz and zip file containing the configured Karaf runtime
|
||||
|
||||
## How to use it
|
||||
|
||||
### Setup with sbt
|
||||
just run:
|
||||
```bash
|
||||
sbt clean
|
||||
sbt package
|
||||
sbt osgi-bundle
|
||||
```
|
||||
sbt will creates the bundles in each subproject akka-sample/akka-sample-osgi-dining-hakkers/(api, command, core)/target directories. To have integration tests and OSGi environment loaded, please use the Maven build (at least for the moment)
|
||||
### Setup with Maven
|
||||
```bash
|
||||
mvn clean install
|
||||
```
|
||||
|
||||
The assembly-dist/target/ directory will now contain a tar.gz file that contains a pre-configured Karaf runtime.
|
||||
This can be extracted to any location, and bin/karaf executed. The provided karaf.sh script automates this.
|
||||
|
||||
### Run
|
||||
Extract the OSGi Framework from the tar.gz described above into any location, or run:
|
||||
``./karaf.sh``
|
||||
|
||||
Execute the framework by running ``bin/karaf`` from inside the extracted directory.
|
||||
|
||||
Then try to restart some bundles, to test the stability of the bundles:
|
||||
|
||||
``list`` to get the list of the bundles
|
||||
``restart #bundle_number`` to restart the bundle using its ID
|
||||
``exit`` or CTRL-D to exit the Karaf console
|
||||
|
||||
Depending on the akka version you're using, you may need to modify the core bundle when deploying on a second machine, to set its akka.remote.netty.hostname in the application.conf.
|
||||
24
akka-samples/akka-sample-osgi-dining-hakkers/api/pom.xml
Normal file
24
akka-samples/akka-sample-osgi-dining-hakkers/api/pom.xml
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<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/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>com.typesafe.akka.akka-sample-osgi-dining-hakkers</groupId>
|
||||
<artifactId>project</artifactId>
|
||||
<version>2.2.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>api</artifactId>
|
||||
<name>Dining Hakker :: Service API</name>
|
||||
<packaging>bundle</packaging>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.typesafe.akka</groupId>
|
||||
<artifactId>akka-osgi_${scala.dep.version}</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
/**
|
||||
* Copyright (C) 2009-2013 Typesafe Inc. <http://www.typesafe.com>.
|
||||
*/
|
||||
package akka.sample.osgi.api
|
||||
|
||||
import akka.actor.ActorRef
|
||||
|
||||
/*
|
||||
* Define our messages, they basically speak for themselves
|
||||
*/
|
||||
sealed trait DiningHakkerMessage
|
||||
|
||||
case class Busy(chopstick: ActorRef) extends DiningHakkerMessage
|
||||
|
||||
case class Put(hakker: ActorRef) extends DiningHakkerMessage
|
||||
|
||||
case class Take(hakker: ActorRef) extends DiningHakkerMessage
|
||||
|
||||
case class Taken(chopstick: ActorRef) extends DiningHakkerMessage
|
||||
|
||||
object Eat extends DiningHakkerMessage
|
||||
|
||||
object Think extends DiningHakkerMessage
|
||||
|
||||
object Identify extends DiningHakkerMessage
|
||||
|
||||
case class Identification(name: String, busyWith: String) extends DiningHakkerMessage
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
Copyright 2013 Crossing-Tech
|
||||
|
||||
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 akka.sample.osgi.api
|
||||
|
||||
import akka.actor.ActorRef
|
||||
|
||||
trait DiningHakkersService {
|
||||
def getHakker(name: String, chairNumber: Int): ActorRef
|
||||
}
|
||||
|
|
@ -0,0 +1,130 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<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/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>com.typesafe.akka.akka-sample-osgi-dining-hakkers</groupId>
|
||||
<artifactId>project</artifactId>
|
||||
<version>2.2.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>akka-sample-osgi-dining-hakkers-dist</artifactId>
|
||||
<name>Dining Hakkers :: Distribution</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>akka-sample-osgi-dining-hakkers</artifactId>
|
||||
<type>pom</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>command</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>${basedir}/src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
<includes>
|
||||
<include>**/*</include>
|
||||
</includes>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.karaf.tooling</groupId>
|
||||
<artifactId>features-maven-plugin</artifactId>
|
||||
<version>${karaf.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>add-features-to-repo</id>
|
||||
<phase>prepare-package</phase>
|
||||
<goals>
|
||||
<goal>add-features-to-repo</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<descriptors>
|
||||
<descriptor>mvn:org.apache.karaf.assemblies.features/standard/${karaf.version}/xml/features</descriptor>
|
||||
<descriptor>mvn:org.apache.karaf.assemblies.features/enterprise/${karaf.version}/xml/features</descriptor>
|
||||
<descriptor>mvn:com.typesafe.akka.akka-sample-osgi-dining-hakkers/akka-sample-osgi-dining-hakkers/${project.version}/xml/features</descriptor>
|
||||
</descriptors>
|
||||
<repository>target/generated-features-repo</repository>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-dependency-plugin</artifactId>
|
||||
<version>2.6</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>copy-cli-dependencies</id>
|
||||
<phase>prepare-package</phase>
|
||||
<goals>
|
||||
<goal>copy-dependencies</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<useRepositoryLayout>true</useRepositoryLayout>
|
||||
<outputDirectory>target/generated-features-repo</outputDirectory>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<!-- Uncompress the standard Karaf distribution -->
|
||||
<id>unpack</id>
|
||||
<phase>prepare-package</phase>
|
||||
<goals>
|
||||
<goal>unpack</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<artifactItems>
|
||||
<artifactItem>
|
||||
<groupId>org.apache.karaf</groupId>
|
||||
<artifactId>apache-karaf</artifactId>
|
||||
<type>tar.gz</type>
|
||||
<outputDirectory>target/dependencies</outputDirectory>
|
||||
</artifactItem>
|
||||
</artifactItems>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<version>2.4</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>bin</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<descriptors>
|
||||
<descriptor>src/main/descriptors/bin.xml</descriptor>
|
||||
</descriptors>
|
||||
<appendAssemblyId>false</appendAssemblyId>
|
||||
<tarLongFileMode>gnu</tarLongFileMode>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
|
||||
|
||||
<id>bin</id>
|
||||
|
||||
<formats>
|
||||
<format>tar.gz</format>
|
||||
</formats>
|
||||
|
||||
<includeBaseDirectory>true</includeBaseDirectory>
|
||||
<baseDirectory>akka-sample-osgi-dining-hakkers-${project.version}</baseDirectory>
|
||||
|
||||
<fileSets>
|
||||
<!-- Copy over jar files -->
|
||||
<fileSet>
|
||||
<directory>${project.build.directory}/dependencies</directory>
|
||||
<includes>
|
||||
<include>*.jar</include>
|
||||
</includes>
|
||||
<outputDirectory>/lib/</outputDirectory>
|
||||
</fileSet>
|
||||
|
||||
<fileSet>
|
||||
<directory>${project.basedir}/src/main/distribution</directory>
|
||||
<outputDirectory>/</outputDirectory>
|
||||
<directoryMode>0755</directoryMode>
|
||||
<fileMode>0644</fileMode>
|
||||
<filtered>true</filtered>
|
||||
<excludes>
|
||||
<exclude>lib/readme.txt</exclude>
|
||||
</excludes>
|
||||
</fileSet>
|
||||
|
||||
<fileSet>
|
||||
<directory>${project.basedir}/src/main/bin</directory>
|
||||
<outputDirectory>/bin</outputDirectory>
|
||||
<directoryMode>0755</directoryMode>
|
||||
<fileMode>0755</fileMode>
|
||||
</fileSet>
|
||||
|
||||
<fileSet>
|
||||
<directory>${project.build.directory}/classes/etc</directory>
|
||||
<outputDirectory>/etc/</outputDirectory>
|
||||
<lineEnding>unix</lineEnding>
|
||||
<directoryMode>0755</directoryMode>
|
||||
<fileMode>0644</fileMode>
|
||||
</fileSet>
|
||||
|
||||
<fileSet>
|
||||
<directory>${project.build.directory}/generated-features-repo</directory>
|
||||
<outputDirectory>/system</outputDirectory>
|
||||
<directoryMode>0755</directoryMode>
|
||||
<fileMode>0644</fileMode>
|
||||
</fileSet>
|
||||
|
||||
<!-- Expanded Karaf Standard Distribution, anything included above will not be overwritten here -->
|
||||
<fileSet>
|
||||
<directory>${project.build.directory}/dependencies/apache-karaf-${karaf.version}</directory>
|
||||
<outputDirectory>/</outputDirectory>
|
||||
<excludes>
|
||||
<exclude>**/demos/**</exclude>
|
||||
<exclude>bin/**</exclude>
|
||||
<exclude>etc/custom.properties</exclude>
|
||||
<exclude>etc/org.apache.karaf.features.cfg</exclude>
|
||||
<exclude>README</exclude>
|
||||
<exclude>RELEASE-NOTES</exclude>
|
||||
<exclude>karaf-manual*.html</exclude>
|
||||
<exclude>karaf-manual*.pdf</exclude>
|
||||
</excludes>
|
||||
</fileSet>
|
||||
|
||||
<!-- Copy over karaf/bin/* separately to get the correct file mode -->
|
||||
<fileSet>
|
||||
<directory>${project.build.directory}/dependencies/apache-karaf-${karaf.version}</directory>
|
||||
<outputDirectory>/</outputDirectory>
|
||||
<includes>
|
||||
<include>bin/**</include>
|
||||
</includes>
|
||||
<lineEnding>unix</lineEnding>
|
||||
<fileMode>0755</fileMode>
|
||||
</fileSet>
|
||||
</fileSets>
|
||||
|
||||
</assembly>
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
==============================================================================
|
||||
|
||||
ZZ:
|
||||
ZZZZ
|
||||
ZZZZZZ
|
||||
ZZZ' ZZZ
|
||||
~7 7ZZ' ZZZ
|
||||
:ZZZ: IZZ' ZZZ
|
||||
,OZZZZ.~ZZ? ZZZ
|
||||
ZZZZ' 'ZZZ$ ZZZ
|
||||
. $ZZZ ~ZZ$ ZZZ
|
||||
.=Z?. .ZZZO ~ZZ7 OZZ
|
||||
.ZZZZ7..:ZZZ~ 7ZZZ ZZZ~
|
||||
.$ZZZ$Z+.ZZZZ ZZZ: ZZZ$
|
||||
.,ZZZZ?' =ZZO= .OZZ 'ZZZ
|
||||
.$ZZZZ+ .ZZZZ IZZZ ZZZ$
|
||||
.ZZZZZ' .ZZZZ' .ZZZ$ ?ZZZ
|
||||
.ZZZZZZ' .OZZZ? ?ZZZ 'ZZZ$
|
||||
.?ZZZZZZ' .ZZZZ? .ZZZ? 'ZZZO
|
||||
.+ZZZZZZ?' .7ZZZZ' .ZZZZ :ZZZZ
|
||||
.ZZZZZZ$' .?ZZZZZ' .~ZZZZ 'ZZZZ.
|
||||
|
||||
|
||||
NNNNN $NNNN+
|
||||
NNNNN $NNNN+
|
||||
NNNNN $NNNN+
|
||||
NNNNN $NNNN+
|
||||
NNNNN $NNNN+
|
||||
=NNNNNNNNND$ NNNNN DDDDDD: $NNNN+ DDDDDN NDDNNNNNNNN,
|
||||
NNNNNNNNNNNNND NNNNN DNNNNN $NNNN+ 8NNNNN= :NNNNNNNNNNNNNN
|
||||
NNNNN$ DNNNNN NNNNN $NNNNN~ $NNNN+ NNNNNN NNNNN, :NNNNN+
|
||||
?DN~ NNNNN NNNNN MNNNNN $NNNN+:NNNNN7 $ND =NNNNN
|
||||
DNNNNN NNNNNDNNNN$ $NNNNDNNNNN :DNNNNN
|
||||
ZNDNNNNNNNNND NNNNNNNNNND, $NNNNNNNNNNN DNDNNNNNNNNNN
|
||||
NNNNNNNDDINNNNN NNNNNNNNNNND $NNNNNNNNNNND ONNNNNNND8+NNNNN
|
||||
:NNNND NNNNN NNNNNN DNNNN, $NNNNNO 7NNNND NNNNNO :NNNNN
|
||||
DNNNN NNNNN NNNNN DNNNN $NNNN+ 8NNNNN NNNNN $NNNNN
|
||||
DNNNNO NNNNNN NNNNN NNNNN $NNNN+ NNNNN$ NNNND, ,NNNNND
|
||||
NNNNNNDDNNNNNNNN NNNNN =NNNNN $NNNN+ DNNNN? DNNNNNNDNNNNNNNND
|
||||
NNNNNNNNN NNNN$ NNNNN 8NNNND $NNNN+ NNNNN= ,DNNNNNNND NNNNN$
|
||||
|
||||
==============================================================================
|
||||
|
||||
Welcome to the Akka ${project.version} OSGi sample.
|
||||
|
||||
The sample runs inside a Karaf environment, but the concepts are easily
|
||||
applicable to any OSGi environment.
|
||||
|
|
@ -0,0 +1 @@
|
|||
Akka ${project.version}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
################################################################################
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You 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.
|
||||
#
|
||||
################################################################################
|
||||
|
||||
#
|
||||
# All the values specified here will override the default values given
|
||||
# in config.properties.
|
||||
#
|
||||
|
||||
karaf.systemBundlesStartLevel=50
|
||||
|
||||
# Use Equinox
|
||||
karaf.framework=equinox
|
||||
|
||||
# Poll etc every 5s (default = 1s)
|
||||
felix.fileinstall.poll=5000
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
#
|
||||
# Comma separated list of features repositories to register by default
|
||||
# Default list + Dining Hakkers feature
|
||||
#
|
||||
featuresRepositories=mvn:org.apache.karaf.assemblies.features/standard/${karaf.version}/xml/features,mvn:org.apache.karaf.assemblies.features/enterprise/${karaf.version}/xml/features,mvn:com.typesafe.akka.akka-sample-osgi-dining-hakkers/akka-sample-osgi-dining-hakkers/${project.version}/xml/features
|
||||
|
||||
# Comma separated list of features to install at startup. Features definitions are looked up from repositories above.
|
||||
featuresBoot=config,ssh,management,dining-hakker
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
################################################################################
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You 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.
|
||||
#
|
||||
################################################################################
|
||||
|
||||
#
|
||||
# If set to true, the following property will not allow any certificate to be used
|
||||
# when accessing Maven repositories through SSL
|
||||
#
|
||||
#org.ops4j.pax.url.mvn.certificateCheck=
|
||||
|
||||
#
|
||||
# Path to the local Maven settings file.
|
||||
# The repositories defined in this file will be automatically added to the list
|
||||
# of default repositories if the 'org.ops4j.pax.url.mvn.repositories' property
|
||||
# below is not set.
|
||||
# The following locations are checked for the existence of the settings.xml file
|
||||
# * 1. looks for the specified url
|
||||
# * 2. if not found looks for ${user.home}/.m2/settings.xml
|
||||
# * 3. if not found looks for ${maven.home}/conf/settings.xml
|
||||
# * 4. if not found looks for ${M2_HOME}/conf/settings.xml
|
||||
#
|
||||
#org.ops4j.pax.url.mvn.settings=
|
||||
|
||||
#
|
||||
# Path to the local Maven repository which is used to avoid downloading
|
||||
# artifacts when they already exist locally.
|
||||
# The value of this property will be extracted from the settings.xml file
|
||||
# above, or defaulted to:
|
||||
# System.getProperty( "user.home" ) + "/.m2/repository"
|
||||
#
|
||||
org.ops4j.pax.url.mvn.localRepository=file:${karaf.home}/${karaf.default.repository}
|
||||
|
||||
#
|
||||
# Default this to false. It's just weird to use undocumented repos
|
||||
#
|
||||
org.ops4j.pax.url.mvn.useFallbackRepositories=false
|
||||
|
||||
#
|
||||
# Uncomment if you don't wanna use the proxy settings
|
||||
# from the Maven conf/settings.xml file
|
||||
#
|
||||
# org.ops4j.pax.url.mvn.proxySupport=false
|
||||
|
||||
#
|
||||
# Disable aether support by default. This ensure that the defaultRepositories
|
||||
# below will be used
|
||||
#
|
||||
org.ops4j.pax.url.mvn.disableAether=true
|
||||
|
||||
#
|
||||
# Comma separated list of repositories scanned when resolving an artifact.
|
||||
# Those repositories will be checked before iterating through the
|
||||
# below list of repositories and even before the local repository
|
||||
# A repository url can be appended with zero or more of the following flags:
|
||||
# @snapshots : the repository contains snaphots
|
||||
# @noreleases : the repository does not contain any released artifacts
|
||||
#
|
||||
# The following property value will add the system folder as a repo.
|
||||
#
|
||||
org.ops4j.pax.url.mvn.defaultRepositories=file:${karaf.home}/${karaf.default.repository}@snapshots,\
|
||||
file:${karaf.home}/local-repo@snapshots
|
||||
|
||||
#
|
||||
# Comma separated list of repositories scanned when resolving an artifact.
|
||||
# The default list includes the following repositories:
|
||||
# http://repo1.maven.org/maven2
|
||||
# http://repository.apache.org/content/groups/snapshots-group
|
||||
# http://svn.apache.org/repos/asf/servicemix/m2-repo
|
||||
# http://repository.springsource.com/maven/bundles/release
|
||||
# http://repository.springsource.com/maven/bundles/external
|
||||
# To add repositories to the default ones, prepend '+' to the list of repositories
|
||||
# to add.
|
||||
# A repository url can be appended with zero or more of the following flags:
|
||||
# @snapshots : the repository contains snaphots
|
||||
# @noreleases : the repository does not contain any released artifacts
|
||||
#
|
||||
org.ops4j.pax.url.mvn.repositories=file:${karaf.home}/${karaf.default.repository}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
Place files like custom.properties and jre.properties here. Files
|
||||
placed here will be copied to the Karaf etc/ directory.
|
||||
|
||||
Exclude the Karaf default version of the file in bin.xml.
|
||||
|
||||
Additional configuration files for etc should be placed into
|
||||
src/main/resources/etc.
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
Jars targeted to the ${app.home}/lib directory should be placed here.
|
||||
See lib/README in the distribution package for more details.
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
Configuration files for the Karaf etc/ directory.
|
||||
|
||||
Place Karaf ConfigAdmin files here.
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<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/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>com.typesafe.akka.akka-sample-osgi-dining-hakkers</groupId>
|
||||
<artifactId>project</artifactId>
|
||||
<version>2.2.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>akka-sample-osgi-dining-hakkers</artifactId>
|
||||
<name>Dining Hakkers :: Features</name>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
<includes>
|
||||
<include>**/*</include>
|
||||
</includes>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-resources-plugin</artifactId>
|
||||
<version>2.6</version>
|
||||
<configuration>
|
||||
<useDefaultDelimiters>false</useDefaultDelimiters>
|
||||
<delimiters>
|
||||
<!--suppress MavenModelInspection -->
|
||||
<delimiter>${*}</delimiter>
|
||||
</delimiters>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>filter</id>
|
||||
<phase>generate-resources</phase>
|
||||
<goals>
|
||||
<goal>resources</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>build-helper-maven-plugin</artifactId>
|
||||
<version>1.7</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-artifact</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>attach-artifact</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<artifacts>
|
||||
<artifact>
|
||||
<file>target/classes/features.xml</file>
|
||||
<type>xml</type>
|
||||
<classifier>features</classifier>
|
||||
</artifact>
|
||||
</artifacts>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<features name="akka.features-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.0.0">
|
||||
|
||||
<feature name='osgi-compendium' description='OSGi compendium feature' version='${osgi.version}' resolver='(obr)'>
|
||||
<bundle start-level="10">mvn:org.osgi/org.osgi.compendium/${osgi.version}</bundle>
|
||||
</feature>
|
||||
|
||||
<feature name='scala' description='Scala' version='${scala.version}' resolver='(obr)'>
|
||||
<bundle start-level="15">mvn:org.scala-lang/scala-library/${scala.version}</bundle>
|
||||
</feature>
|
||||
|
||||
<feature name='uncommons-maths' description='Uncommons Maths' version='1.2.2' resolver='(obr)'>
|
||||
<!-- TODO replace this with upstream uncommons maths 1.2.3 which is OSGi enabled -->
|
||||
<bundle start-level="20">mvn:com.typesafe.akka.akka-sample-osgi-dining-hakkers/uncommons/1.2.2</bundle>
|
||||
</feature>
|
||||
|
||||
<feature name='protobuf' description='Protobuf feature' version='${protobuf.version}' resolver='(obr)'>
|
||||
<bundle start-level="20">mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.protobuf-java/${protobuf.version}_1</bundle>
|
||||
</feature>
|
||||
|
||||
<feature name='netty' description='Netty feature' version='${netty.version}' resolver='(obr)'>
|
||||
<bundle start-level="20">mvn:io.netty/netty/${netty.version}</bundle>
|
||||
</feature>
|
||||
|
||||
<feature name='typesafe-config' description='Typesafe config' version='${typesafe.config.version}' resolver='(obr)'>
|
||||
<feature version="[${scala.version},2.11.0)">scala</feature>
|
||||
<bundle start-level="25">mvn:com.typesafe/config/${typesafe.config.version}</bundle>
|
||||
</feature>
|
||||
|
||||
<feature name='akka' description='Akka' version='${akka.version}' resolver='(obr)'>
|
||||
<feature version="[${scala.version},2.11.0)">scala</feature>
|
||||
<feature version="[${netty.version},4.0.0)">netty</feature>
|
||||
<feature version="[1.2.2,3.0.0)">uncommons-maths</feature>
|
||||
<feature version="[${protobuf.version},3.0.0)">protobuf</feature>
|
||||
<feature version="[${typesafe.config.version},2.0.0)">typesafe-config</feature>
|
||||
<bundle start-level="30">mvn:com.typesafe.akka/akka-cluster-experimental_${scala.dep.version}/${akka.version}</bundle>
|
||||
<bundle start-level="30">mvn:com.typesafe.akka/akka-remote_${scala.dep.version}/${akka.version}</bundle>
|
||||
<bundle start-level="30">mvn:com.typesafe.akka/akka-osgi_${scala.dep.version}/${akka.version}</bundle>
|
||||
</feature>
|
||||
|
||||
<feature name='dining-hakker' description='Akka Dining Hakker Sample' version='${project.version}' resolver='(obr)'>
|
||||
<feature version="[${akka.version},3.0.0)">akka</feature>
|
||||
<bundle start-level="50">mvn:com.typesafe.akka.akka-sample-osgi-dining-hakkers/api/${project.version}</bundle>
|
||||
<bundle start-level="50">mvn:com.typesafe.akka.akka-sample-osgi-dining-hakkers/core/${project.version}</bundle>
|
||||
<bundle start-level="50">mvn:com.typesafe.akka.akka-sample-osgi-dining-hakkers/command/${project.version}</bundle>
|
||||
</feature>
|
||||
</features>
|
||||
48
akka-samples/akka-sample-osgi-dining-hakkers/command/pom.xml
Normal file
48
akka-samples/akka-sample-osgi-dining-hakkers/command/pom.xml
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<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/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>com.typesafe.akka.akka-sample-osgi-dining-hakkers</groupId>
|
||||
<artifactId>project</artifactId>
|
||||
<version>2.2.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>command</artifactId>
|
||||
<name>Dining Hakker :: Service consumer</name>
|
||||
<packaging>bundle</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.osgi</groupId>
|
||||
<artifactId>org.osgi.core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.osgi</groupId>
|
||||
<artifactId>org.osgi.compendium</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.typesafe.akka</groupId>
|
||||
<artifactId>akka-osgi_${scala.dep.version}</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<configuration>
|
||||
<instructions>
|
||||
<Bundle-Activator>akka.sample.osgi.command.Activator</Bundle-Activator>
|
||||
<Import-Package>*</Import-Package>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
Copyright 2013 Crossing-Tech
|
||||
|
||||
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 akka.sample.osgi.command
|
||||
|
||||
import org.osgi.framework.{ ServiceEvent, BundleContext, BundleActivator }
|
||||
import akka.sample.osgi.api.DiningHakkersService
|
||||
import akka.actor.{ ActorRef, PoisonPill }
|
||||
import org.osgi.util.tracker.ServiceTracker
|
||||
|
||||
class Activator extends BundleActivator {
|
||||
println("Command Activator created")
|
||||
var hakker: Option[ActorRef] = None
|
||||
|
||||
def start(context: BundleContext) {
|
||||
val logServiceTracker = new ServiceTracker(context, classOf[DiningHakkersService].getName, null)
|
||||
logServiceTracker.open()
|
||||
val service = Option(logServiceTracker.getService.asInstanceOf[DiningHakkersService])
|
||||
service.foreach(startHakker(_, context.getBundle.getSymbolicName + ":" + context.getBundle.getBundleId))
|
||||
}
|
||||
|
||||
def startHakker(service: DiningHakkersService, name: String) {
|
||||
hakker = Some(service.getHakker(name, (math.floor(math.random * 5)).toInt))
|
||||
}
|
||||
|
||||
def stop(context: BundleContext) {
|
||||
hakker.foreach(_ ! PoisonPill)
|
||||
}
|
||||
}
|
||||
83
akka-samples/akka-sample-osgi-dining-hakkers/core/pom.xml
Normal file
83
akka-samples/akka-sample-osgi-dining-hakkers/core/pom.xml
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<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/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>com.typesafe.akka.akka-sample-osgi-dining-hakkers</groupId>
|
||||
<artifactId>project</artifactId>
|
||||
<version>2.2.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>core</artifactId>
|
||||
<name>Dining Hakker :: Core</name>
|
||||
<packaging>bundle</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.osgi</groupId>
|
||||
<artifactId>org.osgi.core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.osgi</groupId>
|
||||
<artifactId>org.osgi.compendium</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.typesafe.akka</groupId>
|
||||
<artifactId>akka-osgi_${scala.dep.version}</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.typesafe.akka</groupId>
|
||||
<artifactId>akka-remote_${scala.dep.version}</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.typesafe</groupId>
|
||||
<artifactId>config</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!--Test dependencies-->
|
||||
<!-- <dependency>
|
||||
<groupId>org.specs2</groupId>
|
||||
<artifactId>specs2_${scala.version}</artifactId>
|
||||
<version>1.12.3</version>
|
||||
<scope>test</scope>
|
||||
</dependency>-->
|
||||
|
||||
<!--remoting dependencies-->
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.protobuf</groupId>
|
||||
<artifactId>protobuf-java</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.typesafe.akka</groupId>
|
||||
<artifactId>akka-cluster-experimental_${scala.dep.version}</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.fusesource</groupId>
|
||||
<artifactId>sigar</artifactId>
|
||||
<version>1.6.4</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<configuration>
|
||||
<instructions>
|
||||
<Private-Package>akka.sample.osgi.internal, akka.sample.osgi.service</Private-Package>
|
||||
<Bundle-Activator>akka.sample.osgi.activation.Activator</Bundle-Activator>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
akka {
|
||||
|
||||
actor {
|
||||
provider = "akka.cluster.ClusterActorRefProvider"
|
||||
}
|
||||
|
||||
remote {
|
||||
netty.tcp {
|
||||
hostname = "localhost"
|
||||
port = 4242
|
||||
}
|
||||
}
|
||||
|
||||
cluster {
|
||||
seed-nodes = ["akka.tcp://akka-osgi-sample@localhost:4242"]
|
||||
auto-down = on
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
Copyright 2013 Crossing-Tech
|
||||
|
||||
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 akka.sample.osgi.activation
|
||||
|
||||
import akka.osgi.ActorSystemActivator
|
||||
import akka.actor.{ Props, ActorSystem }
|
||||
import akka.sample.osgi.internal.Table
|
||||
import akka.sample.osgi.service.DiningHakkersServiceImpl
|
||||
import akka.sample.osgi.api.DiningHakkersService
|
||||
import akka.event.{ LogSource, Logging }
|
||||
import org.osgi.framework.{ ServiceRegistration, BundleContext }
|
||||
import scala.collection.mutable.ListBuffer
|
||||
|
||||
class Activator extends ActorSystemActivator {
|
||||
|
||||
import Activator._
|
||||
|
||||
var diningHakkerService: Option[ServiceRegistration] = None
|
||||
|
||||
def configure(context: BundleContext, system: ActorSystem) {
|
||||
val log = Logging(system, this)
|
||||
log.info("Core bundle configured")
|
||||
system.actorOf(Props[Table], "table")
|
||||
registerService(context, system)
|
||||
registerHakkersService(context, system)
|
||||
log.info("Hakker service registered")
|
||||
}
|
||||
|
||||
/**
|
||||
* registers the DinningHakkerService as a Service to be tracked and find by other OSGi bundles.
|
||||
* in other words, this instance may be used in other bundles which listen or track the OSGi Service
|
||||
* @param context OSGi BundleContext
|
||||
* @param system ActorSystem
|
||||
*/
|
||||
def registerHakkersService(context: BundleContext, system: ActorSystem) {
|
||||
|
||||
val hakkersService = new DiningHakkersServiceImpl(system)
|
||||
|
||||
diningHakkerService = Some(context.registerService(classOf[DiningHakkersService].getName(), hakkersService, null))
|
||||
|
||||
}
|
||||
|
||||
override def stop(context: BundleContext) {
|
||||
unregisterServices(context)
|
||||
println("Hakker service unregistred")
|
||||
super.stop(context)
|
||||
}
|
||||
|
||||
def unregisterServices(context: BundleContext) {
|
||||
diningHakkerService foreach (_.unregister())
|
||||
}
|
||||
|
||||
override def getActorSystemName(context: BundleContext): String = "akka-osgi-sample"
|
||||
}
|
||||
|
||||
object Activator {
|
||||
implicit val logSource: LogSource[AnyRef] = new LogSource[AnyRef] {
|
||||
def genString(o: AnyRef): String = o.getClass.getName
|
||||
override def getClazz(o: AnyRef): Class[_] = o.getClass
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,170 @@
|
|||
/**
|
||||
* Copyright (C) 2009-2013 Typesafe Inc. <http://www.typesafe.com>.
|
||||
*/
|
||||
package akka.sample.osgi.internal
|
||||
|
||||
import language.postfixOps
|
||||
import akka.cluster.Cluster
|
||||
import akka.cluster.ClusterEvent.{ CurrentClusterState, LeaderChanged }
|
||||
import akka.event.Logging
|
||||
import akka.sample.osgi.api._
|
||||
|
||||
//Akka adaptation of
|
||||
//http://www.dalnefre.com/wp/2010/08/dining-philosophers-in-humus/
|
||||
|
||||
import akka.actor._
|
||||
import scala.concurrent.duration._
|
||||
|
||||
import akka.sample.osgi.api._
|
||||
|
||||
/*
|
||||
* A Chopstick is an actor, it can be taken, and put back
|
||||
*/
|
||||
class Chopstick extends Actor {
|
||||
|
||||
val log = Logging(context.system, this)
|
||||
|
||||
import context._
|
||||
|
||||
//When a Chopstick is taken by a hakker
|
||||
//It will refuse to be taken by other hakkers
|
||||
//But the owning hakker can put it back
|
||||
def takenBy(hakker: ActorRef): Receive = {
|
||||
case Take(otherHakker) ⇒
|
||||
otherHakker ! Busy(self)
|
||||
case Put(`hakker`) ⇒
|
||||
become(available)
|
||||
}
|
||||
|
||||
//When a Chopstick is available, it can be taken by a hakker
|
||||
def available: Receive = {
|
||||
case Take(hakker) ⇒
|
||||
log.info(self.path + " is taken by " + hakker)
|
||||
become(takenBy(hakker))
|
||||
hakker ! Taken(self)
|
||||
}
|
||||
|
||||
//A Chopstick begins its existence as available
|
||||
def receive = available
|
||||
}
|
||||
|
||||
/*
|
||||
* A hakker is an awesome dude or dudett who either thinks about hacking or has to eat ;-)
|
||||
*/
|
||||
class Hakker(name: String, chair: Int) extends Actor {
|
||||
|
||||
val log = Logging(context.system, this)
|
||||
|
||||
log.info("Created Hakker at" + self.path)
|
||||
|
||||
import context._
|
||||
|
||||
val cluster = Cluster(context.system)
|
||||
|
||||
override def preStart() {
|
||||
log.info(s"Hakker ($name) takes position($chair)")
|
||||
cluster.subscribe(self, classOf[LeaderChanged])
|
||||
}
|
||||
|
||||
override def postStop() {
|
||||
log.info(s"Hakker ($name) leaves position($chair)")
|
||||
cluster.unsubscribe(self)
|
||||
}
|
||||
|
||||
//When a hakker is thinking it can become hungry
|
||||
//and try to pick up its chopsticks and eat
|
||||
def thinking(left: ActorRef, right: ActorRef): Receive = {
|
||||
case Eat ⇒
|
||||
become(hungry(left, right) orElse (clusterEvents))
|
||||
left ! Take(self)
|
||||
right ! Take(self)
|
||||
case Identify ⇒ identify("Thinking")
|
||||
}
|
||||
|
||||
//When a hakker is hungry it tries to pick up its chopsticks and eat
|
||||
//When it picks one up, it goes into wait for the other
|
||||
//If the hakkers first attempt at grabbing a chopstick fails,
|
||||
//it starts to wait for the response of the other grab
|
||||
def hungry(left: ActorRef, right: ActorRef): Receive = {
|
||||
case Taken(`left`) ⇒
|
||||
become(waiting_for(left, right, false) orElse (clusterEvents))
|
||||
case Taken(`right`) ⇒
|
||||
become(waiting_for(left, right, true) orElse (clusterEvents))
|
||||
case Busy(chopstick) ⇒
|
||||
become(denied_a_chopstick(left, right) orElse (clusterEvents))
|
||||
case Identify ⇒ identify("Hungry")
|
||||
}
|
||||
|
||||
//When a hakker is waiting for the last chopstick it can either obtain it
|
||||
//and start eating, or the other chopstick was busy, and the hakker goes
|
||||
//back to think about how he should obtain his chopsticks :-)
|
||||
def waiting_for(left: ActorRef, right: ActorRef, waitingForLeft: Boolean): Receive = {
|
||||
case Taken(`left`) if waitingForLeft ⇒
|
||||
log.info("%s has picked up %s and %s and starts to eat".format(name, left.path.name, right.path.name))
|
||||
become(eating(left, right) orElse (clusterEvents))
|
||||
system.scheduler.scheduleOnce(5 seconds, self, Think)
|
||||
case Taken(`right`) if !waitingForLeft ⇒
|
||||
log.info("%s has picked up %s and %s and starts to eat".format(name, left.path.name, right.path.name))
|
||||
become(eating(left, right) orElse (clusterEvents))
|
||||
system.scheduler.scheduleOnce(5 seconds, self, Think)
|
||||
case Busy(chopstick) ⇒
|
||||
become(thinking(left, right) orElse (clusterEvents))
|
||||
if (waitingForLeft) {
|
||||
right ! Put(self)
|
||||
} else {
|
||||
left ! Put(self)
|
||||
}
|
||||
self ! Eat
|
||||
case Identify ⇒ identify("Waiting for Chopstick")
|
||||
}
|
||||
|
||||
//When the results of the other grab comes back,
|
||||
//he needs to put it back if he got the other one.
|
||||
//Then go back and think and try to grab the chopsticks again
|
||||
def denied_a_chopstick(left: ActorRef, right: ActorRef): Receive = {
|
||||
case Taken(chopstick) ⇒
|
||||
become(thinking(left, right) orElse (clusterEvents))
|
||||
chopstick ! Put(self)
|
||||
self ! Eat
|
||||
case Busy(chopstick) ⇒
|
||||
become(thinking(left, right) orElse (clusterEvents))
|
||||
self ! Eat
|
||||
case Identify ⇒ identify("Denied a Chopstick")
|
||||
}
|
||||
|
||||
//When a hakker is eating, he can decide to start to think,
|
||||
//then he puts down his chopsticks and starts to think
|
||||
def eating(left: ActorRef, right: ActorRef): Receive = {
|
||||
case Think ⇒
|
||||
become(thinking(left, right) orElse (clusterEvents))
|
||||
left ! Put(self)
|
||||
right ! Put(self)
|
||||
log.info("%s puts down his chopsticks and starts to think".format(name))
|
||||
system.scheduler.scheduleOnce(5 seconds, self, Eat)
|
||||
case Identify ⇒ identify("Eating")
|
||||
}
|
||||
|
||||
def waitForChopsticks: Receive = {
|
||||
case (left: ActorRef, right: ActorRef) ⇒
|
||||
become(thinking(left, right) orElse (clusterEvents))
|
||||
system.scheduler.scheduleOnce(5 seconds, self, Eat)
|
||||
}
|
||||
|
||||
def clusterEvents: Receive = {
|
||||
case state: CurrentClusterState ⇒ state.leader foreach updateTable
|
||||
case LeaderChanged(Some(leaderAddress)) ⇒ updateTable(leaderAddress)
|
||||
}
|
||||
|
||||
def identify(busyWith: String) {
|
||||
sender ! Identification(name, busyWith)
|
||||
}
|
||||
|
||||
def updateTable(leaderAdress: Address) {
|
||||
become(waitForChopsticks)
|
||||
context.actorFor(RootActorPath(leaderAdress) / "user" / "table") ! chair
|
||||
}
|
||||
|
||||
//All hakkers start in a non-eating state
|
||||
def receive = clusterEvents
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
Copyright 2013 Crossing-Tech
|
||||
|
||||
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 akka.sample.osgi.internal
|
||||
|
||||
import akka.actor.{ Props, Actor }
|
||||
|
||||
class Table extends Actor {
|
||||
val chopsticks = for (i ← 1 to 5) yield context.actorOf(Props[Chopstick], "Chopstick" + i)
|
||||
|
||||
def receive = {
|
||||
case x: Int ⇒ sender ! (chopsticks(x), chopsticks((x + 1) % 5))
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
Copyright 2013 Crossing-Tech
|
||||
|
||||
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 akka.sample.osgi.service
|
||||
|
||||
import akka.sample.osgi.api.DiningHakkersService
|
||||
import akka.actor.{ Props, ActorSystem }
|
||||
import akka.sample.osgi.internal.Hakker
|
||||
|
||||
class DiningHakkersServiceImpl(system: ActorSystem) extends DiningHakkersService {
|
||||
def getHakker(name: String, chairNumber: Int) = {
|
||||
system.actorOf(Props(new Hakker(name, chairNumber)))
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,157 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<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/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>com.typesafe.akka.akka-sample-osgi-dining-hakkers</groupId>
|
||||
<artifactId>project</artifactId>
|
||||
<version>2.2.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>integration-test</artifactId>
|
||||
<name>Dining Hakker :: Integration Test</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.karaf.tooling.exam</groupId>
|
||||
<artifactId>org.apache.karaf.tooling.exam.container</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.ops4j.pax.exam</groupId>
|
||||
<artifactId>pax-exam-junit4</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.typesafe.akka</groupId>
|
||||
<artifactId>akka-testkit_${scala.dep.version}</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.scalatest</groupId>
|
||||
<artifactId>scalatest_${scala.dep.version}</artifactId>
|
||||
</dependency>
|
||||
<!--
|
||||
This is needed only for the scalatest osgi bundle, it has a non-optional import on scala-actors stuff.
|
||||
This can be removed once we are using ScalaTest 2.0.x: https://groups.google.com/d/topic/scalatest-users/XAVWBJ-v6vA/discussion
|
||||
See also TestOptions.testBundles
|
||||
-->
|
||||
<dependency>
|
||||
<groupId>org.scala-lang</groupId>
|
||||
<artifactId>scala-actors</artifactId>
|
||||
<version>${scala.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!--
|
||||
Explicitly import Pax Exam 2.6.0, should be able to remove this once Karaf 2.3.1 is released
|
||||
(http://www.mail-archive.com/user@karaf.apache.org/msg04061.html)
|
||||
-->
|
||||
<dependency>
|
||||
<groupId>org.ops4j.pax.exam</groupId>
|
||||
<artifactId>pax-exam</artifactId>
|
||||
<version>${paxexam.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.ops4j.pax.exam</groupId>
|
||||
<artifactId>pax-exam-container-remote</artifactId>
|
||||
<version>${paxexam.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.ops4j.pax.exam</groupId>
|
||||
<artifactId>pax-exam-invoker-junit</artifactId>
|
||||
<version>${paxexam.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.ops4j.pax.exam</groupId>
|
||||
<artifactId>pax-exam-container-rbc</artifactId>
|
||||
<version>${paxexam.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.ops4j.pax.exam</groupId>
|
||||
<artifactId>pax-exam-container-rbc-client</artifactId>
|
||||
<version>${paxexam.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.ops4j.pax.exam</groupId>
|
||||
<artifactId>pax-exam-extender-service</artifactId>
|
||||
<version>${paxexam.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.ops4j.pax.exam</groupId>
|
||||
<artifactId>pax-exam-inject</artifactId>
|
||||
<version>${paxexam.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.ops4j.pax.swissbox</groupId>
|
||||
<artifactId>pax-swissbox-core</artifactId>
|
||||
<version>${paxswissbox.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.ops4j.pax.swissbox</groupId>
|
||||
<artifactId>pax-swissbox-extender</artifactId>
|
||||
<version>${paxswissbox.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.ops4j.pax.swissbox</groupId>
|
||||
<artifactId>pax-swissbox-lifecycle</artifactId>
|
||||
<version>${paxswissbox.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.ops4j.pax.swissbox</groupId>
|
||||
<artifactId>pax-swissbox-framework</artifactId>
|
||||
<version>${paxswissbox.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!-- End of temporary Pax Exam dependency imports -->
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<!-- This is to allow use of versionAsInProject -->
|
||||
<plugin>
|
||||
<groupId>org.ops4j.pax.exam</groupId>
|
||||
<artifactId>maven-paxexam-plugin</artifactId>
|
||||
<version>1.2.4</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>generate-config</id>
|
||||
<goals>
|
||||
<goal>generate-depends-file</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>2.12.4</version>
|
||||
<configuration>
|
||||
<systemPropertyVariables>
|
||||
<pax.exam.service.timeout>30000</pax.exam.service.timeout>
|
||||
<karaf.version>${karaf.version}</karaf.version>
|
||||
<project.version>${project.version}</project.version>
|
||||
<!--<scalatest.artifact>scalatest_${scala.dep.version}</scalatest.artifact>-->
|
||||
<scala.dep.version>${scala.dep.version}</scala.dep.version>
|
||||
</systemPropertyVariables>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
package akka.sample.osgi.test
|
||||
|
||||
import akka.actor._
|
||||
import akka.sample.osgi.api.{DiningHakkersService, Identify, Identification}
|
||||
import akka.sample.osgi.test.TestOptions._
|
||||
import org.junit.runner.RunWith
|
||||
import org.junit.{Before, Test}
|
||||
import org.ops4j.pax.exam.{Option => PaxOption}
|
||||
import org.ops4j.pax.exam.junit.{Configuration, JUnit4TestRunner}
|
||||
import org.ops4j.pax.exam.util.Filter
|
||||
import org.scalatest.junit.JUnitSuite
|
||||
import org.scalatest.junit.ShouldMatchersForJUnit
|
||||
import javax.inject.Inject
|
||||
import java.util.concurrent.{TimeUnit, SynchronousQueue}
|
||||
import akka.testkit.TestProbe
|
||||
import scala.Some
|
||||
|
||||
/**
|
||||
* This is a ScalaTest based integration test. Pax-Exam, which is responsible for loading the test class into
|
||||
* the OSGi environment and executing it, currently does not support ScalaTest directly. However, ScalaTest
|
||||
* provides a JUnit-compatible runner, so the test is defined to use that runner. Pax-Exam can then invoke
|
||||
* it as a normal JUnit test. Because Pax Exam is using the JUnitRunner and not one of the ScalaTest traits such
|
||||
* as FunSuite, the test must be defined using the JUnit @Test annotation.
|
||||
*
|
||||
* This is a simple test demonstrating in-container integration testing.
|
||||
*
|
||||
* One thing to note is that we only depend on the API bundle, not the implementation in core. The implementation
|
||||
* is injected into the test at runtime via an OSGi service lookup performed by Pax Exam.
|
||||
*
|
||||
* TODO attempt to use the Akka test probe
|
||||
*/
|
||||
@RunWith(classOf[JUnit4TestRunner])
|
||||
class HakkerStatusTest extends JUnitSuite with ShouldMatchersForJUnit {
|
||||
|
||||
@Inject @Filter(timeout = 30000)
|
||||
var actorSystem: ActorSystem = _
|
||||
|
||||
@Inject @Filter(timeout = 30000)
|
||||
var service: DiningHakkersService = _
|
||||
|
||||
var testProbe: TestProbe = _
|
||||
|
||||
@Configuration
|
||||
def config: Array[PaxOption] = Array[PaxOption](
|
||||
karafOptionsWithTestBundles(),
|
||||
featureDiningHakkers()
|
||||
//,debugOptions()
|
||||
)
|
||||
|
||||
// Junit @Before and @After can be used as well
|
||||
|
||||
/* @Before
|
||||
def setupAkkaTestkit() {
|
||||
testProbe = new TestProbe(actorSystem)
|
||||
}*/
|
||||
|
||||
|
||||
@Test
|
||||
def verifyObtainingAHakkerViaTheTheDiningHakkersService() {
|
||||
|
||||
val name = "TestHakker"
|
||||
val hakker = Some(service.getHakker(name, (math.floor(math.random * 5)).toInt))
|
||||
.getOrElse(throw new IllegalStateException("No Hakker was created via DiningHakkerService"))
|
||||
|
||||
hakker should not be (null)
|
||||
|
||||
/* TODO Getting some weird config error with TestProbe, is it a TestProbe inside OSGi issue?
|
||||
Exception in thread "RMI TCP Connection(idle)" java.lang.NullPointerException
|
||||
at com.typesafe.config.impl.SerializedConfigValue.writeOrigin(SerializedConfigValue.java:202)
|
||||
at com.typesafe.config.impl.ConfigImplUtil.writeOrigin(ConfigImplUtil.java:224)
|
||||
at com.typesafe.config.ConfigException.writeObject(ConfigException.java:58)
|
||||
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
|
||||
|
||||
java.io.EOFException
|
||||
at java.io.ObjectInputStream$BlockDataInputStream.readUnsignedByte(ObjectInputStream.java:2747)
|
||||
at java.io.ObjectInputStream.readUnsignedByte(ObjectInputStream.java:924)
|
||||
at com.typesafe.config.impl.SerializedConfigValue.readCode(SerializedConfigValue.java:412)
|
||||
at com.typesafe.config.impl.SerializedConfigValue.readOrigin(SerializedConfigValue.java:218)
|
||||
...
|
||||
testProbe.send(hakker, Identify)
|
||||
val identification = testProbe.expectMsgClass(classOf[Identification])
|
||||
val (fromHakker, busyWith) = (identification.name, identification.busyWith)
|
||||
*/
|
||||
|
||||
// create an "Interrogator" actor that receives a Hakker's identification
|
||||
// this is to work around the TestProbe Exception above
|
||||
val response = new SynchronousQueue[(String, String)]()
|
||||
class Interrogator extends Actor {
|
||||
def receive = {
|
||||
case msg: Identification ⇒ {
|
||||
response.put((msg.name, msg.busyWith))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hakker.tell(Identify, actorSystem.actorOf(Props(new Interrogator()), "Interrogator"))
|
||||
val (fromHakker, busyWith) = response.poll(5, TimeUnit.SECONDS)
|
||||
|
||||
println("---------------> %s is busy with %s.".format(fromHakker, busyWith))
|
||||
fromHakker should be ("TestHakker")
|
||||
busyWith should not be (null)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
package akka.sample.osgi.test
|
||||
|
||||
import org.ops4j.pax.exam.CoreOptions._
|
||||
import org.ops4j.pax.exam.options.DefaultCompositeOption
|
||||
import org.ops4j.pax.exam.{Option => PaxOption}
|
||||
import org.apache.karaf.tooling.exam.options.LogLevelOption
|
||||
import org.apache.karaf.tooling.exam.options.KarafDistributionOption._
|
||||
|
||||
/**
|
||||
* Re-usable PAX Exam option groups.
|
||||
*/
|
||||
object TestOptions {
|
||||
|
||||
val scalaDepVersion = System.getProperty("scala.dep.version")
|
||||
|
||||
def karafOptions(useDeployFolder: Boolean = false): PaxOption = {
|
||||
new DefaultCompositeOption(
|
||||
karafDistributionConfiguration.frameworkUrl(
|
||||
maven.groupId("org.apache.karaf").artifactId("apache-karaf").`type`("zip").version(System.getProperty("karaf.version")))
|
||||
.karafVersion(System.getProperty("karaf.version")).name("Apache Karaf").useDeployFolder(useDeployFolder),
|
||||
editConfigurationFilePut("etc/config.properties", "karaf.framework", "equinox")
|
||||
)
|
||||
}
|
||||
|
||||
def testBundles(): PaxOption = {
|
||||
new DefaultCompositeOption(
|
||||
mavenBundle("com.typesafe.akka", "akka-testkit_%s".format(scalaDepVersion)).versionAsInProject,
|
||||
mavenBundle("org.scalatest", "scalatest_%s".format(scalaDepVersion)).versionAsInProject,
|
||||
// This is needed for the scalatest osgi bundle, it has a non-optional import on a scala-actors package
|
||||
mavenBundle("org.scala-lang", "scala-actors").versionAsInProject,
|
||||
junitBundles
|
||||
)
|
||||
}
|
||||
|
||||
def debugOptions(level: LogLevelOption.LogLevel = LogLevelOption.LogLevel.INFO, debugPort: Int= 5005): PaxOption = {
|
||||
new DefaultCompositeOption(
|
||||
logLevel(level),
|
||||
debugConfiguration(String.valueOf(debugPort), true),
|
||||
configureConsole().startLocalConsole(),
|
||||
configureConsole().startRemoteShell()
|
||||
)
|
||||
}
|
||||
|
||||
def karafOptionsWithTestBundles(useDeployFolder: Boolean = false): PaxOption = {
|
||||
new DefaultCompositeOption(
|
||||
karafOptions(useDeployFolder),
|
||||
testBundles()
|
||||
)
|
||||
}
|
||||
|
||||
def featureDiningHakkers(): PaxOption = {
|
||||
akkaFeature("dining-hakker")
|
||||
}
|
||||
|
||||
def akkaFeature(feature: String): PaxOption = {
|
||||
scanFeatures(maven.groupId("com.typesafe.akka.akka-sample-osgi-dining-hakkers")
|
||||
.artifactId("akka-sample-osgi-dining-hakkers") .`type`("xml").classifier("features")
|
||||
.version(System.getProperty("project.version")), feature)
|
||||
}
|
||||
|
||||
}
|
||||
16
akka-samples/akka-sample-osgi-dining-hakkers/karaf.sh
Executable file
16
akka-samples/akka-sample-osgi-dining-hakkers/karaf.sh
Executable file
|
|
@ -0,0 +1,16 @@
|
|||
#!/bin/bash
|
||||
|
||||
projdir=$(cd $(dirname $0); pwd)
|
||||
version=2.2.0-SNAPSHOT
|
||||
|
||||
# This directory is specified in the build as the root of the tar
|
||||
# Use tar --strip-components=1 to ignore the root
|
||||
outputdir="$projdir/akka-osgi-sample-$version"
|
||||
|
||||
if [[ -d "$outputdir" ]]; then
|
||||
echo Deleting existing $outputdir...
|
||||
rm -fr "$outputdir"
|
||||
fi
|
||||
echo Extracting configured container into $outputdir...
|
||||
tar -C $projdir -zxf assembly-dist/target/assembly-dist-$version.tar.gz
|
||||
echo Extract complete, please run $outputdir/bin/karaf
|
||||
2
akka-samples/akka-sample-osgi-dining-hakkers/osgi-run.sh
Executable file
2
akka-samples/akka-sample-osgi-dining-hakkers/osgi-run.sh
Executable file
|
|
@ -0,0 +1,2 @@
|
|||
#!/bin/bash
|
||||
./apache-karaf-2.3.0/bin/karaf
|
||||
230
akka-samples/akka-sample-osgi-dining-hakkers/pom.xml
Normal file
230
akka-samples/akka-sample-osgi-dining-hakkers/pom.xml
Normal file
|
|
@ -0,0 +1,230 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<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/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.typesafe.akka.akka-sample-osgi-dining-hakkers</groupId>
|
||||
<artifactId>project</artifactId>
|
||||
<version>2.2.0-SNAPSHOT</version>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<akka.version>2.2-SNAPSHOT</akka.version>
|
||||
<karaf.version>2.3.0</karaf.version>
|
||||
<karaf.tooling.exam.version>${karaf.version}</karaf.tooling.exam.version>
|
||||
<netty.version>3.6.2.Final</netty.version>
|
||||
<osgi.version>4.2.0</osgi.version>
|
||||
<paxexam.version>2.6.0</paxexam.version>
|
||||
<paxswissbox.version>1.6.0</paxswissbox.version>
|
||||
<protobuf.version>2.4.1</protobuf.version>
|
||||
<scala.version>2.10.1</scala.version>
|
||||
<scala.dep.version>2.10</scala.dep.version>
|
||||
<scalatest.version>1.9.1</scalatest.version>
|
||||
<typesafe.config.version>1.0.0</typesafe.config.version>
|
||||
</properties>
|
||||
|
||||
<modules>
|
||||
<module>api</module>
|
||||
<module>command</module>
|
||||
<module>uncommons</module>
|
||||
<module>core</module>
|
||||
|
||||
<module>assembly-features</module>
|
||||
<module>assembly-dist</module>
|
||||
<module>integration-test</module>
|
||||
</modules>
|
||||
<packaging>pom</packaging>
|
||||
<name>akka-sample-osgi-dining-hakkers</name>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.osgi</groupId>
|
||||
<artifactId>org.osgi.core</artifactId>
|
||||
<version>${osgi.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.osgi</groupId>
|
||||
<artifactId>org.osgi.compendium</artifactId>
|
||||
<version>${osgi.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>command</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>akka-sample-osgi-dining-hakkers</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<type>pom</type>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.typesafe.akka</groupId>
|
||||
<artifactId>akka-osgi_${scala.dep.version}</artifactId>
|
||||
<version>${akka.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.typesafe.akka</groupId>
|
||||
<artifactId>akka-cluster-experimental_${scala.dep.version}</artifactId>
|
||||
<version>${akka.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.typesafe.akka</groupId>
|
||||
<artifactId>akka-remote_${scala.dep.version}</artifactId>
|
||||
<version>${akka.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.typesafe</groupId>
|
||||
<artifactId>config</artifactId>
|
||||
<version>${typesafe.config.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.protobuf</groupId>
|
||||
<artifactId>protobuf-java</artifactId>
|
||||
<version>${protobuf.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty</artifactId>
|
||||
<version>${netty.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.karaf.tooling.exam</groupId>
|
||||
<artifactId>org.apache.karaf.tooling.exam.container</artifactId>
|
||||
<version>${karaf.tooling.exam.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.ops4j.pax.exam</groupId>
|
||||
<artifactId>pax-exam-junit4</artifactId>
|
||||
<version>${paxexam.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.typesafe.akka</groupId>
|
||||
<artifactId>akka-testkit_${scala.dep.version}</artifactId>
|
||||
<version>${akka.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.scalatest</groupId>
|
||||
<artifactId>scalatest_${scala.dep.version}</artifactId>
|
||||
<version>${scalatest.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.9</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.scala-lang</groupId>
|
||||
<artifactId>scala-compiler</artifactId>
|
||||
<version>${scala.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Depend on both the tar.gz and the zip, Pax Exam then does not have to download them separately -->
|
||||
<dependency>
|
||||
<groupId>org.apache.karaf</groupId>
|
||||
<artifactId>apache-karaf</artifactId>
|
||||
<version>${karaf.version}</version>
|
||||
<type>tar.gz</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.karaf</groupId>
|
||||
<artifactId>apache-karaf</artifactId>
|
||||
<version>${karaf.version}</version>
|
||||
<type>zip</type>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>oss-sonatype-releases</id>
|
||||
<url>https://oss.sonatype.org/content/repositories/releases</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>typesafe-snapshots</id>
|
||||
<url>http://repo.typesafe.com/typesafe/snapshots/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>build-helper-maven-plugin</artifactId>
|
||||
<version>1.7</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>generate-sources</phase>
|
||||
<goals>
|
||||
<goal>add-source</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<sources>
|
||||
<source>src/main/scala</source>
|
||||
</sources>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>net.alchim31.maven</groupId>
|
||||
<artifactId>scala-maven-plugin</artifactId>
|
||||
<version>3.1.2</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>scala-compile-first</id>
|
||||
<phase>process-resources</phase>
|
||||
<goals>
|
||||
<goal>add-source</goal>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>scala-test-compile</id>
|
||||
<phase>process-test-resources</phase>
|
||||
<goals>
|
||||
<goal>testCompile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<args>
|
||||
<arg>-deprecation</arg>
|
||||
<arg>-feature</arg>
|
||||
<arg>-encoding</arg>
|
||||
<arg>UTF-8</arg>
|
||||
<!--<arg>-uniqid</arg>-->
|
||||
</args>
|
||||
<!--<useZincServer>true</useZincServer>-->
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<version>2.3.7</version>
|
||||
<extensions>true</extensions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<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/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>com.typesafe.akka.akka-sample-osgi-dining-hakkers</groupId>
|
||||
<artifactId>project</artifactId>
|
||||
<version>2.2.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<!--
|
||||
Note that 1.2.3 of uncommons-maths has OSGi meta-data, see https://www.assembla.com/spaces/akka/tickets/2990
|
||||
Once that is available, this module can be removed.
|
||||
@see ticket #2990
|
||||
-->
|
||||
|
||||
<artifactId>uncommons</artifactId>
|
||||
<name>org.uncommons.maths.random</name>
|
||||
<version>1.2.2</version>
|
||||
<packaging>bundle</packaging>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.uncommons.maths</groupId>
|
||||
<artifactId>uncommons-maths</artifactId>
|
||||
<version>1.2.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>jfree</groupId>
|
||||
<artifactId>jfreechart</artifactId>
|
||||
<version>1.0.13</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>jfree</groupId>
|
||||
<artifactId>jcommon</artifactId>
|
||||
<version>1.0.16</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
<build>
|
||||
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<configuration>
|
||||
<instructions>
|
||||
<Bundle-Name>${project.name}</Bundle-Name>
|
||||
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
|
||||
<Export-Package>org.uncommons.maths.random</Export-Package>
|
||||
<Import-Package>!sun.misc, *</Import-Package>
|
||||
<Private-Package>org.uncommons.maths.binary, org.uncommons.maths, org.uncommons.maths.number</Private-Package>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
|
@ -344,7 +344,7 @@ object AkkaBuild extends Build {
|
|||
id = "akka-samples",
|
||||
base = file("akka-samples"),
|
||||
settings = parentSettings,
|
||||
aggregate = Seq(camelSample, fsmSample, helloSample, helloKernelSample, remoteSample, clusterSample, multiNodeSample)
|
||||
aggregate = Seq(camelSample, fsmSample, helloSample, helloKernelSample, remoteSample, clusterSample, multiNodeSample, osgiDiningHakkersSample)
|
||||
)
|
||||
|
||||
lazy val camelSample = Project(
|
||||
|
|
@ -414,6 +414,44 @@ object AkkaBuild extends Build {
|
|||
)
|
||||
) configs (MultiJvm)
|
||||
|
||||
lazy val osgiDiningHakkersSample = Project(id = "akka-sample-osgi-dining-hakkers",
|
||||
base = file("akka-samples/akka-sample-osgi-dining-hakkers"),
|
||||
settings = sampleSettings ++ Seq(
|
||||
test in Test ~= { x => {
|
||||
if({List("sh", "-c", "cd akka-samples/akka-sample-osgi-dining-hakkers; mvn clean install") !} != 0 ) {throw new Exception("Osgi sample Dining hakkers failed")}
|
||||
} }
|
||||
)
|
||||
) aggregate(osgiDiningHakkersSampleApi, osgiDiningHakkersSampleCommand, osgiDiningHakkersSampleCore, uncommons)
|
||||
|
||||
lazy val osgiDiningHakkersSampleApi = Project(id = "akka-sample-osgi-dining-hakkers-api",
|
||||
base = file("akka-samples/akka-sample-osgi-dining-hakkers/api"),
|
||||
settings = sampleSettings ++ OSGi.osgiDiningHakkersSampleApi
|
||||
)dependsOn(actor)
|
||||
|
||||
lazy val osgiDiningHakkersSampleCommand = Project(id = "akka-sample-osgi-dining-hakkers-command",
|
||||
base = file("akka-samples/akka-sample-osgi-dining-hakkers/command"),
|
||||
settings = sampleSettings ++ OSGi.osgiDiningHakkersSampleCommand ++ Seq(
|
||||
libraryDependencies ++= Dependencies.osgiDiningHakkerSampleCommand
|
||||
)
|
||||
) dependsOn (osgiDiningHakkersSampleApi, actor)
|
||||
|
||||
|
||||
lazy val osgiDiningHakkersSampleCore = Project(id = "akka-sample-osgi-dining-hakkers-core",
|
||||
base = file("akka-samples/akka-sample-osgi-dining-hakkers/core"),
|
||||
settings = sampleSettings ++ OSGi.osgiDiningHakkersSampleCore ++ Seq(
|
||||
libraryDependencies ++= Dependencies.osgiDiningHakkerSampleCore
|
||||
)
|
||||
) dependsOn (osgiDiningHakkersSampleApi, actor, remote, cluster, osgi)
|
||||
|
||||
//TODO to remove it as soon as the uncommons gets OSGified, see ticket #2990
|
||||
lazy val uncommons = Project(id = "akka-sample-osgi-dining-hakkers-uncommons",
|
||||
base = file("akka-samples/akka-sample-osgi-dining-hakkers//uncommons"),
|
||||
settings = sampleSettings ++ OSGi.osgiDiningHakkersSampleUncommons ++ Seq(
|
||||
libraryDependencies ++= Dependencies.uncommons,
|
||||
version := "1.2.2"
|
||||
)
|
||||
)
|
||||
|
||||
lazy val docs = Project(
|
||||
id = "akka-docs",
|
||||
base = file("akka-docs"),
|
||||
|
|
@ -804,6 +842,14 @@ object AkkaBuild extends Build {
|
|||
OsgiKeys.importPackage := (osgiOptionalImports map optionalResolution) ++ Seq("!sun.misc", scalaImport(),configImport(), "*")
|
||||
)
|
||||
|
||||
val osgiDiningHakkersSampleApi = exports(Seq("akka.sample.osgi.api"))
|
||||
|
||||
val osgiDiningHakkersSampleCommand = osgiSettings ++ Seq(OsgiKeys.bundleActivator := Option("akka.sample.osgi.command.Activator"), OsgiKeys.privatePackage := Seq("akka.sample.osgi.command"))
|
||||
|
||||
val osgiDiningHakkersSampleCore = exports(Seq("")) ++ Seq(OsgiKeys.bundleActivator := Option("akka.sample.osgi.activation.Activator"), OsgiKeys.privatePackage := Seq("akka.sample.osgi.internal", "akka.sample.osgi.activation", "akka.sample.osgi.service"))
|
||||
|
||||
val osgiDiningHakkersSampleUncommons = exports(Seq("org.uncommons.maths.random")) ++ Seq(OsgiKeys.privatePackage := Seq("org.uncommons.maths.binary", "org.uncommons.maths", "org.uncommons.maths.number"))
|
||||
|
||||
val osgiAries = exports() ++ Seq(OsgiKeys.privatePackage := Seq("akka.osgi.aries.*"))
|
||||
|
||||
val remote = exports(Seq("akka.remote.*"), imports = Seq(protobufImport()))
|
||||
|
|
@ -875,7 +921,7 @@ object Dependencies {
|
|||
val camelJetty = "org.apache.camel" % "camel-jetty" % camelCore.revision // ApacheV2
|
||||
|
||||
// Cluster Sample
|
||||
val sigar = "org.fusesource" % "sigar" % "1.6.4" // ApacheV2
|
||||
val sigar = "org.fusesource" % "sigar" % "1.6.4" // ApacheV2
|
||||
|
||||
// Compiler plugins
|
||||
val genjavadoc = compilerPlugin("com.typesafe.genjavadoc" %% "genjavadoc-plugin" % "0.4" cross CrossVersion.full) // ApacheV2
|
||||
|
|
@ -932,7 +978,13 @@ object Dependencies {
|
|||
|
||||
val osgi = Seq(osgiCore, osgiCompendium, Test.logback, Test.commonsIo, Test.pojosr, Test.tinybundles, Test.scalatest, Test.junit)
|
||||
|
||||
val osgiAries = Seq(osgiCore, ariesBlueprint, Test.ariesProxy)
|
||||
val osgiDiningHakkerSampleCore = Seq(config, osgiCore, osgiCompendium)
|
||||
|
||||
val osgiDiningHakkerSampleCommand = Seq(osgiCore, osgiCompendium)
|
||||
|
||||
val uncommons = Seq(uncommonsMath)
|
||||
|
||||
val osgiAries = Seq(osgiCore, osgiCompendium, ariesBlueprint, Test.ariesProxy)
|
||||
|
||||
val docs = Seq(Test.scalatest, Test.junit, Test.junitIntf)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue