Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions src/main/java/com/classes/clients/MemberFeignClient.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.classes.clients;

import com.classes.config.FeignConfig;
import com.classes.dtos.external.MemberInfoDTO;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

import java.util.UUID;

/**
* Cliente Feign para comunicarse con msvc-members
*
* NOTA: Si msvc-members no está corriendo, este cliente fallará con "Connection refused"
* Asegúrate de que msvc-members esté registrado en Eureka o corriendo en el puerto especificado
*/
@FeignClient(
name = "msvc-members", // Usa Eureka para descubrir el servicio
// url = "http://localhost:9098", // Comentado: usa Eureka en lugar de URL fija
configuration = FeignConfig.class
)
public interface MemberFeignClient {

/**
* Obtiene información completa de un miembro por su ID
* Incluye email desde msvc-security y membership activa
* @param memberId ID del miembro
* @return Información del miembro con email y membership
*/
@GetMapping("/member/{memberId}/info")
MemberInfoDTO getMemberInfo(@PathVariable("memberId") UUID memberId);
}
37 changes: 37 additions & 0 deletions src/main/java/com/classes/config/FeignClientInterceptor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.classes.config;

import feign.RequestInterceptor;
import feign.RequestTemplate;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
import org.springframework.stereotype.Component;

/**
* Interceptor para agregar el token JWT a las peticiones de Feign
* Propaga el token de autenticación del usuario actual a los microservicios
*/
@Component
@Slf4j
public class FeignClientInterceptor implements RequestInterceptor {

@Override
public void apply(RequestTemplate template) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

if (authentication instanceof JwtAuthenticationToken jwtAuth) {
Jwt jwt = jwtAuth.getToken();
String token = jwt.getTokenValue();

log.debug("🔐 Agregando token JWT a la petición Feign: {}",
template.method() + " " + template.url());

template.header("Authorization", "Bearer " + token);
} else {
log.warn("⚠️ No hay token JWT disponible para la petición Feign: {}",
template.method() + " " + template.url());
}
}
}
36 changes: 36 additions & 0 deletions src/main/java/com/classes/config/FeignConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.classes.config;

import feign.Logger;
import feign.RequestInterceptor;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
* Configuración para OpenFeign
* Incluye logging y propagación de tokens JWT
*/
@Configuration
@RequiredArgsConstructor
public class FeignConfig {

private final FeignClientInterceptor feignClientInterceptor;

/**
* Configura el nivel de logging de Feign
* BASIC: Log solo método, URL, código de respuesta y tiempo de ejecución
* FULL: Log completo de requests y responses
*/
@Bean
Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}

/**
* Registra el interceptor para propagar tokens JWT
*/
@Bean
public RequestInterceptor requestInterceptor() {
return feignClientInterceptor;
}
}
3 changes: 1 addition & 2 deletions src/main/java/com/classes/dtos/external/MemberInfoDTO.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@
@NoArgsConstructor
@Builder
public class MemberInfoDTO {
@JsonProperty("userId") // msvc-members usa "userId"
private UUID id;
private UUID userId;

private String firstName;
private String lastName;
Expand Down
29 changes: 29 additions & 0 deletions src/main/java/com/classes/dtos/external/MembershipDTO.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.classes.dtos.external;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;

/**
* DTO para recibir información de la membresía desde msvc-members
* Mapea exactamente los campos que devuelve MembershipDto de msvc-members
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class MembershipDTO {
@JsonProperty("planName")
private String type; // Mapea planName a type para mantener compatibilidad

private String status; // "ACTIVE", "EXPIRED", "CANCELLED", "SUSPENDED"
private LocalDateTime startDate;
private LocalDateTime endDate;
private Integer daysRemaining;
private boolean isActive;
private boolean isExpired;
}
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ public List<CalendarClassDTO> getUpcomingClasses() {

private StudentInClassDTO buildStudentDTO(ClassReservation reservation, List<MemberInfoDTO> membersInfo) {
MemberInfoDTO memberInfo = membersInfo.stream()
.filter(m -> m.getId().equals(reservation.getMemberId()))
.filter(m -> m.getUserId().equals(reservation.getMemberId()))
.findFirst()
.orElse(createDefaultMemberInfo(reservation.getMemberId()));

Expand Down Expand Up @@ -181,7 +181,7 @@ private String determineAction(ClassEntity classEntity, int currentStudents) {

private MemberInfoDTO createDefaultMemberInfo(UUID memberId) {
return MemberInfoDTO.builder()
.id(memberId)
.userId(memberId)
.firstName("Usuario")
.lastName("Desconocido")
.email("no-disponible@email.com")
Expand Down
Loading