1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.bremersee.dccon.service;
18
19 import java.util.ArrayList;
20 import java.util.Collections;
21 import java.util.HashSet;
22 import java.util.List;
23 import java.util.Optional;
24 import java.util.Set;
25 import java.util.regex.Pattern;
26 import java.util.stream.Collectors;
27 import javax.validation.constraints.NotNull;
28 import lombok.extern.slf4j.Slf4j;
29 import org.bremersee.comparator.ComparatorBuilder;
30 import org.bremersee.dccon.config.DomainControllerProperties;
31 import org.bremersee.dccon.model.DhcpLease;
32 import org.bremersee.dccon.model.DnsNode;
33 import org.bremersee.dccon.model.DnsZone;
34 import org.bremersee.dccon.model.UnknownFilter;
35 import org.bremersee.dccon.repository.DhcpRepository;
36 import org.bremersee.dccon.repository.DnsNodeRepository;
37 import org.bremersee.dccon.repository.DnsZoneRepository;
38 import org.bremersee.dccon.repository.MockRepository;
39 import org.bremersee.exception.ServiceException;
40 import org.springframework.stereotype.Component;
41 import org.springframework.util.StringUtils;
42
43
44
45
46
47
48 @Component("nameServerService")
49 @Slf4j
50 public class NameServerServiceImpl implements NameServerService {
51
52 private final DhcpRepository dhcpRepository;
53
54 private final DnsZoneRepository dnsZoneRepository;
55
56 private final DnsNodeRepository dnsNodeRepository;
57
58 private final DnsNodeComparator dnsNodeComparator;
59
60 private final DnsZoneComparator dnsZoneComparator;
61
62 private final Pattern patternMac;
63
64 private final Pattern patternIp4;
65
66
67
68
69
70
71
72
73
74 public NameServerServiceImpl(
75 final DomainControllerProperties properties,
76 final DhcpRepository dhcpRepository,
77 final DnsZoneRepository dnsZoneRepository,
78 final DnsNodeRepository dnsNodeRepository) {
79 this.dhcpRepository = dhcpRepository;
80 this.dnsZoneRepository = dnsZoneRepository;
81 this.dnsNodeRepository = dnsNodeRepository;
82
83 this.dnsNodeComparator = new DnsNodeComparator();
84 this.dnsZoneComparator = new DnsZoneComparator(this.dnsZoneRepository);
85
86 this.patternMac = Pattern.compile(properties.getMacRegex());
87 this.patternIp4 = Pattern.compile(properties.getIp4Regex());
88 }
89
90 @Override
91 public List<DnsNode> query(final String query, final UnknownFilter unknownFilter) {
92 log.info("msg=[Query dns nodes.] query=[{}] unknownFilter=[{}]", query, unknownFilter);
93 if (!StringUtils.hasText(query)) {
94 return Collections.emptyList();
95 }
96 final Set<String> ips = new HashSet<>();
97 if (patternMac.matcher(query.toUpperCase()).matches()) {
98 findIpByMac(query).ifPresent(ips::add);
99 } else if (patternIp4.matcher(query).matches()) {
100 ips.add(query);
101 }
102 if (!ips.isEmpty()) {
103 return dnsNodeRepository.findByIps(ips, unknownFilter);
104 }
105 return dnsNodeRepository.findByHostName(query, unknownFilter)
106 .map(Collections::singletonList)
107 .orElseGet(Collections::emptyList);
108 }
109
110 private Optional<String> findIpByMac(String mac) {
111 final String normalizedMac = mac.replace("-", ":").trim();
112 return dhcpRepository.findActiveByIp().values().stream()
113 .filter(dhcpLease -> normalizedMac.equalsIgnoreCase(dhcpLease.getMac()))
114 .map(DhcpLease::getIp)
115 .findFirst();
116 }
117
118 @Override
119 public List<DhcpLease> getDhcpLeases(final Boolean all, final String sort) {
120 final List<DhcpLease> leases;
121 if (Boolean.TRUE.equals(all)) {
122 leases = dhcpRepository.findAll();
123 } else {
124 leases = new ArrayList<>(dhcpRepository.findActiveByIp().values());
125 }
126 final String sortOrder = StringUtils.hasText(sort) ? sort : DhcpLease.SORT_ORDER_BEGIN_HOSTNAME;
127 leases.sort(ComparatorBuilder.builder()
128 .fromWellKnownText(sortOrder)
129 .build());
130 return leases;
131 }
132
133 @Override
134 public List<DnsZone> getDnsZones() {
135 return dnsZoneRepository.findAll()
136 .sorted(dnsZoneComparator)
137 .collect(Collectors.toList());
138 }
139
140 @Override
141 public DnsZone addDnsZone(DnsZone dnsZone) {
142 return dnsZoneRepository.save(dnsZone.getName());
143 }
144
145 @Override
146 public Boolean deleteDnsZone(String zoneName) {
147 final boolean success = dnsZoneRepository.delete(zoneName);
148 if (success && (dnsNodeRepository instanceof MockRepository)) {
149 dnsNodeRepository.deleteAll(zoneName);
150 }
151 return success;
152 }
153
154
155 @Override
156 public List<DnsNode> getDnsNodes(String zoneName, UnknownFilter unknownFilter, String query) {
157 if (!dnsZoneRepository.exists(zoneName)) {
158 throw ServiceException.notFoundWithErrorCode(
159 DnsZone.class.getSimpleName(),
160 zoneName,
161 "org.bremersee:dc-con-app:e7466445-059f-4089-b69a-89bf08a9af1c");
162 }
163 return dnsNodeRepository.findAll(zoneName, unknownFilter, query)
164 .sorted(dnsNodeComparator)
165 .collect(Collectors.toList());
166 }
167
168 @Override
169 public Optional<DnsNode> save(String zoneName, DnsNode dnsNode) {
170 if (!dnsZoneRepository.exists(zoneName)) {
171 throw ServiceException.notFound(DnsZone.class.getSimpleName(), zoneName);
172 }
173 return dnsNodeRepository.save(zoneName, dnsNode);
174 }
175
176 @Override
177 public Optional<DnsNode> getDnsNode(
178 String zoneName,
179 String nodeName,
180 UnknownFilter unknownFilter) {
181 if (!dnsZoneRepository.exists(zoneName)) {
182 throw ServiceException.notFoundWithErrorCode(
183 DnsZone.class.getSimpleName(),
184 zoneName,
185 "org.bremersee:dc-con-app:97333c5a-b7e7-46a4-9034-055675d4a604");
186 }
187 return dnsNodeRepository.findOne(zoneName, nodeName, unknownFilter);
188 }
189
190 @Override
191 public Boolean deleteDnsNode(@NotNull String zoneName, @NotNull String nodeName) {
192 if (!dnsZoneRepository.exists(zoneName)) {
193 throw ServiceException.notFoundWithErrorCode(
194 DnsZone.class.getSimpleName(),
195 zoneName,
196 "org.bremersee:dc-con-app:02b09711-952e-4c05-bcef-2d1ac949b330");
197 }
198 return dnsNodeRepository.delete(zoneName, nodeName);
199 }
200
201 @Override
202 public void deleteAllDnsNodes(@NotNull String zoneName) {
203 if (!dnsZoneRepository.exists(zoneName)) {
204 throw ServiceException.notFoundWithErrorCode(
205 DnsZone.class.getSimpleName(),
206 zoneName,
207 "org.bremersee:dc-con-app:4a24a3db-7d81-4542-ac1d-68e898fed494");
208 }
209 dnsNodeRepository.deleteAll(zoneName);
210 }
211
212 @Override
213 public void deleteAllDnsNodes(@NotNull String zoneName, List<String> nodeNames) {
214 if (!dnsZoneRepository.exists(zoneName)) {
215 throw ServiceException.notFoundWithErrorCode(
216 DnsZone.class.getSimpleName(),
217 zoneName,
218 "org.bremersee:dc-con-app:937cdb01-5c89-46be-aae4-747e360b903e");
219 }
220 dnsNodeRepository.deleteAll(zoneName, nodeNames);
221 }
222
223 }