Skip to content

Commit 3a3c170

Browse files
feat: custom metrics for user service
1 parent a8bb598 commit 3a3c170

File tree

2 files changed

+146
-0
lines changed

2 files changed

+146
-0
lines changed

server/user/src/main/java/meet_at_mensa/user/service/UserService.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@
2323
import org.slf4j.Logger;
2424
import org.slf4j.LoggerFactory;
2525

26+
// Add Micrometer imports for Prometheus metrics
27+
import io.micrometer.core.instrument.Counter;
28+
import io.micrometer.core.instrument.MeterRegistry;
29+
2630
@Service
2731
public class UserService {
2832

@@ -40,6 +44,16 @@ public class UserService {
4044
@Autowired
4145
IdentityRepository identityRepository;
4246

47+
// Prometheus metrics
48+
private final Counter usersCreatedCounter;
49+
50+
public UserService(MeterRegistry meterRegistry) {
51+
// Initialize custom metrics
52+
this.usersCreatedCounter = Counter.builder("users_created_total")
53+
.description("Total number of users created")
54+
.register(meterRegistry);
55+
}
56+
4357
/**
4458
* Searches the database for a user with id {userID}
4559
*
@@ -140,6 +154,7 @@ public User registerUser(UserNew userNew) {
140154
identityEntity = identityRepository.save(identityEntity);
141155
logger.info("User created successfully: {}", userEntity.getUserID());
142156
// throw Exception if duplicate email
157+
usersCreatedCounter.increment(); // Increment the counter for user creation
143158
} catch (DataIntegrityViolationException e) {
144159
logger.error("User registration failed due to duplicate email: {}", userNew.getEmail());
145160
throw new UserConflictException(e.toString());
@@ -366,4 +381,13 @@ public Boolean isValidEmail(String email) {
366381
return email.matches(emailRegex);
367382
}
368383

384+
/**
385+
* Gets the current count of users created (for testing/debugging purposes)
386+
*
387+
* @return current count of users created
388+
*/
389+
public double getUsersCreatedCount() {
390+
return usersCreatedCounter.count();
391+
}
392+
369393
}
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
package meet_at_mensa.user.service;
2+
3+
import io.micrometer.core.instrument.MeterRegistry;
4+
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
5+
import org.junit.jupiter.api.BeforeEach;
6+
import org.junit.jupiter.api.Test;
7+
import org.junit.jupiter.api.extension.ExtendWith;
8+
import org.mockito.Mock;
9+
import org.mockito.junit.jupiter.MockitoExtension;
10+
import org.openapitools.model.UserNew;
11+
12+
import meet_at_mensa.user.repository.UserRepository;
13+
import meet_at_mensa.user.repository.InterestRepository;
14+
import meet_at_mensa.user.repository.IdentityRepository;
15+
import meet_at_mensa.user.exception.UserMalformedException;
16+
17+
import java.time.LocalDate;
18+
import java.util.Arrays;
19+
import java.util.ArrayList;
20+
import java.util.UUID;
21+
22+
import static org.junit.jupiter.api.Assertions.*;
23+
import static org.mockito.ArgumentMatchers.any;
24+
import static org.mockito.Mockito.when;
25+
26+
@ExtendWith(MockitoExtension.class)
27+
public class UserServiceMetricsTest {
28+
29+
@Mock
30+
private UserRepository userRepository;
31+
32+
@Mock
33+
private InterestRepository interestRepository;
34+
35+
@Mock
36+
private IdentityRepository identityRepository;
37+
38+
private MeterRegistry meterRegistry;
39+
private UserService userService;
40+
41+
@BeforeEach
42+
void setUp() {
43+
meterRegistry = new SimpleMeterRegistry();
44+
userService = new UserService(meterRegistry);
45+
46+
// Inject mocked repositories using reflection for testing
47+
try {
48+
java.lang.reflect.Field userRepoField = UserService.class.getDeclaredField("userRepository");
49+
userRepoField.setAccessible(true);
50+
userRepoField.set(userService, userRepository);
51+
52+
java.lang.reflect.Field interestRepoField = UserService.class.getDeclaredField("interestRepository");
53+
interestRepoField.setAccessible(true);
54+
interestRepoField.set(userService, interestRepository);
55+
56+
java.lang.reflect.Field identityRepoField = UserService.class.getDeclaredField("identityRepository");
57+
identityRepoField.setAccessible(true);
58+
identityRepoField.set(userService, identityRepository);
59+
} catch (Exception e) {
60+
throw new RuntimeException("Failed to inject mocked repositories", e);
61+
}
62+
}
63+
64+
@Test
65+
void testUsersCreatedCounterIncrements() {
66+
// Given
67+
UserNew userNew = createValidUserNew();
68+
meet_at_mensa.user.model.UserEntity mockUserEntity = createMockUserEntity();
69+
when(userRepository.save(any())).thenReturn(mockUserEntity);
70+
when(identityRepository.save(any())).thenReturn(createMockIdentityEntity());
71+
when(userRepository.findById(mockUserEntity.getUserID())).thenReturn(java.util.Optional.of(mockUserEntity));
72+
when(interestRepository.findByUserID(mockUserEntity.getUserID())).thenReturn(new ArrayList<>());
73+
74+
// When
75+
double initialCount = userService.getUsersCreatedCount();
76+
userService.registerUser(userNew);
77+
double finalCount = userService.getUsersCreatedCount();
78+
79+
// Then
80+
assertEquals(1.0, finalCount - initialCount, "User creation counter should increment by 1");
81+
}
82+
83+
84+
85+
@Test
86+
void testMetricsAreRegistered() {
87+
// Verify that the metrics are properly registered in the meter registry
88+
assertNotNull(meterRegistry.find("users_created_total").counter());
89+
}
90+
91+
private UserNew createValidUserNew() {
92+
UserNew userNew = new UserNew();
93+
userNew.setEmail("test@example.com");
94+
userNew.setFirstname("John");
95+
userNew.setLastname("Doe");
96+
userNew.setBirthday(LocalDate.of(1990, 1, 1));
97+
userNew.setGender("MALE");
98+
userNew.setDegree("Computer Science");
99+
userNew.setDegreeStart(2020);
100+
userNew.setBio("Test bio");
101+
userNew.setInterests(Arrays.asList("Programming", "Reading"));
102+
userNew.setAuthID("auth0|123456789");
103+
return userNew;
104+
}
105+
106+
private meet_at_mensa.user.model.UserEntity createMockUserEntity() {
107+
meet_at_mensa.user.model.UserEntity entity = new meet_at_mensa.user.model.UserEntity();
108+
// Set required fields using reflection since they might be final
109+
try {
110+
java.lang.reflect.Field idField = meet_at_mensa.user.model.UserEntity.class.getDeclaredField("userID");
111+
idField.setAccessible(true);
112+
idField.set(entity, UUID.randomUUID());
113+
} catch (Exception e) {
114+
throw new RuntimeException("Failed to set user ID", e);
115+
}
116+
return entity;
117+
}
118+
119+
private meet_at_mensa.user.model.IdentityEntity createMockIdentityEntity() {
120+
return new meet_at_mensa.user.model.IdentityEntity(UUID.randomUUID(), "auth0|123456789");
121+
}
122+
}

0 commit comments

Comments
 (0)