Docs: Various improvements
(cherry picked from commit aad2c29c68a239b8f2512abc5e93d58ca4354a49)
This commit is contained in:
parent
0b010b6984
commit
73fd0775f3
19 changed files with 186 additions and 130 deletions
|
|
@ -1,3 +1,5 @@
|
|||
.. _event-handler:
|
||||
|
||||
Event Handler
|
||||
=============
|
||||
|
||||
|
|
@ -17,7 +19,7 @@ You can configure which event handlers should be registered at boot time. That i
|
|||
event-handler-level = "DEBUG" # Options: ERROR, WARNING, INFO, DEBUG
|
||||
}
|
||||
|
||||
The default one logs to STDOUT and is registered by default. It is not intended to be used for production. There is also an SLF4J event handler available in the 'akka-slf4j.jar' module. Read more about it `here <slf4j>`_.
|
||||
The default one logs to STDOUT and is registered by default. It is not intended to be used for production. There is also an :ref:`slf4j` event handler available in the 'akka-slf4j' module.
|
||||
|
||||
Example of creating a listener from Scala (from Java you just have to create an 'UntypedActor' and create a handler for these messages):
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ Akka and the Java Memory Model
|
|||
================================
|
||||
|
||||
Prior to Java 5, the Java Memory Model (JMM) was broken. It was possible to get all kinds of strange results like unpredictable merged writes made by concurrent executing threads, unexpected reordering of instructions, and even final fields were not guaranteed to be final. With Java 5 and JSR-133, the Java Memory Model is clearly specified. This specification makes it possible to write code that performs, but doesn't cause concurrency problems. The Java Memory Model is specified in 'happens before'-rules, e.g.:
|
||||
|
||||
* **monitor lock rule**: a release of a lock happens before every subsequent acquire of the same lock.
|
||||
* **volatile variable rule**: a write of a volatile variable happens before every subsequent read of the same volatile variable
|
||||
|
||||
|
|
@ -11,10 +12,12 @@ Actors and the Java Memory Model
|
|||
--------------------------------
|
||||
|
||||
With the Actors implementation in Akka, there are 2 ways multiple threads can execute actions on shared memory over time:
|
||||
|
||||
* if a message is send to an actor (e.g. by another actor). In most cases messages are immutable, but if that message is not a properly constructed immutable object, without happens before rules, the system still could be subject to instruction re-orderings and visibility problems (so a possible source of concurrency errors).
|
||||
* if an actor makes changes to its internal state in one 'receive' method and access that state while processing another message. With the actors model you don't get any guarantee that the same thread will be executing the same actor for different messages. Without a happens before relation between these actions, there could be another source of concurrency errors.
|
||||
|
||||
To solve the 2 problems above, Akka adds the following 2 'happens before'-rules to the JMM:
|
||||
|
||||
* **the actor send rule**: where the send of the message to an actor happens before the receive of the **same** actor.
|
||||
* **the actor subsequent processing rule**: where processing of one message happens before processing of the next message by the **same** actor.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,15 @@
|
|||
.. _slf4j:
|
||||
|
||||
SLF4J
|
||||
=====
|
||||
|
||||
This module is available in the 'akka-slf4j.jar'. It has one single dependency; the slf4j-api jar.
|
||||
This module is available in the 'akka-slf4j.jar'. It has one single dependency; the slf4j-api jar. In runtime you
|
||||
also need a SLF4J backend, we recommend:
|
||||
|
||||
.. code-block:: scala
|
||||
|
||||
lazy val logback = "ch.qos.logback" % "logback-classic" % "0.9.28" % "runtime"
|
||||
|
||||
|
||||
Event Handler
|
||||
-------------
|
||||
|
|
@ -15,5 +23,5 @@ This module includes a SLF4J Event Handler that works with Akka's standard Event
|
|||
event-handler-level = "DEBUG"
|
||||
}
|
||||
|
||||
Read more about how to use the event handler `here <http://doc.akka.io/event-handler>`_.
|
||||
Read more about how to use the :ref:`event-handler`.
|
||||
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@ Contents
|
|||
project/index
|
||||
additional/index
|
||||
|
||||
Quick Links
|
||||
===========
|
||||
Links
|
||||
=====
|
||||
|
||||
* :ref:`migration`
|
||||
|
||||
|
|
@ -26,4 +26,5 @@ Quick Links
|
|||
|
||||
* :ref:`issue_tracking`
|
||||
|
||||
* :ref:`support`
|
||||
|
||||
|
|
|
|||
|
|
@ -8,12 +8,12 @@ ActorRegistry: Finding Actors
|
|||
|
||||
Actors can be looked up using the 'akka.actor.Actors.registry()' object. Through this registry you can look up actors by:
|
||||
|
||||
* uuid com.eaio.uuid.UUID – this uses the ‘uuid’ field in the Actor class, returns the actor reference for the actor with specified uuid, if one exists, otherwise None
|
||||
* id string – this uses the ‘id’ field in the Actor class, which can be set by the user (default is the class name), returns all actor references to actors with specified id
|
||||
* parameterized type - returns a 'ActorRef[]' with all actors that are a subtype of this specific type
|
||||
* specific actor class - returns a 'ActorRef[]' with all actors of this exact class
|
||||
* uuid com.eaio.uuid.UUID – this uses the ``uuid`` field in the Actor class, returns the actor reference for the actor with specified uuid, if one exists, otherwise None
|
||||
* id string – this uses the ``id`` field in the Actor class, which can be set by the user (default is the class name), returns all actor references to actors with specified id
|
||||
* parameterized type - returns a ``ActorRef[]`` with all actors that are a subtype of this specific type
|
||||
* specific actor class - returns a ``ActorRef[]`` with all actors of this exact class
|
||||
|
||||
Actors are automatically registered in the ActorRegistry when they are started and removed when they are stopped. But you can explicitly register and unregister ActorRef's if you need to using the 'register' and 'unregister' methods.
|
||||
Actors are automatically registered in the ActorRegistry when they are started and removed when they are stopped. But you can explicitly register and unregister ActorRef's if you need to using the ``register`` and ``unregister`` methods.
|
||||
|
||||
Here is a summary of the API for finding actors:
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
Dataflow Concurrency (Java)
|
||||
===========================
|
||||
|
||||
.. sidebar:: Contents
|
||||
|
||||
.. contents:: :local:
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
|
|
@ -13,6 +17,7 @@ Dataflow concurrency is deterministic. This means that it will always behave the
|
|||
The best way to learn how to program with dataflow variables is to read the fantastic book `Concepts, Techniques, and Models of Computer Programming <http://www.info.ucl.ac.be/%7Epvr/book.html>`_. By Peter Van Roy and Seif Haridi.
|
||||
|
||||
The documentation is not as complete as it should be, something we will improve shortly. For now, besides above listed resources on dataflow concurrency, I recommend you to read the documentation for the GPars implementation, which is heavily influenced by the Akka implementation:
|
||||
|
||||
* `<http://gpars.codehaus.org/Dataflow>`_
|
||||
* `<http://www.gpars.org/guide/guide/7.%20Dataflow%20Concurrency.html>`_
|
||||
|
||||
|
|
|
|||
|
|
@ -54,8 +54,8 @@ Then you can create an Typed Actor out of it by creating it through the 'TypedAc
|
|||
(RegistrationService) TypedActor.newInstance(RegistrationService.class, RegistrationServiceImpl.class, 1000);
|
||||
// The last parameter defines the timeout for Future calls
|
||||
|
||||
**Creating Typed Actors with non-default constructor**
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Creating Typed Actors with non-default constructor
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
To create a typed actor that takes constructor arguments use a variant of 'newInstance' or 'newRemoteInstance' that takes an instance of a 'TypedActorFactory' in which you can create the TypedActor in any way you like. If you use this method then make sure that no one can get a reference to the actor instance. Touching actor state directly is bypassing the whole actor dispatching mechanism and create race conditions which can lead to corrupt data.
|
||||
|
||||
|
|
@ -193,3 +193,56 @@ Akka can help you in this regard. It allows you to turn on an option for seriali
|
|||
}
|
||||
|
||||
This will make a deep clone (using Java serialization) of all parameters.
|
||||
|
||||
Guice Integration
|
||||
-----------------
|
||||
|
||||
All Typed Actors support dependency injection using `Guice <http://code.google.com/p/google-guice/>`_ annotations (such as ‘@Inject’ etc.).
|
||||
The ``TypedActorManager`` class understands Guice and will do the wiring for you.
|
||||
|
||||
External Guice modules
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
You can also plug in external Guice modules and have not-actors wired up as part of the configuration.
|
||||
Here is an example:
|
||||
|
||||
.. code-block:: java
|
||||
|
||||
import static akka.config.Supervision.*;
|
||||
import static akka.config.SupervisorConfig.*;
|
||||
|
||||
TypedActorConfigurator manager = new TypedActorConfigurator();
|
||||
|
||||
manager.configure(
|
||||
new AllForOneStrategy(new Class[]{Exception.class}, 3, 1000),
|
||||
new SuperviseTypedActor[] {
|
||||
new SuperviseTypedActor(
|
||||
Foo.class,
|
||||
FooImpl.class,
|
||||
temporary(),
|
||||
1000),
|
||||
new SuperviseTypedActor(
|
||||
Bar.class,
|
||||
BarImpl.class,
|
||||
permanent(),
|
||||
1000)
|
||||
})
|
||||
.addExternalGuiceModule(new AbstractModule() {
|
||||
protected void configure() {
|
||||
bind(Ext.class).to(ExtImpl.class).in(Scopes.SINGLETON);
|
||||
}})
|
||||
.configure()
|
||||
.inject()
|
||||
.supervise();
|
||||
|
||||
Retrieve the external Guice dependency
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The external dependency can be retrieved like this:
|
||||
|
||||
.. code-block:: java
|
||||
|
||||
Ext ext = manager.getExternalDependency(Ext.class);
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -227,6 +227,27 @@ Here is an example:
|
|||
Reply to messages
|
||||
-----------------
|
||||
|
||||
Reply using the channel
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
If you want to have a handle to an object to whom you can reply to the message, you can use the Channel abstraction.
|
||||
Simply call getContext().channel() and then you can forward that to others, store it away or otherwise until you want to reply,
|
||||
which you do by Channel.sendOneWay(msg)
|
||||
|
||||
.. code-block:: java
|
||||
|
||||
public void onReceive(Object message) throws Exception {
|
||||
if (message instanceof String) {
|
||||
String msg = (String)message;
|
||||
if (msg.equals("Hello") && getContext().getSenderFuture().isDefined()) {
|
||||
// Reply to original sender of message using the channel
|
||||
getContext().channel().sendOneWay(msg + " from " + getContext().getUuid());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
We recommend that you as first choice use the channel abstraction instead of the other ways described in the following sections.
|
||||
|
||||
Reply using the 'replySafe' and 'replyUnsafe' methods
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
|
@ -307,24 +328,6 @@ Here is an example of how it can be used:
|
|||
}
|
||||
}
|
||||
|
||||
Reply using the channel
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
If you want to have a handle to an object to whom you can reply to the message, you can use the Channel abstraction.
|
||||
Simply call getContext().channel() and then you can forward that to others, store it away or otherwise until you want to reply,
|
||||
which you do by Channel.sendOneWay(msg)
|
||||
|
||||
.. code-block:: java
|
||||
|
||||
public void onReceive(Object message) throws Exception {
|
||||
if (message instanceof String) {
|
||||
String msg = (String)message;
|
||||
if (msg.equals("Hello") && getContext().getSenderFuture().isDefined()) {
|
||||
// Reply to original sender of message using the channel
|
||||
getContext().channel().sendOneWay(msg + " from " + getContext().getUuid());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Summary of reply semantics and options
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ Browsing
|
|||
Tickets
|
||||
^^^^^^^
|
||||
|
||||
`You can find the Akka tickets here <http://www.assembla.com/spaces/akka>`_
|
||||
`You can find the Akka tickets here <http://www.assembla.com/spaces/akka/tickets>`_
|
||||
|
||||
`You can find the Akka Modules tickets here <https://www.assembla.com/spaces/akka-modules/tickets>`_
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,17 @@
|
|||
.. _links:
|
||||
.. _support:
|
||||
|
||||
`Support <http://scalablesolutions.se>`_
|
||||
========================================
|
||||
`Support <http://scalablesolutions.se>`__
|
||||
=========================================
|
||||
|
||||
`Scalable Solutions <http://scalablesolutions.se>`_
|
||||
|
||||
`Mailing List <http://groups.google.com/group/akka-user>`_
|
||||
==========================================================
|
||||
|
||||
`Akka User Google Group <http://groups.google.com/group/akka-user>`_
|
||||
|
||||
`Akka Developer Google Group <http://groups.google.com/group/akka-dev>`_
|
||||
|
||||
|
||||
`Downloads <http://akka.io/downloads/>`_
|
||||
========================================
|
||||
|
|
@ -27,9 +34,3 @@ Akka uses Git and is hosted at `Github <http://github.com>`_.
|
|||
`<http://akka.io/repository>`_
|
||||
|
||||
|
||||
`Mailing List <http://groups.google.com/group/akka-user>`_
|
||||
==========================================================
|
||||
|
||||
`Akka User Google Group <http://groups.google.com/group/akka-user>`_
|
||||
|
||||
`Akka Developer Google Group <http://groups.google.com/group/akka-dev>`_
|
||||
|
|
@ -6,14 +6,14 @@ Module stability: **SOLID**
|
|||
ActorRegistry: Finding Actors
|
||||
-----------------------------
|
||||
|
||||
Actors can be looked up by using the **akka.actor.Actor.registry: akka.actor.ActorRegistry**. Lookups for actors through this registry can be done by:
|
||||
Actors can be looked up by using the ``akka.actor.Actor.registry: akka.actor.ActorRegistry``. Lookups for actors through this registry can be done by:
|
||||
|
||||
* uuid akka.actor.Uuid – this uses the ‘**uuid**’ field in the Actor class, returns the actor reference for the actor with specified uuid, if one exists, otherwise None
|
||||
* id string – this uses the ‘**id**’ field in the Actor class, which can be set by the user (default is the class name), returns all actor references to actors with specified id
|
||||
* specific actor class - returns an '**Array[Actor]**' with all actors of this exact class
|
||||
* parameterized type - returns an '**Array[Actor]**' with all actors that are a subtype of this specific type
|
||||
* uuid akka.actor.Uuid – this uses the ``uuid`` field in the Actor class, returns the actor reference for the actor with specified uuid, if one exists, otherwise None
|
||||
* id string – this uses the ``id`` field in the Actor class, which can be set by the user (default is the class name), returns all actor references to actors with specified id
|
||||
* specific actor class - returns an ``Array[Actor]`` with all actors of this exact class
|
||||
* parameterized type - returns an ``Array[Actor]`` with all actors that are a subtype of this specific type
|
||||
|
||||
Actors are automatically registered in the ActorRegistry when they are started, removed or stopped. You can explicitly register and unregister ActorRef's by using the '**register**' and '**unregister**' methods. The ActorRegistry contains many convenience methods for looking up typed actors.
|
||||
Actors are automatically registered in the ActorRegistry when they are started, removed or stopped. You can explicitly register and unregister ActorRef's by using the ``register`` and ``unregister`` methods. The ActorRegistry contains many convenience methods for looking up typed actors.
|
||||
|
||||
Here is a summary of the API for finding actors:
|
||||
|
||||
|
|
|
|||
|
|
@ -260,6 +260,25 @@ Let's start by looking how we can reply to messages in a convenient way using th
|
|||
Reply to messages
|
||||
-----------------
|
||||
|
||||
Reply using the channel
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
If you want to have a handle to an object to whom you can reply to the message, you can use the ``Channel`` abstraction.
|
||||
Simply call ``self.channel`` and then you can forward that to others, store it away or otherwise until you want to reply, which you do by ``Channel ! response``:
|
||||
|
||||
.. code-block:: scala
|
||||
|
||||
case request =>
|
||||
val result = process(request)
|
||||
self.channel ! result
|
||||
|
||||
.. code-block:: scala
|
||||
|
||||
case request =>
|
||||
friend forward self.channel
|
||||
|
||||
We recommend that you as first choice use the channel abstraction instead of the other ways described in the following sections.
|
||||
|
||||
Reply using the reply and reply\_? methods
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
|
@ -325,22 +344,6 @@ Here is an example of how it can be used:
|
|||
senderFuture.foreach(_.completeWithException(this, e))
|
||||
}
|
||||
|
||||
Reply using the channel
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
If you want to have a handle to an object to whom you can reply to the message, you can use the ``Channel`` abstraction.
|
||||
Simply call ``self.channel`` and then you can forward that to others, store it away or otherwise until you want to reply, which you do by ``Channel ! response``:
|
||||
|
||||
.. code-block:: scala
|
||||
|
||||
case request =>
|
||||
val result = process(request)
|
||||
self.channel ! result
|
||||
|
||||
.. code-block:: scala
|
||||
|
||||
case request =>
|
||||
friend forward self.channel
|
||||
|
||||
Summary of reply semantics and options
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
Dataflow Concurrency (Scala)
|
||||
============================
|
||||
|
||||
.. sidebar:: Contents
|
||||
|
||||
.. contents:: :local:
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
Futures (Scala)
|
||||
===============
|
||||
|
||||
.. sidebar:: Contents
|
||||
|
||||
.. contents:: :local:
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,12 @@
|
|||
|
||||
.. _http-module:
|
||||
|
||||
######
|
||||
HTTP
|
||||
######
|
||||
HTTP
|
||||
====
|
||||
|
||||
.. sidebar:: Contents
|
||||
|
||||
.. contents:: :local:
|
||||
|
||||
Module stability: **SOLID**
|
||||
|
||||
|
|
@ -523,3 +526,5 @@ Using the Akka Mist module with the Facebook Graph API and WebGL
|
|||
|
||||
Example project using Akka Mist with the Facebook Graph API and WebGL
|
||||
`<https://github.com/buka/fbgl1>`_
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -697,30 +697,3 @@ Using the generated message builder to send the message to a remote actor:
|
|||
.setName("Coltrane")
|
||||
.build
|
||||
|
||||
SBinary
|
||||
^^^^^^^
|
||||
|
||||
.. code-block:: scala
|
||||
|
||||
case class User(firstNameLastName: Tuple2[String, String], email: String, age: Int) extends Serializable.SBinary[User] {
|
||||
import sbinary.DefaultProtocol._
|
||||
|
||||
def this() = this(null, null, 0)
|
||||
|
||||
implicit object UserFormat extends Format[User] {
|
||||
def reads(in : Input) = User(
|
||||
read[Tuple2[String, String]](in),
|
||||
read[String](in),
|
||||
read[Int](in))
|
||||
def writes(out: Output, value: User) = {
|
||||
write[Tuple2[String, String]](out, value. firstNameLastName)
|
||||
write[String](out, value.email)
|
||||
write[Int](out, value.age)
|
||||
}
|
||||
}
|
||||
|
||||
def fromBytes(bytes: Array[Byte]) = fromByteArray[User](bytes)
|
||||
|
||||
def toBytes: Array[Byte] = toByteArray(this)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,16 @@
|
|||
Security
|
||||
========
|
||||
HTTP Security
|
||||
=============
|
||||
|
||||
.. sidebar:: Contents
|
||||
|
||||
.. contents:: :local:
|
||||
|
||||
Module stability: **IN PROGRESS**
|
||||
|
||||
Akka supports security for access to RESTful Actors through `HTTP Authentication <http://en.wikipedia.org/wiki/HTTP_Authentication>`_. The security is implemented as a jersey ResourceFilter which delegates the actual authentication to an authentication actor.
|
||||
|
||||
Akka provides authentication via the following authentication schemes:
|
||||
|
||||
* `Basic Authentication <http://en.wikipedia.org/wiki/Basic_access_authentication>`_
|
||||
* `Digest Authentication <http://en.wikipedia.org/wiki/Digest_access_authentication>`_
|
||||
* `Kerberos SPNEGO Authentication <http://en.wikipedia.org/wiki/SPNEGO>`_
|
||||
|
|
@ -13,16 +18,14 @@ Akka provides authentication via the following authentication schemes:
|
|||
The authentication is performed by implementations of akka.security.AuthenticationActor.
|
||||
|
||||
Akka provides a trait for each authentication scheme:
|
||||
|
||||
* BasicAuthenticationActor
|
||||
* DigestAuthenticationActor
|
||||
* SpnegoAuthenticationActor
|
||||
|
||||
With Akka’s excellent support for distributed databases, it’s a one-liner to do a distributed authentication scheme.
|
||||
|
||||
^
|
||||
|
||||
Setup
|
||||
=====
|
||||
-----
|
||||
|
||||
To secure your RESTful actors you need to perform the following steps:
|
||||
|
||||
|
|
@ -54,6 +57,7 @@ To secure your RESTful actors you need to perform the following steps:
|
|||
3. Start your authentication actor in your 'Boot' class. The security package consists of the following parts:
|
||||
|
||||
4. Secure your RESTful actors using class or resource level annotations:
|
||||
|
||||
* @DenyAll
|
||||
* @RolesAllowed(listOfRoles)
|
||||
* @PermitAll
|
||||
|
|
@ -65,6 +69,7 @@ The akka-samples-security module contains a small sample application with sample
|
|||
You can start the sample app using the jetty plugin: mvn jetty:run.
|
||||
|
||||
The RESTful actor can then be accessed using your browser of choice under:
|
||||
|
||||
* permit access only to users having the “chef” role: `<http://localhost:8080//secureticker/chef>`_
|
||||
* public access: `<http://localhost:8080//secureticker/public>`_
|
||||
|
||||
|
|
@ -72,7 +77,6 @@ You can access the secured resource using any user for basic authentication (whi
|
|||
|
||||
Digest authentication can be directly enabled in the sample app. Kerberos/SPNEGO authentication is a bit more involved an is described below.
|
||||
|
||||
^
|
||||
|
||||
Kerberos/SPNEGO Authentication
|
||||
------------------------------
|
||||
|
|
@ -83,11 +87,12 @@ In a kerberos enabled environment a user will need to sign on only once. Subsequ
|
|||
Most prominently the kerberos protocol is used to authenticate users in a windows network. When deploying web applications to a corporate intranet an important feature will be to support the single sign on (SSO), which comes to make the application kerberos aware.
|
||||
|
||||
How does it work (at least for REST actors)?
|
||||
# When accessing a secured resource the server will check the request for the *Authorization* header as with basic or digest authentication.
|
||||
# If it is not set, the server will respond with a challenge to “Negotiate”. The negotiation is in fact the NEGO part of the `SPNEGO <http://tools.ietf.org/html/rfc4178>`_ specification)
|
||||
# The browser will then try to acquire a so called *service ticket* from a ticket granting service, i.e. the kerberos server
|
||||
# The browser will send the *service ticket* to the web application encoded in the header value of the *Authorization*header
|
||||
# The web application must validate the ticket based on a shared secret between the web application and the kerberos server. As a result the web application will know the name of the user
|
||||
|
||||
- When accessing a secured resource the server will check the request for the *Authorization* header as with basic or digest authentication.
|
||||
- If it is not set, the server will respond with a challenge to "Negotiate". The negotiation is in fact the NEGO part of the `SPNEGO <http://tools.ietf.org/html/rfc4178>`_ specification
|
||||
- The browser will then try to acquire a so called *service ticket* from a ticket granting service, i.e. the kerberos server
|
||||
- The browser will send the *service ticket* to the web application encoded in the header value of the *Authorization* header
|
||||
- The web application must validate the ticket based on a shared secret between the web application and the kerberos server. As a result the web application will know the name of the user
|
||||
|
||||
To activate the kerberos/SPNEGO authentication for your REST actor you need to enable the kerberos/SPNEGOauthentication actor in the akka.conf like this:
|
||||
|
||||
|
|
@ -103,8 +108,9 @@ To activate the kerberos/SPNEGO authentication for your REST actor you need to e
|
|||
}
|
||||
|
||||
Furthermore you must provide the SpnegoAuthenticator with the following information.
|
||||
# Service principal name: the name of your web application in the kerberos servers user database. This name is always has the form “HTTP/{server}@{realm}”
|
||||
# Path to the keytab file: this is a kind of certificate for your web application to acquire tickets from the kerberos server
|
||||
|
||||
- Service principal name: the name of your web application in the kerberos servers user database. This name is always has the form ``HTTP/{server}@{realm}``
|
||||
- Path to the keytab file: this is a kind of certificate for your web application to acquire tickets from the kerberos server
|
||||
|
||||
.. code-block:: ruby
|
||||
|
||||
|
|
@ -122,7 +128,6 @@ Furthermore you must provide the SpnegoAuthenticator with the following informat
|
|||
...
|
||||
}
|
||||
|
||||
^
|
||||
|
||||
How to setup kerberos on localhost for Ubuntu
|
||||
---------------------------------------------
|
||||
|
|
@ -233,9 +238,9 @@ This seems correct. To remove the ticket cache simply type kdestroy.
|
|||
Verifying - Password:
|
||||
eckart@dilbert:~$
|
||||
|
||||
This command will create a keytab file for the service principal named “http.keytab” in the current directory. You can specify other encryption methods than ‘aes256-cts-hmac-sha1-96’, but this is the e default encryption method for the heimdal client, so there is no additional configuration needed. You can specify other encryption types in the krb5.conf.
|
||||
This command will create a keytab file for the service principal named ``http.keytab`` in the current directory. You can specify other encryption methods than ‘aes256-cts-hmac-sha1-96’, but this is the e default encryption method for the heimdal client, so there is no additional configuration needed. You can specify other encryption types in the krb5.conf.
|
||||
|
||||
Note that you might need to install the unlimited strength policy files for java from here:`<http://java.sun.com/javase/downloads/index_jdk5.jsp>`_ to use the aes256 encryption from your application.
|
||||
Note that you might need to install the unlimited strength policy files for java from here: `<http://java.sun.com/javase/downloads/index_jdk5.jsp>`_ to use the aes256 encryption from your application.
|
||||
|
||||
Again we can test if the keytab generation worked with the kinit command:
|
||||
|
||||
|
|
@ -249,13 +254,13 @@ Again we can test if the keytab generation worked with the kinit command:
|
|||
Issued Expires Principal
|
||||
Oct 24 21:59:20 Oct 25 06:59:20 krbtgt/EXAMPLE.COM@EXAMPLE.COM
|
||||
|
||||
Now point the configuration of the key in 'akka.conf' to the correct location and set the correct service principal name. The web application should now startup and produce at least a 401 response with a header “WWW-Authenticate” = “Negotiate”. The last step is to configure the browser.
|
||||
Now point the configuration of the key in 'akka.conf' to the correct location and set the correct service principal name. The web application should now startup and produce at least a 401 response with a header ``WWW-Authenticate`` = "Negotiate". The last step is to configure the browser.
|
||||
|
||||
6. Set up Firefox to use Kerberos/SPNEGO
|
||||
This is done by typing 'about:config'. Filter the config entries for “network.neg” and set the config entries “network.negotiate-auth.delegation-uris” and “network.negotiate-auth.trusted-uris” to “localhost”.
|
||||
This is done by typing ``about:config``. Filter the config entries for ``network.neg`` and set the config entries ``network.negotiate-auth.delegation-uris`` and ``network.negotiate-auth.trusted-uris`` to ``localhost``.
|
||||
and now …
|
||||
|
||||
7. Access the RESTful Actor.
|
||||
|
||||
8. Have fun
|
||||
… but acquire an initial ticket for the user principal first: kinit zaphod
|
||||
… but acquire an initial ticket for the user principal first: ``kinit zaphod``
|
||||
|
|
|
|||
|
|
@ -371,22 +371,8 @@ Akka currently provides three different transactional abstractions; 'Map', 'Vect
|
|||
|
||||
What you get is transactional memory in which multiple Actors are allowed to read and write to the same memory concurrently and if there is a clash between two transactions then both of them are aborted and retried. Aborting a transaction means that the memory is rolled back to the state it were in when the transaction was started.
|
||||
|
||||
In database terms STM gives you 'ACI' semantics; 'Atomicity', 'Consistency' and 'Isolation'. The 'D' in 'ACID'; 'Durability', you can't get with an STM since it is in memory. This however is addressed by the persistence module in Akka.
|
||||
|
||||
Persistence: Storing the chat log
|
||||
---------------------------------
|
||||
|
||||
Akka modules provides the possibility of taking the transactional data structures we discussed above and making them persistent. It is an extension to the STM which guarantees that it has the same semantics.
|
||||
|
||||
The `persistence module <persistence>`_ has pluggable storage back-ends.
|
||||
|
||||
They all implement persistent 'Map', 'Vector' and 'Ref'. Which can be created and retrieved by id through one of the storage modules.
|
||||
|
||||
.. code-block:: scala
|
||||
|
||||
val map = RedisStorage.newMap(id)
|
||||
val vector = CassandraStorage.newVector(id)
|
||||
val ref = MongoStorage.newRef(id)
|
||||
In database terms STM gives you 'ACI' semantics; 'Atomicity', 'Consistency' and 'Isolation'. The 'D' in 'ACID'; 'Durability', you can't get with an STM since it is in memory.
|
||||
It possible to implement durable persistence for the transactional data structures, but in this sample we keep them in memory.
|
||||
|
||||
Chat storage: Backed with simple in-memory
|
||||
------------------------------------------
|
||||
|
|
|
|||
|
|
@ -53,8 +53,8 @@ Then you can create an Typed Actor out of it by creating it through the 'TypedAc
|
|||
val service = TypedActor.newInstance(classOf[RegistrationService], classOf[RegistrationServiceImpl], 1000)
|
||||
// The last parameter defines the timeout for Future calls
|
||||
|
||||
**Creating Typed Actors with non-default constructor**
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Creating Typed Actors with non-default constructor
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
To create a typed actor that takes constructor arguments use a variant of 'newInstance' or 'newRemoteInstance' that takes a call-by-name block in which you can create the Typed Actor in any way you like.
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue