Update to latest http whiteboard api

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1676581 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/http/api/src/main/java/org/osgi/service/http/runtime/dto/RuntimeDTO.java b/http/api/src/main/java/org/osgi/service/http/runtime/dto/RuntimeDTO.java
index 6facc36..757c47c 100644
--- a/http/api/src/main/java/org/osgi/service/http/runtime/dto/RuntimeDTO.java
+++ b/http/api/src/main/java/org/osgi/service/http/runtime/dto/RuntimeDTO.java
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) OSGi Alliance (2012, 2014). All Rights Reserved.
- * 
+ * Copyright (c) OSGi Alliance (2012, 2015). All Rights Reserved.
+ *
  * 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
@@ -16,69 +16,71 @@
 
 package org.osgi.service.http.runtime.dto;
 
-import java.util.Map;
 import org.osgi.dto.DTO;
+import org.osgi.framework.dto.ServiceReferenceDTO;
 
 /**
  * Represents the state of a Http Service Runtime.
- * 
+ *
  * @NotThreadSafe
  * @author $Id$
  */
 public class RuntimeDTO extends DTO {
 
-	/**
-	 * The runtime attributes. This value is never {@code null}.
-	 */
-	public Map<String, String>	attributes;
+    /**
+     * The DTO for the corresponding
+     * {@code org.osgi.service.http.runtime.HttpServiceRuntime}. This value is
+     * never {@code null}.
+     */
+    public ServiceReferenceDTO          serviceDTO;
 
-	/**
-	 * Returns the representations of the {@code javax.servlet.ServletContext}
-	 * objects used by the Http Service Runtime. The returned array may be empty
-	 * if the Http Service Runtime is currently not using any
-	 * {@code javax.servlet.ServletContext} objects.
-	 */
-	public ServletContextDTO[] servletContextDTOs;
+    /**
+     * Returns the representations of the {@code javax.servlet.ServletContext}
+     * objects used by the Http Service Runtime. The returned array may be empty
+     * if the Http Service Runtime is currently not using any
+     * {@code javax.servlet.ServletContext} objects.
+     */
+    public ServletContextDTO[] servletContextDTOs;
 
-	/**
-	 * Returns the representations of the {@code javax.servlet.ServletContext} objects
-	 * currently not used by the Http service runtime due to some problem.
-	 * The returned array may be empty.
-	 */
-	public FailedServletContextDTO[] failedServletContextDTOs;
+    /**
+     * Returns the representations of the {@code javax.servlet.ServletContext} objects
+     * currently not used by the Http service runtime due to some problem.
+     * The returned array may be empty.
+     */
+    public FailedServletContextDTO[] failedServletContextDTOs;
 
-	/**
-	 * Returns the representations of the {@code javax.servlet.Servlet} services
-	 * associated with this runtime but currently not used due to some problem.
-	 * The returned array may be empty.
-	 */
-	public FailedServletDTO[] failedServletDTOs;
+    /**
+     * Returns the representations of the {@code javax.servlet.Servlet} services
+     * associated with this runtime but currently not used due to some problem.
+     * The returned array may be empty.
+     */
+    public FailedServletDTO[] failedServletDTOs;
 
-	/**
-	 * Returns the representations of the resources associated with this runtime
-	 * but currently not used due to some problem. The returned array may be
-	 * empty.
-	 */
-	public FailedResourceDTO[] failedResourceDTOs;
+    /**
+     * Returns the representations of the resources associated with this runtime
+     * but currently not used due to some problem. The returned array may be
+     * empty.
+     */
+    public FailedResourceDTO[] failedResourceDTOs;
 
-	/**
-	 * Returns the representations of the servlet {@code javax.servlet.Filter}
-	 * services associated with this runtime but currently not used due to some
-	 * problem. The returned array may be empty.
-	 */
-	public FailedFilterDTO[] failedFilterDTOs;
+    /**
+     * Returns the representations of the servlet {@code javax.servlet.Filter}
+     * services associated with this runtime but currently not used due to some
+     * problem. The returned array may be empty.
+     */
+    public FailedFilterDTO[] failedFilterDTOs;
 
-	/**
-	 * Returns the representations of the error page
-	 * {@code javax.servlet.Servlet} services associated with this runtime but
-	 * currently not used due to some problem. The returned array may be empty.
-	 */
-	public FailedErrorPageDTO[] failedErrorPageDTOs;
+    /**
+     * Returns the representations of the error page
+     * {@code javax.servlet.Servlet} services associated with this runtime but
+     * currently not used due to some problem. The returned array may be empty.
+     */
+    public FailedErrorPageDTO[] failedErrorPageDTOs;
 
-	/**
-	 * Returns the representations of the listeners associated with this runtime
-	 * but currently not used due to some problem. The returned array may be
-	 * empty.
-	 */
-	public FailedListenerDTO[] failedListenerDTOs;
+    /**
+     * Returns the representations of the listeners associated with this runtime
+     * but currently not used due to some problem. The returned array may be
+     * empty.
+     */
+    public FailedListenerDTO[] failedListenerDTOs;
 }
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/RuntimeDTOBuilder.java b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/RuntimeDTOBuilder.java
index ac6c302..2161d6a 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/RuntimeDTOBuilder.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/RuntimeDTOBuilder.java
@@ -24,7 +24,11 @@
 import java.util.List;
 import java.util.Map;
 
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceReference;
+import org.osgi.framework.dto.ServiceReferenceDTO;
+import org.osgi.service.http.runtime.HttpServiceRuntime;
 import org.osgi.service.http.runtime.dto.ErrorPageDTO;
 import org.osgi.service.http.runtime.dto.FilterDTO;
 import org.osgi.service.http.runtime.dto.ListenerDTO;
@@ -37,20 +41,20 @@
 {
 
     private final RegistryRuntime registry;
-    private final Map<String, Object> serviceProperties;
+    private final ServiceReference<HttpServiceRuntime> serviceReference;
 
-    public RuntimeDTOBuilder(RegistryRuntime registry, Map<String, Object> serviceProperties)
+    public RuntimeDTOBuilder(final RegistryRuntime registry, final ServiceReference<HttpServiceRuntime> ref)
     {
         this.registry = registry;
-        this.serviceProperties = serviceProperties;
+        this.serviceReference = ref;
     }
 
     public RuntimeDTO build()
     {
-        FailureRuntime failureRuntime = registry.getFailureRuntime();
+        final FailureRuntime failureRuntime = registry.getFailureRuntime();
 
-        RuntimeDTO runtimeDTO = new RuntimeDTO();
-        runtimeDTO.attributes = createAttributes();
+        final RuntimeDTO runtimeDTO = new RuntimeDTO();
+        runtimeDTO.serviceDTO = createServiceDTO();
         runtimeDTO.failedErrorPageDTOs = failureRuntime.getErrorPageDTOs();
         runtimeDTO.failedFilterDTOs = failureRuntime.getFilterDTOs();
         runtimeDTO.failedListenerDTOs = failureRuntime.getListenerDTOs();
@@ -61,14 +65,33 @@
         return runtimeDTO;
     }
 
-    private Map<String, String> createAttributes()
+    private ServiceReferenceDTO createServiceDTO()
     {
-        Map<String, String> attributes = new HashMap<String, String>();
-        for (Map.Entry<String, Object> entry : this.serviceProperties.entrySet())
+        final ServiceReferenceDTO dto = new ServiceReferenceDTO();
+        dto.bundle = this.serviceReference.getBundle().getBundleId();
+        dto.id = (Long) this.serviceReference.getProperty(Constants.SERVICE_ID);
+        final Map<String, Object> props = new HashMap<String, Object>();
+        for (String key : this.serviceReference.getPropertyKeys())
         {
-            attributes.put(entry.getKey(), entry.getValue().toString());
+            props.put(key, this.serviceReference.getProperty(key));
         }
-        return attributes;
+        dto.properties = props;
+
+        final Bundle[] ubs = this.serviceReference.getUsingBundles();
+        if (ubs == null)
+        {
+            dto.usingBundles = new long[0];
+        }
+        else
+        {
+            dto.usingBundles = new long[ubs.length];
+            for (int j=0; j < ubs.length; j++)
+            {
+                dto.usingBundles[j] = ubs[j].getBundleId();
+            }
+        }
+
+        return dto;
     }
 
     private ServletContextDTO[] createContextDTOs()
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceRuntimeImpl.java b/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceRuntimeImpl.java
index aae2679..58d8521 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceRuntimeImpl.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceRuntimeImpl.java
@@ -26,6 +26,7 @@
 import org.apache.felix.http.base.internal.runtime.dto.RequestInfoDTOBuilder;
 import org.apache.felix.http.base.internal.runtime.dto.RuntimeDTOBuilder;
 import org.apache.felix.http.base.internal.whiteboard.WhiteboardManager;
+import org.osgi.framework.ServiceReference;
 import org.osgi.service.http.runtime.HttpServiceRuntime;
 import org.osgi.service.http.runtime.dto.RequestInfoDTO;
 import org.osgi.service.http.runtime.dto.RuntimeDTO;
@@ -37,6 +38,8 @@
     private final HandlerRegistry registry;
     private final WhiteboardManager contextManager;
 
+    private volatile ServiceReference<HttpServiceRuntime> serviceReference;
+
     public HttpServiceRuntimeImpl(HandlerRegistry registry,
             WhiteboardManager contextManager)
     {
@@ -48,7 +51,7 @@
     public RuntimeDTO getRuntimeDTO()
     {
         RegistryRuntime runtime = contextManager.getRuntime(registry);
-        RuntimeDTOBuilder runtimeDTOBuilder = new RuntimeDTOBuilder(runtime, attributes);
+        RuntimeDTOBuilder runtimeDTOBuilder = new RuntimeDTOBuilder(runtime, this.serviceReference);
         return runtimeDTOBuilder.build();
     }
 
@@ -77,6 +80,11 @@
 
     public Dictionary<String, Object> getAttributes()
     {
-        return new Hashtable<String, Object>(attributes);
+        return attributes;
+    }
+
+    public void setServiceReference(
+            final ServiceReference<HttpServiceRuntime> reference) {
+        this.serviceReference = reference;
     }
 }
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/WhiteboardManager.java b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/WhiteboardManager.java
index 4120ac9..7dab454 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/WhiteboardManager.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/WhiteboardManager.java
@@ -138,6 +138,7 @@
         this.runtimeServiceReg = this.bundleContext.registerService(HttpServiceRuntime.class,
                 serviceRuntime,
                 this.serviceRuntime.getAttributes());
+        this.serviceRuntime.setServiceReference(this.runtimeServiceReg.getReference());
 
         this.webContext = context;
 
@@ -208,6 +209,8 @@
         }
         this.trackers.clear();
 
+        this.serviceRuntime.setServiceReference(null);
+
         // TODO cleanup
         if (this.defaultContextRegistration != null)
         {
diff --git a/http/base/src/test/java/org/apache/felix/http/base/internal/runtime/dto/RuntimeDTOBuilderTest.java b/http/base/src/test/java/org/apache/felix/http/base/internal/runtime/dto/RuntimeDTOBuilderTest.java
index d989b38..8ffb691 100644
--- a/http/base/src/test/java/org/apache/felix/http/base/internal/runtime/dto/RuntimeDTOBuilderTest.java
+++ b/http/base/src/test/java/org/apache/felix/http/base/internal/runtime/dto/RuntimeDTOBuilderTest.java
@@ -75,6 +75,7 @@
 import org.osgi.framework.Bundle;
 import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceReference;
+import org.osgi.service.http.runtime.HttpServiceRuntime;
 import org.osgi.service.http.runtime.dto.ErrorPageDTO;
 import org.osgi.service.http.runtime.dto.FilterDTO;
 import org.osgi.service.http.runtime.dto.ListenerDTO;
@@ -135,6 +136,8 @@
 
     @Mock private ServiceReference<Object> resource;
 
+    @Mock private ServiceReference<HttpServiceRuntime> runtimeReference;
+
     private RegistryRuntime registry;
     private Map<String, Object> runtimeAttributes;
 
@@ -143,6 +146,15 @@
     {
         registry = null;
         runtimeAttributes = RUNTIME_ATTRIBUTES;
+        when(bundle.getBundleId()).thenReturn(47L);
+        when(runtimeReference.getBundle()).thenReturn(bundle);
+        when(runtimeReference.getUsingBundles()).thenReturn(null);
+        when(runtimeReference.getPropertyKeys()).thenReturn(runtimeAttributes.keySet().toArray(new String[5]));
+        for(final String key : runtimeAttributes.keySet())
+        {
+            when(runtimeReference.getProperty(key)).thenReturn(runtimeAttributes.get(key));
+        }
+        when(runtimeReference.getProperty(Constants.SERVICE_ID)).thenReturn(39L);
     }
 
     public ServletContextHelperRuntime setupContext(ServletContext context, String name, long serviceId)
@@ -259,7 +271,7 @@
                 listenerRuntimes,
                 FailureRuntime.empty());
 
-        RuntimeDTO runtimeDTO = new RuntimeDTOBuilder(registry, runtimeAttributes).build();
+        RuntimeDTO runtimeDTO = new RuntimeDTOBuilder(registry, runtimeReference).build();
 
         assertEquals(0, runtimeDTO.failedErrorPageDTOs.length);
         assertEquals(0, runtimeDTO.failedFilterDTOs.length);
@@ -606,7 +618,7 @@
                 Collections.<Long, Collection<ServiceReference<?>>>emptyMap(),
                 FailureRuntime.empty());
 
-        RuntimeDTO runtimeDTO = new RuntimeDTOBuilder(registry, runtimeAttributes).build();
+        RuntimeDTO runtimeDTO = new RuntimeDTOBuilder(registry, runtimeReference).build();
 
         assertEquals(1, runtimeDTO.servletContextDTOs.length);
         assertEquals(1, runtimeDTO.servletContextDTOs[0].servletDTOs.length);
@@ -630,7 +642,7 @@
                 Collections.<Long, Collection<ServiceReference<?>>>emptyMap(),
                 FailureRuntime.empty());
 
-        RuntimeDTO runtimeDTO = new RuntimeDTOBuilder(registry, runtimeAttributes).build();
+        RuntimeDTO runtimeDTO = new RuntimeDTOBuilder(registry, runtimeReference).build();
 
         assertEquals(2, runtimeDTO.servletContextDTOs.length);
         assertEquals(0, runtimeDTO.servletContextDTOs[0].servletDTOs.length);
@@ -666,7 +678,7 @@
                 Collections.<Long, Collection<ServiceReference<?>>>emptyMap(),
                 FailureRuntime.empty());
 
-        new RuntimeDTOBuilder(registry, runtimeAttributes).build();
+        new RuntimeDTOBuilder(registry, runtimeReference).build();
     }
 
     public FailureRuntime setupFailures()
@@ -744,7 +756,7 @@
                 Collections.<Long, Collection<ServiceReference<?>>>emptyMap(),
                 setupFailures());
 
-        RuntimeDTO runtimeDTO = new RuntimeDTOBuilder(registry, runtimeAttributes).build();
+        RuntimeDTO runtimeDTO = new RuntimeDTOBuilder(registry, runtimeReference).build();
 
         assertEquals(0, runtimeDTO.servletContextDTOs.length);
 
diff --git a/http/itest/src/test/java/org/apache/felix/http/itest/HttpServiceRuntimeTest.java b/http/itest/src/test/java/org/apache/felix/http/itest/HttpServiceRuntimeTest.java
index f1d55e6..bfe6680 100644
--- a/http/itest/src/test/java/org/apache/felix/http/itest/HttpServiceRuntimeTest.java
+++ b/http/itest/src/test/java/org/apache/felix/http/itest/HttpServiceRuntimeTest.java
@@ -52,7 +52,6 @@
 import java.util.Collection;
 import java.util.Dictionary;
 import java.util.List;
-import java.util.Map;
 import java.util.NoSuchElementException;
 import java.util.SortedSet;
 import java.util.TreeSet;
@@ -80,6 +79,7 @@
 import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceReference;
 import org.osgi.framework.ServiceRegistration;
+import org.osgi.framework.dto.ServiceReferenceDTO;
 import org.osgi.service.http.HttpService;
 import org.osgi.service.http.context.ServletContextHelper;
 import org.osgi.service.http.runtime.HttpServiceRuntime;
@@ -253,14 +253,18 @@
         assertNotNull("HttpServiceRuntime unavailable", serviceRuntime);
 
         RuntimeDTO runtimeDTO = serviceRuntime.getRuntimeDTO();
-        Map<String, String> runtimeDTOAttributes = runtimeDTO.attributes;
+        ServiceReferenceDTO serviceDTO = runtimeDTO.serviceDTO;
 
-        assertNotNull(runtimeDTOAttributes);
-        assertTrue(runtimeDTOAttributes.containsKey(HTTP_SERVICE_ID));
-        assertTrue(runtimeDTOAttributes.containsKey(HTTP_SERVICE_ENDPOINT));
-/** TODO */
-//        assertTrue(runtimeDTOAttributes.get(HTTP_SERVICE_ID) instanceof Collection);
-//        assertTrue(0 < Integer.valueOf(runtimeDTOAttributes.get(HTTP_SERVICE_ID_ATTRIBUTE)));
+        assertNotNull(serviceDTO);
+        assertNotNull(serviceDTO.properties);
+        assertTrue(serviceDTO.properties.containsKey(HTTP_SERVICE_ID));
+        assertTrue(serviceDTO.properties.containsKey(HTTP_SERVICE_ENDPOINT));
+
+        assertTrue(serviceDTO.properties.get(HTTP_SERVICE_ID) instanceof Collection);
+        final Collection ids = (Collection)serviceDTO.properties.get(HTTP_SERVICE_ID);
+        assertTrue(ids.size() == 1);
+        assertTrue(ids.iterator().next() instanceof Long);
+        assertTrue(0 < (Long)ids.iterator().next());
 
         assertEquals(0, runtimeDTO.failedErrorPageDTOs.length);
         assertEquals(0, runtimeDTO.failedFilterDTOs.length);
@@ -1218,12 +1222,11 @@
         ServiceReference<?> httpServiceRef = m_context.getServiceReference(HttpService.class.getName());
         ServiceReference<?> httpServiceRuntimeRef = m_context.getServiceReference(HttpServiceRuntime.class.getName());
 
-        /** TODO
-        Long expectedId = (Long) httpServiceRef.getProperty(SERVICE_ID);
-        Long actualId = (Long) httpServiceRuntimeRef.getProperty(HTTP_SERVICE_ID_ATTRIBUTE);
+        Long expectedId = (Long) httpServiceRef.getProperty(Constants.SERVICE_ID);
+        Collection col = (Collection)httpServiceRuntimeRef.getProperty(HTTP_SERVICE_ID);
+        Long actualId = (Long) col.iterator().next();
 
         assertEquals(expectedId, actualId);
-        */
     }
 
     // As specified in OSGi Compendium Release 6, Chapter 140.9
@@ -1338,7 +1341,7 @@
         // if there is more than one network interface, there might be more than one endpoint!
         final String[] endpoint = (String[]) m_context.getServiceReference(HttpServiceRuntime.class).getProperty(HTTP_SERVICE_ENDPOINT);
         assertNotNull(endpoint);
-        assertTrue(endpoint.length > 1);
+        assertTrue(Arrays.toString(endpoint), endpoint.length > 0);
         assertTrue(endpoint[0].startsWith("http://"));
         assertTrue(endpoint[0].endsWith(":8080/"));
     }