I would like to create service which searching and returns objects from repositories, so: I created interface which has method:
public interface ShapeServicesInterface {
List<ShapeEntity> getAll();
String getName();
}
and few services which implements that interface:
@Service
@RequiredArgsConstructor
public class CircleEntityService implements ShapeServicesInterface {
private final CircleEntityRepository circleEntityRepository;
@Override
public List<ShapeEntity> getAll() {
return new ArrayList<>(circleEntityRepository.findAll());
}
@Override
public String getName() {
return "circle";
}
}
and second one:
@Service
@RequiredArgsConstructor
public class SquareEntityService implements ShapeServicesInterface {
private final SquareEntityRepository squareEntityRepository;
@Override
public List<ShapeEntity> getAll() {
return new ArrayList<>(squareEntityRepository.findAll());
}
@Override
public String getName() {
return "square";
}
}
and next in other service I would like to call that method for getting all entites from that repositories (entites extend abstract class ShapeEntity) - found solution like that:
@Service
@RequiredArgsConstructor
public class TestService {
private final ShapeServiceFacade facade;
private final ExecutorService executorService;
public List<ShapeEntity> getAll() throws ExecutionException, InterruptedException {
List<ShapeEntity> allShapes = new ArrayList<>();
List<Future<List<ShapeEntity>>> futures = new ArrayList<>();
for (ShapeServicesInterface shapeDownloader : facade.getServices()) {
futures.add(executorService.submit(new ShapeTask(shapeDownloader)));
}
for (Future<List<ShapeEntity>> future : futures) {
allShapes.addAll(future.get());
}
return allShapes;
}
ShapeTask is:
@RequiredArgsConstructor
private static class ShapeTask implements Callable<List<ShapeEntity>> {
private final ShapeServicesInterface servicesInterface;
@Override
public List<ShapeEntity> call() {
return servicesInterface.getAll();
}
}
Facade is:
@Service
public class ShapeServiceFacade {
private final Map<String, ShapeServicesInterface> shapeServices;
public ShapeServiceFacade(Set<ShapeServicesInterface> allServices) {
this.shapeServices = allServices.stream()
.collect(Collectors.toMap(ShapeServicesInterface::getName,Function.identity()));
}
public List<ShapeServicesInterface> getServices() {
return new ArrayList<>(shapeServices.values());
}
}
but it is a little complicated. Is there a easier way to call that methods? I would like to add more methods so I will have to implement another task and another method in service, and in interface. I care about searching in every repostiory.