X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;ds=inline;f=opendaylight%2Fconfig%2Fconfig-api%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fconfig%2Fapi%2Fosgi%2FWaitingServiceTracker.java;fp=opendaylight%2Fconfig%2Fconfig-api%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fconfig%2Fapi%2Fosgi%2FWaitingServiceTracker.java;h=1549e6b26a4d715d70dbe31b1c4a1f9891fd9301;hb=dceb9db7853dabfbd4abdfb3d886a79871097831;hp=0000000000000000000000000000000000000000;hpb=2608b7032d0d019f5125704609eaaa0590c4598a;p=controller.git diff --git a/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/osgi/WaitingServiceTracker.java b/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/osgi/WaitingServiceTracker.java new file mode 100644 index 0000000000..1549e6b26a --- /dev/null +++ b/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/osgi/WaitingServiceTracker.java @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2016 Brocade Communications Systems, Inc. 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.controller.config.api.osgi; + +import java.util.concurrent.TimeUnit; +import javax.annotation.Nonnull; +import org.osgi.framework.BundleContext; +import org.osgi.framework.Constants; +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.util.tracker.ServiceTracker; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Tracker that waits for an OSGi service. + * + * @author Thomas Pantelis + */ +public final class WaitingServiceTracker implements AutoCloseable { + private static final Logger LOG = LoggerFactory.getLogger(WaitingServiceTracker.class); + public static final long FIVE_MINUTES = TimeUnit.MILLISECONDS.convert(5, TimeUnit.MINUTES); + + private final ServiceTracker tracker; + private final Class serviceInterface; + + private WaitingServiceTracker(Class serviceInterface, ServiceTracker tracker) { + this.tracker = tracker; + this.serviceInterface = serviceInterface; + } + + /** + * Waits for an OSGi services. + * + * @param timeoutInMillis the timeout in millis + * @return the service instance + * @throws ServiceNotFoundException if it times out or is interrupted + */ + @SuppressWarnings("unchecked") + public T waitForService(long timeoutInMillis) throws ServiceNotFoundException { + try { + T service = (T) tracker.waitForService(timeoutInMillis); + if(service == null) { + throw new ServiceNotFoundException(String.format("OSGi Service %s was not found after %d ms", + serviceInterface, timeoutInMillis)); + } + + return service; + } catch(InterruptedException e) { + throw new ServiceNotFoundException(String.format("Wait for OSGi service %s was interrrupted", + serviceInterface)); + } + } + + /** + * Creates an instance. + * + * @param serviceInterface the service interface + * @param context the BundleContext + * @return new WaitingServiceTracker instance + */ + public static WaitingServiceTracker create(@Nonnull Class serviceInterface, @Nonnull BundleContext context) { + ServiceTracker tracker = new ServiceTracker<>(context, serviceInterface, null); + tracker.open(); + return new WaitingServiceTracker(serviceInterface, tracker); + } + + /** + * Creates an instance. + * + * @param serviceInterface the service interface + * @param context the BundleContext + * @param filter the OSGi service filter + * @return new WaitingServiceTracker instance + */ + public static WaitingServiceTracker create(@Nonnull Class serviceInterface, @Nonnull BundleContext context, + @Nonnull String filter) { + String newFilter = String.format("(&(%s=%s)%s)", Constants.OBJECTCLASS, serviceInterface.getName(), filter); + try { + ServiceTracker tracker = new ServiceTracker<>(context, context.createFilter(newFilter), null); + tracker.open(); + return new WaitingServiceTracker(serviceInterface, tracker); + } catch(InvalidSyntaxException e) { + throw new IllegalArgumentException(String.format("Invalid OSGi filter %s", newFilter), e); + } + } + + @Override + public void close() { + try { + tracker.close(); + } catch(RuntimeException e) { + // The ServiceTracker could throw IllegalStateException if the BundleContext is already closed. + // This is benign so ignore it. + LOG.debug("Error closing ServiceTracker", e); + } + } +}