test_class.declarator: events
test_class.modifier: private
test_class.original_string: private List<Object> events;
test_class.type: List<Object>
test_class.var_name: events
test_class.declarator: loc
test_class.modifier: private
test_class.original_string: private Location loc;
test_class.type: Location
test_class.var_name: loc
test_class.file: common/src/test/java/brooklyn/networking/AttributeMungerTest.java
test_class.identifier: AttributeMungerTest
test_class.superclass: extends BrooklynAppUnitTestSupport
test_case.body: @Test
      public void testTransformSensorStringReplacingWithPublicAddressAndPort() throws Exception {
          final AttributeSensor<String> TARGET_HOSTNAME = new BasicAttributeSensor<String>(String.class, "hostname");
          final AttributeSensor<String> OTHER_HOSTNAME = new BasicAttributeSensor<String>(String.class, "otherhostname");
          final AttributeSensor<Integer> TARGET_PORT = new BasicAttributeSensor<Integer>(Integer.class, "target.port");
          final AttributeSensor<String> ENDPOINT = new BasicAttributeSensor<String>(String.class, "endpoint");
          final AttributeSensor<String> PUBLIC_ENDPOINT = new BasicAttributeSensor<String>(String.class, "publicEndpoint");
  
          AttributeMunger munger = new AttributeMunger(app);
  
          munger.transformSensorStringReplacingWithPublicAddressAndPort(
                  new EntityAndAttribute<String>(app, ENDPOINT),
                  Optional.of(new EntityAndAttribute<Integer>(app, TARGET_PORT)),
                  ImmutableList.of(TARGET_HOSTNAME, OTHER_HOSTNAME),
                  new EntityAndAttribute<String>(app, PUBLIC_ENDPOINT));
  
          app.sensors().set(TARGET_HOSTNAME, "myprivatehostname");
          app.sensors().set(TARGET_PORT, 1234);
          app.sensors().set(ENDPOINT, "PREFIX://myprivatehostname:1234/POSTFIX");
          app.sensors().set(PUBLIC_ENDPOINT, "mypublichostname:5678");
  
          EntityAsserts.assertAttributeEqualsEventually(app, ENDPOINT, "PREFIX://mypublichostname:5678/POSTFIX");
      }
test_case.class_method_signature: AttributeMungerTest.testTransformSensorStringReplacingWithPublicAddressAndPort()
test_case.full_signature: @Test public void testTransformSensorStringReplacingWithPublicAddressAndPort()
test_case.identifier: testTransformSensorStringReplacingWithPublicAddressAndPort
test_case.invocations: transformSensorStringReplacingWithPublicAddressAndPort of of set sensors set sensors set sensors set sensors assertAttributeEqualsEventually
test_case.modifiers: @Test public
test_case.parameters: ()
test_case.return: void
test_case.signature: void testTransformSensorStringReplacingWithPublicAddressAndPort()
focal_class.declarator: log = LoggerFactory.getLogger(AttributeMunger.class)
focal_class.modifier: private static final
focal_class.original_string: private static final Logger log = LoggerFactory.getLogger(AttributeMunger.class);
focal_class.type: Logger
focal_class.var_name: log
focal_class.declarator: adjunctEntity
focal_class.modifier: private final
focal_class.original_string: private final Entity adjunctEntity;
focal_class.type: Entity
focal_class.var_name: adjunctEntity
focal_class.file: common/src/main/java/brooklyn/networking/AttributeMunger.java
focal_class.identifier: AttributeMunger
focal_class.class_method_signature: AttributeMunger.AttributeMunger(Entity adjunctEntity)
focal_class.full_signature: public  AttributeMunger(Entity adjunctEntity)
focal_class.identifier: AttributeMunger
focal_class.modifiers: public
focal_class.parameters: (Entity adjunctEntity)
focal_class.signature:  AttributeMunger(Entity adjunctEntity)
focal_class.class_method_signature: AttributeMunger.transformSensorStringReplacingWithPublicAddressAndPort(
              final EntityAndAttribute<String> targetToUpdate,
              final Optional<EntityAndAttribute<Integer>> optionalTargetPort,
              final Iterable<? extends AttributeSensor<String>> targetsToMatch,
              final EntityAndAttribute<String> replacementSource)
focal_class.full_signature: public void transformSensorStringReplacingWithPublicAddressAndPort(
              final EntityAndAttribute<String> targetToUpdate,
              final Optional<EntityAndAttribute<Integer>> optionalTargetPort,
              final Iterable<? extends AttributeSensor<String>> targetsToMatch,
              final EntityAndAttribute<String> replacementSource)
focal_class.identifier: transformSensorStringReplacingWithPublicAddressAndPort
focal_class.modifiers: public
focal_class.parameters: (
              final EntityAndAttribute<String> targetToUpdate,
              final Optional<EntityAndAttribute<Integer>> optionalTargetPort,
              final Iterable<? extends AttributeSensor<String>> targetsToMatch,
              final EntityAndAttribute<String> replacementSource)
focal_class.return: void
focal_class.signature: void transformSensorStringReplacingWithPublicAddressAndPort(
              final EntityAndAttribute<String> targetToUpdate,
              final Optional<EntityAndAttribute<Integer>> optionalTargetPort,
              final Iterable<? extends AttributeSensor<String>> targetsToMatch,
              final EntityAndAttribute<String> replacementSource)
focal_class.class_method_signature: AttributeMunger.replaceIfNotNull(String string, String searchFor, String replaceWith)
focal_class.full_signature: public static String replaceIfNotNull(String string, String searchFor, String replaceWith)
focal_class.identifier: replaceIfNotNull
focal_class.modifiers: public static
focal_class.parameters: (String string, String searchFor, String replaceWith)
focal_class.return: String
focal_class.signature: String replaceIfNotNull(String string, String searchFor, String replaceWith)
focal_class.class_method_signature: AttributeMunger.setAttributeIfChanged(EntityAndAttribute<T> entityAndAttribute, T val)
focal_class.full_signature: public static void setAttributeIfChanged(EntityAndAttribute<T> entityAndAttribute, T val)
focal_class.identifier: setAttributeIfChanged
focal_class.modifiers: public static
focal_class.parameters: (EntityAndAttribute<T> entityAndAttribute, T val)
focal_class.return: void
focal_class.signature: void setAttributeIfChanged(EntityAndAttribute<T> entityAndAttribute, T val)
focal_class.class_method_signature: AttributeMunger.setAttributeIfChanged(Entity entity, AttributeSensor<T> attribute, T val)
focal_class.full_signature: public static void setAttributeIfChanged(Entity entity, AttributeSensor<T> attribute, T val)
focal_class.identifier: setAttributeIfChanged
focal_class.modifiers: public static
focal_class.parameters: (Entity entity, AttributeSensor<T> attribute, T val)
focal_class.return: void
focal_class.signature: void setAttributeIfChanged(Entity entity, AttributeSensor<T> attribute, T val)
focal_class.class_method_signature: AttributeMunger.subscribe(Entity target, AttributeSensor<T> sensor, SensorEventListener<? super T> listener)
focal_class.full_signature: private void subscribe(Entity target, AttributeSensor<T> sensor, SensorEventListener<? super T> listener)
focal_class.identifier: subscribe
focal_class.modifiers: private
focal_class.parameters: (Entity target, AttributeSensor<T> sensor, SensorEventListener<? super T> listener)
focal_class.return: void
focal_class.signature: void subscribe(Entity target, AttributeSensor<T> sensor, SensorEventListener<? super T> listener)
focal_method.body: public void transformSensorStringReplacingWithPublicAddressAndPort(
              final EntityAndAttribute<String> targetToUpdate,
              final Optional<EntityAndAttribute<Integer>> optionalTargetPort,
              final Iterable<? extends AttributeSensor<String>> targetsToMatch,
              final EntityAndAttribute<String> replacementSource) {
          SensorPropagaterWithReplacement mapper = new SensorPropagaterWithReplacement(targetToUpdate, false, new Function<String,String>() {
              @Override
              public String apply(String sensorVal) {
                  if (sensorVal==null) return null;
                  String input = targetToUpdate.get();
                  String replacementText = replacementSource.get();
                  log.debug("sensor mapper transforming address in "+targetToUpdate+", with "+replacementText+" (old value is "+input+")");
                  String suffix = "";
                  if (optionalTargetPort.isPresent()) {
                      Integer port = optionalTargetPort.get().get();
                      if (port==null) {
                          log.warn("no map-from port available for sensor mapper replacing addresses in "+targetToUpdate+
                                  " (listening on "+optionalTargetPort+")");
                          return input;
                      }
                      suffix = ":"+port;
                  }
                  Map<AttributeSensor<String>, String> targetValsToMatch = Maps.newLinkedHashMap();
                  for (AttributeSensor<String> targetToMatch : targetsToMatch) {
                      targetValsToMatch.put(targetToMatch, targetToUpdate.getEntity().getAttribute(targetToMatch));
                  }
                  String output = input;
                  for (String targetValToMatch : targetValsToMatch.values()) {
                      output = replaceIfNotNull(output, targetValToMatch+suffix, replacementText);
                  }
  
                  log.debug("sensor mapper transforming address in "+targetToUpdate+": "+
                          "input="+input+"; output="+output+"; suffix="+suffix+
                          "; replacementSource="+replacementSource+
                          "; replacementText="+replacementText+
                          "; targetValsToMatch="+targetValsToMatch);
                  return output;
              }
          });
  
          // TODO Should we subscribe to each of targetsToMatch?
          // And should we subscribe to optionalTargetPort?
          for (AttributeSensor<String> targetToMatch : targetsToMatch) {
              subscribe(targetToUpdate.getEntity(), targetToMatch, mapper);
          }
          subscribe(targetToUpdate.getEntity(), targetToUpdate.getAttribute(), mapper);
          subscribe(replacementSource.getEntity(), replacementSource.getAttribute(), mapper);
          // assume hostname and port are set before the above subscription
          String newval = mapper.apply(targetToUpdate.get());
          if (newval != null) {
              setAttributeIfChanged(targetToUpdate, newval);
          }
      }
focal_method.class_method_signature: AttributeMunger.transformSensorStringReplacingWithPublicAddressAndPort(
              final EntityAndAttribute<String> targetToUpdate,
              final Optional<EntityAndAttribute<Integer>> optionalTargetPort,
              final Iterable<? extends AttributeSensor<String>> targetsToMatch,
              final EntityAndAttribute<String> replacementSource)
focal_method.full_signature: public void transformSensorStringReplacingWithPublicAddressAndPort(
              final EntityAndAttribute<String> targetToUpdate,
              final Optional<EntityAndAttribute<Integer>> optionalTargetPort,
              final Iterable<? extends AttributeSensor<String>> targetsToMatch,
              final EntityAndAttribute<String> replacementSource)
focal_method.identifier: transformSensorStringReplacingWithPublicAddressAndPort
focal_method.invocations: get get debug isPresent get get warn newLinkedHashMap put getAttribute getEntity values replaceIfNotNull debug subscribe getEntity subscribe getEntity getAttribute subscribe getEntity getAttribute apply get setAttributeIfChanged
focal_method.modifiers: public
focal_method.parameters: (
              final EntityAndAttribute<String> targetToUpdate,
              final Optional<EntityAndAttribute<Integer>> optionalTargetPort,
              final Iterable<? extends AttributeSensor<String>> targetsToMatch,
              final EntityAndAttribute<String> replacementSource)
focal_method.return: void
focal_method.signature: void transformSensorStringReplacingWithPublicAddressAndPort(
              final EntityAndAttribute<String> targetToUpdate,
              final Optional<EntityAndAttribute<Integer>> optionalTargetPort,
              final Iterable<? extends AttributeSensor<String>> targetsToMatch,
              final EntityAndAttribute<String> replacementSource)