예제 #1
0
 @Override
 public void reloadBundles(String[] bundleIdStrings) {
   for (String bundleIdString : bundleIdStrings) {
     long id;
     try {
       id = Long.parseLong(bundleIdString);
     } catch (NumberFormatException e) {
       log.error("Invalid bundle id: " + bundleIdString, e);
       continue;
     }
     List<Set<Long>> bundleIdLayers = Generic.list(bundles.dependentBundles(id));
     Collections.reverse(bundleIdLayers);
     for (Set<Long> bundleIds : bundleIdLayers) {
       for (long bundleId : bundleIds) {
         unmanage(bundleId);
       }
     }
     for (Set<Long> bundleIds : bundleIdLayers) {
       for (long bundleId : bundleIds) {
         try {
           bundles.reload(bundleId);
         } catch (UnknownBundleException e) {
           log.warn("Unknown bundle: " + id + " Exception: " + e.getMessage());
         } catch (Exception e) {
           log.error("Failed to reload " + id, e);
         }
       }
     }
   }
 }
예제 #2
0
 private Collection<ServiceStatus> serviceStatii(String type) {
   List<ServiceStatus> statii = Generic.list();
   for (Map.Entry<ModuleSpecification, ServiceStatus> entry : servicesStatus.entrySet()) {
     if (entry.getKey().getType().equals(type)) {
       statii.add(entry.getValue());
     }
   }
   return statii;
 }
예제 #3
0
 private static Iterable<ModuleSpecification> parseModuleSpecifications(String[] nameTypeArray) {
   List<ModuleSpecification> moduleSpecifications = Generic.list(nameTypeArray.length);
   for (String nameType : nameTypeArray) {
     if (nameType.contains(":")) {
       String[] nameAndType = nameType.split(":");
       moduleSpecifications.add(ModuleSpecification.create(nameAndType[1], nameAndType[0]));
     } else {
       moduleSpecifications.add(ModuleSpecification.create(nameType, nameType));
     }
   }
   return moduleSpecifications;
 }
예제 #4
0
@Module(moduleType = "httpwhiteboard", launch = @AutoLaunch(name = "httpwhiteboard"))
public class HttpWhiteboardModule {

  private final Collection<HttpService> httpServices = Generic.list();

  private final Map<String, ServletRegistration> servlets = Generic.linkedHashMap();

  private final Map<Servlet, String> aliasedServlets = Generic.linkedHashMap();

  @Inject(required = false)
  public void addHttpService(HttpService service) {
    store(service);
    add(service);
  }

  @Retract
  public void removeHttpService(HttpService service) {
    if (clearedService(service)) {
      remove(service);
    }
  }

  @Inject(required = false)
  public void addServlet(Servlet servlet, ServiceProperties<Servlet> properties) {
    ServletRegistration registration = new ServletRegistration(servlet, properties);
    String alias = availableAlias(registration);
    storeAlias(servlet, registration, alias);
    add(registration);
  }

  @Retract
  public void removeServlet(Servlet servlet) {
    String alias = clearedAlias(servlet);
    if (alias == null) {
      log.info(this + " was asked to remove unknown servlet " + servlet);
    } else {
      remove(clearedRegistration(alias));
    }
  }

  private String availableAlias(ServletRegistration registration) {
    String alias = registration.getAlias();
    if (inUse(alias)) {
      throw new IllegalArgumentException(
          this + " could not add " + registration + ", alias already in use!");
    }
    return alias;
  }

  private boolean inUse(String alias) {
    return servlets.containsKey(alias);
  }

  private void storeAlias(Servlet servlet, ServletRegistration registration, String alias) {
    servlets.put(alias, registration);
    aliasedServlets.put(servlet, alias);
  }

  private ServletRegistration clearedRegistration(String alias) {
    return servlets.remove(alias);
  }

  private String clearedAlias(Servlet servlet) {
    return aliasedServlets.remove(servlet);
  }

  private boolean clearedService(HttpService service) {
    return httpServices.remove(service);
  }

  private void store(HttpService service) {
    httpServices.add(service);
  }

  private Iterable<ServletRegistration> servlets() {
    return servlets.values();
  }

  private void add(HttpService service) {
    for (ServletRegistration registration : servlets()) {
      registration.activateIn(service);
    }
  }

  private void remove(HttpService service) {
    for (ServletRegistration registration : servlets()) {
      registration.deactivateIn(service);
    }
  }

  private void add(ServletRegistration registration) {
    for (HttpService service : httpServices) {
      registration.activateIn(service);
    }
  }

  private void remove(ServletRegistration registration) {
    for (HttpService service : httpServices) {
      registration.deactivateIn(service);
    }
  }

  private static final Logger log = LoggerFactory.getLogger(HttpWhiteboardModule.class);

  @Override
  public String toString() {
    return ToString.of(
        this, "servlets", servlets.size(), "services", httpServices.size(), "aliases", servlets);
  }
}
예제 #5
0
class SystemEventsImpl implements SystemEvents {

  private final OperationQueuer queuer;

  private final Map<Long, BundleManager> bundleManagers = Generic.map();

  private final Map<String, BundleManager> typedBundleManagers = Generic.map();

  private final Map<ModuleSpecification, ServiceStatus> servicesStatus = Generic.map();

  private SystemEvents asynch;

  private final Bundles bundles;

  private final AtomicReference<Thread> shutdownThread = new AtomicReference();

  SystemEventsImpl(BundleContext bundleContext, Context context, OperationQueuer queuer) {
    this.queuer = queuer;
    this.bundles = new Bundles(bundleContext, context);
  }

  Bundles getBundles() {
    return bundles;
  }

  public void setAsynchYou(SystemEvents asynch) {
    Not.nil(asynch, "asynch reference");
    if (this.asynch != null) {
      throw new IllegalStateException(this + " already received asynch pointer to itself");
    }
    this.asynch = asynch;
    this.asynch.spool(bundles);
  }

  @Override
  public void moduleSpecificationAdded(ModuleSpecification moduleSpecification) {
    if (isShuttingDown()) {
      log.info(
          "Ignoring service specification add:"
              + moduleSpecification
              + ", shutdown initiated in "
              + shutdownThread()
              + "!");
    } else {
      store(moduleSpecification);
      launch(moduleSpecification);
    }
  }

  @Override
  public void moduleSpecificationRemoved(ModuleSpecification moduleSpecification) {
    disbandModuleSpecification(moduleSpecification);
  }

  @Override
  public void bundleSpecificationAdded(BundleSpecification bundleSpecification) {
    if (isShuttingDown()) {
      log.info(
          "Ignoring bundle add:"
              + bundleSpecification
              + ", shutdown initiated in "
              + shutdownThread()
              + "!");
    } else {
      log.info("Installing " + bundleSpecification);
      try {
        bundles.install(bundleSpecification);
      } catch (Exception e) {
        log.error(this + " failed to install " + bundleSpecification, e);
      }
    }
  }

  @Override
  public void bundleSpecificationRemoved(BundleSpecification bundleSpecification) {
    if (bundles.isHosting(bundleSpecification)) {
      Long bundleId = bundles.getBundleId(bundleSpecification);
      if (isManaged(bundleId)) {
        unmanage(bundleId);
      }
      bundles.uninstall(bundleSpecification);
    }
  }

  @Override
  public void spool(Iterable<Bundle> bundles) {
    for (Bundle bundle : bundles) {
      this.bundles.getBundle(bundle.getBundleId());
      if (bundle.getState() == Bundle.ACTIVE) {
        considerTracking(bundle);
      }
    }
  }

  @Override
  public void activated(Bundle bundle) {
    considerTracking(bundle);
  }

  @Override
  public void deactivated(Bundle bundle) {
    long bundleId = bundle.getBundleId();
    unmanage(bundleId);
    bundles.uninstall(bundleId);
  }

  @Override
  public void updated(ObjectManager objectManager) {
    log.info(this + " notified of state change in " + objectManager);
    if (objectManager.isLaunchable()) {
      objectManager.launch();
    }
  }

  @Override
  public void launchBundles(String[] strings) {
    Iterable<ModuleSpecification> serviceSpecifications = parseModuleSpecifications(strings);
    for (ModuleSpecification moduleSpecification : serviceSpecifications) {
      launch(moduleSpecification);
    }
  }

  @Override
  public void reloadBundles(String[] bundleIdStrings) {
    for (String bundleIdString : bundleIdStrings) {
      long id;
      try {
        id = Long.parseLong(bundleIdString);
      } catch (NumberFormatException e) {
        log.error("Invalid bundle id: " + bundleIdString, e);
        continue;
      }
      List<Set<Long>> bundleIdLayers = Generic.list(bundles.dependentBundles(id));
      Collections.reverse(bundleIdLayers);
      for (Set<Long> bundleIds : bundleIdLayers) {
        for (long bundleId : bundleIds) {
          unmanage(bundleId);
        }
      }
      for (Set<Long> bundleIds : bundleIdLayers) {
        for (long bundleId : bundleIds) {
          try {
            bundles.reload(bundleId);
          } catch (UnknownBundleException e) {
            log.warn("Unknown bundle: " + id + " Exception: " + e.getMessage());
          } catch (Exception e) {
            log.error("Failed to reload " + id, e);
          }
        }
      }
    }
  }

  void close() {
    if (setShutdownThread()) {
      closeBundleManagers();
      closeResources();
    } else {
      throw new IllegalStateException(
          this
              + " initiated shutdown in "
              + shutdownThread()
              + ", completeClose cannot be called in "
              + Thread.currentThread());
    }
  }

  private void closeResources() {
    bundles.close();
    queuer.synchUp();
    try {
      queuer.close();
    } catch (IOException e) {
      throw new IORuntimeException(this + " failed to close " + queuer, e);
    }
  }

  private void closeBundleManagers() {
    for (BundleManager bundleManager : bundleManagers()) {
      if (!bundleManager.isClosed()) {
        disbandBundleManager(bundleManager);
      }
    }
  }

  private boolean setShutdownThread() {
    return shutdownThread.compareAndSet(null, Thread.currentThread());
  }

  private Thread shutdownThread() {
    return shutdownThread.get();
  }

  private boolean isShuttingDown() {
    return shutdownThread() != null;
  }

  private void considerTracking(Bundle bundle) {
    BundleManager existing = bundleManagers.get(bundle.getBundleId());
    if (existing == null) {
      BundleManager bundleManager = BundleManager.manage(bundle, asynch, queuer);
      if (bundleManager != null) {
        storeBundleManager(bundle.getBundleId(), bundleManager);
        launchUnhostedModuleSpecifications(bundleManager);
        log.info(this + " tracks bundle " + bundle + ": " + bundleManager);
      }
    } else {
      log.info(this + " already tracking " + bundle + ": " + existing);
    }
  }

  private BundleManager bundleManager(ModuleSpecification moduleSpecification) {
    return typedBundleManagers.get(moduleSpecification.getType());
  }

  private void disbandModuleSpecification(ModuleSpecification moduleSpecification) {
    if (moduleSpecification != null) {
      BundleManager bundleManager = bundleManager(moduleSpecification);
      if (bundleManager != null && !bundleManager.isClosed()) {
        disbandModuleSpecification(bundleManager, moduleSpecification);
      }
    }
  }

  private void disbandBundleManager(BundleManager bundleManager) {
    for (String type : bundleManager) {
      for (ServiceStatus serviceStatus : serviceStatii(type)) {
        if (serviceStatus != null && serviceStatus.isHosted()) {
          disbandModuleSpecification(bundleManager, serviceStatus.getModuleSpecification());
        }
      }
    }
    bundleManager.close();
  }

  private Collection<ServiceStatus> serviceStatii(String type) {
    List<ServiceStatus> statii = Generic.list();
    for (Map.Entry<ModuleSpecification, ServiceStatus> entry : servicesStatus.entrySet()) {
      if (entry.getKey().getType().equals(type)) {
        statii.add(entry.getValue());
      }
    }
    return statii;
  }

  private void disbandModuleSpecification(
      BundleManager bundleManager, ModuleSpecification moduleSpecification) {
    try {
      bundleManager.disband(moduleSpecification);
    } finally {
      serviceStatus(moduleSpecification).becameUnhosted();
    }
  }

  private void launch(ModuleSpecification moduleSpecification) {
    BundleManager bundleManager = bundleManager(moduleSpecification);
    if (bundleManager == null) {
      log.info(
          this
              + " received "
              + moduleSpecification
              + ", no object manager factory for that type yet");
    } else if (bundleManager.isClosed()) {
      log.info(
          this
              + " received "
              + moduleSpecification
              + ", object manager factory closed: "
              + bundleManager);
    } else {
      launch(bundleManager, moduleSpecification);
    }
  }

  private void launch(BundleManager bundleManager, ModuleSpecification moduleSpecification) {
    try {
      ObjectManager objectManager = bundleManager.launch(moduleSpecification);
      serviceStatus(moduleSpecification).nowHostedBy(bundleManager);
      log.info(this + " launched " + moduleSpecification + " -> " + objectManager);
    } catch (RuntimeException e) {
      throw new ModuleSystemException(
          this + " failed to launch " + moduleSpecification + " from " + bundleManager, e);
    }
  }

  private Set<BundleManager> bundleManagers() {
    return Generic.set(bundleManagers.values());
  }

  private boolean isManaged(long bundleId) {
    return bundleManagers.containsKey(bundleId);
  }

  private Bundle unmanage(long bundleId) {
    if (isManaged(bundleId)) {
      BundleManager bundleManager = removeBundleManager(bundleId);
      if (bundleManager != null) {
        disbandBundleManager(bundleManager);
        bundleManager.close();
      }
      return bundleManager.getBundle();
    }
    return null;
  }

  private void launchUnhostedModuleSpecifications(BundleManager bundleManager) {
    for (String type : bundleManager) {
      for (ServiceStatus serviceStatus : serviceStatii(type)) {
        if (serviceStatus != null && !serviceStatus.isHosted()) {
          launch(bundleManager, serviceStatus.getModuleSpecification());
        }
      }
    }
  }

  private void storeBundleManager(long bundleId, BundleManager bundleManager) {
    for (String type : bundleManager) {
      BundleManager existing = typedBundleManagers.get(type);
      if (existing != null) {
        throw new ModuleSystemException(
            this
                + " already maps type '"
                + type
                + "' to "
                + existing
                + ", refusing to manage "
                + bundleManager);
      }
    }
    BundleManager existing = bundleManagers.get(bundleId);
    if (existing != null) {
      throw new ModuleSystemException(
          this
              + " already maps id "
              + bundleId
              + " to "
              + existing
              + ", refusing to manage "
              + bundleManager);
    }
    for (String type : bundleManager) {
      typedBundleManagers.put(type, bundleManager);
    }
    bundleManagers.put(bundleId, bundleManager);
  }

  private BundleManager removeBundleManager(long bundleId) {
    BundleManager bundleManager = bundleManagers.remove(bundleId);
    if (bundleManager == null) {
      log.warn(this + " tried to remove unknown bundle manager for bundle " + bundleId);
      return null;
    }
    for (String type : bundleManager) {
      typedBundleManagers.remove(type);
    }
    return bundleManager;
  }

  private void store(ModuleSpecification moduleSpecification) {
    ServiceStatus existing = servicesStatus.get(moduleSpecification);
    if (existing != null && existing.isHosted()) {
      throw new ModuleSystemException(
          this + " already hosts " + moduleSpecification + ": " + existing);
    }
    if (existing == null) {
      servicesStatus.put(moduleSpecification, new ServiceStatus(moduleSpecification));
    }
  }

  private ServiceStatus serviceStatus(ModuleSpecification moduleSpecification) {
    ServiceStatus existing = servicesStatus.get(moduleSpecification);
    if (existing != null) {
      return existing;
    }
    ServiceStatus serviceStatus = new ServiceStatus(moduleSpecification);
    this.servicesStatus.put(moduleSpecification, serviceStatus);
    return serviceStatus;
  }

  private static Iterable<ModuleSpecification> parseModuleSpecifications(String[] nameTypeArray) {
    List<ModuleSpecification> moduleSpecifications = Generic.list(nameTypeArray.length);
    for (String nameType : nameTypeArray) {
      if (nameType.contains(":")) {
        String[] nameAndType = nameType.split(":");
        moduleSpecifications.add(ModuleSpecification.create(nameAndType[1], nameAndType[0]));
      } else {
        moduleSpecifications.add(ModuleSpecification.create(nameType, nameType));
      }
    }
    return moduleSpecifications;
  }

  private static final Logger log = LoggerFactory.getLogger(SystemEventsImpl.class);

  @Override
  public String toString() {
    return ToString.of(this, "types", typedBundleManagers.keySet());
  }
}
예제 #6
0
 private Set<BundleManager> bundleManagers() {
   return Generic.set(bundleManagers.values());
 }