activemq-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From chir...@apache.org
Subject svn commit: r1127908 - in /activemq/activemq-apollo/trunk: apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/jetty/ apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/ apollo-dto/src/main/java/org/apache/activemq/apoll...
Date Thu, 26 May 2011 13:44:14 GMT
Author: chirino
Date: Thu May 26 13:44:13 2011
New Revision: 1127908

URL: http://svn.apache.org/viewvc?rev=1127908&view=rev
Log:
- Adding admin and monitor permissions to the ACL lists.
- The web admin now authenticates and authorizes against the same security system that the broker users

Added:
    activemq/activemq-apollo/trunk/apollo-web/src/main/scala/org/apache/activemq/apollo/web/resources/RootResource.scala
      - copied, changed from r1127907, activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/TopicAclDTO.java
Modified:
    activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/jetty/JettyWebServer.scala
    activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/AclAuthorizer.scala
    activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/Authorizer.scala
    activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/BrokerAclDTO.java
    activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/TopicAclDTO.java
    activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/VirtualHostAclDTO.java
    activemq/activemq-apollo/trunk/apollo-web/src/main/scala/org/apache/activemq/apollo/web/resources/BrokerResource.scala
    activemq/activemq-apollo/trunk/apollo-web/src/main/scala/org/apache/activemq/apollo/web/resources/Support.scala
    activemq/activemq-apollo/trunk/apollo-web/src/main/webapp/WEB-INF/web.xml

Modified: activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/jetty/JettyWebServer.scala
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/jetty/JettyWebServer.scala?rev=1127908&r1=1127907&r2=1127908&view=diff
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/jetty/JettyWebServer.scala (original)
+++ activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/jetty/JettyWebServer.scala Thu May 26 13:44:13 2011
@@ -229,32 +229,33 @@ class JettyWebServer(val broker:Broker) 
 
 
       def secured(handler:Handler) = {
-        if( config.authentication!=null && config.acl!=null ) {
-          val security_handler = new ConstraintSecurityHandler
-          val login_service = new JAASLoginService(config.authentication.domain)
-          val role_class_names:List[String] = config.authentication.acl_principal_kinds().toList
-
-          login_service.setRoleClassNames(role_class_names.toArray)
-          security_handler.setLoginService(login_service)
-          security_handler.setIdentityService(new DefaultIdentityService)
-          security_handler.setAuthenticator(new BasicAuthenticator)
-
-          val cm = new ConstraintMapping
-          val c = new org.eclipse.jetty.http.security.Constraint()
-          c.setName("BASIC")
-          val admins:Set[PrincipalDTO] = config.acl.admins.toSet
-          c.setRoles(admins.map(_.allow).toArray)
-          c.setAuthenticate(true)
-          cm.setConstraint(c)
-          cm.setPathSpec("/*")
-          cm.setMethod("GET")
-          security_handler.addConstraintMapping(cm)
-
-          security_handler.setHandler(handler)
-          security_handler
-        } else {
-          handler
-        }
+        handler
+//        if( config.authentication!=null && config.acl!=null ) {
+//          val security_handler = new ConstraintSecurityHandler
+//          val login_service = new JAASLoginService(config.authentication.domain)
+//          val role_class_names:List[String] = config.authentication.acl_principal_kinds().toList
+//
+//          login_service.setRoleClassNames(role_class_names.toArray)
+//          security_handler.setLoginService(login_service)
+//          security_handler.setIdentityService(new DefaultIdentityService)
+//          security_handler.setAuthenticator(new BasicAuthenticator)
+//
+//          val cm = new ConstraintMapping
+//          val c = new org.eclipse.jetty.http.security.Constraint()
+//          c.setName("BASIC")
+//          val admins:Set[PrincipalDTO] = config.acl.admins.toSet ++ config.acl.monitors.toSet
+//          c.setRoles(admins.map(_.allow).toArray)
+//          c.setAuthenticate(true)
+//          cm.setConstraint(c)
+//          cm.setPathSpec("/*")
+//          cm.setMethod("GET")
+//          security_handler.addConstraintMapping(cm)
+//
+//          security_handler.setHandler(handler)
+//          security_handler
+//        } else {
+//          handler
+//        }
       }
 
       val context_list = new HandlerList

Modified: activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/AclAuthorizer.scala
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/AclAuthorizer.scala?rev=1127908&r1=1127907&r2=1127908&view=diff
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/AclAuthorizer.scala (original)
+++ activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/AclAuthorizer.scala Thu May 26 13:44:13 2011
@@ -45,8 +45,50 @@ class AclAuthorizer(val default_kinds:Li
     rc
   }
 
-  def can_admin(ctx: SecurityContext, broker: Broker) = log_result(ctx, "administration", "broker") {
-    broker.config.acl==null  || is_in(ctx, broker.config.acl.admins)
+  private def can_broker(ctx: SecurityContext, broker: Broker)(func: BrokerAclDTO=>java.util.List[PrincipalDTO]) = {
+    broker.config.acl==null || is_in(ctx, func(broker.config.acl))
+  }
+
+  def _can_admin(ctx: SecurityContext, broker: Broker): Boolean = {
+    can_broker(ctx, broker)(_.admins)
+  }
+
+  def can_admin(ctx: SecurityContext, broker: Broker):Boolean = log_result(ctx, "administration", "broker") {
+    _can_admin(ctx, broker)
+  }
+
+  def _can_monitor(ctx: SecurityContext, broker: Broker): Boolean = {
+    can_broker(ctx, broker)(_.monitors) || can_broker(ctx, broker)(_.admins)
+  }
+
+  def can_monitor(ctx: SecurityContext, broker: Broker):Boolean = log_result(ctx, "monitor", "broker") {
+    _can_monitor(ctx, broker)
+  }
+
+  def _can_admin(ctx: SecurityContext, host: VirtualHost): Boolean = {
+    val acl = host.config.acl
+    if (acl != null) {
+      is_in(ctx, acl.admins)
+    } else {
+      _can_admin(ctx, host.broker)
+    }
+  }
+
+  def can_admin(ctx: SecurityContext, host: VirtualHost):Boolean = log_result(ctx, "administration", "virtual host "+host.id) {
+    _can_admin(ctx, host)
+  }
+
+  def _can_monitor(ctx: SecurityContext, host: VirtualHost): Boolean = {
+    val acl = host.config.acl
+    if (acl != null) {
+      is_in(ctx, acl.monitors) || is_in(ctx, acl.admins)
+    } else {
+      _can_monitor(ctx, host.broker)
+    }
+  }
+
+  def can_monitor(ctx: SecurityContext, host: VirtualHost):Boolean = log_result(ctx, "monitor", "virtual host "+host.id) {
+    _can_monitor(ctx, host)
   }
 
   def can_connect_to(ctx: SecurityContext, host: VirtualHost, connector:Connector):Boolean = {
@@ -57,50 +99,86 @@ class AclAuthorizer(val default_kinds:Li
     }
   }
 
-  private def can_dest(ctx: SecurityContext, host: VirtualHost, dest: TopicDTO)(func: TopicAclDTO=>java.util.List[PrincipalDTO]) = {
-    dest.acl==null || is_in(ctx, func(dest.acl))
+  private def can_topic(ctx: SecurityContext, topic: TopicDTO)(func: TopicAclDTO=>java.util.List[PrincipalDTO]) = {
+    topic.acl==null || is_in(ctx, func(topic.acl))
   }
 
 
-  def name(dest: TopicDTO) = Option(dest.name).getOrElse("**")
+  def name(topic: TopicDTO) = Option(topic.name).getOrElse("**")
 
-  def can_send_to(ctx: SecurityContext, host: VirtualHost, dest: TopicDTO) = log_result(ctx, "send", "topic "+name(dest)) {
-    can_dest(ctx, host, dest)(_.sends)
+  def can_send_to(ctx: SecurityContext, host: VirtualHost, topic: TopicDTO) = log_result(ctx, "send", "topic "+name(topic)) {
+    can_topic(ctx, topic)(_.sends)
+  }
+  def can_receive_from(ctx: SecurityContext, host: VirtualHost, topic: TopicDTO) = log_result(ctx, "receive", "topic "+name(topic)) {
+    can_topic(ctx, topic)(_.receives)
   }
-  def can_receive_from(ctx: SecurityContext, host: VirtualHost, dest: TopicDTO) = log_result(ctx, "receive", "topic "+name(dest)) {
-    can_dest(ctx, host, dest)(_.receives)
+  def can_destroy(ctx: SecurityContext, host: VirtualHost, topic: TopicDTO) = log_result(ctx, "destroy", "topic "+name(topic)) {
+    can_topic(ctx, topic)(_.destroys)
   }
-  def can_destroy(ctx: SecurityContext, host: VirtualHost, dest: TopicDTO) = log_result(ctx, "destroy", "topic "+name(dest)) {
-    can_dest(ctx, host, dest)(_.destroys)
+  def can_create(ctx: SecurityContext, host: VirtualHost, topic: TopicDTO) = log_result(ctx, "create", "topic "+name(topic)) {
+    can_topic(ctx, topic)(_.creates)
   }
-  def can_create(ctx: SecurityContext, host: VirtualHost, dest: TopicDTO) = log_result(ctx, "create", "topic "+name(dest)) {
-    can_dest(ctx, host, dest)(_.creates)
+  
+  def can_admin(ctx: SecurityContext, host: VirtualHost, topic: TopicDTO) = log_result(ctx, "administration", "topic") {
+    val acl = topic.acl
+    if (acl != null) {
+      is_in(ctx, acl.admins)
+    } else {
+      _can_admin(ctx, host)
+    }
+  }
+
+  def can_monitor(ctx: SecurityContext, host: VirtualHost, topic: TopicDTO) = log_result(ctx, "monitor", "topic") {
+    val acl = topic.acl
+    if (acl != null) {
+      is_in(ctx, acl.monitors) || is_in(ctx, acl.admins)
+    } else {
+      _can_admin(ctx, host)
+    }
   }
 
-  private def can_queue(ctx: SecurityContext, host: VirtualHost, queue: QueueDTO)(func: QueueAclDTO=>java.util.List[PrincipalDTO]) = {
+  private def can_queue(ctx: SecurityContext, queue: QueueDTO)(func: QueueAclDTO=>java.util.List[PrincipalDTO]) = {
     queue.acl==null || is_in(ctx, func(queue.acl))
   }
 
-  def name(dest: QueueDTO) = Option(dest.name).getOrElse("**")
+  def name(queue: QueueDTO) = Option(queue.name).getOrElse("**")
 
   def can_send_to(ctx: SecurityContext, host: VirtualHost, queue: QueueDTO) = log_result(ctx, "send", "queue "+name(queue)) {
-    can_queue(ctx, host, queue)(_.sends)
+    can_queue(ctx, queue)(_.sends)
   }
 
   def can_receive_from(ctx: SecurityContext, host: VirtualHost, queue: QueueDTO) = log_result(ctx, "receive", "queue "+name(queue)) {
-    can_queue(ctx, host, queue)(_.receives)
+    can_queue(ctx, queue)(_.receives)
   }
 
   def can_destroy(ctx: SecurityContext, host: VirtualHost, queue: QueueDTO) = log_result(ctx, "destroy", "queue "+name(queue)) {
-    can_queue(ctx, host, queue)(_.destroys)
+    can_queue(ctx, queue)(_.destroys)
   }
 
   def can_create(ctx: SecurityContext, host: VirtualHost, queue: QueueDTO) = log_result(ctx, "create", "queue "+name(queue)) {
-    can_queue(ctx, host, queue)(_.creates)
+    can_queue(ctx, queue)(_.creates)
   }
 
   def can_consume_from(ctx: SecurityContext, host: VirtualHost, queue: QueueDTO) = log_result(ctx, "consume", "queue "+name(queue)) {
-    can_queue(ctx, host, queue)(_.consumes)
+    can_queue(ctx, queue)(_.consumes)
+  }
+
+  def can_admin(ctx: SecurityContext, host: VirtualHost, queue: QueueDTO) = log_result(ctx, "administration", "queue") {
+    val acl = queue.acl
+    if (acl != null) {
+      is_in(ctx, acl.admins)
+    } else {
+      _can_admin(ctx, host)
+    }
+  }
+
+  def can_monitor(ctx: SecurityContext, host: VirtualHost, queue: QueueDTO) = log_result(ctx, "monitor", "queue") {
+    val acl = queue.acl
+    if (acl != null) {
+      is_in(ctx, acl.monitors) || is_in(ctx, acl.admins)
+    } else {
+      _can_admin(ctx, host)
+    }
   }
 
 }
\ No newline at end of file

Modified: activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/Authorizer.scala
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/Authorizer.scala?rev=1127908&r1=1127907&r2=1127908&view=diff
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/Authorizer.scala (original)
+++ activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/Authorizer.scala Thu May 26 13:44:13 2011
@@ -15,14 +15,12 @@
  * limitations under the License.
  */
 package org.apache.activemq.apollo.broker.security
-import scala.util.continuations._
 import org.apache.activemq.apollo.broker._
-import org.apache.activemq.apollo.util.path.Path
-import org.apache.activemq.apollo.dto.{TopicDTO, QueueDTO, DestinationDTO}
+import org.apache.activemq.apollo.dto.{TopicDTO, QueueDTO}
 
 /**
- * <p>
- * </p>
+ * <p>This interface allows the authorization information to come
+  * from other sources besides the configuration model.</p>
  *
  * @author <a href="http://hiramchirino.com">Hiram Chirino</a>
  */
@@ -33,6 +31,12 @@ trait Authorizer {
    */
   def can_admin(ctx:SecurityContext, broker:Broker):Boolean
 
+  def can_monitor(ctx:SecurityContext, broker:Broker):Boolean
+
+  def can_admin(ctx:SecurityContext, host:VirtualHost):Boolean
+
+  def can_monitor(ctx:SecurityContext, host:VirtualHost):Boolean
+
   /**
    * @returns true if the user is allowed to connect to the virtual host
    */
@@ -43,6 +47,11 @@ trait Authorizer {
    */
   def can_send_to(ctx:SecurityContext, host:VirtualHost, dest:TopicDTO):Boolean
 
+
+  def can_admin(ctx:SecurityContext, host:VirtualHost, dest:TopicDTO):Boolean
+
+  def can_monitor(ctx:SecurityContext, host:VirtualHost, dest:TopicDTO):Boolean
+
   /**
    * @returns true if the user is allowed to receive from the destination
    */
@@ -59,6 +68,10 @@ trait Authorizer {
   def can_destroy(ctx:SecurityContext, host:VirtualHost, dest:TopicDTO):Boolean
 
 
+  def can_admin(ctx:SecurityContext, host:VirtualHost, dest:QueueDTO):Boolean
+
+  def can_monitor(ctx:SecurityContext, host:VirtualHost, dest:QueueDTO):Boolean
+
   /**
    * @returns true if the user is allowed to send to the queue
    */

Modified: activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/BrokerAclDTO.java
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/BrokerAclDTO.java?rev=1127908&r1=1127907&r2=1127908&view=diff
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/BrokerAclDTO.java (original)
+++ activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/BrokerAclDTO.java Thu May 26 13:44:13 2011
@@ -33,5 +33,7 @@ public class BrokerAclDTO {
     @XmlElement(name="admin")
     public List<PrincipalDTO> admins = new ArrayList<PrincipalDTO>();
 
+    @XmlElement(name="monitor")
+    public List<PrincipalDTO> monitors = new ArrayList<PrincipalDTO>();
 
 }

Modified: activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/TopicAclDTO.java
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/TopicAclDTO.java?rev=1127908&r1=1127907&r2=1127908&view=diff
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/TopicAclDTO.java (original)
+++ activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/TopicAclDTO.java Thu May 26 13:44:13 2011
@@ -42,4 +42,9 @@ public class TopicAclDTO {
     @XmlElement(name="receive")
     public List<PrincipalDTO> receives = new ArrayList<PrincipalDTO>();
 
+    @XmlElement(name="admin")
+    public List<PrincipalDTO> admins = new ArrayList<PrincipalDTO>();
+
+    @XmlElement(name="monitor")
+    public List<PrincipalDTO> monitors = new ArrayList<PrincipalDTO>();
 }

Modified: activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/VirtualHostAclDTO.java
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/VirtualHostAclDTO.java?rev=1127908&r1=1127907&r2=1127908&view=diff
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/VirtualHostAclDTO.java (original)
+++ activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/VirtualHostAclDTO.java Thu May 26 13:44:13 2011
@@ -31,6 +31,12 @@ import java.util.*;
 @XmlAccessorType(XmlAccessType.FIELD)
 public class VirtualHostAclDTO {
 
+    @XmlElement(name="admin")
+    public List<PrincipalDTO> admins = new ArrayList<PrincipalDTO>();
+
+    @XmlElement(name="monitor")
+    public List<PrincipalDTO> monitors = new ArrayList<PrincipalDTO>();
+
     @XmlElement(name="connect")
     public List<PrincipalDTO> connects = new ArrayList<PrincipalDTO>();
 

Modified: activemq/activemq-apollo/trunk/apollo-web/src/main/scala/org/apache/activemq/apollo/web/resources/BrokerResource.scala
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-web/src/main/scala/org/apache/activemq/apollo/web/resources/BrokerResource.scala?rev=1127908&r1=1127907&r2=1127908&view=diff
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-web/src/main/scala/org/apache/activemq/apollo/web/resources/BrokerResource.scala (original)
+++ activemq/activemq-apollo/trunk/apollo-web/src/main/scala/org/apache/activemq/apollo/web/resources/BrokerResource.scala Thu May 26 13:44:13 2011
@@ -26,6 +26,7 @@ import org.apache.activemq.apollo.broker
 import scala.collection.Iterable
 import org.apache.activemq.apollo.util.{Failure, Success, Dispatched, Result}
 import scala.Some
+import security.{SecurityContext, Authorizer}
 
 /**
  * <p>
@@ -35,125 +36,47 @@ import scala.Some
  *
  * @author <a href="http://hiramchirino.com">Hiram Chirino</a>
  */
-@Path("/")
 @Produces(Array("application/json", "application/xml","text/xml", "text/html;qs=5"))
-case class BrokerResource() extends Resource() {
-
-  type FutureResult[T] = Future[Result[T, Throwable]]
-
-  def FutureResult[T]() = Future[Result[T, Throwable]]()
-
-  private def sync[T](dispached:Dispatched)(func: =>FutureResult[T]):FutureResult[T] = {
-    val rc = Future[Result[T, Throwable]]()
-    dispached.dispatch_queue.apply {
-      try {
-        func.onComplete(x=> rc.apply(x))
-      } catch {
-        case e:Throwable => rc.apply(Failure(e))
-      }
-    }
-    rc
-  }
-
-
-  def sync_all[T,D<:Dispatched](values:Iterable[D])(func: (D)=>FutureResult[T]) = {
-    Future.all {
-      values.map { value=>
-        sync(value) {
-          func(value)
-        }
-      }
-    }
-  }
-
-  private implicit def to_local_router(host:VirtualHost):LocalRouter = {
-    host.router.asInstanceOf[LocalRouter]
-  }
-
-  private implicit def wrap_future_result[T](value:T):FutureResult[T] = {
-    val rc = FutureResult[T]()
-    rc.apply(Success(value))
-    rc
-  }
-
-  private implicit def unwrap_future_result[T](value:FutureResult[T]):T = {
-    value.await() match {
-      case Success(value) => value
-      case Failure(value) => throw value
-    }
-  }
-
-  private def with_broker[T](func: (org.apache.activemq.apollo.broker.Broker)=>FutureResult[T]):FutureResult[T] = {
-    BrokerRegistry.list.headOption match {
-      case Some(broker)=>
-        sync(broker) {
-          func(broker)
-        }
-      case None=>
-        result(NOT_FOUND)
-    }
-  }
-
-  private def with_virtual_host[T](id:String)(func: (VirtualHost)=>FutureResult[T]):FutureResult[T] = {
-    with_broker { broker =>
-      broker.virtual_hosts.valuesIterator.find( _.id == id) match {
-        case Some(virtualHost)=>
-          sync(virtualHost) {
-            func(virtualHost)
-          }
-        case None=>
-          result(NOT_FOUND)
-      }
-    }
-  }
-
-  private def with_connection[T](id:Long)(func: BrokerConnection=>FutureResult[T]):FutureResult[T] = {
-    with_broker { broker =>
-      broker.connectors.flatMap{ _.connections.get(id) }.headOption match {
-        case Some(connection:BrokerConnection) =>
-          sync(connection) {
-            func(connection)
-          }
-        case None=>
-          result(NOT_FOUND)
-      }
-    }
-  }
-
+case class BrokerResource(parent:Resource) extends Resource(parent) {
 
   @Path("config")
   def config_resource:ConfigurationResource = {
     with_broker { broker =>
-      ConfigurationResource(this, broker.config)
+      admining(broker) {
+        ConfigurationResource(this, broker.config)
+      }
     }
   }
 
   @GET
   def get_broker():BrokerStatusDTO = {
     with_broker { broker =>
-      val result = new BrokerStatusDTO
-
-      result.id = broker.id
-      result.current_time = System.currentTimeMillis
-      result.state = broker.service_state.toString
-      result.state_since = broker.service_state.since
+      monitoring(broker) {
+        val result = new BrokerStatusDTO
 
-      broker.virtual_hosts.values.foreach{ host=>
-        // TODO: may need to sync /w virtual host's dispatch queue
-        result.virtual_hosts.add( host.id )
-      }
+        result.id = broker.id
+        result.current_time = System.currentTimeMillis
+        result.state = broker.service_state.toString
+        result.state_since = broker.service_state.since
+
+        broker.virtual_hosts.values.foreach{ host=>
+          // TODO: may need to sync /w virtual host's dispatch queue
+          result.virtual_hosts.add( host.id )
+        }
 
-      broker.connectors.foreach{ c=>
-        result.connectors.add( c.id )
-      }
+        broker.connectors.foreach{ c=>
+          result.connectors.add( c.id )
+        }
 
-      broker.connectors.foreach{ connector=>
-        connector.connections.foreach { case (id,connection) =>
-          // TODO: may need to sync /w connection's dispatch queue
-          result.connections.add( new LongIdLabeledDTO(id, connection.transport.getRemoteAddress ) )
+        broker.connectors.foreach{ connector=>
+          connector.connections.foreach { case (id,connection) =>
+            // TODO: may need to sync /w connection's dispatch queue
+            result.connections.add( new LongIdLabeledDTO(id, connection.transport.getRemoteAddress ) )
+          }
         }
+        result
+
       }
-      result
     }
   }
 
@@ -161,7 +84,9 @@ case class BrokerResource() extends Reso
   @Path("queue-metrics")
   def get_queue_metrics(): AggregateQueueMetricsDTO = {
     with_broker { broker =>
-      get_queue_metrics(broker)
+      monitoring(broker) {
+        get_queue_metrics(broker)
+      }
     }
   }
 
@@ -231,44 +156,50 @@ case class BrokerResource() extends Reso
   @GET @Path("virtual-hosts/{id}")
   def virtual_host(@PathParam("id") id : String):VirtualHostStatusDTO = {
     with_virtual_host(id) { host =>
-      val result = new VirtualHostStatusDTO
-      result.id = host.id
-      result.state = host.service_state.toString
-      result.state_since = host.service_state.since
-      result.store = host.store!=null
+      monitoring(host) {
+        val result = new VirtualHostStatusDTO
+        result.id = host.id
+        result.state = host.service_state.toString
+        result.state_since = host.service_state.since
+        result.store = host.store!=null
 
-      val router:LocalRouter = host
+        val router:LocalRouter = host
 
-      router.topic_domain.destinations.foreach { node=>
-        result.topics.add(new LongIdLabeledDTO(node.id, node.name))
-      }
+        router.topic_domain.destinations.foreach { node=>
+          result.topics.add(new LongIdLabeledDTO(node.id, node.name))
+        }
 
-      router.queue_domain.destinations.foreach { node=>
-        result.queues.add(new LongIdLabeledDTO(node.id, node.binding.label))
-      }
+        router.queue_domain.destinations.foreach { node=>
+          result.queues.add(new LongIdLabeledDTO(node.id, node.binding.label))
+        }
 
-      result
+        result
+      }
     }
   }
 
   @GET @Path("virtual-hosts/{id}/queue-metrics")
   def virtual_host_queue_metrics(@PathParam("id") id : String): AggregateQueueMetricsDTO = {
-    with_virtual_host(id) { virtualHost =>
-      get_queue_metrics(virtualHost)
+    with_virtual_host(id) { host =>
+      monitoring(host) {
+        get_queue_metrics(host)
+      }
     }
   }
 
   @GET @Path("virtual-hosts/{id}/store")
   def store(@PathParam("id") id : String):StoreStatusDTO = {
-    with_virtual_host(id) { virtualHost =>
-      if(virtualHost.store!=null) {
-        val rc = FutureResult[StoreStatusDTO]()
-        virtualHost.store.get_store_status { status =>
-          rc(Success(status))
+    with_virtual_host(id) { host =>
+      monitoring(host) {
+        if(host.store!=null) {
+          val rc = FutureResult[StoreStatusDTO]()
+          host.store.get_store_status { status =>
+            rc(Success(status))
+          }
+          rc
+        } else {
+          result(NOT_FOUND)
         }
-        rc
-      } else {
-        result(NOT_FOUND)
       }
     }
   }
@@ -295,29 +226,32 @@ case class BrokerResource() extends Reso
 
       val router:LocalRouter = host
       val node = router.topic_domain.destination_by_id.get(dest).getOrElse(result(NOT_FOUND))
-      val rc = new TopicStatusDTO
-      rc.id = node.id
-      rc.name = node.name
-      rc.config = node.config
-
-      node.durable_subscriptions.foreach { q=>
-        rc.durable_subscriptions.add(new LongIdLabeledDTO(q.id, q.binding.label))
-      }
-      node.consumers.foreach { consumer=>
-        consumer match {
-          case queue:Queue =>
-            rc.consumers.add(link(queue))
-          case _ =>
-            consumer.connection.foreach{c=>
-              rc.consumers.add(link(c))
-            }
+
+      monitoring(node) {
+        val rc = new TopicStatusDTO
+        rc.id = node.id
+        rc.name = node.name
+        rc.config = node.config
+
+        node.durable_subscriptions.foreach { q=>
+          rc.durable_subscriptions.add(new LongIdLabeledDTO(q.id, q.binding.label))
+        }
+        node.consumers.foreach { consumer=>
+          consumer match {
+            case queue:Queue =>
+              rc.consumers.add(link(queue))
+            case _ =>
+              consumer.connection.foreach{c=>
+                rc.consumers.add(link(c))
+              }
+          }
+        }
+        node.producers.flatMap( _.connection ).foreach { connection=>
+          rc.producers.add(link(connection))
         }
-      }
-      node.producers.flatMap( _.connection ).foreach { connection=>
-        rc.producers.add(link(connection))
-      }
 
-      rc
+        rc
+      }
     }
   }
 
@@ -376,62 +310,63 @@ case class BrokerResource() extends Reso
   def status(qo:Option[Queue], entries:Boolean=false) = qo match {
     case None=> result(NOT_FOUND)
     case Some(q)=> sync(q) {
-
-      val rc = new QueueStatusDTO
-      rc.id = q.id
-      rc.destination = q.binding.binding_dto
-      rc.config = q.config
-      rc.metrics = get_queue_metrics(q)
-
-      if( entries ) {
-        var cur = q.head_entry
-        while( cur!=null ) {
-
-          val e = new EntryStatusDTO
-          e.seq = cur.seq
-          e.count = cur.count
-          e.size = cur.size
-          e.consumer_count = cur.parked.size
-          e.is_prefetched = cur.is_prefetched
-          e.state = cur.label
-
-          rc.entries.add(e)
-
-          cur = if( cur == q.tail_entry ) {
-            null
-          } else {
-            cur.nextOrTail
+      monitoring(q) {
+        val rc = new QueueStatusDTO
+        rc.id = q.id
+        rc.destination = q.binding.binding_dto
+        rc.config = q.config
+        rc.metrics = get_queue_metrics(q)
+
+        if( entries ) {
+          var cur = q.head_entry
+          while( cur!=null ) {
+
+            val e = new EntryStatusDTO
+            e.seq = cur.seq
+            e.count = cur.count
+            e.size = cur.size
+            e.consumer_count = cur.parked.size
+            e.is_prefetched = cur.is_prefetched
+            e.state = cur.label
+
+            rc.entries.add(e)
+
+            cur = if( cur == q.tail_entry ) {
+              null
+            } else {
+              cur.nextOrTail
+            }
           }
-        }
-      } else {
+        } else {
 //        rc.entries = null
-      }
+        }
 
-      q.inbound_sessions.flatMap( _.producer.connection ).foreach { connection=>
-        rc.producers.add(link(connection))
-      }
-      q.all_subscriptions.valuesIterator.toSeq.foreach{ sub =>
-        val status = new QueueConsumerStatusDTO
-        sub.consumer.connection.foreach(x=> status.link = link(x))
-        status.position = sub.pos.seq
-        status.total_dispatched_count = sub.total_dispatched_count
-        status.total_dispatched_size = sub.total_dispatched_size
-        status.total_ack_count = sub.total_ack_count
-        status.total_nack_count = sub.total_nack_count
-        status.acquired_size = sub.acquired_size
-        status.acquired_count = sub.acquired_count
-        status.waiting_on = if( sub.full ) {
-          "ack"
-        } else if( sub.pos.is_tail ) {
-          "producer"
-        } else if( !sub.pos.is_loaded ) {
-          "load"
-        } else {
-          "dispatch"
+        q.inbound_sessions.flatMap( _.producer.connection ).foreach { connection=>
+          rc.producers.add(link(connection))
+        }
+        q.all_subscriptions.valuesIterator.toSeq.foreach{ sub =>
+          val status = new QueueConsumerStatusDTO
+          sub.consumer.connection.foreach(x=> status.link = link(x))
+          status.position = sub.pos.seq
+          status.total_dispatched_count = sub.total_dispatched_count
+          status.total_dispatched_size = sub.total_dispatched_size
+          status.total_ack_count = sub.total_ack_count
+          status.total_nack_count = sub.total_nack_count
+          status.acquired_size = sub.acquired_size
+          status.acquired_count = sub.acquired_count
+          status.waiting_on = if( sub.full ) {
+            "ack"
+          } else if( sub.pos.is_tail ) {
+            "producer"
+          } else if( !sub.pos.is_loaded ) {
+            "load"
+          } else {
+            "dispatch"
+          }
+          rc.consumers.add(status)
         }
-        rc.consumers.add(status)
+        rc
       }
-      rc
     }
   }
 
@@ -446,22 +381,24 @@ case class BrokerResource() extends Reso
   @GET @Path("connectors/{id}")
   def connector(@PathParam("id") id : String):ConnectorStatusDTO = {
     with_broker { broker =>
-      broker.connectors.find(_.id == id) match {
-        case None=> result(NOT_FOUND)
-        case Some(connector)=>
-
-          val result = new ConnectorStatusDTO
-          result.id = connector.id.toString
-          result.state = connector.service_state.toString
-          result.state_since = connector.service_state.since
-
-          result.accepted = connector.connection_counter.get
-          connector.connections.foreach { case (id,connection) =>
-            // TODO: may need to sync /w connection's dispatch queue
-            result.connections.add( new LongIdLabeledDTO(id, connection.transport.getRemoteAddress ) )
-          }
+      monitoring(broker) {
+        broker.connectors.find(_.id == id) match {
+          case None=> result(NOT_FOUND)
+          case Some(connector)=>
+
+            val result = new ConnectorStatusDTO
+            result.id = connector.id.toString
+            result.state = connector.service_state.toString
+            result.state_since = connector.service_state.since
+
+            result.accepted = connector.connection_counter.get
+            connector.connections.foreach { case (id,connection) =>
+              // TODO: may need to sync /w connection's dispatch queue
+              result.connections.add( new LongIdLabeledDTO(id, connection.transport.getRemoteAddress ) )
+            }
 
-          result
+            result
+        }
       }
     }
   }
@@ -470,23 +407,27 @@ case class BrokerResource() extends Reso
   @GET @Path("connections")
   def connections:LongIdListDTO = {
     with_broker { broker =>
-      val rc = new LongIdListDTO
+      monitoring(broker) {
+        val rc = new LongIdListDTO
 
-      broker.connectors.foreach { connector=>
-        connector.connections.foreach { case (id,connection) =>
-          // TODO: may need to sync /w connection's dispatch queue
-          rc.items.add(new LongIdLabeledDTO(id, connection.transport.getRemoteAddress ))
+        broker.connectors.foreach { connector=>
+          connector.connections.foreach { case (id,connection) =>
+            // TODO: may need to sync /w connection's dispatch queue
+            rc.items.add(new LongIdLabeledDTO(id, connection.transport.getRemoteAddress ))
+          }
         }
+
+        rc
       }
-      
-      rc
     }
   }
 
   @GET @Path("connections/{id}")
   def connections(@PathParam("id") id : Long):ConnectionStatusDTO = {
     with_connection(id){ connection=>
-      connection.get_connection_status
+      monitoring(connection.connector.broker) {
+        connection.get_connection_status
+      }
     }
   }
 
@@ -494,7 +435,9 @@ case class BrokerResource() extends Reso
   @Produces(Array("application/json", "application/xml","text/xml"))
   def post_connection_shutdown(@PathParam("id") id : Long):Unit = {
     with_connection(id){ connection=>
-      connection.stop
+      admining(connection.connector.broker) {
+        connection.stop
+      }
     }
   }
 
@@ -510,12 +453,15 @@ case class BrokerResource() extends Reso
   @Path("action/shutdown")
   def command_shutdown:Unit = {
     info("JVM shutdown requested via web interface")
-
-    // do the the exit async so that we don't
-    // kill the current request.
-    Broker.BLOCKABLE_THREAD_POOL.apply {
-      Thread.sleep(200)
-      System.exit(0)
+    with_broker { broker =>
+      admining(broker) {
+        // do the the exit async so that we don't
+        // kill the current request.
+        Broker.BLOCKABLE_THREAD_POOL.apply {
+          Thread.sleep(200)
+          System.exit(0)
+        }
+      }
     }
   }
 

Copied: activemq/activemq-apollo/trunk/apollo-web/src/main/scala/org/apache/activemq/apollo/web/resources/RootResource.scala (from r1127907, activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/TopicAclDTO.java)
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-web/src/main/scala/org/apache/activemq/apollo/web/resources/RootResource.scala?p2=activemq/activemq-apollo/trunk/apollo-web/src/main/scala/org/apache/activemq/apollo/web/resources/RootResource.scala&p1=activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/TopicAclDTO.java&r1=1127907&r2=1127908&rev=1127908&view=diff
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/TopicAclDTO.java (original)
+++ activemq/activemq-apollo/trunk/apollo-web/src/main/scala/org/apache/activemq/apollo/web/resources/RootResource.scala Thu May 26 13:44:13 2011
@@ -1,3 +1,9 @@
+package org.apache.activemq.apollo.web.resources
+
+import javax.ws.rs._
+import core.Response.Status._
+import com.sun.jersey.api.view.ImplicitProduces
+
 /**
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
@@ -14,32 +20,28 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.activemq.apollo.dto;
-
-
-
-import javax.xml.bind.annotation.*;
-import java.util.*;
-
 /**
- * <p>
- * </p>
  *
  * @author <a href="http://hiramchirino.com">Hiram Chirino</a>
  */
-@XmlAccessorType(XmlAccessType.FIELD)
-public class TopicAclDTO {
-
-    @XmlElement(name="create")
-    public List<PrincipalDTO> creates = new ArrayList<PrincipalDTO>();
-
-    @XmlElement(name="destroy")
-    public List<PrincipalDTO> destroys = new ArrayList<PrincipalDTO>();
+@Path("/")
+case class RootResource() extends Resource() {
 
-    @XmlElement(name="send")
-    public List<PrincipalDTO> sends = new ArrayList<PrincipalDTO>();
+  @GET
+  @Path("/")
+  @Produces(Array("application/json", "application/xml","text/xml","text/html"))
+  def post_connection_shutdown_and_redirect():Unit = {
+    result(strip_resolve("broker"))
+  }
+
+  @Path("{name}")
+  def path(@PathParam("name") name:String):AnyRef = {
+    name match {
+      case "broker" => new BrokerResource(this)
+      case _ =>
+        result(NOT_FOUND)
+    }
 
-    @XmlElement(name="receive")
-    public List<PrincipalDTO> receives = new ArrayList<PrincipalDTO>();
+  }
 
 }

Modified: activemq/activemq-apollo/trunk/apollo-web/src/main/scala/org/apache/activemq/apollo/web/resources/Support.scala
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-web/src/main/scala/org/apache/activemq/apollo/web/resources/Support.scala?rev=1127908&r1=1127907&r2=1127908&view=diff
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-web/src/main/scala/org/apache/activemq/apollo/web/resources/Support.scala (original)
+++ activemq/activemq-apollo/trunk/apollo-web/src/main/scala/org/apache/activemq/apollo/web/resources/Support.scala Thu May 26 13:44:13 2011
@@ -29,11 +29,41 @@ import com.sun.jersey.api.core.ResourceC
 import java.util.concurrent.TimeUnit
 import org.apache.activemq.apollo.dto._
 import java.util.{Arrays, Collections}
-import org.apache.activemq.apollo.util.Logging
 import org.fusesource.hawtdispatch._
 import java.net.URI
 import org.fusesource.scalate.{NoValueSetException, RenderContext}
-import org.apache.activemq.apollo.broker.{Broker, ConfigStore, BrokerRegistry}
+import com.sun.jersey.core.util.Base64
+import javax.servlet.http.{HttpServletResponse, HttpServletRequest}
+import java.io.{IOException, UnsupportedEncodingException}
+import org.apache.activemq.apollo.broker.security.{Authorizer, SecurityContext, Authenticator}
+import org.apache.activemq.apollo.broker._
+import java.lang.reflect.Proxy
+import com.sun.jersey.server.impl.ThreadLocalInvoker
+import util.continuations._
+import org.apache.activemq.apollo.util.Success._
+import org.apache.activemq.apollo.util.Failure._
+import org.apache.activemq.apollo.util._
+import javax.management.remote.rmi._RMIConnection_Stub
+
+object Resource {
+
+  val SECURITY_CONTEXT_ATTRIBUTE: String = classOf[SecurityContext].getName
+  val HEADER_WWW_AUTHENTICATE: String = "WWW-Authenticate"
+  val HEADER_AUTHORIZATION: String = "Authorization"
+  val AUTHENTICATION_SCHEME_BASIC: String = "Basic"
+
+  private def decode_base64(value: String): String = {
+    var transformed: Array[Byte] = Base64.decode(value)
+    try {
+      return new String(transformed, "ISO-8859-1")
+    } catch {
+      case uee: UnsupportedEncodingException => {
+        return new String(transformed)
+      }
+    }
+  }
+
+}
 
 /**
  * Defines the default representations to be used on resources
@@ -41,12 +71,23 @@ import org.apache.activemq.apollo.broker
 @ImplicitProduces(Array("text/html;qs=5"))
 @Produces(Array("application/json", "application/xml","text/xml"))
 abstract class Resource(private val parent:Resource=null) extends Logging {
+  import Resource._
 
   @Context
   var uri_info:UriInfo = null
+  @Context
+  var http_request: HttpServletRequest = null
 
   if( parent!=null ) {
     this.uri_info = parent.uri_info
+    this.http_request = parent.http_request
+
+    try {
+      val invoker = Proxy.getInvocationHandler(http_request).asInstanceOf[ThreadLocalInvoker[HttpServletRequest]]
+      http_request = invoker.get()
+    } catch {
+      case e:Throwable => e.printStackTrace()
+    }
   }
 
   def result(value:Status, message:Any=null):Nothing = {
@@ -67,6 +108,206 @@ abstract class Resource(private val pare
     new URI(uri_info.getAbsolutePath.resolve(value).toString.stripSuffix("/"))
   }
 
+
+  protected def authorize[T](authenticator:Authenticator, authorizer:Authorizer, block: =>FutureResult[T])(func: (Authorizer, SecurityContext)=>Boolean):FutureResult[T] = {
+    if ( authenticator != null ) {
+      val rc = FutureResult[T]()
+      authenticate(authenticator) { security_context =>
+        try {
+          if (security_context != null) {
+            if (authorizer == null) {
+              block.onComplete(rc)
+            } else {
+              if (func(authorizer, security_context)) {
+                block.onComplete(rc)
+              } else {
+                unauthroized
+              }
+            }
+          } else {
+            unauthroized
+          }
+        } catch {
+          case e:Throwable =>
+            rc.apply(Failure(e))
+        }
+      }
+      rc
+    } else {
+      block
+    }
+  }
+
+  protected def monitoring[T](broker:Broker)(func: =>FutureResult[T]):FutureResult[T] = {
+    authorize(broker.authenticator, broker.authorizer, func) {  _.can_monitor(_, broker) }
+  }
+
+  protected def admining[T](broker:Broker)(func: =>FutureResult[T]):FutureResult[T] = {
+    authorize(broker.authenticator, broker.authorizer, func) {  _.can_admin(_, broker) }
+  }
+
+  protected def admining[T](host:VirtualHost)(func: =>FutureResult[T]):FutureResult[T] = {
+    authorize(host.authenticator, host.authorizer, func) {  _.can_admin(_, host) }
+  }
+  protected def monitoring[T](host:VirtualHost)(func: =>FutureResult[T]):FutureResult[T] = {
+    authorize(host.authenticator, host.authorizer, func) {  _.can_monitor(_, host) }
+  }
+
+  protected def admining[T](dest:Queue)(func: =>FutureResult[T]):FutureResult[T] = {
+    authorize(dest.virtual_host.authenticator, dest.virtual_host.authorizer, func) {  _.can_admin(_, dest.virtual_host, dest.config) }
+  }
+  protected def monitoring[T](dest:Queue)(func: =>FutureResult[T]):FutureResult[T] = {
+    authorize(dest.virtual_host.authenticator, dest.virtual_host.authorizer, func) {  _.can_monitor(_, dest.virtual_host, dest.config) }
+  }
+
+  protected def admining[T](dest:Topic)(func: =>FutureResult[T]):FutureResult[T] = {
+    authorize(dest.virtual_host.authenticator, dest.virtual_host.authorizer, func) {  _.can_admin(_, dest.virtual_host, dest.config) }
+  }
+  protected def monitoring[T](dest:Topic)(func: =>FutureResult[T]):FutureResult[T] = {
+    authorize(dest.virtual_host.authenticator, dest.virtual_host.authorizer, func) {  _.can_monitor(_, dest.virtual_host, dest.config) }
+  }
+
+  protected def authenticate[T](authenticator:Authenticator)(func: (SecurityContext)=>Unit): Unit = {
+
+    var security_context = http_request.getAttribute(SECURITY_CONTEXT_ATTRIBUTE).asInstanceOf[SecurityContext]
+    if( security_context!=null ) {
+      func(security_context)
+    } else {
+      security_context = new SecurityContext
+      security_context.local_address = http_request.getLocalAddr+":"+http_request.getLocalPort
+      security_context.remote_address = http_request.getRemoteAddr+":"+http_request.getRemotePort
+
+      var auth_header = http_request.getHeader(HEADER_AUTHORIZATION)
+      if (auth_header != null && auth_header.length > 0) {
+        auth_header = auth_header.trim
+        var blank = auth_header.indexOf(' ')
+        if (blank > 0) {
+          var auth_type = auth_header.substring(0, blank)
+          var auth_info = auth_header.substring(blank).trim
+          if (auth_type.equalsIgnoreCase(AUTHENTICATION_SCHEME_BASIC)) {
+            try {
+              var srcString = decode_base64(auth_info)
+              var i = srcString.indexOf(':')
+              var username: String = srcString.substring(0, i)
+              var password: String = srcString.substring(i + 1)
+
+
+//            connection.transport match {
+//              case t:SslTransport=>
+//                security_context.certificates = Option(t.getPeerX509Certificates).getOrElse(Array[X509Certificate]())
+//              case _ => None
+//            }
+              security_context.user = username
+              security_context.password = password
+
+            } catch {
+              case e: Exception =>
+            }
+          }
+        }
+      }
+
+      reset {
+        if( authenticator.authenticate(security_context) ) {
+          http_request.setAttribute(SECURITY_CONTEXT_ATTRIBUTE, security_context)
+          func(security_context)
+        } else {
+          func(null)
+        }
+      }
+    }
+  }
+
+  protected def unauthroized = {
+    // TODO: perhaps get the realm from the authenticator
+    var http_realm = "Apollo"
+    throw new WebApplicationException(Response.
+      status(HttpServletResponse.SC_UNAUTHORIZED).
+      header(HEADER_WWW_AUTHENTICATE, AUTHENTICATION_SCHEME_BASIC + " realm=\"" + http_realm + "\"").
+      build())
+  }
+
+  type FutureResult[T] = Future[Result[T, Throwable]]
+
+  protected def FutureResult[T]() = Future[Result[T, Throwable]]()
+
+  protected def sync[T](dispached:Dispatched)(func: =>FutureResult[T]):FutureResult[T] = {
+    val rc = Future[Result[T, Throwable]]()
+    dispached.dispatch_queue.apply {
+      try {
+        func.onComplete(x=> rc.apply(x))
+      } catch {
+        case e:Throwable => rc.apply(Failure(e))
+      }
+    }
+    rc
+  }
+
+
+  protected def sync_all[T,D<:Dispatched](values:Iterable[D])(func: (D)=>FutureResult[T]) = {
+    Future.all {
+      values.map { value=>
+        sync(value) {
+          func(value)
+        }
+      }
+    }
+  }
+
+  protected implicit def to_local_router(host:VirtualHost):LocalRouter = {
+    host.router.asInstanceOf[LocalRouter]
+  }
+
+  protected implicit def wrap_future_result[T](value:T):FutureResult[T] = {
+    val rc = FutureResult[T]()
+    rc.apply(Success(value))
+    rc
+  }
+
+  protected implicit def unwrap_future_result[T](value:FutureResult[T]):T = {
+    value.await() match {
+      case Success(value) => value
+      case Failure(value) => throw value
+    }
+  }
+
+  protected def with_broker[T](func: (org.apache.activemq.apollo.broker.Broker)=>FutureResult[T]):FutureResult[T] = {
+    BrokerRegistry.list.headOption match {
+      case Some(broker)=>
+        sync(broker) {
+          func(broker)
+        }
+      case None=>
+        result(NOT_FOUND)
+    }
+  }
+
+  protected def with_virtual_host[T](id:String)(func: (VirtualHost)=>FutureResult[T]):FutureResult[T] = {
+    with_broker { broker =>
+      broker.virtual_hosts.valuesIterator.find( _.id == id) match {
+        case Some(virtualHost)=>
+          sync(virtualHost) {
+            func(virtualHost)
+          }
+        case None=>
+          result(NOT_FOUND)
+      }
+    }
+  }
+
+  protected def with_connection[T](id:Long)(func: BrokerConnection=>FutureResult[T]):FutureResult[T] = {
+    with_broker { broker =>
+      broker.connectors.flatMap{ _.connections.get(id) }.headOption match {
+        case Some(connection:BrokerConnection) =>
+          sync(connection) {
+            func(connection)
+          }
+        case None=>
+          result(NOT_FOUND)
+      }
+    }
+  }
+
 }
 
 object ViewHelper {
@@ -130,7 +371,6 @@ class ViewHelper {
       } else if (duration < HOURS) {
         "%d minutes".format(duration / MINUTES)
       } else if (duration < DAYS) {
-        println("<")
         "%d hours %s".format(duration / HOURS, friendly(duration%HOURS))
       } else if (duration < YEARS) {
         "%d days %s".format(duration / DAYS, friendly(duration%DAYS))

Modified: activemq/activemq-apollo/trunk/apollo-web/src/main/webapp/WEB-INF/web.xml
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-web/src/main/webapp/WEB-INF/web.xml?rev=1127908&r1=1127907&r2=1127908&view=diff
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-web/src/main/webapp/WEB-INF/web.xml (original)
+++ activemq/activemq-apollo/trunk/apollo-web/src/main/webapp/WEB-INF/web.xml Thu May 26 13:44:13 2011
@@ -34,7 +34,7 @@
     <filter-class>com.sun.jersey.spi.container.servlet.ServletContainer</filter-class>
     <init-param>
       <param-name>com.sun.jersey.config.feature.Trace</param-name>
-      <param-value>false</param-value>
+      <param-value>true</param-value>
     </init-param>
     <init-param>
       <param-name>com.sun.jersey.config.feature.Redirect</param-name>
@@ -51,7 +51,7 @@
     <init-param>
       <param-name>com.sun.jersey.config.property.classnames</param-name>
       <param-value>
-        org.apache.activemq.apollo.web.resources.BrokerResource,
+        org.apache.activemq.apollo.web.resources.RootResource,
         org.apache.activemq.apollo.web.resources.JacksonJsonProvider
       </param-value>
     </init-param>



Mime
View raw message