/**
  * Write a drop flow for the given ethertype at the given priority. If the ethertype is null, then
  * drop all traffic
  */
 public Flow dropFlow(Integer priority, Long etherType, Short tableId) {
   FlowId flowid;
   FlowBuilder flowb = base().setPriority(priority).setInstructions(FlowUtils.dropInstructions());
   if (etherType != null) {
     MatchBuilder mb =
         new MatchBuilder().setEthernetMatch(FlowUtils.ethernetMatch(null, null, etherType));
     Match match = mb.build();
     flowid = FlowIdUtils.newFlowId(tableId, "drop", match);
     flowb.setMatch(match);
   } else {
     flowid = FlowIdUtils.newFlowId("dropAll");
   }
   flowb.setId(flowid);
   return flowb.build();
 }
  BasicFlowletContext(
      Program program,
      final String flowletId,
      int instanceId,
      RunId runId,
      int instanceCount,
      Set<String> datasets,
      Arguments runtimeArguments,
      FlowletSpecification flowletSpec,
      MetricsCollectionService metricsCollectionService,
      DiscoveryServiceClient discoveryServiceClient,
      DatasetFramework dsFramework) {
    super(
        program,
        runId,
        runtimeArguments,
        datasets,
        getMetricCollector(metricsCollectionService, program, flowletId, runId.getId(), instanceId),
        dsFramework,
        discoveryServiceClient);
    this.namespaceId = program.getNamespaceId();
    this.flowId = program.getName();
    this.flowletId = flowletId;
    this.groupId = FlowUtils.generateConsumerGroupId(program, flowletId);
    this.instanceId = instanceId;
    this.instanceCount = instanceCount;
    this.flowletSpec = flowletSpec;
    this.userMetrics =
        new ProgramUserMetrics(
            getMetricCollector(
                metricsCollectionService, program, flowletId, runId.getId(), instanceId));
    // TODO - does this have to cache the metric collectors? Metrics framework itself has a cache
    // [CDAP-2334]
    this.queueMetrics =
        CacheBuilder.newBuilder()
            .expireAfterAccess(1, TimeUnit.HOURS)
            .build(
                new CacheLoader<String, MetricsContext>() {
                  @Override
                  public MetricsContext load(String key) throws Exception {
                    return getProgramMetrics()
                        .childContext(Constants.Metrics.Tag.FLOWLET_QUEUE, key);
                  }
                });

    this.producerMetrics =
        CacheBuilder.newBuilder()
            .expireAfterAccess(1, TimeUnit.HOURS)
            .build(
                new CacheLoader<ImmutablePair<String, String>, MetricsContext>() {
                  @Override
                  public MetricsContext load(ImmutablePair<String, String> key) throws Exception {
                    return getProgramMetrics()
                        .childContext(
                            ImmutableMap.of(
                                Constants.Metrics.Tag.PRODUCER, key.getFirst(),
                                Constants.Metrics.Tag.FLOWLET_QUEUE, key.getSecond(),
                                Constants.Metrics.Tag.CONSUMER,
                                    BasicFlowletContext.this.flowletId));
                  }
                });
  }