First of all, I want to mention that this post continues the previous one where we have added AOP to execute some additional logic on cucumber steps. My recommendation will be to read mentioned post. Let’s start…
About Spring Profile
From official documentation a profile has the following role:
Spring Profiles provide a way to segregate parts of your application configuration and make it only available in certain environments. Any @Component
or @Configuration
can be marked with @Profile
to limit when it is loaded:
@Configuration
@Profile("production")
public class ProductionConfiguration {
// ...
}
In the normal Spring way, you can use a spring.profiles.active
Environment
property to specify which profiles are active. You can specify the property in any of the usual ways, for example, you could include it in your application.properties
:
spring.profiles.active=dev,hsqldb
or specify on the command line using the switch --spring.profiles.active=dev,hsqldb
.
Adding additional logic in JoinPoint Processor
Let’s start adding additional logic in JoinPoint to process string and to return a generated value. Under the code that calculates the execution time of the step, we will add the following snippet.
Stream methodArgs = Stream.of(joinPoint.getArgs());
Object[] updatedArgs = methodArgs.map(this::getValueBaseOnPattern).toArray();
log.info("Proper value from property is {}", updatedArgs);
return joinPoint.proceed(updatedArgs);
Method getValueBaseOnPattern and his dependency we will create as private in our class.
private Object getValueBaseOnPattern(Object objectArg) {
Object result = objectArg;
if (Objects.nonNull(objectArg)) {
if (objectArg instanceof String) {
String stringArg = (String) objectArg;
if (stringArg.matches("^env\\(.*\\)")) {
result = getPropertyValue(StringUtils.substringBetween(stringArg, "\"", "\""));
}
}
}
return result;
}
private Object getPropertyValue(final String param) {
if (Objects.nonNull(param)) {
return environment.getProperty(param);
} else throw new RuntimeException("Method parameter is null");
}
Testing our results
To validate that we are getting proper property base on the spring profile we will create two properties files:
application-dev.yml
data:
users:
userName: DevUser
application-prod.yml
data:
users:
userName: ProdUser
Creating cucumber feature file:
Feature: Sending Property name from step and use value base on profile
@Run
Scenario: Prints value that is send in step argument
Given following property is printed env("data.users.userName")
With the following huge logic implementation:
@Given("following property is printed {}")
public void followingProperyIsPrinted(String property) {
soutAction.print(property);
}
And Depending on that spring profile we will set from the runner we expecting the corresponding value to be printed.
In moment then -Dspring.profiles.active=prod the printed value will be property from prod property file: ProdUser.
Full code example can be found under the following repo.