I have the following scenario:
I have a Springboot microservice that can gather a list of products from different providers (external SOAP web services). We currently get the information from 2 providers, for instance Amazon and EBay.
But in the future I can have more providers, so my application needs to be scalable.
Additionally, I can gather the information either from Amazon or Ebay as well as get the information from both services and if the list of providers increase, for instance, I can add AliExpress and I should be able to pick Amazon + AliExpress or Ebay + AliExpress or the three of them.
I created an interface:
public interface ProductsService {
List<Product> getProducts();
}
As well as the classes that implement this interface:
public class AmazonProductsService implements ProductService {
public List<Product> getProducts() {
// Logic to call SOAP Web Service for Amazon Products
}
}
public class EbayProductsService implements ProductService {
public List<Product> getProducts() {
// Logic to call SOAP Web Service for Ebay Products
}
}
So far, I managed to make them work, I have also some adapter classes that get the information from the services and adapt them to a POJO I defined.
The problem comes because I need to provide a mechanism to mock each of the different services. I mean, I need to have a mock for Amazon, for Ebay and for each provider my Springboot application would need to contact.
In another project I used Spring Profiles which was useful, because I was able to define a "mock" profile, but in that case I have only one service, in this case I have many of them implementing the same interface.
So far, what I tried was:
public class MockAmazonProductsService implements ProductsService {
public List<Product> getProducts() {
return new ArrayList<Product>();
}
}
I created its configuration as well:
@Configuration
@Profile("mockamazon")
public class MockAmazonProductsServiceAutoconfiguration {
@Bean
public ProductsService amazonProductsService() {
return new MockAmazonProductsService();
}
}
I did the same for the Ebay service (profile is "mockebay").
My question is, how can I can call the mock services when the profiles are set, for example:
spring.profiles.active=mockamazon
Before the requirement of the mock I had the following class:
@Service
public class ProductsServiceFactory {
@Autowired
@Qualifier("AmazonProductsService")
private ProductsService amazonProductsService;
@Autowired
@Qualifier("EbayProductsService")
private ProductsService ebayProductsService;
public List<ProductsService> getProductsService(String selectedServicesParameter) {
String[] selectedServices = selectedServicesParameter.split(",");
List<ProductsService> servicesList = new ArrayList<>();
for (String selectedService : selectedServices) {
if (selectedService.equals("AMAZON") {
servicesList.add(amazonProductsService);
} else if (selectedService.equals("EBAY") {
servicesList.add(ebayProductsService);
}
}
return servicesList;
}
}
But now, I am not sure how can I call the mock services. I thought of creating an additional Service Factory for mock services, but I can be in an scenario in which I would need to mock only one service and not all of them.
Any suggestion would be highly appreciated.
I can't say that my solution is perfect but it works.
You can create profiles for each of your cases and make config like that:
@Configuration
public class MockServiceAutoconfiguration {
@Profile({"mockAmazon", "mockAll", "mockAmazonAndEbay"})
@Bean
public ProductsService amazonProductsService() {
return new MockAmazonProductsService();
}
@Profile({"mockAliexpress", "mockAll"})
@Bean
public ProductsService aliexpressProductsService() {
return new MockAliexpressProductsService();
}
}