-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(network-api): 자신의 내부 아이피를 주기적으로 main-api에 저장하는 기능
- Loading branch information
1 parent
168323f
commit cd2e72c
Showing
6 changed files
with
167 additions
and
0 deletions.
There are no files selected for viewing
14 changes: 14 additions & 0 deletions
14
modules/network-api/src/main/java/com/whoz_in/network_api/config/RestTemplateConfig.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package com.whoz_in.network_api.config; | ||
|
||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.web.client.RestTemplate; | ||
|
||
@Configuration | ||
public class RestTemplateConfig { | ||
|
||
@Bean | ||
public RestTemplate restTemplate() { | ||
return new RestTemplate(); | ||
} | ||
} |
72 changes: 72 additions & 0 deletions
72
...les/network-api/src/main/java/com/whoz_in/network_api/private_ip/HttpPrivateIpWriter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
package com.whoz_in.network_api.private_ip; | ||
|
||
import com.fasterxml.jackson.core.JsonProcessingException; | ||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import java.util.Map; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.beans.factory.annotation.Value; | ||
import org.springframework.http.HttpEntity; | ||
import org.springframework.http.HttpHeaders; | ||
import org.springframework.http.HttpMethod; | ||
import org.springframework.stereotype.Component; | ||
import org.springframework.web.client.HttpClientErrorException; | ||
import org.springframework.web.client.ResourceAccessException; | ||
import org.springframework.web.client.RestTemplate; | ||
|
||
//http로 알리도록 구현 | ||
@Slf4j | ||
@Component | ||
public final class HttpPrivateIpWriter implements PrivateIpWriter { | ||
private final RestTemplate restTemplate; | ||
private final ObjectMapper objectMapper; | ||
private final String mainApiBaseUrl; | ||
private final String mainApiKey; | ||
|
||
public HttpPrivateIpWriter(RestTemplate restTemplate, ObjectMapper objectMapper, | ||
@Value("${main-api.base-url}") String mainApiBaseUrl, | ||
@Value("${main-api.api-key}") String mainApiKey) { | ||
this.restTemplate = restTemplate; | ||
this.objectMapper = objectMapper; | ||
this.mainApiBaseUrl = mainApiBaseUrl; | ||
this.mainApiKey = mainApiKey; | ||
} | ||
|
||
//TODO: 다른 요청도 하게 되면 공통 로직 묶기 | ||
@Override | ||
public boolean write(String room, Map<String, String> privateIps) { | ||
|
||
HttpHeaders headers = new HttpHeaders(); | ||
headers.set("Authorization", mainApiKey); | ||
headers.set("Content-Type", "application/json"); | ||
|
||
HttpEntity<String> requestEntity = new HttpEntity<>(createRequestBody(room, privateIps), headers); | ||
|
||
try { | ||
restTemplate.exchange( | ||
mainApiBaseUrl + "/api/v1/private-ip", | ||
HttpMethod.PUT, | ||
requestEntity, | ||
Void.class | ||
); | ||
return true; | ||
} catch (ResourceAccessException e){ | ||
log.error("main api에 접근할 수 없음 : {}", e.getMessage()); //서버가 꺼져있는지 확인 | ||
} catch (HttpClientErrorException.Forbidden e) { | ||
log.error("Api key 인증 실패 : {}", e.getMessage()); | ||
} catch (Exception e) { | ||
log.error("알 수 없는 예외 : {}", e.getMessage()); | ||
} | ||
return false; | ||
} | ||
|
||
private String createRequestBody(String room, Map<String, String> privateIps) { | ||
try { | ||
return objectMapper.writeValueAsString(Map.of( | ||
"room", room, | ||
"private_ip_list", privateIps | ||
)); | ||
} catch (JsonProcessingException e) { | ||
throw new RuntimeException("Failed to serialize request body", e); | ||
} | ||
} | ||
} |
43 changes: 43 additions & 0 deletions
43
modules/network-api/src/main/java/com/whoz_in/network_api/private_ip/PrivateIpUpdater.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package com.whoz_in.network_api.private_ip; | ||
|
||
import com.whoz_in.network_api.common.NetworkInterface; | ||
import com.whoz_in.network_api.config.NetworkConfig; | ||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.scheduling.annotation.Scheduled; | ||
import org.springframework.stereotype.Component; | ||
|
||
//주기적으로 자신의 내부 아이피를 알아내고 PrivateIpWriter를 이용하여 main-api에 저장 | ||
@Slf4j | ||
@Component | ||
@RequiredArgsConstructor | ||
public class PrivateIpUpdater { | ||
private Map<String, String> sent = Map.of(); | ||
private final NetworkConfig networkConfig; | ||
private final PrivateIpWriter writer; | ||
|
||
@Scheduled(fixedRate = 30000) | ||
private void update() { | ||
Map<String, String> privateIp = getPrivateIpPerSsid(); | ||
if (sent.equals(privateIp)) | ||
return; | ||
if (writer.write(networkConfig.getRoom(), privateIp)) { | ||
sent = privateIp; | ||
log.info("[private ip] updated"); | ||
} | ||
} | ||
|
||
private Map<String, String> getPrivateIpPerSsid(){ | ||
List<NetworkInterface> networkInterfaces = networkConfig.getManagedNIs(); | ||
//아이피를 얻지 못했을 경우 담지 않는다. | ||
Map<String, String> privateIps = new HashMap<>(); | ||
for (NetworkInterface ni : networkInterfaces) { | ||
SystemPrivateIpResolver.getIPv4(ni.getInterfaceName()) | ||
.ifPresent(ip->privateIps.put(ni.getAltSsid(), ip)); | ||
} | ||
return privateIps; | ||
} | ||
} |
9 changes: 9 additions & 0 deletions
9
modules/network-api/src/main/java/com/whoz_in/network_api/private_ip/PrivateIpWriter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package com.whoz_in.network_api.private_ip; | ||
|
||
import java.util.Map; | ||
|
||
//main-api에게 자신(network-api)이 가진 내부 아이피를 알리는 기능 | ||
public interface PrivateIpWriter { | ||
//반환 값은 성공 여부를 나타낸다. | ||
boolean write(String room, Map<String, String> privateIps); //Map<방, Optional<아이피>> | ||
} |
25 changes: 25 additions & 0 deletions
25
...network-api/src/main/java/com/whoz_in/network_api/private_ip/SystemPrivateIpResolver.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package com.whoz_in.network_api.private_ip; | ||
|
||
import java.net.InetAddress; | ||
import java.net.SocketException; | ||
import java.util.Collections; | ||
import java.util.Optional; | ||
import lombok.AccessLevel; | ||
import lombok.NoArgsConstructor; | ||
|
||
//내부 아이피를 알아내는 클래스 | ||
@NoArgsConstructor(access = AccessLevel.PRIVATE) | ||
public final class SystemPrivateIpResolver { | ||
public static Optional<String> getIPv4(String interfaceName) { | ||
try { | ||
return Collections.list(java.net.NetworkInterface.getNetworkInterfaces()).stream() | ||
.filter(networkInterface -> networkInterface.getName().equals(interfaceName)) | ||
.flatMap(networkInterface -> Collections.list(networkInterface.getInetAddresses()).stream()) | ||
.filter(address -> !address.isLoopbackAddress() && address instanceof java.net.Inet4Address) | ||
.map(InetAddress::getHostAddress) | ||
.findAny(); | ||
} catch (SocketException e) { | ||
throw new IllegalStateException("시스템에 네트워크 인터페이스가 아예 존재하지 않음"); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters