Skip to content

Enrichers

Gal Koren edited this page Nov 12, 2020 · 1 revision

I assume you read the State Consumers chapter because an enricher is a state consumer.
An enricher can change the state of the command. It does so after PL has fetched all the required fields from the database but before the validation (because the validators needs to see the correct final state).

In this example, we implement an enricher that modifies the URL of the Ad entity by converting "http://" to "https://". It is always invoked, regardles whether the URL field is present in the command or not. Even if the command contains other fields, we shall still fetch the existing URL from the database and modify it. Of course you don't have to implement it this way. For example, you can write your own code, filtering only commands that contains the URL field.

class ConvertHttpToHttps implements PostFetchCommandEnricher<AdEntity> {

   @Override
   public SupportedChangeOperation getSupportedChangeOperation() {
       return UPDATE_CREATE;
   }

   @Override
   public Stream<? extends EntityField<?, ?>> getRequiredFields(Collection<? extends EntityField<AdEntity, ?>> fieldsToUpdate, ChangeOperation operator) {
       return Stream.of(URL);
   }

   // you MUST declare what you can possibly change
   @Override
   public Stream<EntityField<AdEntity, ?>> fieldsToEnrich() {
       return Stream.of(URL);
   }
   
   @Override
   public void enrich(
                 Collection<? extends ChangeEntityCommand<AdEntity>> commands, 
                 ChangeOperation op, 
                 ChangeContext ctx) {

       commands.forEach(cmd -> {
           String url = ctx.getFinalEntity(cmd).get(URL);

           if (url != null && url.startsWith("http://")) {
               cmd.set(URL, "https://" + url.substring(7));
           }});
   }
}

The enricher can then be added to the flow of the AdPersistence pretty much like we added validators.

private ChangeFlowConfig.Builder<AdEntity> flowBuilder() {
    return changeFlowConfigBuilder.newInstance(AdEntity.INSTANCE)
           .withValidator(buildChangesValidator(AdEntity.INSTANCE, asList(
                //
                // list of validators comes here
                //
                new HeadlineLengthValidator()
            )))
            .withPostFetchCommandEnricher(new ConvertHttpToHttps())
            ;
}