90 lines
3.0 KiB
Java
90 lines
3.0 KiB
Java
package ru.kirillius.pf.sdn.service;
|
|
|
|
import jakarta.annotation.PostConstruct;
|
|
import jakarta.annotation.PreDestroy;
|
|
import lombok.RequiredArgsConstructor;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import org.springframework.stereotype.Service;
|
|
import ru.kirillius.pf.sdn.Util.WorkerUtils;
|
|
import ru.kirillius.pf.sdn.api.Networking.DomainResolver;
|
|
|
|
import java.net.Inet4Address;
|
|
import java.time.Duration;
|
|
import java.util.List;
|
|
import java.util.concurrent.ExecutionException;
|
|
import java.util.concurrent.ExecutorService;
|
|
import java.util.concurrent.Future;
|
|
|
|
@Service
|
|
@RequiredArgsConstructor
|
|
@Slf4j
|
|
public class DomainUpdaterService {
|
|
private final DomainCacheService domainCacheService;
|
|
private final DomainResolver domainResolver;
|
|
private final ExecutorService executor;
|
|
private final SubscriptionService subscriptionService;
|
|
|
|
public List<Inet4Address> getActualAddresses(String domain) {
|
|
var cached = domainCacheService.load(domain, true);
|
|
if (!cached.isEmpty()) {
|
|
var resolved = domainResolver.getAddresses(domain);
|
|
while (!resolved.isDone() && !resolved.isCancelled()) {
|
|
Thread.yield();
|
|
}
|
|
if (resolved.isDone()) {
|
|
try {
|
|
domainCacheService.update(domain, resolved.get());
|
|
cached.addAll(resolved.get());
|
|
} catch (InterruptedException | ExecutionException e) {
|
|
throw new RuntimeException(e);
|
|
}
|
|
}
|
|
}
|
|
return cached;
|
|
}
|
|
|
|
private Future<?> worker;
|
|
private final RuntimeConfigService configService;
|
|
|
|
@PostConstruct
|
|
private void initialize() {
|
|
worker = executor.submit(() -> new WorkerUtils.LoopedWorker() {
|
|
@Override
|
|
protected void doWork() {
|
|
subscriptionService.getSubscriptions().forEach(subscription -> {
|
|
var scope = subscription.getScope();
|
|
if (scope.getResolveDomains().isEmpty()) {
|
|
return;
|
|
}
|
|
scope.getDomains().forEach(domain -> {
|
|
var future = domainResolver.getAddresses(domain);
|
|
while (!future.isDone() && !future.isCancelled()) {
|
|
Thread.yield();
|
|
}
|
|
|
|
if (future.isDone()) {
|
|
try {
|
|
domainCacheService.update(domain, future.get());
|
|
} catch (InterruptedException | ExecutionException e) {
|
|
log.error("Domain {} resolve failed", domain);
|
|
}
|
|
}
|
|
});
|
|
});
|
|
|
|
WorkerUtils.waitForTimer(() -> Duration.ofMinutes(configService.getConfig().getDomainResolveInterval()));
|
|
|
|
}
|
|
});
|
|
|
|
}
|
|
|
|
@PreDestroy
|
|
private void destroy() {
|
|
if (worker != null) {
|
|
worker.cancel(true);
|
|
worker = null;
|
|
}
|
|
}
|
|
}
|