Teach DynamicBindingAdapter about properties 93/73993/5
authorRobert Varga <robert.varga@pantheon.tech>
Thu, 12 Jul 2018 21:48:55 +0000 (23:48 +0200)
committerTom Pantelis <tompantelis@gmail.com>
Mon, 16 Jul 2018 20:20:48 +0000 (20:20 +0000)
We needs to exert some control over how a we re-export services,
like ignoring re-exports and overriding properties.

Define the API contract in ServiceProperties and implement the two
features mentioned.

Change-Id: I37b4ab53517842cd21bf090ea83c8d11a527d49e
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/osgi/AdaptingTracker.java
binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/osgi/Dict.java
binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/osgi/ServiceProperties.java [new file with mode: 0644]

index 4971b0eb6558c04d18082a08666a64a3322b0e33..1858c2e0eaea1a02481196f429de3d8ff64ac9ab 100644 (file)
@@ -53,6 +53,11 @@ final class AdaptingTracker<D extends DOMService, B extends BindingService>
             LOG.debug("Null reference for {}, ignoring it", bindingClass.getName());
             return null;
         }
+        if (reference.getProperty(ServiceProperties.IGNORE_PROP) != null) {
+            LOG.debug("Ignoring reference {} due to {}", reference, ServiceProperties.IGNORE_PROP);
+            return null;
+        }
+
         final D dom = context.getService(reference);
         if (dom == null) {
             LOG.debug("Could not get {} service from {}, ignoring it", bindingClass.getName(), reference);
index d837548decb61dd833cd19ea2e2460a5a4b7234a..ab4fa7faef48d0ace3808dcf4da65e3cedc566d3 100644 (file)
@@ -7,26 +7,27 @@
  */
 package org.opendaylight.mdsal.binding.dom.adapter.osgi;
 
-import static java.util.Objects.requireNonNull;
-
 import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableMap.Builder;
 import com.google.common.collect.Iterators;
+import com.google.common.collect.Maps;
 import java.util.Dictionary;
 import java.util.Enumeration;
 import java.util.Map;
 import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.eclipse.jdt.annotation.Nullable;
 import org.osgi.framework.ServiceReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 @NonNullByDefault
 final class Dict extends Dictionary<String, Object> {
+    private static final Logger LOG = LoggerFactory.getLogger(Dict.class);
     private static final Dict EMPTY = new Dict(ImmutableMap.of());
 
     private final Map<String, Object> map;
 
     private Dict(final Map<String, Object> map) {
-        this.map = requireNonNull(map);
+        this.map = ImmutableMap.copyOf(map);
     }
 
     static Dict fromReference(final ServiceReference<?> ref) {
@@ -35,15 +36,32 @@ final class Dict extends Dictionary<String, Object> {
             return EMPTY;
         }
 
-        final Builder<String, Object> b = ImmutableMap.builderWithExpectedSize(keys.length);
+        final Map<String, Object> props = Maps.newHashMapWithExpectedSize(keys.length);
+        for (String key : keys) {
+            // Ignore properties with our prefix: we are not exporting those
+            if (!key.startsWith(ServiceProperties.PREFIX)) {
+                final Object value = ref.getProperty(key);
+                if (value != null) {
+                    props.put(key, value);
+                }
+            }
+        }
+
+        // Second phase: apply any our properties
         for (String key : keys) {
-            final Object value = ref.getProperty(key);
-            if (value != null) {
-                b.put(key, value);
+            if (key.startsWith(ServiceProperties.OVERRIDE_PREFIX)) {
+                final Object value = ref.getProperty(key);
+                if (value != null) {
+                    final String newKey = key.substring(ServiceProperties.OVERRIDE_PREFIX.length());
+                    if (!newKey.isEmpty()) {
+                        LOG.debug("Overriding property {}", newKey);
+                        props.put(newKey, value);
+                    }
+                }
             }
         }
 
-        return new Dict(b.build());
+        return new Dict(props);
     }
 
     @Override
diff --git a/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/osgi/ServiceProperties.java b/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/osgi/ServiceProperties.java
new file mode 100644 (file)
index 0000000..d5555ad
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2018 Pantheon Technologies, s.r.o. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.mdsal.binding.dom.adapter.osgi;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * Properties recognized and manipulated by {@link DynamicBindingAdapter}. All properties starting with
+ * {@code odl.mdsal.binding.adapter.} are stripped from the re-exported service.
+ *
+ * @author Robert Varga
+ */
+@Beta
+public final class ServiceProperties {
+    static final String PREFIX = "odl.mdsal.binding.adapter.";
+
+    /**
+     * Instruction to ignore the service. When a service with this property is found, {@link DynamicBindingAdapter}
+     * will completely ignore it.
+     */
+    public static final String IGNORE_PROP = "odl.mdsal.binding.adapter.ignore";
+
+    /**
+     * Prefix for properties which should be replaced. For any property with a name which starts with this prefix,
+     * {@link DynamicBindingAdapter} will strip this prefix and advertise the resulting property in the re-exported
+     * service.
+     */
+    public static final String OVERRIDE_PREFIX = "odl.mdsal.binding.adapter.override.";
+
+    private ServiceProperties() {
+
+    }
+}