0

I have a restful API which has to be enabled or disabled based on the flag value which I would be fetching during application load. But I am unable enable/disable the API using @Conditional Annotation. I can achieve this by @ConditionOnProperty by setting an property in application.properties file. But, I need a dynamic value from DB to enable/disable the API.

Condition class looks like below

@Component
public class CheckCondition implements Condition {

  @Autowired
  private AppProperties appProp;
  
  @Override
  public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
    //Get the Flag value from DB which is fetched from AppProperties
    String value = appProp.getProperty(AppPropertiesEnum.ENABLE_LOGSTASH);
    boolean flag = false;
    if(value != null && value.equalsIgnoreCase("YES"))
      flag = true;
    return flag;
  }
}
Controller class which uses CheckCondition.

@RestController
@CrossOrigin
@Conditional(CheckCondition.class)
public class CheckController {

  private static final String URL_PUT_CHECKS        = "v1/core/checks";              // PUT
  
  @Autowired
  private ContextService serviceContext;
  @Autowired
  private CheckService serviceCheck;
  
  @RequestMapping(value=URL_PUT_CHECKS, method=RequestMethod.PUT)
  public void putLogstash(@RequestBody String jsonValue) {
    serviceCheck.storeValue(request, serviceContext.getAppNameVerified(request), jsonValue);
  }
}

AppProperties is also a component in which I am making a database call to fetch flag to set the condition. While application is loaded the CheckCondition class gets initiated first and the appProp will be null. Seems it is implementing condition interface spring boot doesnot load the postProcessor methods/beans. I tried using DependsOn and Order for this. I am not sure what am I missing.

Any suggestions appreciated. Thanks in advance.

Usha
  • 194
  • 1
  • 4
  • 17
  • You cannot autowire in a condition, also why write your own condition here, as it seems to be just a property, why not use the existing `ConditionalOnProperty`. – M. Deinum Feb 06 '23 at 15:12
  • @M.Deinum the value which I am trying will be loaded from database not a static value where I can store it in properties file. ConditionalOnProperty works fine when I read it from Application.properties file. – Usha Feb 06 '23 at 16:37
  • You could use [BeanPostProcessor](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/beans/factory/config/BeanPostProcessor.html) – bilak Feb 06 '23 at 17:49
  • No conditionalonproperty works for properties in the `Environment`. You could create a database driven property source (use an `EnvironmentPostProcessor` to set it up) and load the properties in a `PropertySource` (not to be confused with `@PropertySource`). – M. Deinum Feb 07 '23 at 07:50

1 Answers1

0

You can try like this way.

@RestController
public class TestController {

  @Autowired
  private CheckRepository checkRepository;

  @GetMapping("/test")
  public ResponseEntity<Object> getData() {
    boolean flag = checkRepository.findByName("value");
    if (!flag) {
      return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
    }

  }
}
Shalika
  • 1,457
  • 2
  • 19
  • 38
  • As of now I am using the above solution. In my case I need to disable the endpoint. End point itself should not be visible to the User – Usha Feb 07 '23 at 07:04