+++ /dev/null
-/*
- * 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 static java.util.Objects.requireNonNull;
-
-import java.util.function.Function;
-import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.mdsal.binding.api.BindingService;
-import org.opendaylight.mdsal.dom.api.DOMService;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
-import org.osgi.util.tracker.ServiceTracker;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * A ServiceTracker which adapts a DOMService to a BindingService.
- *
- * @param <D> DOMService type
- * @param <B> BindingService type
- * @author Robert Varga
- */
-abstract class AbstractAdaptingTracker<D extends DOMService, B extends BindingService, T>
- extends ServiceTracker<D, T> {
- private static final Logger LOG = LoggerFactory.getLogger(AbstractAdaptingTracker.class);
-
- private final Function<D, B> bindingFactory;
- final @NonNull Class<B> bindingClass;
-
- AbstractAdaptingTracker(final BundleContext ctx, final Class<D> domClass, final Class<B> bindingClass,
- final Function<D, B> bindingFactory) {
- super(ctx, domClass, null);
- this.bindingClass = requireNonNull(bindingClass);
- this.bindingFactory = requireNonNull(bindingFactory);
- }
-
- @Override
- public final void open(final boolean trackAllServices) {
- LOG.debug("Starting tracker for {}", bindingClass.getName());
- super.open(trackAllServices);
- LOG.debug("Tracker for {} started", bindingClass.getName());
- }
-
- @Override
- public final T addingService(final ServiceReference<D> reference) {
- if (reference == null) {
- 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);
- return null;
- }
-
- return addingService(reference, dom, bindingFactory.apply(dom));
- }
-
- abstract @NonNull T addingService(@NonNull ServiceReference<D> reference, @NonNull D dom, @NonNull B binding);
-
- @Override
- public final void modifiedService(final ServiceReference<D> reference, final T service) {
- if (service != null && reference != null) {
- updatedService(reference, service);
- }
- }
-
- abstract void updatedService(@NonNull ServiceReference<D> reference, @NonNull T service);
-
- @Override
- public final void removedService(final ServiceReference<D> reference, final T service) {
- if (service != null) {
- context.ungetService(reference);
- removedService(service);
- LOG.debug("Unregistered service {}", service);
- }
- }
-
- abstract void removedService(@NonNull T service);
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2020 PANTHEON.tech, 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 static java.util.Objects.requireNonNull;
-
-import java.util.function.Function;
-import org.opendaylight.mdsal.binding.api.BindingService;
-import org.opendaylight.mdsal.dom.api.DOMService;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
-import org.osgi.service.component.ComponentFactory;
-import org.osgi.service.component.ComponentInstance;
-
-final class AdaptingComponentTracker<D extends DOMService, B extends BindingService>
- extends AbstractAdaptingTracker<D, B, AdaptingComponentTracker.ComponentHolder<B>> {
- static final class ComponentHolder<B extends BindingService> {
- final B binding;
- ComponentInstance component;
-
- ComponentHolder(final B binding, final ComponentInstance component) {
- this.binding = requireNonNull(binding);
- this.component = requireNonNull(component);
- }
- }
-
- private final ComponentFactory componentFactory;
-
- AdaptingComponentTracker(final BundleContext ctx, final Class<D> domClass, final Class<B> bindingClass,
- final Function<D, B> bindingFactory, final ComponentFactory componentFactory) {
- super(ctx, domClass, bindingClass, bindingFactory);
- this.componentFactory = requireNonNull(componentFactory);
- }
-
- @Override
- ComponentHolder<B> addingService(final ServiceReference<D> reference, final D dom, final B binding) {
- return new ComponentHolder<>(binding, componentFactory.newInstance(Dict.fromReference(reference, binding)));
- }
-
- @Override
- void removedService(final ComponentHolder<B> service) {
- service.component.dispose();
- }
-
- @Override
- void updatedService(final ServiceReference<D> reference, final ComponentHolder<B> service) {
- service.component.dispose();
- service.component = componentFactory.newInstance(Dict.fromReference(reference, service.binding));
- }
-}
/*
- * Copyright (c) 2018 Pantheon Technologies, s.r.o. and others. All rights reserved.
+ * Copyright (c) 2020 PANTHEON.tech, 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,
*/
package org.opendaylight.mdsal.binding.dom.adapter.osgi;
+import static java.util.Objects.requireNonNull;
+
import java.util.function.Function;
+import org.eclipse.jdt.annotation.NonNull;
import org.opendaylight.mdsal.binding.api.BindingService;
import org.opendaylight.mdsal.dom.api.DOMService;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
-import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.component.ComponentFactory;
+import org.osgi.service.component.ComponentInstance;
+import org.osgi.util.tracker.ServiceTracker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
* @author Robert Varga
*/
final class AdaptingTracker<D extends DOMService, B extends BindingService>
- extends AbstractAdaptingTracker<D, B, ServiceRegistration<B>> {
+ extends ServiceTracker<D, AdaptingTracker.ComponentHolder<B>> {
+ static final class ComponentHolder<B extends BindingService> {
+ final B binding;
+ ComponentInstance component;
+
+ ComponentHolder(final B binding, final ComponentInstance component) {
+ this.binding = requireNonNull(binding);
+ this.component = requireNonNull(component);
+ }
+ }
+
private static final Logger LOG = LoggerFactory.getLogger(AdaptingTracker.class);
+ private final Function<D, B> bindingFactory;
+ private final @NonNull Class<B> bindingClass;
+ private final ComponentFactory componentFactory;
+
AdaptingTracker(final BundleContext ctx, final Class<D> domClass, final Class<B> bindingClass,
- final Function<D, B> bindingFactory) {
- super(ctx, domClass, bindingClass, bindingFactory);
+ final Function<D, B> bindingFactory, final ComponentFactory componentFactory) {
+ super(ctx, domClass, null);
+ this.bindingClass = requireNonNull(bindingClass);
+ this.bindingFactory = requireNonNull(bindingFactory);
+ this.componentFactory = requireNonNull(componentFactory);
}
@Override
- ServiceRegistration<B> addingService(final ServiceReference<D> reference, final D dom, final B binding) {
- final Dict props = Dict.fromReference(reference);
- final ServiceRegistration<B> reg = context.registerService(bindingClass, binding, props);
- LOG.debug("Registered {} adapter {} of {} with {} as {}", bindingClass.getName(), binding, dom, props, reg);
- return reg;
+ public void open(final boolean trackAllServices) {
+ LOG.debug("Starting tracker for {}", bindingClass.getName());
+ super.open(trackAllServices);
+ LOG.debug("Tracker for {} started", bindingClass.getName());
+ }
+
+ @Override
+ public ComponentHolder<B> addingService(final ServiceReference<D> reference) {
+ if (reference == null) {
+ 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);
+ return null;
+ }
+
+ final B binding = bindingFactory.apply(dom);
+ return new ComponentHolder<>(binding, componentFactory.newInstance(Dict.fromReference(reference, binding)));
}
@Override
- void removedService(final ServiceRegistration<B> service) {
- service.unregister();
+ public void modifiedService(final ServiceReference<D> reference, final ComponentHolder<B> service) {
+ if (service != null && reference != null) {
+ service.component.dispose();
+ service.component = componentFactory.newInstance(Dict.fromReference(reference, service.binding));
+ }
}
@Override
- void updatedService(final ServiceReference<D> reference, final ServiceRegistration<B> service) {
- final Dict newProps = Dict.fromReference(reference);
- LOG.debug("Updating service {} with properties {}", service, newProps);
- service.setProperties(newProps);
+ public void removedService(final ServiceReference<D> reference, final ComponentHolder<B> service) {
+ if (service != null) {
+ context.ungetService(reference);
+ service.component.dispose();
+ LOG.debug("Unregistered service {}", service);
+ }
}
}
@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;
this.map = ImmutableMap.copyOf(map);
}
- static Dict fromReference(final ServiceReference<?> ref) {
- final String[] keys = ref.getPropertyKeys();
- if (keys.length == 0) {
- return EMPTY;
- }
-
- return new Dict(populateProperties(ref, keys, 0));
- }
-
static Dict fromReference(final ServiceReference<?> ref, final BindingService service) {
- final Map<String, Object> props = populateProperties(ref, ref.getPropertyKeys(), 1);
- props.put(AbstractAdaptedService.DELEGATE, service);
- return new Dict(props);
- }
-
- private static Map<String, Object> populateProperties(final ServiceReference<?> ref, final String[] keys,
- final int extra) {
- final Map<String, Object> props = Maps.newHashMapWithExpectedSize(keys.length + extra);
+ final String[] keys = ref.getPropertyKeys();
+ final Map<String, Object> props = Maps.newHashMapWithExpectedSize(keys.length + 1);
for (String key : keys) {
// Ignore properties with our prefix: we are not exporting those
if (!key.startsWith(ServiceProperties.PREFIX)) {
}
}
- return props;
+ props.put(AbstractAdaptedService.DELEGATE, service);
+ return new Dict(props);
}
@Override
public final class DynamicBindingAdapter {
private static final Logger LOG = LoggerFactory.getLogger(DynamicBindingAdapter.class);
- private List<AbstractAdaptingTracker<?, ?, ?>> trackers = ImmutableList.of();
+ private List<AdaptingTracker<?, ?>> trackers = ImmutableList.of();
@Reference
AdapterFactory factory = null;
ComponentFactory actionServiceFactory = null;
@Reference(target = "(component.factory=" + OSGiActionProviderService.FACTORY_NAME + ")")
ComponentFactory actionProviderServiceFactory = null;
+ @Reference(target = "(component.factory=" + OSGiDataBroker.FACTORY_NAME + ")")
+ ComponentFactory dataBrokerFactory = null;
+ @Reference(target = "(component.factory=" + OSGiDataTreeService.FACTORY_NAME + ")")
+ ComponentFactory dataTreeServiceFactory = null;
@Reference(target = "(component.factory=" + OSGiMountPointService.FACTORY_NAME + ")")
ComponentFactory mountPointServiceFactory = null;
@Reference(target = "(component.factory=" + OSGiNotificationService.FACTORY_NAME + ")")
@Activate
void activate(final BundleContext ctx) {
trackers = ImmutableList.of(
- new AdaptingTracker<>(ctx, DOMDataBroker.class, DataBroker.class, factory::createDataBroker),
- new AdaptingTracker<>(ctx, DOMDataTreeService.class, DataTreeService.class, factory::createDataTreeService),
- new AdaptingComponentTracker<>(ctx, DOMMountPointService.class, MountPointService.class,
+ new AdaptingTracker<>(ctx, DOMDataBroker.class, DataBroker.class, factory::createDataBroker,
+ dataBrokerFactory),
+ new AdaptingTracker<>(ctx, DOMDataTreeService.class, DataTreeService.class, factory::createDataTreeService,
+ dataTreeServiceFactory),
+ new AdaptingTracker<>(ctx, DOMMountPointService.class, MountPointService.class,
factory::createMountPointService, mountPointServiceFactory),
- new AdaptingComponentTracker<>(ctx, DOMNotificationService.class, NotificationService.class,
+ new AdaptingTracker<>(ctx, DOMNotificationService.class, NotificationService.class,
factory::createNotificationService, notificationServiceFactory),
- new AdaptingComponentTracker<>(ctx, DOMNotificationPublishService.class, NotificationPublishService.class,
+ new AdaptingTracker<>(ctx, DOMNotificationPublishService.class, NotificationPublishService.class,
factory::createNotificationPublishService, notificationPublishServiceFactory),
- new AdaptingComponentTracker<>(ctx, DOMRpcService.class, RpcConsumerRegistry.class,
+ new AdaptingTracker<>(ctx, DOMRpcService.class, RpcConsumerRegistry.class,
factory::createRpcConsumerRegistry, rpcConsumerRegistryFactory),
- new AdaptingComponentTracker<>(ctx, DOMRpcProviderService.class, RpcProviderService.class,
+ new AdaptingTracker<>(ctx, DOMRpcProviderService.class, RpcProviderService.class,
factory::createRpcProviderService, rpcProviderServiceFactory),
- new AdaptingComponentTracker<>(ctx, DOMActionService.class, ActionService.class,
- factory::createActionService, actionServiceFactory),
- new AdaptingComponentTracker<>(ctx, DOMActionProviderService.class, ActionProviderService.class,
- factory::createActionProviderService, actionProviderServiceFactory));
+ new AdaptingTracker<>(ctx, DOMActionService.class, ActionService.class, factory::createActionService,
+ actionServiceFactory),
+ new AdaptingTracker<>(ctx, DOMActionProviderService.class, ActionProviderService.class,
+ factory::createActionProviderService, actionProviderServiceFactory));
LOG.debug("Starting {} DOMService trackers", trackers.size());
trackers.forEach(ServiceTracker::open);
void deactivate() {
LOG.debug("Stopping {} DOMService trackers", trackers.size());
if (!trackers.isEmpty()) {
- trackers.forEach(AbstractAdaptingTracker::close);
+ trackers.forEach(AdaptingTracker::close);
LOG.info("{} DOMService trackers stopped", trackers.size());
}
trackers = ImmutableList.of();
--- /dev/null
+/*
+ * Copyright (c) 2020 PANTHEON.tech, 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;
+import java.util.Map;
+import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.mdsal.binding.api.DataBroker;
+import org.opendaylight.mdsal.binding.api.DataTreeChangeListener;
+import org.opendaylight.mdsal.binding.api.DataTreeIdentifier;
+import org.opendaylight.mdsal.binding.api.ReadTransaction;
+import org.opendaylight.mdsal.binding.api.ReadWriteTransaction;
+import org.opendaylight.mdsal.binding.api.TransactionChain;
+import org.opendaylight.mdsal.binding.api.TransactionChainListener;
+import org.opendaylight.mdsal.binding.api.WriteTransaction;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Deactivate;
+
+@Beta
+@Component(factory = OSGiDataBroker.FACTORY_NAME)
+public final class OSGiDataBroker extends AbstractAdaptedService<DataBroker> implements DataBroker {
+ // OSGi DS Component Factory name
+ static final String FACTORY_NAME = "org.opendaylight.mdsal.binding.dom.adapter.osgi.OSGiDataBroker";
+
+ public OSGiDataBroker() {
+ super(DataBroker.class);
+ }
+
+ @Override
+ public ReadTransaction newReadOnlyTransaction() {
+ return delegate().newReadOnlyTransaction();
+ }
+
+ @Override
+ public ReadWriteTransaction newReadWriteTransaction() {
+ return delegate().newReadWriteTransaction();
+ }
+
+ @Override
+ public WriteTransaction newWriteOnlyTransaction() {
+ return delegate().newWriteOnlyTransaction();
+ }
+
+ @Override
+ public <T extends DataObject, L extends DataTreeChangeListener<T>>
+ ListenerRegistration<L> registerDataTreeChangeListener(final DataTreeIdentifier<T> treeId,
+ final L listener) {
+ return delegate().registerDataTreeChangeListener(treeId, listener);
+ }
+
+ @Override
+ public TransactionChain createTransactionChain(@NonNull final TransactionChainListener listener) {
+ return delegate().createTransactionChain(listener);
+ }
+
+ @Override
+ public TransactionChain createMergingTransactionChain(final TransactionChainListener listener) {
+ return delegate().createMergingTransactionChain(listener);
+ }
+
+ @Activate
+ void activate(final Map<String, ?> properties) {
+ start(properties);
+ }
+
+ @Deactivate
+ void deactivate() {
+ stop();
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2020 PANTHEON.tech, 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;
+import java.util.Collection;
+import java.util.Map;
+import org.opendaylight.mdsal.binding.api.DataTreeIdentifier;
+import org.opendaylight.mdsal.binding.api.DataTreeListener;
+import org.opendaylight.mdsal.binding.api.DataTreeLoopException;
+import org.opendaylight.mdsal.binding.api.DataTreeProducer;
+import org.opendaylight.mdsal.binding.api.DataTreeService;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Deactivate;
+
+@Beta
+@Component(factory = OSGiDataTreeService.FACTORY_NAME)
+public final class OSGiDataTreeService extends AbstractAdaptedService<DataTreeService> implements DataTreeService {
+ // OSGi DS Component Factory name
+ static final String FACTORY_NAME = "org.opendaylight.mdsal.binding.dom.adapter.osgi.OSGiDataTreeService";
+
+ public OSGiDataTreeService() {
+ super(DataTreeService.class);
+ }
+
+ @Override
+ public DataTreeProducer createProducer(final Collection<DataTreeIdentifier<?>> subtrees) {
+ return delegate().createProducer(subtrees);
+ }
+
+ @Override
+ public <T extends DataTreeListener> ListenerRegistration<T> registerListener(final T listener,
+ final Collection<DataTreeIdentifier<?>> subtrees, final boolean allowRxMerges,
+ final Collection<DataTreeProducer> producers) throws DataTreeLoopException {
+ return delegate().registerListener(listener, subtrees, allowRxMerges, producers);
+ }
+
+ @Activate
+ void activate(final Map<String, ?> properties) {
+ start(properties);
+ }
+
+ @Deactivate
+ void deactivate() {
+ stop();
+ }
+}