@Override
  public <T> Collection<Resource> getAllocatedResources(Resource parent, Class<T> cls) {
    checkNotNull(parent);
    checkNotNull(cls);
    checkArgument(parent instanceof DiscreteResource);

    Versioned<Set<Resource>> children = childMap.get((DiscreteResource) parent);
    if (children == null) {
      return ImmutableList.of();
    }

    Stream<DiscreteResource> discrete =
        children
            .value()
            .stream()
            .filter(x -> x.last().getClass().equals(cls))
            .filter(x -> x instanceof DiscreteResource)
            .map(x -> (DiscreteResource) x)
            .filter(discreteConsumers::containsKey);

    Stream<ContinuousResource> continuous =
        children
            .value()
            .stream()
            .filter(x -> x.id().equals(parent.id().child(cls)))
            .filter(x -> x instanceof ContinuousResource)
            .map(x -> (ContinuousResource) x)
            .filter(x -> continuousConsumers.containsKey(x.id()))
            .filter(x -> continuousConsumers.get(x.id()) != null)
            .filter(x -> !continuousConsumers.get(x.id()).value().allocations().isEmpty());

    return Stream.concat(discrete, continuous).collect(Collectors.toList());
  }
  @Override
  public Collection<Resource> getResources(ResourceConsumer consumer) {
    checkNotNull(consumer);

    // NOTE: getting all entries may become performance bottleneck
    // TODO: revisit for better backend data structure
    Stream<DiscreteResource> discreteStream =
        discreteConsumers
            .entrySet()
            .stream()
            .filter(x -> x.getValue().value().equals(consumer))
            .map(Map.Entry::getKey);

    Stream<ContinuousResource> continuousStream =
        continuousConsumers
            .values()
            .stream()
            .flatMap(
                x ->
                    x.value()
                        .allocations()
                        .stream()
                        .map(y -> Maps.immutableEntry(x.value().original(), y)))
            .filter(x -> x.getValue().consumer().equals(consumer))
            .map(x -> x.getKey());

    return Stream.concat(discreteStream, continuousStream).collect(Collectors.toList());
  }
  @Activate
  protected void activate() {
    Serializer serializer =
        Serializer.using(
            Arrays.asList(KryoNamespaces.API),
            Identifier.class,
            RegionId.class,
            Region.class,
            DefaultRegion.class,
            Region.Type.class);

    regionsRepo =
        storageService
            .<RegionId, Region>consistentMapBuilder()
            .withSerializer(serializer)
            .withName("onos-regions")
            .withRelaxedReadConsistency()
            .build();
    regionsRepo.addListener(listener);
    regionsById = regionsRepo.asJavaMap();

    membershipRepo =
        storageService
            .<RegionId, Set<DeviceId>>consistentMapBuilder()
            .withSerializer(serializer)
            .withName("onos-region-devices")
            .withRelaxedReadConsistency()
            .build();
    membershipRepo.addListener(membershipListener);
    regionDevices = membershipRepo.asJavaMap();
    log.info("Started");
  }
 @Deactivate
 protected void deactivate() {
   regionsRepo.removeListener(listener);
   membershipRepo.removeListener(membershipListener);
   regionsByDevice.clear();
   log.info("Stopped");
 }
  @Override
  public void addTunnelInfo(TunnelId tunnelId, ResourceConsumer tunnelConsumerId) {
    checkNotNull(tunnelId, TUNNEL_ID_NULL);
    checkNotNull(tunnelConsumerId, PCECC_TUNNEL_INFO_NULL);

    tunnelInfoMap.put(tunnelId, tunnelConsumerId);
  }
 @Override
 public Map<TunnelId, ResourceConsumer> getTunnelInfos() {
   return tunnelInfoMap
       .entrySet()
       .stream()
       .collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().value()));
 }
  private List<ResourceConsumer> getConsumers(DiscreteResource resource) {
    Versioned<ResourceConsumer> consumer = discreteConsumers.get(resource);
    if (consumer == null) {
      return ImmutableList.of();
    }

    return ImmutableList.of(consumer.value());
  }
  private boolean isAvailable(ContinuousResource resource) {
    Versioned<ContinuousResourceAllocation> allocation = continuousConsumers.get(resource.id());
    if (allocation == null) {
      // no allocation (=no consumer) full registered resources available
      return true;
    }

    return hasEnoughResource(allocation.value().original(), resource, allocation.value());
  }
  @Override
  public boolean removeTunnelInfo(TunnelId tunnelId) {
    checkNotNull(tunnelId, TUNNEL_ID_NULL);

    if (tunnelInfoMap.remove(tunnelId) == null) {
      log.error("Tunnel info deletion for tunnel id {} has failed.", tunnelId.toString());
      return false;
    }
    return true;
  }
 @Override
 public Region updateRegion(
     RegionId regionId, String name, Region.Type type, List<Set<NodeId>> masterNodeIds) {
   return regionsRepo
       .compute(
           regionId,
           (id, region) -> {
             nullIsNotFound(region, NO_REGION);
             return new DefaultRegion(regionId, name, type, masterNodeIds);
           })
       .value();
 }
 @Override
 public Region createRegion(
     RegionId regionId, String name, Region.Type type, List<Set<NodeId>> masterNodeIds) {
   return regionsRepo
       .compute(
           regionId,
           (id, region) -> {
             checkArgument(region == null, DUPLICATE_REGION);
             return new DefaultRegion(regionId, name, type, masterNodeIds);
           })
       .value();
 }
  private List<ResourceConsumer> getConsumers(ContinuousResource resource) {
    Versioned<ContinuousResourceAllocation> allocations = continuousConsumers.get(resource.id());
    if (allocations == null) {
      return ImmutableList.of();
    }

    return allocations
        .value()
        .allocations()
        .stream()
        .filter(x -> x.resource().equals(resource))
        .map(ResourceAllocation::consumer)
        .collect(GuavaCollectors.toImmutableList());
  }
  @Activate
  public void activate() {

    mcastRib =
        storageService
            .<McastRoute, MulticastData>consistentMapBuilder()
            .withName(MCASTRIB)
            .withSerializer(
                Serializer.using(
                    KryoNamespace.newBuilder()
                        .register(KryoNamespaces.API)
                        .register(
                            AtomicReference.class,
                            MulticastData.class,
                            McastRoute.class,
                            McastRoute.Type.class)
                        .build()))
            // .withRelaxedReadConsistency()
            .build();

    mcastRoutes = mcastRib.asJavaMap();

    log.info("Started");
  }
 @Override
 public ResourceConsumer getTunnelInfo(TunnelId tunnelId) {
   checkNotNull(tunnelId, TUNNEL_ID_NULL);
   return tunnelInfoMap.get(tunnelId) == null ? null : tunnelInfoMap.get(tunnelId).value();
 }
 @Override
 public int getTunnelInfoCount() {
   return tunnelInfoMap.size();
 }
 @Override
 public boolean existsTunnelInfo(TunnelId tunnelId) {
   checkNotNull(tunnelId, TUNNEL_ID_NULL);
   return tunnelInfoMap.containsKey(tunnelId);
 }
 @Override
 public void removeRegion(RegionId regionId) {
   membershipRepo.remove(regionId);
   regionsRepo.remove(regionId);
 }