Commit 1fcb1d68 authored by Kelly Zhou's avatar Kelly Zhou Committed by Rostislav Vatolin [SLB]
Browse files

send logs from catalog service to Azure application insights

parent 0cbe53cc
......@@ -703,7 +703,6 @@ The following software have components provided under the terms of this license:
- Plexus Default Interactivity Handler (from )
- Project Lombok (from https://projectlombok.org)
- SLF4J API Module (from http://www.slf4j.org)
- SLF4J API Module (from http://www.slf4j.org)
- Spongy Castle (from http://rtyley.github.io/spongycastle/)
- Spring Data for Azure Cosmos DB SQL API (from https://github.com/Azure/azure-sdk-for-java/tree/master/sdk/cosmos/azure-spring-data-cosmos)
- adal4j (from https://github.com/AzureAD/azure-activedirectory-library-for-java)
......
......@@ -120,16 +120,6 @@
<artifactId>objectify</artifactId>
<version>${objectify.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
<!-- Test Dependencies -->
<dependency>
......
......@@ -27,6 +27,8 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import javax.inject.Inject;
import org.opengroup.osdu.core.common.logging.JaxRsDpsLog;
import org.opengroup.osdu.crs.logging.AuditLogger;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
......@@ -61,8 +63,8 @@ public class CrsCatalogApi {
@Inject
private AuditLogger auditLogger;
private static final Logger log = Logger.getLogger(CrsCatalogApi.class.getName());
@Inject
private JaxRsDpsLog log;
public CrsCatalogApi(Catalog catalog) {
this.catalog = catalog;
......@@ -120,7 +122,7 @@ public class CrsCatalogApi {
}
}
catch(Exception ex) {
log.log(Level.WARNING, ex.toString(), ex);
log.warning(ex.toString(), ex);
throw AppException.createBadRequest(ex.getMessage());
}
if (Objects.nonNull(results)) {
......@@ -155,7 +157,7 @@ public class CrsCatalogApi {
}
}
catch (Exception ex) {
log.log(Level.WARNING, ex.toString(), ex);
log.warning(ex.toString(), ex);
throw AppException.createBadRequest(ex.getMessage());
}
if (Objects.nonNull(aou)) {
......@@ -200,7 +202,7 @@ public class CrsCatalogApi {
}
}
catch(Exception ex) {
log.log(Level.WARNING, ex.toString(), ex);
log.warning(ex.toString(), ex);
throw AppException.createBadRequest(ex.getMessage());
}
if (Objects.nonNull(results)) {
......@@ -236,7 +238,7 @@ public class CrsCatalogApi {
}
}
catch(Exception ex) {
log.log(Level.WARNING, ex.toString(), ex);
log.warning(ex.toString(), ex);
throw AppException.createBadRequest(ex.getMessage());
}
if (Objects.nonNull(crs)) {
......@@ -281,7 +283,7 @@ public class CrsCatalogApi {
}
}
catch(Exception ex) {
log.log(Level.WARNING, ex.toString(), ex);
log.warning(ex.toString(), ex);
throw AppException.createBadRequest(ex.getMessage());
}
if (Objects.nonNull(results)) {
......@@ -317,7 +319,7 @@ public class CrsCatalogApi {
}
}
catch (Exception ex) {
log.log(Level.WARNING, ex.toString(), ex);
log.warning(ex.toString(), ex);
throw AppException.createBadRequest(ex.getMessage());
}
if (Objects.nonNull(crs)) {
......@@ -362,7 +364,7 @@ public class CrsCatalogApi {
}
}
catch(Exception ex) {
log.log(Level.WARNING, ex.toString(), ex);
log.warning(ex.toString(), ex);
throw AppException.createBadRequest(ex.getMessage());
}
if (Objects.nonNull(results)) {
......@@ -397,7 +399,7 @@ public class CrsCatalogApi {
}
}
catch (Exception ex) {
log.log(Level.WARNING, ex.toString(), ex);
log.warning(ex.toString(), ex);
throw AppException.createBadRequest(ex.getMessage());
}
if (Objects.nonNull(crs)) {
......@@ -442,7 +444,7 @@ public class CrsCatalogApi {
}
}
catch(Exception ex) {
log.log(Level.WARNING, ex.toString(), ex);
log.warning(ex.toString(), ex);
throw AppException.createBadRequest(ex.getMessage());
}
if (Objects.nonNull(results)) {
......@@ -477,7 +479,7 @@ public class CrsCatalogApi {
}
}
catch (Exception ex) {
log.log(Level.WARNING, ex.toString(), ex);
log.warning(ex.toString(), ex);
throw AppException.createBadRequest(ex.getMessage());
}
if (Objects.nonNull(crs)) {
......@@ -522,7 +524,7 @@ public class CrsCatalogApi {
}
}
catch(Exception ex) {
log.log(Level.WARNING, ex.toString(), ex);
log.warning(ex.toString(), ex);
throw AppException.createBadRequest(ex.getMessage());
}
if (Objects.nonNull(results)) {
......@@ -558,7 +560,7 @@ public class CrsCatalogApi {
}
}
catch (Exception ex) {
log.log(Level.WARNING, ex.toString(), ex);
log.warning(ex.toString(), ex);
throw AppException.createBadRequest(ex.getMessage());
}
if (Objects.nonNull(ct)) {
......@@ -603,7 +605,7 @@ public class CrsCatalogApi {
}
}
catch(Exception ex) {
log.log(Level.WARNING, ex.toString(), ex);
log.warning(ex.toString(), ex);
throw AppException.createBadRequest(ex.getMessage());
}
if (Objects.nonNull(results)) {
......@@ -638,7 +640,7 @@ public class CrsCatalogApi {
}
}
catch (Exception ex) {
log.log(Level.WARNING, ex.toString(), ex);
log.warning(ex.toString(), ex);
throw AppException.createBadRequest(ex.getMessage());
}
if (Objects.nonNull(ct)) {
......@@ -683,7 +685,7 @@ public class CrsCatalogApi {
}
}
catch(Exception ex) {
log.log(Level.WARNING, ex.toString(), ex);
log.warning(ex.toString(), ex);
throw AppException.createBadRequest(ex.getMessage());
}
if (Objects.nonNull(results)) {
......@@ -717,7 +719,7 @@ public class CrsCatalogApi {
ct = ct.convert(mode);
}
catch (Exception ex) {
log.log(Level.WARNING, ex.toString(), ex);
log.warning(ex.toString(), ex);
throw AppException.createBadRequest(ex.getMessage());
}
if (Objects.nonNull(ct)) {
......@@ -762,7 +764,7 @@ public class CrsCatalogApi {
return results;
}
catch(Exception ex) {
log.log(Level.WARNING, ex.toString(), ex);
log.warning(ex.toString(), ex);
throw AppException.createBadRequest(ex.getMessage());
}
}
......@@ -797,7 +799,7 @@ public class CrsCatalogApi {
return results;
}
catch(Exception ex) {
log.log(Level.WARNING, ex.toString(), ex);
log.warning(ex.toString(), ex);
throw AppException.createBadRequest(ex.getMessage());
}
}
......@@ -832,7 +834,7 @@ public class CrsCatalogApi {
return results;
}
catch(Exception ex) {
log.log(Level.WARNING, ex.toString(), ex);
log.warning(ex.toString(), ex);
throw AppException.createBadRequest(ex.getMessage());
}
}
......
package org.opengroup.osdu.crs.middleware;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.opengroup.osdu.core.common.entitlements.EntitlementsAPIConfig;
import org.opengroup.osdu.core.common.entitlements.EntitlementsFactory;
import org.opengroup.osdu.core.common.entitlements.IEntitlementsFactory;
import org.opengroup.osdu.core.common.entitlements.IEntitlementsService;
import org.opengroup.osdu.core.common.http.json.HttpResponseBodyMapper;
import org.opengroup.osdu.core.common.model.entitlements.EntitlementsException;
import org.opengroup.osdu.core.common.model.entitlements.Groups;
import org.opengroup.osdu.core.common.model.http.DpsHeaders;
import org.opengroup.osdu.crs.util.AppException;
import org.springframework.http.HttpHeaders;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.util.CollectionUtils;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.servlet.HandlerExceptionResolver;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
......@@ -34,68 +10,19 @@ import javax.servlet.http.HttpServletResponse;
public class AuthenticationRequestFilter extends OncePerRequestFilter {
private static Logger logger = Logger.getLogger(AuthenticationRequestFilter.class.getName());
private final AuthenticationService authenticationService;
private final String entitlementsUrl;
private final HandlerExceptionResolver handlerExceptionResolver;
private HttpResponseBodyMapper httpResponseBodyMapper;
public AuthenticationRequestFilter(AuthenticationService authenticationService) {
this.authenticationService = authenticationService;
public AuthenticationRequestFilter(String entitlementsUrl,
HandlerExceptionResolver handlerExceptionResolver) {
this.entitlementsUrl = entitlementsUrl;
this.handlerExceptionResolver = handlerExceptionResolver;
httpResponseBodyMapper = new HttpResponseBodyMapper(new ObjectMapper());
}
@Override
protected void doFilterInternal(@NonNull HttpServletRequest httpServletRequest,
@NonNull HttpServletResponse httpServletResponse,
@NonNull FilterChain filterChain) throws ServletException, IOException {
MultiValueMap<String, String> requestHeaders = httpHeaders(httpServletRequest);
DpsHeaders dpsHeaders = DpsHeaders.createFromEntrySet(requestHeaders.entrySet());
dpsHeaders.addCorrelationIdIfMissing();
IEntitlementsFactory factory = getEntitlementsFactory();
IEntitlementsService service = factory.create(dpsHeaders);
try {
Groups groups = service.getGroups();
String message = String.format("User authenticated | User: %s", groups.getMemberEmail());
logger.info(message);
putAuthenticationIntoContext(groups);
httpServletResponse.addHeader(DpsHeaders.CORRELATION_ID, dpsHeaders.getCorrelationId());
if (authenticationService.isAuthorized(httpServletRequest, httpServletResponse)) {
filterChain.doFilter(httpServletRequest, httpServletResponse);
} catch (EntitlementsException e) {
String message = String.format(String.format("User not authenticated. Response: %s", e.getHttpResponse()), e);
logger.warning(message);
AppException unauthorized = AppException.createUnauthorized("Error: " + e.getMessage());
handlerExceptionResolver.resolveException(httpServletRequest, httpServletResponse, null, unauthorized);
}
catch (NullPointerException e) { // Common library throws null pointer exception when auth permission is denied.
String message = String.format("User not authenticated. Null pointer exception: %s", e.getMessage());
logger.warning(message);
AppException unauthorized = AppException.createUnauthorized("Error: " + e.getMessage());
handlerExceptionResolver.resolveException(httpServletRequest, httpServletResponse, null, unauthorized);
}
}
private HttpHeaders httpHeaders(@NonNull HttpServletRequest httpRequest) {
return Collections
.list(httpRequest.getHeaderNames())
.stream()
.collect(Collectors.toMap(
Function.identity(),
h -> Collections.list(httpRequest.getHeaders(h)),
(oldValue, newValue) -> newValue,
HttpHeaders::new
));
}
private IEntitlementsFactory getEntitlementsFactory() {
return new EntitlementsFactory(EntitlementsAPIConfig.builder().rootUrl(entitlementsUrl).build(), httpResponseBodyMapper);
}
private void putAuthenticationIntoContext(Groups groups) {
AuthenticationToken authentication = new AuthenticationToken(groups, Collections.emptyList());
authentication.setAuthenticated(true);
SecurityContextHolder.getContext().setAuthentication(authentication);
}
}
}
package org.opengroup.osdu.crs.middleware;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.opengroup.osdu.core.common.entitlements.EntitlementsAPIConfig;
import org.opengroup.osdu.core.common.entitlements.EntitlementsFactory;
import org.opengroup.osdu.core.common.entitlements.IEntitlementsFactory;
import org.opengroup.osdu.core.common.entitlements.IEntitlementsService;
import org.opengroup.osdu.core.common.http.json.HttpResponseBodyMapper;
import org.opengroup.osdu.core.common.logging.JaxRsDpsLog;
import org.opengroup.osdu.core.common.model.entitlements.EntitlementsException;
import org.opengroup.osdu.core.common.model.entitlements.Groups;
import org.opengroup.osdu.core.common.model.http.DpsHeaders;
import org.opengroup.osdu.crs.util.AppException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.lang.NonNull;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.util.MultiValueMap;
import org.springframework.web.servlet.HandlerExceptionResolver;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Collections;
import java.util.function.Function;
import java.util.stream.Collectors;
@Service
public class AuthenticationService {
@Inject
private JaxRsDpsLog logger;
@Inject
private HandlerExceptionResolver handlerExceptionResolver;
@Value("${osdu.entitlement.url}")
private String entitlementsUrl;
private EntitlementsFactory entitlementsFactory;
@PostConstruct
public void initEntitlementsFactory() {
HttpResponseBodyMapper httpResponseBodyMapper = new HttpResponseBodyMapper(new ObjectMapper());
EntitlementsAPIConfig config = EntitlementsAPIConfig.builder().rootUrl(entitlementsUrl).build();
entitlementsFactory = new EntitlementsFactory(config, httpResponseBodyMapper);
}
public boolean isAuthorized(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
MultiValueMap<String, String> requestHeaders = httpHeaders(httpServletRequest);
DpsHeaders dpsHeaders = DpsHeaders.createFromEntrySet(requestHeaders.entrySet());
dpsHeaders.addCorrelationIdIfMissing();
IEntitlementsService service = entitlementsFactory.create(dpsHeaders);
try {
Groups groups = service.getGroups();
String message = String.format("User authenticated | User: %s", groups.getMemberEmail());
logger.info(message);
putAuthenticationIntoContext(groups);
httpServletResponse.addHeader(DpsHeaders.CORRELATION_ID, dpsHeaders.getCorrelationId());
} catch (EntitlementsException e) {
String message = String.format(String.format("User not authenticated. Response: %s", e.getHttpResponse()), e);
logger.warning(message);
AppException unauthorized = AppException.createUnauthorized("Error: " + e.getMessage());
handlerExceptionResolver.resolveException(httpServletRequest, httpServletResponse, null, unauthorized);
return false;
}
catch (NullPointerException e) { // Common library throws null pointer exception when auth permission is denied.
String message = String.format("User not authenticated. Null pointer exception: %s", e.getMessage());
logger.warning(message);
AppException unauthorized = AppException.createUnauthorized("Error: " + e.getMessage());
handlerExceptionResolver.resolveException(httpServletRequest, httpServletResponse, null, unauthorized);
return false;
}
return true;
}
private HttpHeaders httpHeaders(@NonNull HttpServletRequest httpRequest) {
return Collections
.list(httpRequest.getHeaderNames())
.stream()
.collect(Collectors.toMap(
Function.identity(),
h -> Collections.list(httpRequest.getHeaders(h)),
(oldValue, newValue) -> newValue,
HttpHeaders::new
));
}
private void putAuthenticationIntoContext(Groups groups) {
AuthenticationToken authentication = new AuthenticationToken(groups, Collections.emptyList());
authentication.setAuthenticated(true);
SecurityContextHolder.getContext().setAuthentication(authentication);
}
}
......@@ -14,6 +14,8 @@
package org.opengroup.osdu.crs.middleware;
import io.swagger.jaxrs.config.JaxrsScanner;
import org.opengroup.osdu.core.common.logging.JaxRsDpsLog;
import org.opengroup.osdu.crs.util.AppError;
import org.opengroup.osdu.crs.util.AppException;
import org.springframework.http.ResponseEntity;
......@@ -21,11 +23,16 @@ import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
import javax.inject.Inject;
import static org.springframework.http.HttpStatus.*;
@RestControllerAdvice
public class GlobalExceptionMapper extends ResponseEntityExceptionHandler {
@Inject
private JaxRsDpsLog log;
@ExceptionHandler(AppException.class)
protected ResponseEntity<AppError> handleAppException(AppException e) {
return this.getErrorResponse(e);
......@@ -39,7 +46,7 @@ public class GlobalExceptionMapper extends ResponseEntityExceptionHandler {
}
private ResponseEntity<AppError> getErrorResponse(AppException e) {
logger.error(e);
log.error(e.getMessage(), e);
AppError appError = e.getError();
return new ResponseEntity<>(appError, resolve(appError.getCode()));
}
......
......@@ -41,8 +41,6 @@ import org.opengroup.osdu.crs.model.*;
import org.opengroup.osdu.crs.model.search.parser.SpatialUtility;
public class Indexer {
private static final Logger log = Logger.getLogger(Indexer.class.getName());
private Analyzer analyzer = null;
private Directory indexDirectory = null;
private IndexWriter indexWriter = null;
......
......@@ -18,9 +18,9 @@
package org.opengroup.osdu.crs.logging;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.util.Collections;
import java.util.List;
......@@ -49,7 +49,7 @@ public class AuditLoggerTest {
@Before
public void setup() {
when(this.headers.getUserEmail()).thenReturn("test_user@email.com");
lenient().when(this.headers.getUserEmail()).thenReturn("test_user@email.com");
resources = Collections.singletonList("resources");
}
......
package org.opengroup.osdu.crs.middleware;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import javax.servlet.FilterChain;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@RunWith(MockitoJUnitRunner.class)
public class AuthenticationRequestFilterTest {
@InjectMocks
private AuthenticationRequestFilter sut;
@Mock
private AuthenticationService authenticationService;
@Test
public void shouldContinueFilteringWhenAuthenticated() throws Exception {
HttpServletRequest httpServletRequest = Mockito.mock(HttpServletRequest.class);
HttpServletResponse httpServletResponse = Mockito.mock(HttpServletResponse.class);
FilterChain filterChain = Mockito.mock(FilterChain.class);
Mockito.when(authenticationService.isAuthorized(httpServletRequest, httpServletResponse)).thenReturn(true);
sut.doFilterInternal(httpServletRequest, httpServletResponse, filterChain);
Mockito.verify(authenticationService).isAuthorized(httpServletRequest, httpServletResponse);
Mockito.verify(filterChain).doFilter(httpServletRequest, httpServletResponse);
}
@Test
public void shouldStopFilteringWhenNotAuthenticated() throws Exception {
HttpServletRequest httpServletRequest = Mockito.mock(HttpServletRequest.class);
HttpServletResponse httpServletResponse = Mockito.mock(HttpServletResponse.class);
FilterChain filterChain = Mockito.mock(FilterChain.class);
Mockito.when(authenticationService.isAuthorized(httpServletRequest, httpServletResponse)).thenReturn(false);
sut.doFilterInternal(httpServletRequest, httpServletResponse, filterChain);
Mockito.verify(authenticationService).isAuthorized(httpServletRequest, httpServletResponse);
Mockito.verifyNoMoreInteractions(filterChain);
}
}
package org.opengroup.osdu.crs.middleware;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import org.opengroup.osdu.core.common.entitlements.EntitlementsFactory;
import org.opengroup.osdu.core.common.entitlements.IEntitlementsService;
import org.opengroup.osdu.core.common.logging.JaxRsDpsLog;
import org.opengroup.osdu.core.common.model.entitlements.EntitlementsException;
import org.opengroup.osdu.core.common.model.entitlements.Groups;
import org.opengroup.osdu.core.common.model.http.DpsHeaders;
import org.opengroup.osdu.crs.util.AppException;
import org.powermock.reflect.Whitebox;
import org.springframework.web.servlet.HandlerExceptionResolver;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Enumeration;
@RunWith(MockitoJUnitRunner.class)
public class AuthenticationServiceTest {
@InjectMocks
private AuthenticationService sut;
@Mock
private JaxRsDpsLog logger;
@Mock
private HandlerExceptionResolver handlerExceptionResolver;
@Before