Repository: corona-warn-app/cwa-server
File: services/distribution/src/main/java/app/coronawarn/server/services/distribution/dgc/client/ProdDigitalCovidCertificateClient.java (Java)

Code before:
  @Override
  public List<ValueSetMetadata> getValueSets() throws FetchValueSetsException {
    return getResponseAndTreatExceptions(digitalCovidCertificateClient::getValueSets,
        "value sets",
        FetchValueSetsException::new);
  }

  @Override
  public ValueSet getValueSet(String hash) throws FetchValueSetsException {
    return getResponseAndTreatExceptions(
        () -> digitalCovidCertificateClient.getValueSet(hash),
        "value set",
        FetchValueSetsException::new);
  }

  @Override
  public List<BusinessRuleItem> getRules() throws FetchBusinessRulesException {
    return getResponseAndTreatExceptions(digitalCovidCertificateClient::getRules,
        "business rules",
        FetchBusinessRulesException::new);
  }

  @Override
  public List<BusinessRuleItem> getBnRules() throws FetchBusinessRulesException {
    return getResponseAndTreatExceptions(digitalCovidCertificateClient::getBnRules,
        "business rules",
        FetchBusinessRulesException::new);
  }

  @Override
  public BusinessRule getCountryRuleByHash(String country, String hash) throws FetchBusinessRulesException {
    return getResponseAndTreatExceptions(
        () -> digitalCovidCertificateClient.getCountryRule(country, hash),
        "country rule",
        FetchBusinessRulesException::new);
  }

  private <T, E extends ThirdPartyServiceException> T getResponseAndTreatExceptions(
      Supplier<ResponseEntity<T>> responseSupplier,
      String fetchEntityName,
      BiFunction<String, Exception, E> exceptionConverter)
      throws E {
    logger.debug("Get " + fetchEntityName + " from DCC");
    try {
      ResponseEntity<T> response = responseSupplier.get();

      if (response.getBody() == null) {
        throw exceptionConverter.apply("Response body for " + fetchEntityName + " is null",
            new NullPointerException());
      }


Review comment (bug):
the string argument here is used to log exceptions about failed calls. There are also another method using "business rules" entity name. Maybe would not be bad to specifically say here "booster" in order to differentiate the loggers between the two. 

Code after:
  @Override
  public List<ValueSetMetadata> getValueSets() throws FetchValueSetsException {
    return getResponseAndTreatExceptions(digitalCovidCertificateClient::getValueSets,
        "value sets",
        FetchValueSetsException::new);
  }

  @Override
  public ValueSet getValueSet(String hash) throws FetchValueSetsException {
    return getResponseAndTreatExceptions(
        () -> digitalCovidCertificateClient.getValueSet(hash),
        "value set",
        FetchValueSetsException::new);
  }

  @Override
  public List<BusinessRuleItem> getRules() throws FetchBusinessRulesException {
    return getResponseAndTreatExceptions(digitalCovidCertificateClient::getRules,
        "business rules",
        FetchBusinessRulesException::new);
  }

  @Override
  public List<BusinessRuleItem> getBoosterNotificationRules() throws FetchBusinessRulesException {
    return getResponseAndTreatExceptions(digitalCovidCertificateClient::getBoosterNotificationRules,
        "booster notification business rules",
        FetchBusinessRulesException::new);
  }

  @Override
  public BusinessRule getCountryRuleByHash(String country, String hash) throws FetchBusinessRulesException {
    return getResponseAndTreatExceptions(
        () -> digitalCovidCertificateClient.getCountryRule(country, hash),
        "country rule",
        FetchBusinessRulesException::new);
  }

  private <T, E extends ThirdPartyServiceException> T getResponseAndTreatExceptions(
      Supplier<ResponseEntity<T>> responseSupplier,
      String fetchEntityName,
      BiFunction<String, Exception, E> exceptionConverter)
      throws E {
    logger.debug("Get " + fetchEntityName + " from DCC");
    try {
      ResponseEntity<T> response = responseSupplier.get();

      if (response.getBody() == null) {
        throw exceptionConverter.apply("Response body for " + fetchEntityName + " is null",
            new NullPointerException());
      }