This is an automated email from the ASF dual-hosted git repository.

zqr10159 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hertzbeat.git


The following commit(s) were added to refs/heads/master by this push:
     new aafa8cc2e7 [fix] validate managed API tokens passed as query parameter 
(#4442)
aafa8cc2e7 is described below

commit aafa8cc2e717e20814686b848aea0c0350aa0b2a
Author: Duansg <[email protected]>
AuthorDate: Fri Oct 9 14:32:51 2026 +0800

    [fix] validate managed API tokens passed as query parameter (#4442)
---
 .../manager/config/ApiTokenValidationFilter.java   |  63 ++++--
 .../config/ApiTokenValidationFilterTest.java       | 235 ++++++++++++---------
 2 files changed, 191 insertions(+), 107 deletions(-)

diff --git 
a/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/config/ApiTokenValidationFilter.java
 
b/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/config/ApiTokenValidationFilter.java
index 4075d2e1d6..0da8c65197 100644
--- 
a/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/config/ApiTokenValidationFilter.java
+++ 
b/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/config/ApiTokenValidationFilter.java
@@ -19,15 +19,20 @@ package org.apache.hertzbeat.manager.config;
 
 import com.usthe.sureness.subject.PrincipalMap;
 import com.usthe.sureness.subject.SubjectSum;
+import com.usthe.sureness.util.JsonWebTokenUtil;
 import com.usthe.sureness.util.SurenessContextHolder;
+import io.jsonwebtoken.Claims;
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
 
 import java.io.IOException;
 import java.io.PrintWriter;
+import java.util.ArrayList;
 import java.util.Collections;
+import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import lombok.extern.slf4j.Slf4j;
 import org.apache.hertzbeat.collector.dispatch.DispatchConstants;
@@ -63,6 +68,8 @@ public class ApiTokenValidationFilter implements 
HandlerInterceptor {
 
     private static final String ROLES_CLAIM = "roles";
     private static final String TOKEN_VALIDATION_UNAVAILABLE = "Token 
validation unavailable";
+    private static final String TOKEN_NOT_RESOLVED = "Token could not be 
resolved";
+    private static final String TOKEN_PARAM = "token";
 
     private final AccountService accountService;
 
@@ -77,24 +84,54 @@ public class ApiTokenValidationFilter implements 
HandlerInterceptor {
         if (subject == null || !isManagedToken(subject)) {
             return true;
         }
-        String authorization = 
request.getHeader(NetworkConstants.AUTHORIZATION);
+        // Sureness reads a jwt from the Authorization header and from the 
token query parameter,
+        // so every managed token the request carries is validated, and a 
managed subject whose
+        // token cannot be found is rejected rather than let through unchecked
+        List<String> managedTokens = resolveManagedTokens(request);
+        if (managedTokens.isEmpty()) {
+            return writeError(response, HttpStatus.UNAUTHORIZED, 
TOKEN_NOT_RESOLVED);
+        }
+        try {
+            for (String token : managedTokens) {
+                String rejectReason = checkManagedToken(subject, token);
+                if (rejectReason != null) {
+                    return writeError(response, HttpStatus.UNAUTHORIZED, 
rejectReason);
+                }
+            }
+        } catch (RuntimeException e) {
+            log.warn("Managed token validation failed", e);
+            return writeError(response, HttpStatus.SERVICE_UNAVAILABLE, 
TOKEN_VALIDATION_UNAVAILABLE);
+        }
+        return true;
+    }
 
+    private List<String> resolveManagedTokens(HttpServletRequest request) {
+        Set<String> candidates = new LinkedHashSet<>(2);
+        String authorization = 
request.getHeader(NetworkConstants.AUTHORIZATION);
         if (authorization != null && 
authorization.startsWith(DispatchConstants.BEARER)) {
-            String token = 
authorization.substring(DispatchConstants.BEARER.length()).trim();
-            if (!token.isEmpty()) {
-                try {
-                    String rejectReason = checkManagedToken(subject, token);
-                    if (rejectReason != null) {
-                        return writeError(response, HttpStatus.UNAUTHORIZED, 
rejectReason);
-                    }
-                } catch (RuntimeException e) {
-                    log.warn("Managed token validation failed", e);
-                    return writeError(response, 
HttpStatus.SERVICE_UNAVAILABLE, TOKEN_VALIDATION_UNAVAILABLE);
-                }
+            // mirror Sureness JwtSubjectJakartaServletCreator exactly, so the 
validated token is the one it authenticated
+            candidates.add(authorization.replace(DispatchConstants.BEARER, 
"").trim());
+        }
+        String queryToken = request.getParameter(TOKEN_PARAM);
+        if (queryToken != null) {
+            candidates.add(queryToken.trim());
+        }
+        List<String> managedTokens = new ArrayList<>(candidates.size());
+        for (String candidate : candidates) {
+            if (!candidate.isEmpty() && isManagedJwt(candidate)) {
+                managedTokens.add(candidate);
             }
         }
+        return managedTokens;
+    }
 
-        return true;
+    private boolean isManagedJwt(String token) {
+        try {
+            Claims claims = JsonWebTokenUtil.parseJwt(token);
+            return 
Boolean.TRUE.equals(claims.get(AccountServiceImpl.CLAIM_MANAGED, 
Boolean.class));
+        } catch (Exception e) {
+            return false;
+        }
     }
 
     /**
diff --git 
a/hertzbeat-manager/src/test/java/org/apache/hertzbeat/manager/config/ApiTokenValidationFilterTest.java
 
b/hertzbeat-manager/src/test/java/org/apache/hertzbeat/manager/config/ApiTokenValidationFilterTest.java
index 36414d88f2..042d966725 100644
--- 
a/hertzbeat-manager/src/test/java/org/apache/hertzbeat/manager/config/ApiTokenValidationFilterTest.java
+++ 
b/hertzbeat-manager/src/test/java/org/apache/hertzbeat/manager/config/ApiTokenValidationFilterTest.java
@@ -17,27 +17,34 @@
 
 package org.apache.hertzbeat.manager.config;
 
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.mockStatic;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
-import static org.mockito.Mockito.mockStatic;
 
 import com.usthe.sureness.subject.PrincipalMap;
 import com.usthe.sureness.subject.SubjectSum;
+import com.usthe.sureness.util.JsonWebTokenUtil;
 import com.usthe.sureness.util.SurenessContextHolder;
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
 import java.io.PrintWriter;
 import java.io.StringWriter;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import org.apache.hertzbeat.common.constants.NetworkConstants;
 import org.apache.hertzbeat.manager.service.AccountService;
+import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.mockito.Mock;
+import org.mockito.MockedStatic;
 import org.mockito.junit.jupiter.MockitoExtension;
 
 /**
@@ -46,6 +53,12 @@ import org.mockito.junit.jupiter.MockitoExtension;
 @ExtendWith(MockitoExtension.class)
 class ApiTokenValidationFilterTest {
 
+    private static String managedToken;
+
+    private static String otherManagedToken;
+
+    private static String legacyToken;
+
     private ApiTokenValidationFilter filter;
 
     @Mock
@@ -60,141 +73,180 @@ class ApiTokenValidationFilterTest {
     @Mock
     private PrincipalMap principalMap;
 
+    @BeforeAll
+    static void issueTokens() {
+        
JsonWebTokenUtil.setDefaultSecretKey("dKhaX0csgOCTlCxq20yhmUea6H6JIpSE2Rwp"
+                + "CyaFv0bwq2Eik0jdrKUtsA6bx3sDJeFV643R"
+                + "LnfKefTjsIfJLBa2YkhEqEGtcHDTNe4CU6+9"
+                + "dKhaX0csgOCTlCxq20yhmUea6H6JIpSE2Rwp");
+        Map<String, Object> managedClaims = new HashMap<>(1);
+        managedClaims.put("managed", true);
+        managedToken = JsonWebTokenUtil.issueJwt("admin", 3600L, 
List.of("admin"), managedClaims);
+        otherManagedToken = JsonWebTokenUtil.issueJwt("admin", 7200L, 
List.of("admin"), managedClaims);
+        legacyToken = JsonWebTokenUtil.issueJwt("admin", 3600L, 
List.of("admin"), new HashMap<>(0));
+    }
+
     @BeforeEach
     void setUp() {
         filter = new ApiTokenValidationFilter(accountService);
     }
 
     @Test
-    void testNoAuthorizationHeaderPassesThrough() throws Exception {
+    void testManagedSubjectWithoutTokenRejected() throws Exception {
         
when(request.getHeader(NetworkConstants.AUTHORIZATION)).thenReturn(null);
+        mockErrorWriter();
         SubjectSum subject = mockManagedSubject();
 
-        try (var mockedStatic = mockStatic(SurenessContextHolder.class)) {
-            
mockedStatic.when(SurenessContextHolder::getBindSubject).thenReturn(subject);
-
-            
org.junit.jupiter.api.Assertions.assertTrue(filter.preHandle(request, response, 
new Object()));
-        }
+        assertFalse(preHandle(subject));
+        verify(response).setStatus(401);
+        verify(accountService, never()).checkTokenStatus(any());
     }
 
     @Test
-    void testNonBearerAuthorizationPassesThrough() throws Exception {
+    void testManagedSubjectWithNonBearerAuthorizationRejected() throws 
Exception {
         
when(request.getHeader(NetworkConstants.AUTHORIZATION)).thenReturn("Basic 
dXNlcjpwYXNz");
+        mockErrorWriter();
         SubjectSum subject = mockManagedSubject();
 
-        try (var mockedStatic = mockStatic(SurenessContextHolder.class)) {
-            
mockedStatic.when(SurenessContextHolder::getBindSubject).thenReturn(subject);
+        assertFalse(preHandle(subject));
+        verify(response).setStatus(401);
+    }
 
-            
org.junit.jupiter.api.Assertions.assertTrue(filter.preHandle(request, response, 
new Object()));
-        }
+    @Test
+    void testManagedSubjectWithEmptyBearerRejected() throws Exception {
+        
when(request.getHeader(NetworkConstants.AUTHORIZATION)).thenReturn("Bearer ");
+        mockErrorWriter();
+        SubjectSum subject = mockManagedSubject();
+
+        assertFalse(preHandle(subject));
+        verify(response).setStatus(401);
     }
 
     @Test
     void testLegacyTokenPassesThrough() throws Exception {
         SubjectSum subject = mockSubject();
 
-        try (var mockedStatic = mockStatic(SurenessContextHolder.class)) {
-            
mockedStatic.when(SurenessContextHolder::getBindSubject).thenReturn(subject);
-
-            
org.junit.jupiter.api.Assertions.assertTrue(filter.preHandle(request, response, 
new Object()));
-            verify(accountService, never()).checkTokenStatus(any());
-        }
+        assertTrue(preHandle(subject));
+        verify(accountService, never()).checkTokenStatus(any());
     }
 
     @Test
     void testManagedTokenActivePassesThrough() throws Exception {
-        String managedToken = "managed-token";
         
when(request.getHeader(NetworkConstants.AUTHORIZATION)).thenReturn("Bearer " + 
managedToken);
         when(accountService.checkTokenStatus(managedToken)).thenReturn(null);
         when(accountService.checkManagedTokenAccess("admin", 
List.of("admin"))).thenReturn(null);
         doNothing().when(accountService).touchTokenLastUsedTime(managedToken);
         SubjectSum subject = mockManagedSubjectWithClaims();
 
-        try (var mockedStatic = mockStatic(SurenessContextHolder.class)) {
-            
mockedStatic.when(SurenessContextHolder::getBindSubject).thenReturn(subject);
-
-            
org.junit.jupiter.api.Assertions.assertTrue(filter.preHandle(request, response, 
new Object()));
-            verify(accountService).checkTokenStatus(managedToken);
-            verify(accountService).checkManagedTokenAccess("admin", 
List.of("admin"));
-            verify(accountService).touchTokenLastUsedTime(managedToken);
-        }
+        assertTrue(preHandle(subject));
+        verify(accountService).checkTokenStatus(managedToken);
+        verify(accountService).checkManagedTokenAccess("admin", 
List.of("admin"));
+        verify(accountService).touchTokenLastUsedTime(managedToken);
     }
 
     @Test
     void testManagedTokenRevokedRejected() throws Exception {
-        String revokedToken = "revoked-token";
-        
when(request.getHeader(NetworkConstants.AUTHORIZATION)).thenReturn("Bearer " + 
revokedToken);
-        when(accountService.checkTokenStatus(revokedToken)).thenReturn("Token 
has been revoked");
+        
when(request.getHeader(NetworkConstants.AUTHORIZATION)).thenReturn("Bearer " + 
managedToken);
+        when(accountService.checkTokenStatus(managedToken)).thenReturn("Token 
has been revoked");
+        mockErrorWriter();
+        SubjectSum subject = mockManagedSubject();
+
+        assertFalse(preHandle(subject));
+        verify(response).setStatus(401);
+    }
 
-        StringWriter stringWriter = new StringWriter();
-        PrintWriter printWriter = new PrintWriter(stringWriter);
-        when(response.getWriter()).thenReturn(printWriter);
+    @Test
+    void testManagedTokenInQueryParameterRevokedRejected() throws Exception {
+        
when(request.getHeader(NetworkConstants.AUTHORIZATION)).thenReturn(null);
+        when(request.getParameter("token")).thenReturn(managedToken);
+        when(accountService.checkTokenStatus(managedToken)).thenReturn("Token 
has been revoked");
+        mockErrorWriter();
         SubjectSum subject = mockManagedSubject();
 
-        try (var mockedStatic = mockStatic(SurenessContextHolder.class)) {
-            
mockedStatic.when(SurenessContextHolder::getBindSubject).thenReturn(subject);
+        assertFalse(preHandle(subject));
+        verify(response).setStatus(401);
+    }
 
-            
org.junit.jupiter.api.Assertions.assertFalse(filter.preHandle(request, 
response, new Object()));
-            verify(response).setStatus(401);
-        }
+    @Test
+    void testManagedTokenInQueryParameterActivePassesThrough() throws 
Exception {
+        
when(request.getHeader(NetworkConstants.AUTHORIZATION)).thenReturn(null);
+        when(request.getParameter("token")).thenReturn(managedToken);
+        when(accountService.checkTokenStatus(managedToken)).thenReturn(null);
+        when(accountService.checkManagedTokenAccess("admin", 
List.of("admin"))).thenReturn(null);
+        SubjectSum subject = mockManagedSubjectWithClaims();
+
+        assertTrue(preHandle(subject));
+        verify(accountService).touchTokenLastUsedTime(managedToken);
     }
 
     @Test
-    void testManagedTokenStatusCheckFailureRejectsRequest() throws Exception {
-        
when(request.getHeader(NetworkConstants.AUTHORIZATION)).thenReturn("Bearer 
managed-token");
-        when(accountService.checkTokenStatus("managed-token")).thenThrow(new 
RuntimeException("DB down"));
+    void testRevokedQueryTokenRejectedEvenWithActiveHeaderToken() throws 
Exception {
+        
when(request.getHeader(NetworkConstants.AUTHORIZATION)).thenReturn("Bearer " + 
otherManagedToken);
+        when(request.getParameter("token")).thenReturn(managedToken);
+        
when(accountService.checkTokenStatus(otherManagedToken)).thenReturn(null);
+        when(accountService.checkTokenStatus(managedToken)).thenReturn("Token 
has been revoked");
+        when(accountService.checkManagedTokenAccess("admin", 
List.of("admin"))).thenReturn(null);
+        mockErrorWriter();
+        SubjectSum subject = mockManagedSubjectWithClaims();
 
-        StringWriter stringWriter = new StringWriter();
-        PrintWriter printWriter = new PrintWriter(stringWriter);
-        when(response.getWriter()).thenReturn(printWriter);
-        SubjectSum subject = mockManagedSubject();
+        assertFalse(preHandle(subject));
+        verify(response).setStatus(401);
+    }
 
-        try (var mockedStatic = mockStatic(SurenessContextHolder.class)) {
-            
mockedStatic.when(SurenessContextHolder::getBindSubject).thenReturn(subject);
+    @Test
+    void testHeaderTokenExtractedLikeSurenessRejectsRevokedToken() throws 
Exception {
+        // Sureness strips every "Bearer" from the header, so a trailing 
"Bearer" still authenticates the token
+        
when(request.getHeader(NetworkConstants.AUTHORIZATION)).thenReturn("Bearer " + 
managedToken + "Bearer");
+        when(request.getParameter("token")).thenReturn(otherManagedToken);
+        when(accountService.checkTokenStatus(managedToken)).thenReturn("Token 
has been revoked");
+        mockErrorWriter();
+        SubjectSum subject = mockManagedSubject();
 
-            
org.junit.jupiter.api.Assertions.assertFalse(filter.preHandle(request, 
response, new Object()));
-            verify(response).setStatus(503);
-            verify(accountService, never()).touchTokenLastUsedTime(any());
-        }
+        assertFalse(preHandle(subject));
+        verify(response).setStatus(401);
+        verify(accountService, never()).checkTokenStatus(otherManagedToken);
     }
 
     @Test
-    void testManagedTokenOutdatedRolesRejected() throws Exception {
-        String managedToken = "managed-token";
+    void testNonManagedCandidatesAreIgnored() throws Exception {
         
when(request.getHeader(NetworkConstants.AUTHORIZATION)).thenReturn("Bearer " + 
managedToken);
+        when(request.getParameter("token")).thenReturn(legacyToken);
         when(accountService.checkTokenStatus(managedToken)).thenReturn(null);
-        when(accountService.checkManagedTokenAccess("admin", List.of("admin")))
-                .thenReturn("Token permissions are outdated");
-
-        StringWriter stringWriter = new StringWriter();
-        PrintWriter printWriter = new PrintWriter(stringWriter);
-        when(response.getWriter()).thenReturn(printWriter);
+        when(accountService.checkManagedTokenAccess("admin", 
List.of("admin"))).thenReturn(null);
         SubjectSum subject = mockManagedSubjectWithClaims();
 
-        try (var mockedStatic = mockStatic(SurenessContextHolder.class)) {
-            
mockedStatic.when(SurenessContextHolder::getBindSubject).thenReturn(subject);
-
-            
org.junit.jupiter.api.Assertions.assertFalse(filter.preHandle(request, 
response, new Object()));
-            verify(response).setStatus(401);
-            verify(accountService, 
never()).touchTokenLastUsedTime(managedToken);
-        }
+        assertTrue(preHandle(subject));
+        verify(accountService, never()).checkTokenStatus(legacyToken);
     }
 
     @Test
-    void testEmptyBearerTokenPassesThrough() throws Exception {
-        
when(request.getHeader(NetworkConstants.AUTHORIZATION)).thenReturn("Bearer ");
+    void testManagedTokenStatusCheckFailureRejectsRequest() throws Exception {
+        
when(request.getHeader(NetworkConstants.AUTHORIZATION)).thenReturn("Bearer " + 
managedToken);
+        when(accountService.checkTokenStatus(managedToken)).thenThrow(new 
RuntimeException("DB down"));
+        mockErrorWriter();
         SubjectSum subject = mockManagedSubject();
 
-        try (var mockedStatic = mockStatic(SurenessContextHolder.class)) {
-            
mockedStatic.when(SurenessContextHolder::getBindSubject).thenReturn(subject);
+        assertFalse(preHandle(subject));
+        verify(response).setStatus(503);
+        verify(accountService, never()).touchTokenLastUsedTime(any());
+    }
+
+    @Test
+    void testManagedTokenOutdatedRolesRejected() throws Exception {
+        
when(request.getHeader(NetworkConstants.AUTHORIZATION)).thenReturn("Bearer " + 
managedToken);
+        when(accountService.checkTokenStatus(managedToken)).thenReturn(null);
+        when(accountService.checkManagedTokenAccess("admin", List.of("admin")))
+                .thenReturn("Token permissions are outdated");
+        mockErrorWriter();
+        SubjectSum subject = mockManagedSubjectWithClaims();
 
-            
org.junit.jupiter.api.Assertions.assertTrue(filter.preHandle(request, response, 
new Object()));
-        }
+        assertFalse(preHandle(subject));
+        verify(response).setStatus(401);
+        verify(accountService, never()).touchTokenLastUsedTime(managedToken);
     }
 
     @Test
     void testTouchLastUsedTimeFailureDoesNotRejectRequest() throws Exception {
-        String managedToken = "managed-token";
         
when(request.getHeader(NetworkConstants.AUTHORIZATION)).thenReturn("Bearer " + 
managedToken);
         when(accountService.checkTokenStatus(managedToken)).thenReturn(null);
         when(accountService.checkManagedTokenAccess("admin", 
List.of("admin"))).thenReturn(null);
@@ -203,45 +255,40 @@ class ApiTokenValidationFilterTest {
                 .when(accountService).touchTokenLastUsedTime(managedToken);
         SubjectSum subject = mockManagedSubjectWithClaims();
 
-        try (var mockedStatic = mockStatic(SurenessContextHolder.class)) {
-            
mockedStatic.when(SurenessContextHolder::getBindSubject).thenReturn(subject);
-
-            
org.junit.jupiter.api.Assertions.assertTrue(filter.preHandle(request, response, 
new Object()));
-        }
+        assertTrue(preHandle(subject));
     }
 
     @Test
     void testUnauthenticatedRequestSkipsValidation() throws Exception {
-        try (var mockedStatic = mockStatic(SurenessContextHolder.class)) {
-            
mockedStatic.when(SurenessContextHolder::getBindSubject).thenReturn(null);
-
-            
org.junit.jupiter.api.Assertions.assertTrue(filter.preHandle(request, response, 
new Object()));
-            verify(accountService, never()).checkTokenStatus(any());
-        }
+        assertTrue(preHandle(null));
+        verify(accountService, never()).checkTokenStatus(any());
     }
 
     @Test
     void testManagedTokenAccountValidationFailureRejectsRequest() throws 
Exception {
-        String managedToken = "managed-token";
         
when(request.getHeader(NetworkConstants.AUTHORIZATION)).thenReturn("Bearer " + 
managedToken);
         when(accountService.checkTokenStatus(managedToken)).thenReturn(null);
         when(accountService.checkManagedTokenAccess("admin", List.of("admin")))
                 .thenThrow(new RuntimeException("account store unavailable"));
-
-        StringWriter stringWriter = new StringWriter();
-        PrintWriter printWriter = new PrintWriter(stringWriter);
-        when(response.getWriter()).thenReturn(printWriter);
+        mockErrorWriter();
         SubjectSum subject = mockManagedSubjectWithClaims();
 
-        try (var mockedStatic = mockStatic(SurenessContextHolder.class)) {
-            
mockedStatic.when(SurenessContextHolder::getBindSubject).thenReturn(subject);
+        assertFalse(preHandle(subject));
+        verify(response).setStatus(503);
+        verify(accountService, never()).touchTokenLastUsedTime(managedToken);
+    }
 
-            
org.junit.jupiter.api.Assertions.assertFalse(filter.preHandle(request, 
response, new Object()));
-            verify(response).setStatus(503);
-            verify(accountService, 
never()).touchTokenLastUsedTime(managedToken);
+    private boolean preHandle(SubjectSum subject) throws Exception {
+        try (MockedStatic<SurenessContextHolder> holder = 
mockStatic(SurenessContextHolder.class)) {
+            
holder.when(SurenessContextHolder::getBindSubject).thenReturn(subject);
+            return filter.preHandle(request, response, new Object());
         }
     }
 
+    private void mockErrorWriter() throws Exception {
+        when(response.getWriter()).thenReturn(new PrintWriter(new 
StringWriter()));
+    }
+
     private SubjectSum mockSubject() {
         SubjectSum subjectSum = org.mockito.Mockito.mock(SubjectSum.class);
         when(subjectSum.getPrincipalMap()).thenReturn(principalMap);


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to