/* * Copyright (c) 2016, 2017 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(final Class serviceInterface, final 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(final 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 (final 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 final Class serviceInterface, @Nonnull final 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 final Class serviceInterface, @Nonnull final BundleContext context, @Nonnull final 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 (final InvalidSyntaxException e) { throw new IllegalArgumentException(String.format("Invalid OSGi filter %s", newFilter), e); } } @Override public void close() { tracker.close(); } }