mirror of
https://github.com/datahub-project/datahub.git
synced 2025-12-28 10:28:22 +00:00
feat(logging): unified request logging (graphql, openapi, restli) (#10802)
This commit is contained in:
parent
a35089048a
commit
b4e05050d1
@ -7,6 +7,8 @@ dependencies {
|
||||
api project(':metadata-auth:auth-api')
|
||||
|
||||
implementation externalDependency.slf4jApi
|
||||
implementation externalDependency.servletApi
|
||||
implementation spec.product.pegasus.restliServer
|
||||
compileOnly externalDependency.lombok
|
||||
|
||||
annotationProcessor externalDependency.lombok
|
||||
|
||||
@ -1,5 +1,8 @@
|
||||
package io.datahubproject.metadata.context;
|
||||
|
||||
import com.google.common.net.HttpHeaders;
|
||||
import com.linkedin.restli.server.ResourceContext;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
@ -11,7 +14,9 @@ import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
@Getter
|
||||
@Builder
|
||||
public class RequestContext implements ContextInterface {
|
||||
@ -19,6 +24,8 @@ public class RequestContext implements ContextInterface {
|
||||
public static final RequestContext TEST =
|
||||
RequestContext.builder().requestID("test").requestAPI(RequestAPI.TEST).build();
|
||||
|
||||
@Nonnull private final String actorUrn;
|
||||
@Nonnull private final String sourceIP;
|
||||
@Nonnull private final RequestAPI requestAPI;
|
||||
|
||||
/**
|
||||
@ -27,6 +34,23 @@ public class RequestContext implements ContextInterface {
|
||||
*/
|
||||
@Nonnull private final String requestID;
|
||||
|
||||
@Nonnull private final String userAgent;
|
||||
|
||||
public RequestContext(
|
||||
@Nonnull String actorUrn,
|
||||
@Nonnull String sourceIP,
|
||||
@Nonnull RequestAPI requestAPI,
|
||||
@Nonnull String requestID,
|
||||
@Nonnull String userAgent) {
|
||||
this.actorUrn = actorUrn;
|
||||
this.sourceIP = sourceIP;
|
||||
this.requestAPI = requestAPI;
|
||||
this.requestID = requestID;
|
||||
this.userAgent = userAgent;
|
||||
// Uniform common logging of requests across APIs
|
||||
log.info(toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Integer> getCacheKeyComponent() {
|
||||
return Optional.empty();
|
||||
@ -34,39 +58,76 @@ public class RequestContext implements ContextInterface {
|
||||
|
||||
public static class RequestContextBuilder {
|
||||
private RequestContext build() {
|
||||
return new RequestContext(this.requestAPI, this.requestID);
|
||||
return new RequestContext(
|
||||
this.actorUrn, this.sourceIP, this.requestAPI, this.requestID, this.userAgent);
|
||||
}
|
||||
|
||||
public RequestContext buildGraphql(@Nonnull String queryName, Map<String, Object> variables) {
|
||||
public RequestContext buildGraphql(
|
||||
@Nonnull String actorUrn,
|
||||
@Nonnull HttpServletRequest request,
|
||||
@Nonnull String queryName,
|
||||
Map<String, Object> variables) {
|
||||
actorUrn(actorUrn);
|
||||
sourceIP(extractSourceIP(request));
|
||||
requestAPI(RequestAPI.GRAPHQL);
|
||||
requestID(buildRequestId(queryName, Set.of()));
|
||||
userAgent(extractUserAgent(request));
|
||||
return build();
|
||||
}
|
||||
|
||||
public RequestContext buildRestli(String action, @Nullable String entityName) {
|
||||
return buildRestli(action, entityName == null ? null : List.of(entityName));
|
||||
public RequestContext buildRestli(
|
||||
@Nonnull String actorUrn,
|
||||
@Nullable ResourceContext resourceContext,
|
||||
String action,
|
||||
@Nullable String entityName) {
|
||||
return buildRestli(
|
||||
actorUrn, resourceContext, action, entityName == null ? null : List.of(entityName));
|
||||
}
|
||||
|
||||
public RequestContext buildRestli(@Nonnull String action, @Nullable String[] entityNames) {
|
||||
public RequestContext buildRestli(
|
||||
@Nonnull String actorUrn,
|
||||
@Nullable ResourceContext resourceContext,
|
||||
@Nonnull String action,
|
||||
@Nullable String[] entityNames) {
|
||||
return buildRestli(
|
||||
actorUrn,
|
||||
resourceContext,
|
||||
action,
|
||||
entityNames == null ? null : Arrays.stream(entityNames).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
public RequestContext buildRestli(String action, @Nullable Collection<String> entityNames) {
|
||||
public RequestContext buildRestli(
|
||||
@Nonnull String actorUrn,
|
||||
@Nullable ResourceContext resourceContext,
|
||||
String action,
|
||||
@Nullable Collection<String> entityNames) {
|
||||
actorUrn(actorUrn);
|
||||
sourceIP(resourceContext == null ? "" : extractSourceIP(resourceContext));
|
||||
requestAPI(RequestAPI.RESTLI);
|
||||
requestID(buildRequestId(action, entityNames));
|
||||
userAgent(resourceContext == null ? "" : extractUserAgent(resourceContext));
|
||||
return build();
|
||||
}
|
||||
|
||||
public RequestContext buildOpenapi(@Nonnull String action, @Nullable String entityName) {
|
||||
return buildOpenapi(action, entityName == null ? null : List.of(entityName));
|
||||
public RequestContext buildOpenapi(
|
||||
@Nonnull String actorUrn,
|
||||
@Nonnull HttpServletRequest request,
|
||||
@Nonnull String action,
|
||||
@Nullable String entityName) {
|
||||
return buildOpenapi(
|
||||
actorUrn, request, action, entityName == null ? null : List.of(entityName));
|
||||
}
|
||||
|
||||
public RequestContext buildOpenapi(
|
||||
@Nonnull String action, @Nullable Collection<String> entityNames) {
|
||||
@Nonnull String actorUrn,
|
||||
@Nullable HttpServletRequest request,
|
||||
@Nonnull String action,
|
||||
@Nullable Collection<String> entityNames) {
|
||||
actorUrn(actorUrn);
|
||||
sourceIP(request == null ? "" : extractSourceIP(request));
|
||||
requestAPI(RequestAPI.OPENAPI);
|
||||
requestID(buildRequestId(action, entityNames));
|
||||
userAgent(request == null ? "" : extractUserAgent(request));
|
||||
return build();
|
||||
}
|
||||
|
||||
@ -77,6 +138,46 @@ public class RequestContext implements ContextInterface {
|
||||
: String.format(
|
||||
"%s(%s)", action, entityNames.stream().distinct().collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
private static String extractUserAgent(@Nonnull HttpServletRequest request) {
|
||||
return Optional.ofNullable(request.getHeader(HttpHeaders.USER_AGENT)).orElse("");
|
||||
}
|
||||
|
||||
private static String extractUserAgent(@Nonnull ResourceContext resourceContext) {
|
||||
return Optional.ofNullable(resourceContext.getRequestHeaders().get(HttpHeaders.USER_AGENT))
|
||||
.orElse("");
|
||||
}
|
||||
|
||||
private static String extractSourceIP(@Nonnull HttpServletRequest request) {
|
||||
return Optional.ofNullable(request.getHeader(HttpHeaders.X_FORWARDED_FOR))
|
||||
.orElse(request.getRemoteAddr());
|
||||
}
|
||||
|
||||
private static String extractSourceIP(@Nonnull ResourceContext resourceContext) {
|
||||
return Optional.ofNullable(
|
||||
resourceContext.getRequestHeaders().get(HttpHeaders.X_FORWARDED_FOR))
|
||||
.orElse(resourceContext.getRawRequestContext().getLocalAttr("REMOTE_ADDR").toString());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "RequestContext{"
|
||||
+ "actorUrn='"
|
||||
+ actorUrn
|
||||
+ '\''
|
||||
+ ", sourceIP='"
|
||||
+ sourceIP
|
||||
+ '\''
|
||||
+ ", requestAPI="
|
||||
+ requestAPI
|
||||
+ ", requestID='"
|
||||
+ requestID
|
||||
+ '\''
|
||||
+ ", userAgent='"
|
||||
+ userAgent
|
||||
+ '\''
|
||||
+ '}';
|
||||
}
|
||||
|
||||
public enum RequestAPI {
|
||||
|
||||
@ -59,7 +59,8 @@ public class GraphQLController {
|
||||
private static final int MAX_LOG_WIDTH = 512;
|
||||
|
||||
@PostMapping(value = "/graphql", produces = "application/json;charset=utf-8")
|
||||
CompletableFuture<ResponseEntity<String>> postGraphQL(HttpEntity<String> httpEntity) {
|
||||
CompletableFuture<ResponseEntity<String>> postGraphQL(
|
||||
HttpServletRequest request, HttpEntity<String> httpEntity) {
|
||||
|
||||
String jsonStr = httpEntity.getBody();
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
@ -117,13 +118,18 @@ public class GraphQLController {
|
||||
|
||||
SpringQueryContext context =
|
||||
new SpringQueryContext(
|
||||
true, authentication, _authorizerChain, systemOperationContext, query, variables);
|
||||
true,
|
||||
authentication,
|
||||
_authorizerChain,
|
||||
systemOperationContext,
|
||||
request,
|
||||
operationName,
|
||||
query,
|
||||
variables);
|
||||
Span.current().setAttribute("actor.urn", context.getActorUrn());
|
||||
|
||||
// operationName is an optional field only required if multiple operations are present
|
||||
final String queryName = operationName != null ? operationName : context.getQueryName();
|
||||
final String threadName = Thread.currentThread().getName();
|
||||
log.info("Processing request, operation: {}, actor urn: {}", queryName, context.getActorUrn());
|
||||
final String queryName = context.getQueryName();
|
||||
log.debug("Query: {}, variables: {}", query, variables);
|
||||
|
||||
return GraphQLConcurrencyUtils.supplyAsync(
|
||||
|
||||
@ -7,8 +7,10 @@ import graphql.language.OperationDefinition;
|
||||
import graphql.parser.Parser;
|
||||
import io.datahubproject.metadata.context.OperationContext;
|
||||
import io.datahubproject.metadata.context.RequestContext;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import java.util.Map;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@ -25,26 +27,33 @@ public class SpringQueryContext implements QueryContext {
|
||||
final Authentication authentication,
|
||||
final Authorizer authorizer,
|
||||
@Nonnull final OperationContext systemOperationContext,
|
||||
@Nonnull final HttpServletRequest request,
|
||||
@Nullable final String operationName,
|
||||
String jsonQuery,
|
||||
Map<String, Object> variables) {
|
||||
this.isAuthenticated = isAuthenticated;
|
||||
this.authentication = authentication;
|
||||
this.authorizer = authorizer;
|
||||
|
||||
// operationName is an optional field only required if multiple operations are present
|
||||
this.queryName =
|
||||
new Parser()
|
||||
.parseDocument(jsonQuery).getDefinitions().stream()
|
||||
.filter(def -> def instanceof OperationDefinition)
|
||||
.map(def -> (OperationDefinition) def)
|
||||
.filter(opDef -> opDef.getOperation().equals(OperationDefinition.Operation.QUERY))
|
||||
.findFirst()
|
||||
.map(OperationDefinition::getName)
|
||||
.orElse("graphql");
|
||||
operationName != null
|
||||
? operationName
|
||||
: new Parser()
|
||||
.parseDocument(jsonQuery).getDefinitions().stream()
|
||||
.filter(def -> def instanceof OperationDefinition)
|
||||
.map(def -> (OperationDefinition) def)
|
||||
.filter(
|
||||
opDef -> opDef.getOperation().equals(OperationDefinition.Operation.QUERY))
|
||||
.findFirst()
|
||||
.map(OperationDefinition::getName)
|
||||
.orElse("graphql");
|
||||
|
||||
this.operationContext =
|
||||
OperationContext.asSession(
|
||||
systemOperationContext,
|
||||
RequestContext.builder().buildGraphql(queryName, variables),
|
||||
RequestContext.builder()
|
||||
.buildGraphql(authentication.getActor().toUrnStr(), request, queryName, variables),
|
||||
authorizer,
|
||||
authentication,
|
||||
true);
|
||||
|
||||
@ -19,7 +19,7 @@ dependencies {
|
||||
implementation externalDependency.springWebMVC
|
||||
implementation externalDependency.springBeans
|
||||
implementation externalDependency.springContext
|
||||
|
||||
implementation externalDependency.servletApi
|
||||
implementation externalDependency.reflections
|
||||
implementation externalDependency.slf4jApi
|
||||
compileOnly externalDependency.lombok
|
||||
|
||||
@ -12,6 +12,7 @@ import io.datahubproject.metadata.context.OperationContext;
|
||||
import io.datahubproject.metadata.context.RequestContext;
|
||||
import io.datahubproject.openapi.exception.UnauthorizedException;
|
||||
import io.datahubproject.openapi.v2.generated.controller.DatahubUsageEventsApiDelegate;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -27,6 +28,8 @@ public class DatahubUsageEventsImpl implements DatahubUsageEventsApiDelegate {
|
||||
@Qualifier("systemOperationContext")
|
||||
OperationContext systemOperationContext;
|
||||
|
||||
@Autowired private HttpServletRequest request;
|
||||
|
||||
public static final String DATAHUB_USAGE_INDEX = "datahub_usage_event";
|
||||
|
||||
@Override
|
||||
@ -36,7 +39,8 @@ public class DatahubUsageEventsImpl implements DatahubUsageEventsApiDelegate {
|
||||
OperationContext opContext =
|
||||
OperationContext.asSession(
|
||||
systemOperationContext,
|
||||
RequestContext.builder().buildOpenapi("raw", List.of()),
|
||||
RequestContext.builder()
|
||||
.buildOpenapi(authentication.getActor().toUrnStr(), request, "raw", List.of()),
|
||||
_authorizationChain,
|
||||
authentication,
|
||||
true);
|
||||
|
||||
@ -59,6 +59,7 @@ import io.datahubproject.openapi.generated.StatusAspectRequestV2;
|
||||
import io.datahubproject.openapi.generated.StatusAspectResponseV2;
|
||||
import io.datahubproject.openapi.util.OpenApiEntitiesUtil;
|
||||
import io.datahubproject.openapi.v1.entities.EntitiesController;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -85,6 +86,7 @@ public class EntityApiDelegateImpl<I, O, S> {
|
||||
private final Class<I> _reqClazz;
|
||||
private final Class<O> _respClazz;
|
||||
private final Class<S> _scrollRespClazz;
|
||||
private final HttpServletRequest request;
|
||||
|
||||
private static final String BUSINESS_ATTRIBUTE_ERROR_MESSAGE =
|
||||
"business attribute is disabled, enable it using featureflag : BUSINESS_ATTRIBUTE_ENTITY_ENABLED";
|
||||
@ -92,6 +94,7 @@ public class EntityApiDelegateImpl<I, O, S> {
|
||||
|
||||
public EntityApiDelegateImpl(
|
||||
OperationContext systemOperationContext,
|
||||
HttpServletRequest request,
|
||||
EntityService<?> entityService,
|
||||
SearchService searchService,
|
||||
EntitiesController entitiesController,
|
||||
@ -100,6 +103,7 @@ public class EntityApiDelegateImpl<I, O, S> {
|
||||
Class<O> respClazz,
|
||||
Class<S> scrollRespClazz) {
|
||||
this.systemOperationContext = systemOperationContext;
|
||||
this.request = request;
|
||||
this._entityService = entityService;
|
||||
this._searchService = searchService;
|
||||
this._entityRegistry = systemOperationContext.getEntityRegistry();
|
||||
@ -119,7 +123,7 @@ public class EntityApiDelegateImpl<I, O, S> {
|
||||
.map(asp -> asp.stream().distinct().toArray(String[]::new))
|
||||
.orElse(null);
|
||||
ResponseEntity<UrnResponseMap> result =
|
||||
_v1Controller.getEntities(new String[] {urn}, requestedAspects);
|
||||
_v1Controller.getEntities(request, new String[] {urn}, requestedAspects);
|
||||
return ResponseEntity.of(
|
||||
OpenApiEntitiesUtil.convertEntity(
|
||||
Optional.ofNullable(result).map(HttpEntity::getBody).orElse(null),
|
||||
@ -146,7 +150,7 @@ public class EntityApiDelegateImpl<I, O, S> {
|
||||
throw new UnsupportedOperationException(BUSINESS_ATTRIBUTE_ERROR_MESSAGE);
|
||||
}
|
||||
}
|
||||
_v1Controller.postEntities(aspects, false, createIfNotExists, createEntityIfNotExists);
|
||||
_v1Controller.postEntities(request, aspects, false, createIfNotExists, createEntityIfNotExists);
|
||||
List<O> responses =
|
||||
body.stream()
|
||||
.map(req -> OpenApiEntitiesUtil.convertToResponse(req, _respClazz, _entityRegistry))
|
||||
@ -158,7 +162,7 @@ public class EntityApiDelegateImpl<I, O, S> {
|
||||
if (checkBusinessAttributeFlagFromUrn(urn)) {
|
||||
throw new UnsupportedOperationException(BUSINESS_ATTRIBUTE_ERROR_MESSAGE);
|
||||
}
|
||||
_v1Controller.deleteEntities(new String[] {urn}, false, false);
|
||||
_v1Controller.deleteEntities(request, new String[] {urn}, false, false);
|
||||
return new ResponseEntity<>(HttpStatus.OK);
|
||||
}
|
||||
|
||||
@ -177,7 +181,9 @@ public class EntityApiDelegateImpl<I, O, S> {
|
||||
OperationContext opContext =
|
||||
OperationContext.asSession(
|
||||
systemOperationContext,
|
||||
RequestContext.builder().buildOpenapi("head", entityUrn.getEntityType()),
|
||||
RequestContext.builder()
|
||||
.buildOpenapi(
|
||||
auth.getActor().toUrnStr(), request, "head", entityUrn.getEntityType()),
|
||||
_authorizationChain,
|
||||
auth,
|
||||
true);
|
||||
@ -200,7 +206,7 @@ public class EntityApiDelegateImpl<I, O, S> {
|
||||
Class<A> aspectRespClazz) {
|
||||
String[] requestedAspects = new String[] {aspect};
|
||||
ResponseEntity<UrnResponseMap> result =
|
||||
_v1Controller.getEntities(new String[] {urn}, requestedAspects);
|
||||
_v1Controller.getEntities(request, new String[] {urn}, requestedAspects);
|
||||
return ResponseEntity.of(
|
||||
OpenApiEntitiesUtil.convertAspect(
|
||||
result.getBody(), aspect, entityRespClass, aspectRespClazz, systemMetadata));
|
||||
@ -217,6 +223,7 @@ public class EntityApiDelegateImpl<I, O, S> {
|
||||
UpsertAspectRequest aspectUpsert =
|
||||
OpenApiEntitiesUtil.convertAspectToUpsert(urn, body, reqClazz);
|
||||
_v1Controller.postEntities(
|
||||
request,
|
||||
Stream.of(aspectUpsert).filter(Objects::nonNull).collect(Collectors.toList()),
|
||||
false,
|
||||
createIfNotExists,
|
||||
@ -238,7 +245,9 @@ public class EntityApiDelegateImpl<I, O, S> {
|
||||
OperationContext opContext =
|
||||
OperationContext.asSession(
|
||||
systemOperationContext,
|
||||
RequestContext.builder().buildOpenapi("headAspect", entityUrn.getEntityType()),
|
||||
RequestContext.builder()
|
||||
.buildOpenapi(
|
||||
auth.getActor().toUrnStr(), request, "headAspect", entityUrn.getEntityType()),
|
||||
_authorizationChain,
|
||||
auth,
|
||||
true);
|
||||
@ -259,12 +268,14 @@ public class EntityApiDelegateImpl<I, O, S> {
|
||||
OperationContext opContext =
|
||||
OperationContext.asSession(
|
||||
systemOperationContext,
|
||||
RequestContext.builder().buildOpenapi("deleteAspect", entityUrn.getEntityType()),
|
||||
RequestContext.builder()
|
||||
.buildOpenapi(
|
||||
auth.getActor().toUrnStr(), request, "deleteAspect", entityUrn.getEntityType()),
|
||||
_authorizationChain,
|
||||
auth,
|
||||
true);
|
||||
_entityService.deleteAspect(opContext, urn, aspect, Map.of(), false);
|
||||
_v1Controller.deleteEntities(new String[] {urn}, false, false);
|
||||
_v1Controller.deleteEntities(request, new String[] {urn}, false, false);
|
||||
return new ResponseEntity<>(HttpStatus.OK);
|
||||
}
|
||||
|
||||
@ -606,7 +617,9 @@ public class EntityApiDelegateImpl<I, O, S> {
|
||||
OperationContext opContext =
|
||||
OperationContext.asSession(
|
||||
systemOperationContext,
|
||||
RequestContext.builder().buildOpenapi("scroll", entitySpec.getName()),
|
||||
RequestContext.builder()
|
||||
.buildOpenapi(
|
||||
authentication.getActor().toUrnStr(), request, "scroll", entitySpec.getName()),
|
||||
_authorizationChain,
|
||||
authentication,
|
||||
true);
|
||||
@ -644,7 +657,7 @@ public class EntityApiDelegateImpl<I, O, S> {
|
||||
.map(asp -> asp.stream().distinct().toArray(String[]::new))
|
||||
.orElse(null);
|
||||
List<O> entities =
|
||||
Optional.ofNullable(_v1Controller.getEntities(urns, requestedAspects).getBody())
|
||||
Optional.ofNullable(_v1Controller.getEntities(request, urns, requestedAspects).getBody())
|
||||
.map(body -> body.getResponses().entrySet())
|
||||
.map(
|
||||
entries -> OpenApiEntitiesUtil.convertEntities(entries, _respClazz, systemMetadata))
|
||||
|
||||
@ -98,7 +98,7 @@ public class {{classname}}Controller implements {{classname}} {
|
||||
SearchService searchService, EntitiesController v1Controller, AuthorizerChain authorizationChain) {
|
||||
this.objectMapper = objectMapper;
|
||||
this.request = request;
|
||||
this.delegate = new EntityApiDelegateImpl<{{requestClass}}, {{responseClass}}, {{scrollResponseClass}}>(systemOperationContext, entityService, searchService, v1Controller,
|
||||
this.delegate = new EntityApiDelegateImpl<{{requestClass}}, {{responseClass}}, {{scrollResponseClass}}>(systemOperationContext, request, entityService, searchService, v1Controller,
|
||||
authorizationChain, {{requestClass}}.class, {{responseClass}}.class, {{scrollResponseClass}}.class);
|
||||
}
|
||||
{{#isJava8or11}}
|
||||
|
||||
@ -3,6 +3,7 @@ package io.datahubproject.openapi.config;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyList;
|
||||
import static org.mockito.ArgumentMatchers.nullable;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ -33,6 +34,7 @@ import io.datahubproject.openapi.v1.entities.EntitiesController;
|
||||
import io.datahubproject.openapi.v1.relationships.RelationshipsController;
|
||||
import io.datahubproject.openapi.v2.controller.TimelineControllerV2;
|
||||
import io.datahubproject.test.metadata.context.TestOperationContexts;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
@ -109,11 +111,11 @@ public class OpenAPIEntityTestConfiguration {
|
||||
@Primary
|
||||
public EntitiesController entitiesController() {
|
||||
EntitiesController entitiesController = mock(EntitiesController.class);
|
||||
when(entitiesController.getEntities(any(), any()))
|
||||
when(entitiesController.getEntities(nullable(HttpServletRequest.class), any(), any()))
|
||||
.thenAnswer(
|
||||
params -> {
|
||||
String[] urns = params.getArgument(0);
|
||||
String[] aspects = params.getArgument(1);
|
||||
String[] urns = params.getArgument(1);
|
||||
String[] aspects = params.getArgument(2);
|
||||
return ResponseEntity.ok(
|
||||
UrnResponseMap.builder()
|
||||
.responses(
|
||||
|
||||
@ -21,6 +21,7 @@ dependencies {
|
||||
implementation externalDependency.springWebMVC
|
||||
implementation externalDependency.springBeans
|
||||
implementation externalDependency.springContext
|
||||
implementation externalDependency.servletApi
|
||||
implementation externalDependency.slf4jApi
|
||||
compileOnly externalDependency.lombok
|
||||
implementation externalDependency.antlr4Runtime
|
||||
|
||||
@ -52,6 +52,7 @@ import io.datahubproject.openapi.models.GenericEntity;
|
||||
import io.datahubproject.openapi.models.GenericEntityScrollResult;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
@ -133,6 +134,7 @@ public abstract class GenericEntitiesController<
|
||||
@GetMapping(value = "/{entityName}", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@Operation(summary = "Scroll entities")
|
||||
public ResponseEntity<S> getEntities(
|
||||
HttpServletRequest request,
|
||||
@PathVariable("entityName") String entityName,
|
||||
@RequestParam(value = "aspectNames", defaultValue = "") Set<String> aspects1,
|
||||
@RequestParam(value = "aspects", defaultValue = "") Set<String> aspects2,
|
||||
@ -159,7 +161,9 @@ public abstract class GenericEntitiesController<
|
||||
OperationContext opContext =
|
||||
OperationContext.asSession(
|
||||
systemOperationContext,
|
||||
RequestContext.builder().buildOpenapi("getEntities", entityName),
|
||||
RequestContext.builder()
|
||||
.buildOpenapi(
|
||||
authentication.getActor().toUrnStr(), request, "getEntities", entityName),
|
||||
authorizationChain,
|
||||
authentication,
|
||||
true);
|
||||
@ -199,6 +203,7 @@ public abstract class GenericEntitiesController<
|
||||
value = "/{entityName}/{entityUrn:urn:li:.+}",
|
||||
produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public ResponseEntity<E> getEntity(
|
||||
HttpServletRequest request,
|
||||
@PathVariable("entityName") String entityName,
|
||||
@PathVariable("entityUrn") String entityUrn,
|
||||
@RequestParam(value = "aspectNames", defaultValue = "") Set<String> aspects1,
|
||||
@ -217,7 +222,9 @@ public abstract class GenericEntitiesController<
|
||||
OperationContext opContext =
|
||||
OperationContext.asSession(
|
||||
systemOperationContext,
|
||||
RequestContext.builder().buildOpenapi("getEntity", entityName),
|
||||
RequestContext.builder()
|
||||
.buildOpenapi(
|
||||
authentication.getActor().toUrnStr(), request, "getEntity", entityName),
|
||||
authorizationChain,
|
||||
authentication,
|
||||
true);
|
||||
@ -239,6 +246,7 @@ public abstract class GenericEntitiesController<
|
||||
method = {RequestMethod.HEAD})
|
||||
@Operation(summary = "Entity exists")
|
||||
public ResponseEntity<Object> headEntity(
|
||||
HttpServletRequest request,
|
||||
@PathVariable("entityName") String entityName,
|
||||
@PathVariable("entityUrn") String entityUrn,
|
||||
@PathVariable(value = "includeSoftDelete", required = false) Boolean includeSoftDelete)
|
||||
@ -254,7 +262,9 @@ public abstract class GenericEntitiesController<
|
||||
OperationContext opContext =
|
||||
OperationContext.asSession(
|
||||
systemOperationContext,
|
||||
RequestContext.builder().buildOpenapi("headEntity", entityName),
|
||||
RequestContext.builder()
|
||||
.buildOpenapi(
|
||||
authentication.getActor().toUrnStr(), request, "headEntity", entityName),
|
||||
authorizationChain,
|
||||
authentication,
|
||||
true);
|
||||
@ -270,6 +280,7 @@ public abstract class GenericEntitiesController<
|
||||
produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@Operation(summary = "Get an entity's generic aspect.")
|
||||
public ResponseEntity<Object> getAspect(
|
||||
HttpServletRequest request,
|
||||
@PathVariable("entityName") String entityName,
|
||||
@PathVariable("entityUrn") String entityUrn,
|
||||
@PathVariable("aspectName") String aspectName,
|
||||
@ -287,7 +298,9 @@ public abstract class GenericEntitiesController<
|
||||
OperationContext opContext =
|
||||
OperationContext.asSession(
|
||||
systemOperationContext,
|
||||
RequestContext.builder().buildOpenapi("getAspect", entityName),
|
||||
RequestContext.builder()
|
||||
.buildOpenapi(
|
||||
authentication.getActor().toUrnStr(), request, "getAspect", entityName),
|
||||
authorizationChain,
|
||||
authentication,
|
||||
true);
|
||||
@ -311,6 +324,7 @@ public abstract class GenericEntitiesController<
|
||||
method = {RequestMethod.HEAD})
|
||||
@Operation(summary = "Whether an entity aspect exists.")
|
||||
public ResponseEntity<Object> headAspect(
|
||||
HttpServletRequest request,
|
||||
@PathVariable("entityName") String entityName,
|
||||
@PathVariable("entityUrn") String entityUrn,
|
||||
@PathVariable("aspectName") String aspectName,
|
||||
@ -327,7 +341,9 @@ public abstract class GenericEntitiesController<
|
||||
OperationContext opContext =
|
||||
OperationContext.asSession(
|
||||
systemOperationContext,
|
||||
RequestContext.builder().buildOpenapi("headAspect", entityName),
|
||||
RequestContext.builder()
|
||||
.buildOpenapi(
|
||||
authentication.getActor().toUrnStr(), request, "headAspect", entityName),
|
||||
authorizationChain,
|
||||
authentication,
|
||||
true);
|
||||
@ -341,7 +357,9 @@ public abstract class GenericEntitiesController<
|
||||
@DeleteMapping(value = "/{entityName}/{entityUrn:urn:li:.+}")
|
||||
@Operation(summary = "Delete an entity")
|
||||
public void deleteEntity(
|
||||
@PathVariable("entityName") String entityName, @PathVariable("entityUrn") String entityUrn)
|
||||
HttpServletRequest request,
|
||||
@PathVariable("entityName") String entityName,
|
||||
@PathVariable("entityUrn") String entityUrn)
|
||||
throws InvalidUrnException {
|
||||
|
||||
EntitySpec entitySpec = entityRegistry.getEntitySpec(entityName);
|
||||
@ -355,7 +373,9 @@ public abstract class GenericEntitiesController<
|
||||
OperationContext opContext =
|
||||
OperationContext.asSession(
|
||||
systemOperationContext,
|
||||
RequestContext.builder().buildOpenapi("deleteEntity", entityName),
|
||||
RequestContext.builder()
|
||||
.buildOpenapi(
|
||||
authentication.getActor().toUrnStr(), request, "deleteEntity", entityName),
|
||||
authorizationChain,
|
||||
authentication,
|
||||
true);
|
||||
@ -367,6 +387,7 @@ public abstract class GenericEntitiesController<
|
||||
@PostMapping(value = "/{entityName}", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@Operation(summary = "Create a batch of entities.")
|
||||
public ResponseEntity<List<E>> createEntity(
|
||||
HttpServletRequest request,
|
||||
@PathVariable("entityName") String entityName,
|
||||
@RequestParam(value = "async", required = false, defaultValue = "true") Boolean async,
|
||||
@RequestParam(value = "systemMetadata", required = false, defaultValue = "false")
|
||||
@ -385,7 +406,9 @@ public abstract class GenericEntitiesController<
|
||||
OperationContext opContext =
|
||||
OperationContext.asSession(
|
||||
systemOperationContext,
|
||||
RequestContext.builder().buildOpenapi("createEntity", entityName),
|
||||
RequestContext.builder()
|
||||
.buildOpenapi(
|
||||
authentication.getActor().toUrnStr(), request, "createEntity", entityName),
|
||||
authorizationChain,
|
||||
authentication,
|
||||
true);
|
||||
@ -404,6 +427,7 @@ public abstract class GenericEntitiesController<
|
||||
@DeleteMapping(value = "/{entityName}/{entityUrn:urn:li:.+}/{aspectName}")
|
||||
@Operation(summary = "Delete an entity aspect.")
|
||||
public void deleteAspect(
|
||||
HttpServletRequest request,
|
||||
@PathVariable("entityName") String entityName,
|
||||
@PathVariable("entityUrn") String entityUrn,
|
||||
@PathVariable("aspectName") String aspectName)
|
||||
@ -419,7 +443,9 @@ public abstract class GenericEntitiesController<
|
||||
OperationContext opContext =
|
||||
OperationContext.asSession(
|
||||
systemOperationContext,
|
||||
RequestContext.builder().buildOpenapi("deleteAspect", entityName),
|
||||
RequestContext.builder()
|
||||
.buildOpenapi(
|
||||
authentication.getActor().toUrnStr(), request, "deleteAspect", entityName),
|
||||
authorizationChain,
|
||||
authentication,
|
||||
true);
|
||||
@ -434,6 +460,7 @@ public abstract class GenericEntitiesController<
|
||||
produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@Operation(summary = "Create an entity aspect.")
|
||||
public ResponseEntity<E> createAspect(
|
||||
HttpServletRequest request,
|
||||
@PathVariable("entityName") String entityName,
|
||||
@PathVariable("entityUrn") String entityUrn,
|
||||
@PathVariable("aspectName") String aspectName,
|
||||
@ -456,7 +483,9 @@ public abstract class GenericEntitiesController<
|
||||
OperationContext opContext =
|
||||
OperationContext.asSession(
|
||||
systemOperationContext,
|
||||
RequestContext.builder().buildOpenapi("createAspect", entityName),
|
||||
RequestContext.builder()
|
||||
.buildOpenapi(
|
||||
authentication.getActor().toUrnStr(), request, "createAspect", entityName),
|
||||
authorizationChain,
|
||||
authentication,
|
||||
true);
|
||||
@ -494,6 +523,7 @@ public abstract class GenericEntitiesController<
|
||||
produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@Operation(summary = "Patch an entity aspect. (Experimental)")
|
||||
public ResponseEntity<E> patchAspect(
|
||||
HttpServletRequest request,
|
||||
@PathVariable("entityName") String entityName,
|
||||
@PathVariable("entityUrn") String entityUrn,
|
||||
@PathVariable("aspectName") String aspectName,
|
||||
@ -517,7 +547,9 @@ public abstract class GenericEntitiesController<
|
||||
OperationContext opContext =
|
||||
OperationContext.asSession(
|
||||
systemOperationContext,
|
||||
RequestContext.builder().buildOpenapi("patchAspect", entityName),
|
||||
RequestContext.builder()
|
||||
.buildOpenapi(
|
||||
authentication.getActor().toUrnStr(), request, "patchAspect", entityName),
|
||||
authorizationChain,
|
||||
authentication,
|
||||
true);
|
||||
|
||||
@ -14,6 +14,7 @@ import io.datahubproject.openapi.openlineage.mapping.RunEventMapper;
|
||||
import io.datahubproject.openlineage.generated.controller.LineageApi;
|
||||
import io.openlineage.client.OpenLineage;
|
||||
import io.openlineage.client.OpenLineageClientUtils;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
@ -50,6 +51,8 @@ public class LineageApiImpl implements LineageApi {
|
||||
return Optional.of(OBJECT_MAPPER);
|
||||
}
|
||||
|
||||
@Autowired private HttpServletRequest request;
|
||||
|
||||
@Override
|
||||
public ResponseEntity<Void> postRunEventRaw(String body) {
|
||||
try {
|
||||
@ -68,7 +71,9 @@ public class LineageApiImpl implements LineageApi {
|
||||
OperationContext opContext =
|
||||
OperationContext.asSession(
|
||||
systemOperationContext,
|
||||
RequestContext.builder().buildOpenapi("postRunEventRaw", List.of()),
|
||||
RequestContext.builder()
|
||||
.buildOpenapi(
|
||||
authentication.getActor().toUrnStr(), request, "postRunEventRaw", List.of()),
|
||||
_authorizerChain,
|
||||
authentication,
|
||||
true);
|
||||
|
||||
@ -31,6 +31,7 @@ import io.datahubproject.openapi.util.ElasticsearchUtils;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
@ -133,7 +134,7 @@ public class OperationsController {
|
||||
@Tag(name = "ElasticSearchOperations")
|
||||
@GetMapping(path = "/getIndexSizes", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@Operation(summary = "Get Index Sizes")
|
||||
public ResponseEntity<String> getIndexSizes() {
|
||||
public ResponseEntity<String> getIndexSizes(HttpServletRequest request) {
|
||||
Authentication authentication = AuthenticationContext.getAuthentication();
|
||||
String actorUrnStr = authentication.getActor().toUrnStr();
|
||||
|
||||
@ -145,7 +146,7 @@ public class OperationsController {
|
||||
OperationContext opContext =
|
||||
OperationContext.asSession(
|
||||
systemOperationContext,
|
||||
RequestContext.builder().buildOpenapi("getIndexSizes", List.of()),
|
||||
RequestContext.builder().buildOpenapi(actorUrnStr, request, "getIndexSizes", List.of()),
|
||||
authorizerChain,
|
||||
authentication,
|
||||
true);
|
||||
@ -171,6 +172,7 @@ public class OperationsController {
|
||||
@GetMapping(path = "/explainSearchQuery", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@Operation(summary = "Explain Search Query")
|
||||
public ResponseEntity<ExplainResponse> explainSearchQuery(
|
||||
HttpServletRequest request,
|
||||
@Parameter(
|
||||
name = "query",
|
||||
required = true,
|
||||
@ -229,7 +231,8 @@ public class OperationsController {
|
||||
OperationContext opContext =
|
||||
systemOperationContext
|
||||
.asSession(
|
||||
RequestContext.builder().buildOpenapi("explainSearchQuery", entityName),
|
||||
RequestContext.builder()
|
||||
.buildOpenapi(actorUrnStr, request, "explainSearchQuery", entityName),
|
||||
authorizerChain,
|
||||
authentication)
|
||||
.withSearchFlags(
|
||||
@ -263,6 +266,7 @@ public class OperationsController {
|
||||
@GetMapping(path = "/explainSearchQueryDiff", produces = MediaType.TEXT_PLAIN_VALUE)
|
||||
@Operation(summary = "Explain the differences in scoring for 2 documents")
|
||||
public ResponseEntity<String> explainSearchQueryDiff(
|
||||
HttpServletRequest request,
|
||||
@Parameter(
|
||||
name = "query",
|
||||
required = true,
|
||||
@ -328,7 +332,8 @@ public class OperationsController {
|
||||
OperationContext opContext =
|
||||
systemOperationContext
|
||||
.asSession(
|
||||
RequestContext.builder().buildOpenapi("explainSearchQuery", entityName),
|
||||
RequestContext.builder()
|
||||
.buildOpenapi(actorUrnStr, request, "explainSearchQuery", entityName),
|
||||
authorizerChain,
|
||||
authentication)
|
||||
.withSearchFlags(
|
||||
@ -400,6 +405,7 @@ public class OperationsController {
|
||||
@GetMapping(path = "/restoreIndices", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@Operation(summary = "Restore ElasticSearch indices from primary storage based on URNs.")
|
||||
public ResponseEntity<List<RestoreIndicesResult>> restoreIndices(
|
||||
HttpServletRequest request,
|
||||
@RequestParam(required = false, name = "aspectName") @Nullable String aspectName,
|
||||
@RequestParam(required = false, name = "urn") @Nullable String urn,
|
||||
@RequestParam(required = false, name = "urnLike") @Nullable String urnLike,
|
||||
@ -419,7 +425,9 @@ public class OperationsController {
|
||||
OperationContext opContext =
|
||||
OperationContext.asSession(
|
||||
systemOperationContext,
|
||||
RequestContext.builder().buildOpenapi("restoreIndices", List.of()),
|
||||
RequestContext.builder()
|
||||
.buildOpenapi(
|
||||
authentication.getActor().toUrnStr(), request, "restoreIndices", List.of()),
|
||||
authorizerChain,
|
||||
authentication,
|
||||
true);
|
||||
@ -445,6 +453,7 @@ public class OperationsController {
|
||||
@PostMapping(path = "/restoreIndices", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@Operation(summary = "Restore ElasticSearch indices from primary storage based on URNs.")
|
||||
public ResponseEntity<List<RestoreIndicesResult>> restoreIndices(
|
||||
HttpServletRequest request,
|
||||
@RequestParam(required = false, name = "aspectNames") @Nullable Set<String> aspectNames,
|
||||
@RequestParam(required = false, name = "batchSize", defaultValue = "100") @Nullable
|
||||
Integer batchSize,
|
||||
@ -459,7 +468,9 @@ public class OperationsController {
|
||||
OperationContext opContext =
|
||||
OperationContext.asSession(
|
||||
systemOperationContext,
|
||||
RequestContext.builder().buildOpenapi("restoreIndices", List.of()),
|
||||
RequestContext.builder()
|
||||
.buildOpenapi(
|
||||
authentication.getActor().toUrnStr(), request, "restoreIndices", List.of()),
|
||||
authorizerChain,
|
||||
authentication,
|
||||
true);
|
||||
|
||||
@ -30,6 +30,7 @@ import io.datahubproject.openapi.generated.AspectRowSummary;
|
||||
import io.datahubproject.openapi.util.MappingUtil;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import java.net.URLDecoder;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
@ -90,6 +91,7 @@ public class EntitiesController {
|
||||
|
||||
@GetMapping(value = "/latest", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public ResponseEntity<UrnResponseMap> getEntities(
|
||||
HttpServletRequest request,
|
||||
@Parameter(
|
||||
name = "urns",
|
||||
required = true,
|
||||
@ -122,6 +124,8 @@ public class EntitiesController {
|
||||
systemOperationContext,
|
||||
RequestContext.builder()
|
||||
.buildOpenapi(
|
||||
actorUrnStr,
|
||||
request,
|
||||
"getEntities",
|
||||
entityUrns.stream()
|
||||
.map(Urn::getEntityType)
|
||||
@ -169,6 +173,7 @@ public class EntitiesController {
|
||||
|
||||
@PostMapping(value = "/", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public ResponseEntity<List<String>> postEntities(
|
||||
HttpServletRequest request,
|
||||
@RequestBody @Nonnull List<UpsertAspectRequest> aspectRequests,
|
||||
@RequestParam(required = false, name = "async") Boolean async,
|
||||
@RequestParam(required = false, name = "createIfNotExists") Boolean createIfNotExists,
|
||||
@ -191,6 +196,8 @@ public class EntitiesController {
|
||||
systemOperationContext,
|
||||
RequestContext.builder()
|
||||
.buildOpenapi(
|
||||
actorUrnStr,
|
||||
request,
|
||||
"postEntities",
|
||||
proposals.stream()
|
||||
.map(MetadataChangeProposal::getEntityType)
|
||||
@ -241,6 +248,7 @@ public class EntitiesController {
|
||||
|
||||
@DeleteMapping(value = "/", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public ResponseEntity<List<RollbackRunResultDto>> deleteEntities(
|
||||
HttpServletRequest request,
|
||||
@Parameter(
|
||||
name = "urns",
|
||||
required = true,
|
||||
@ -278,6 +286,8 @@ public class EntitiesController {
|
||||
systemOperationContext,
|
||||
RequestContext.builder()
|
||||
.buildOpenapi(
|
||||
actorUrnStr,
|
||||
request,
|
||||
"deleteEntities",
|
||||
entityUrns.stream().map(Urn::getEntityType).collect(Collectors.toSet())),
|
||||
_authorizerChain,
|
||||
|
||||
@ -38,6 +38,7 @@ import io.datahubproject.openapi.v2.models.GenericEntityScrollResultV2;
|
||||
import io.datahubproject.openapi.v2.models.GenericEntityV2;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
@ -87,7 +88,9 @@ public class EntityController
|
||||
@PostMapping(value = "/batch/{entityName}", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@Operation(summary = "Get a batch of entities")
|
||||
public ResponseEntity<BatchGetUrnResponse> getEntityBatch(
|
||||
@PathVariable("entityName") String entityName, @RequestBody BatchGetUrnRequest request)
|
||||
HttpServletRequest httpServletRequest,
|
||||
@PathVariable("entityName") String entityName,
|
||||
@RequestBody BatchGetUrnRequest request)
|
||||
throws URISyntaxException {
|
||||
|
||||
List<Urn> urns = request.getUrns().stream().map(UrnUtils::getUrn).collect(Collectors.toList());
|
||||
@ -100,7 +103,12 @@ public class EntityController
|
||||
OperationContext opContext =
|
||||
OperationContext.asSession(
|
||||
systemOperationContext,
|
||||
RequestContext.builder().buildOpenapi("getEntityBatch", entityName),
|
||||
RequestContext.builder()
|
||||
.buildOpenapi(
|
||||
authentication.getActor().toUrnStr(),
|
||||
httpServletRequest,
|
||||
"getEntityBatch",
|
||||
entityName),
|
||||
authorizationChain,
|
||||
authentication,
|
||||
true);
|
||||
|
||||
@ -17,6 +17,7 @@ import io.datahubproject.openapi.exception.UnauthorizedException;
|
||||
import io.datahubproject.openapi.generated.MetadataChangeProposal;
|
||||
import io.datahubproject.openapi.util.MappingUtil;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
@ -58,6 +59,7 @@ public class PlatformEntitiesController {
|
||||
|
||||
@PostMapping(value = "/", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public ResponseEntity<List<String>> postEntities(
|
||||
HttpServletRequest request,
|
||||
@RequestBody @Nonnull List<MetadataChangeProposal> metadataChangeProposals,
|
||||
@RequestParam(required = false, name = "async") Boolean async) {
|
||||
log.info("INGEST PROPOSAL proposal: {}", metadataChangeProposals);
|
||||
@ -69,6 +71,8 @@ public class PlatformEntitiesController {
|
||||
systemOperationContext,
|
||||
RequestContext.builder()
|
||||
.buildOpenapi(
|
||||
actorUrnStr,
|
||||
request,
|
||||
"postEntities",
|
||||
metadataChangeProposals.stream()
|
||||
.map(MetadataChangeProposal::getEntityType)
|
||||
|
||||
@ -22,6 +22,7 @@ import io.datahubproject.openapi.exception.UnauthorizedException;
|
||||
import io.datahubproject.openapi.models.GenericScrollResult;
|
||||
import io.datahubproject.openapi.v2.models.GenericTimeseriesAspect;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
@ -56,6 +57,7 @@ public class TimeseriesController {
|
||||
|
||||
@GetMapping(value = "/{entityName}/{aspectName}", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public ResponseEntity<GenericScrollResult<GenericTimeseriesAspect>> getAspects(
|
||||
HttpServletRequest request,
|
||||
@PathVariable("entityName") String entityName,
|
||||
@PathVariable("aspectName") String aspectName,
|
||||
@RequestParam(value = "count", defaultValue = "10") Integer count,
|
||||
@ -76,7 +78,9 @@ public class TimeseriesController {
|
||||
OperationContext opContext =
|
||||
OperationContext.asSession(
|
||||
systemOperationContext,
|
||||
RequestContext.builder().buildOpenapi("getAspects", entityName),
|
||||
RequestContext.builder()
|
||||
.buildOpenapi(
|
||||
authentication.getActor().toUrnStr(), request, "getAspects", entityName),
|
||||
authorizationChain,
|
||||
authentication,
|
||||
true);
|
||||
|
||||
@ -214,7 +214,7 @@ public class EntitiesControllerTest {
|
||||
.build();
|
||||
datasetAspects.add(glossaryTerms);
|
||||
|
||||
_entitiesController.postEntities(datasetAspects, false, false, false);
|
||||
_entitiesController.postEntities(null, datasetAspects, false, false, false);
|
||||
}
|
||||
|
||||
// @Test
|
||||
|
||||
@ -14,6 +14,7 @@ import com.linkedin.restli.common.HttpStatus;
|
||||
import com.linkedin.restli.server.RestLiServiceException;
|
||||
import com.linkedin.restli.server.annotations.Action;
|
||||
import com.linkedin.restli.server.annotations.ActionParam;
|
||||
import com.linkedin.restli.server.annotations.Context;
|
||||
import com.linkedin.restli.server.annotations.Optional;
|
||||
import com.linkedin.restli.server.annotations.RestLiSimpleResource;
|
||||
import com.linkedin.restli.server.resources.SimpleResourceTemplate;
|
||||
@ -28,6 +29,7 @@ import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import io.datahubproject.metadata.context.OperationContext;
|
||||
import io.datahubproject.metadata.context.RequestContext;
|
||||
@ -80,7 +82,8 @@ public class Analytics extends SimpleResourceTemplate<GetTimeseriesAggregatedSta
|
||||
HttpStatus.S_403_FORBIDDEN, "User is unauthorized to get entity " + entityName);
|
||||
}
|
||||
final OperationContext opContext = OperationContext.asSession(
|
||||
systemOperationContext, RequestContext.builder().buildRestli(ACTION_GET_TIMESERIES_STATS, entityName), authorizer, auth, true);
|
||||
systemOperationContext, RequestContext.builder().buildRestli(auth.getActor().toUrnStr(), getContext(),
|
||||
ACTION_GET_TIMESERIES_STATS, entityName), authorizer, auth, true);
|
||||
|
||||
log.info("Attempting to query timeseries stats");
|
||||
GetTimeseriesAggregatedStatsResponse resp = new GetTimeseriesAggregatedStatsResponse();
|
||||
|
||||
@ -148,7 +148,7 @@ public class AspectResource extends CollectionResourceTaskTemplate<String, Versi
|
||||
HttpStatus.S_403_FORBIDDEN, "User is unauthorized to get aspect for " + urn);
|
||||
}
|
||||
final OperationContext opContext = OperationContext.asSession(
|
||||
systemOperationContext, RequestContext.builder().buildRestli("authorizerChain", urn.getEntityType()), _authorizer, auth, true);
|
||||
systemOperationContext, RequestContext.builder().buildRestli(auth.getActor().toUrnStr(), getContext(), "authorizerChain", urn.getEntityType()), _authorizer, auth, true);
|
||||
|
||||
final VersionedAspect aspect =
|
||||
_entityService.getVersionedAspect(opContext, urn, aspectName, version);
|
||||
@ -199,7 +199,7 @@ public class AspectResource extends CollectionResourceTaskTemplate<String, Versi
|
||||
"User is unauthorized to get timeseries aspect for " + urn);
|
||||
}
|
||||
final OperationContext opContext = OperationContext.asSession(
|
||||
systemOperationContext, RequestContext.builder().buildRestli(ACTION_GET_TIMESERIES_ASPECT, urn.getEntityType()), _authorizer, auth, true);
|
||||
systemOperationContext, RequestContext.builder().buildRestli(auth.getActor().toUrnStr(), getContext(), ACTION_GET_TIMESERIES_ASPECT, urn.getEntityType()), _authorizer, auth, true);
|
||||
|
||||
GetTimeseriesAspectValuesResponse response = new GetTimeseriesAspectValuesResponse();
|
||||
response.setEntityName(entityName);
|
||||
@ -280,7 +280,7 @@ public class AspectResource extends CollectionResourceTaskTemplate<String, Versi
|
||||
.map(MetadataChangeProposal::getEntityType)
|
||||
.collect(Collectors.toSet());
|
||||
final OperationContext opContext = OperationContext.asSession(
|
||||
systemOperationContext, RequestContext.builder().buildRestli(ACTION_INGEST_PROPOSAL, entityTypes), _authorizer, authentication, true);
|
||||
systemOperationContext, RequestContext.builder().buildRestli(authentication.getActor().toUrnStr(), getContext(), ACTION_INGEST_PROPOSAL, entityTypes), _authorizer, authentication, true);
|
||||
|
||||
// Ingest Authorization Checks
|
||||
List<Pair<MetadataChangeProposal, Integer>> exceptions = isAPIAuthorized(authentication, _authorizer, ENTITY,
|
||||
@ -344,7 +344,7 @@ public class AspectResource extends CollectionResourceTaskTemplate<String, Versi
|
||||
HttpStatus.S_403_FORBIDDEN, "User is unauthorized to get aspect counts.");
|
||||
}
|
||||
final OperationContext opContext = OperationContext.asSession(
|
||||
systemOperationContext, RequestContext.builder().buildRestli(ACTION_GET_COUNT, List.of()), _authorizer, authentication, true);
|
||||
systemOperationContext, RequestContext.builder().buildRestli(authentication.getActor().toUrnStr(), getContext(), ACTION_GET_COUNT, List.of()), _authorizer, authentication, true);
|
||||
|
||||
return _entityService.getCountAspect(opContext, aspectName, urnLike);
|
||||
},
|
||||
@ -373,7 +373,7 @@ public class AspectResource extends CollectionResourceTaskTemplate<String, Versi
|
||||
HttpStatus.S_403_FORBIDDEN, "User is unauthorized to update entities.");
|
||||
}
|
||||
|
||||
return Utils.restoreIndices(systemOperationContext,
|
||||
return Utils.restoreIndices(systemOperationContext, getContext(),
|
||||
aspectName, urn, urnLike, start, batchSize, limit, gePitEpochMs, lePitEpochMs, _authorizer, _entityService);
|
||||
},
|
||||
MetricRegistry.name(this.getClass(), "restoreIndices"));
|
||||
|
||||
@ -95,7 +95,7 @@ public class BatchIngestionRunResource
|
||||
HttpStatus.S_403_FORBIDDEN, "User is unauthorized to update entity");
|
||||
}
|
||||
final OperationContext opContext = OperationContext.asSession(
|
||||
systemOperationContext, RequestContext.builder().buildRestli("rollback", List.of()), authorizer, auth, true);
|
||||
systemOperationContext, RequestContext.builder().buildRestli(auth.getActor().toUrnStr(), getContext(), "rollback", List.of()), authorizer, auth, true);
|
||||
|
||||
log.info("ROLLBACK RUN runId: {} dry run: {}", runId, dryRun);
|
||||
|
||||
@ -171,7 +171,7 @@ public class BatchIngestionRunResource
|
||||
HttpStatus.S_403_FORBIDDEN, "User is unauthorized to get entity");
|
||||
}
|
||||
final OperationContext opContext = OperationContext.asSession(
|
||||
systemOperationContext, RequestContext.builder().buildRestli("describe", List.of()), authorizer, auth, true);
|
||||
systemOperationContext, RequestContext.builder().buildRestli(auth.getActor().toUrnStr(), getContext(), "describe", List.of()), authorizer, auth, true);
|
||||
|
||||
List<AspectRowSummary> summaries =
|
||||
systemMetadataService.findByRunId(
|
||||
|
||||
@ -200,7 +200,7 @@ public class EntityResource extends CollectionResourceTaskTemplate<String, Entit
|
||||
HttpStatus.S_403_FORBIDDEN, "User is unauthorized to get entity " + urn);
|
||||
}
|
||||
final OperationContext opContext = OperationContext.asSession(
|
||||
systemOperationContext, RequestContext.builder().buildRestli("restrictedService", urn.getEntityType()), authorizer, auth, true);
|
||||
systemOperationContext, RequestContext.builder().buildRestli(auth.getActor().toUrnStr(), getContext(), "restrictedService", urn.getEntityType()), authorizer, auth, true);
|
||||
|
||||
return RestliUtil.toTask(
|
||||
() -> {
|
||||
@ -240,7 +240,7 @@ public class EntityResource extends CollectionResourceTaskTemplate<String, Entit
|
||||
HttpStatus.S_403_FORBIDDEN, "User is unauthorized to get entities: " + urnStrs);
|
||||
}
|
||||
final OperationContext opContext = OperationContext.asSession(
|
||||
systemOperationContext, RequestContext.builder().buildRestli("batchGet", urnStrs), authorizer, auth, true);
|
||||
systemOperationContext, RequestContext.builder().buildRestli(auth.getActor().toUrnStr(), getContext(), "batchGet", urnStrs), authorizer, auth, true);
|
||||
|
||||
return RestliUtil.toTask(
|
||||
() -> {
|
||||
@ -289,7 +289,7 @@ public class EntityResource extends CollectionResourceTaskTemplate<String, Entit
|
||||
HttpStatus.S_403_FORBIDDEN, "User is unauthorized to edit entity " + urn);
|
||||
}
|
||||
final OperationContext opContext = OperationContext.asSession(
|
||||
systemOperationContext, RequestContext.builder().buildRestli(ACTION_INGEST, urn.getEntityType()), authorizer, authentication, true);
|
||||
systemOperationContext, RequestContext.builder().buildRestli(authentication.getActor().toUrnStr(), getContext(), ACTION_INGEST, urn.getEntityType()), authorizer, authentication, true);
|
||||
|
||||
try {
|
||||
validateOrThrow(entity);
|
||||
@ -334,7 +334,7 @@ public class EntityResource extends CollectionResourceTaskTemplate<String, Entit
|
||||
HttpStatus.S_403_FORBIDDEN, "User is unauthorized to edit entities.");
|
||||
}
|
||||
final OperationContext opContext = OperationContext.asSession(
|
||||
systemOperationContext, RequestContext.builder().buildRestli(ACTION_BATCH_INGEST, urns.stream()
|
||||
systemOperationContext, RequestContext.builder().buildRestli(authentication.getActor().toUrnStr(), getContext(), ACTION_BATCH_INGEST, urns.stream()
|
||||
.map(Urn::getEntityType).collect(Collectors.toList())), authorizer, authentication, true);
|
||||
|
||||
for (Entity entity : entities) {
|
||||
@ -394,7 +394,7 @@ public class EntityResource extends CollectionResourceTaskTemplate<String, Entit
|
||||
}
|
||||
|
||||
OperationContext opContext = OperationContext.asSession(systemOperationContext,
|
||||
RequestContext.builder().buildRestli(ACTION_SEARCH, entityName), authorizer, auth, true)
|
||||
RequestContext.builder().buildRestli(auth.getActor().toUrnStr(), getContext(), ACTION_SEARCH, entityName), authorizer, auth, true)
|
||||
.withSearchFlags(flags -> searchFlags != null ? searchFlags : new SearchFlags().setFulltext(Boolean.TRUE.equals(fulltext)));
|
||||
|
||||
log.info("GET SEARCH RESULTS for {} with query {}", entityName, input);
|
||||
@ -434,7 +434,7 @@ public class EntityResource extends CollectionResourceTaskTemplate<String, Entit
|
||||
|
||||
final Authentication auth = AuthenticationContext.getAuthentication();
|
||||
OperationContext opContext = OperationContext.asSession(
|
||||
systemOperationContext, RequestContext.builder().buildRestli(ACTION_SEARCH_ACROSS_ENTITIES, entities), authorizer, auth, true)
|
||||
systemOperationContext, RequestContext.builder().buildRestli(auth.getActor().toUrnStr(), getContext(), ACTION_SEARCH_ACROSS_ENTITIES, entities), authorizer, auth, true)
|
||||
.withSearchFlags(flags -> searchFlags != null ? searchFlags : new SearchFlags().setFulltext(true));
|
||||
|
||||
List<String> entityList = searchService.getEntitiesToSearch(opContext, entities == null ? Collections.emptyList() : Arrays.asList(entities), count);
|
||||
@ -478,7 +478,7 @@ public class EntityResource extends CollectionResourceTaskTemplate<String, Entit
|
||||
|
||||
final Authentication auth = AuthenticationContext.getAuthentication();
|
||||
OperationContext opContext = OperationContext.asSession(
|
||||
systemOperationContext, RequestContext.builder().buildRestli(ACTION_SCROLL_ACROSS_ENTITIES, entities), authorizer, auth, true)
|
||||
systemOperationContext, RequestContext.builder().buildRestli(auth.getActor().toUrnStr(), getContext(), ACTION_SCROLL_ACROSS_ENTITIES, entities), authorizer, auth, true)
|
||||
.withSearchFlags(flags -> searchFlags != null ? searchFlags : new SearchFlags().setFulltext(true));
|
||||
|
||||
List<String> entityList = searchService.getEntitiesToSearch(opContext, entities == null ? Collections.emptyList() : Arrays.asList(entities), count);
|
||||
@ -547,7 +547,7 @@ public class EntityResource extends CollectionResourceTaskTemplate<String, Entit
|
||||
}
|
||||
|
||||
OperationContext opContext = OperationContext.asSession(
|
||||
systemOperationContext, RequestContext.builder().buildRestli(ACTION_SEARCH_ACROSS_LINEAGE, entities), authorizer, auth, true)
|
||||
systemOperationContext, RequestContext.builder().buildRestli(auth.getActor().toUrnStr(), getContext(), ACTION_SEARCH_ACROSS_LINEAGE, entities), authorizer, auth, true)
|
||||
.withSearchFlags(flags -> (searchFlags != null ? searchFlags : new SearchFlags().setFulltext(true))
|
||||
.setIncludeRestricted(true))
|
||||
.withLineageFlags(flags -> flags.setStartTimeMillis(startTimeMillis, SetMode.REMOVE_IF_NULL)
|
||||
@ -606,7 +606,7 @@ public class EntityResource extends CollectionResourceTaskTemplate<String, Entit
|
||||
}
|
||||
|
||||
OperationContext opContext = OperationContext.asSession(
|
||||
systemOperationContext, RequestContext.builder().buildRestli(ACTION_SCROLL_ACROSS_LINEAGE, entities),
|
||||
systemOperationContext, RequestContext.builder().buildRestli(auth.getActor().toUrnStr(), getContext(), ACTION_SCROLL_ACROSS_LINEAGE, entities),
|
||||
authorizer, auth, true)
|
||||
.withSearchFlags(flags -> (searchFlags != null ? searchFlags : new SearchFlags().setSkipCache(true))
|
||||
.setIncludeRestricted(true))
|
||||
@ -661,7 +661,7 @@ public class EntityResource extends CollectionResourceTaskTemplate<String, Entit
|
||||
}
|
||||
|
||||
OperationContext opContext = OperationContext.asSession(
|
||||
systemOperationContext, RequestContext.builder().buildRestli(ACTION_LIST, entityName), authorizer, auth, true)
|
||||
systemOperationContext, RequestContext.builder().buildRestli(auth.getActor().toUrnStr(), getContext(), ACTION_LIST, entityName), authorizer, auth, true)
|
||||
.withSearchFlags(flags -> new SearchFlags().setFulltext(false));
|
||||
|
||||
log.info("GET LIST RESULTS for {} with filter {}", entityName, filter);
|
||||
@ -702,7 +702,7 @@ public class EntityResource extends CollectionResourceTaskTemplate<String, Entit
|
||||
}
|
||||
|
||||
OperationContext opContext = OperationContext.asSession(
|
||||
systemOperationContext, RequestContext.builder().buildRestli(ACTION_AUTOCOMPLETE, entityName), authorizer, auth, true)
|
||||
systemOperationContext, RequestContext.builder().buildRestli(auth.getActor().toUrnStr(), getContext(), ACTION_AUTOCOMPLETE, entityName), authorizer, auth, true)
|
||||
.withSearchFlags(flags -> searchFlags != null ? searchFlags : flags);
|
||||
|
||||
return RestliUtil.toTask(
|
||||
@ -740,7 +740,7 @@ public class EntityResource extends CollectionResourceTaskTemplate<String, Entit
|
||||
}
|
||||
|
||||
OperationContext opContext = OperationContext.asSession(
|
||||
systemOperationContext, RequestContext.builder().buildRestli(ACTION_BROWSE, entityName), authorizer, auth, true)
|
||||
systemOperationContext, RequestContext.builder().buildRestli(auth.getActor().toUrnStr(), getContext(), ACTION_BROWSE, entityName), authorizer, auth, true)
|
||||
.withSearchFlags(flags -> searchFlags != null ? searchFlags : flags);
|
||||
|
||||
log.info("GET BROWSE RESULTS for {} at path {}", entityName, path);
|
||||
@ -779,7 +779,7 @@ public class EntityResource extends CollectionResourceTaskTemplate<String, Entit
|
||||
log.info("GET BROWSE PATHS for {}", urn);
|
||||
|
||||
OperationContext opContext = OperationContext.asSession(
|
||||
systemOperationContext, RequestContext.builder().buildRestli(ACTION_GET_BROWSE_PATHS, urn.getEntityType()), authorizer, auth, true);
|
||||
systemOperationContext, RequestContext.builder().buildRestli(auth.getActor().toUrnStr(), getContext(), ACTION_GET_BROWSE_PATHS, urn.getEntityType()), authorizer, auth, true);
|
||||
|
||||
return RestliUtil.toTask(
|
||||
() -> new StringArray(entitySearchService.getBrowsePaths(opContext, urnToEntityName(urn), urn)),
|
||||
@ -848,7 +848,7 @@ public class EntityResource extends CollectionResourceTaskTemplate<String, Entit
|
||||
HttpStatus.S_403_FORBIDDEN, "User is unauthorized to delete entities.");
|
||||
}
|
||||
OperationContext opContext = OperationContext.asSession(
|
||||
systemOperationContext, RequestContext.builder().buildRestli("deleteAll", urns), authorizer, auth, true);
|
||||
systemOperationContext, RequestContext.builder().buildRestli(auth.getActor().toUrnStr(), getContext(), "deleteAll", urns), authorizer, auth, true);
|
||||
|
||||
response.setEntitiesAffected(urns.size());
|
||||
response.setEntitiesDeleted(
|
||||
@ -899,7 +899,7 @@ public class EntityResource extends CollectionResourceTaskTemplate<String, Entit
|
||||
HttpStatus.S_403_FORBIDDEN, "User is unauthorized to delete entity: " + urnStr);
|
||||
}
|
||||
final OperationContext opContext = OperationContext.asSession(
|
||||
systemOperationContext, RequestContext.builder().buildRestli(ACTION_DELETE, urn.getEntityType()), authorizer, auth, true);
|
||||
systemOperationContext, RequestContext.builder().buildRestli(auth.getActor().toUrnStr(), getContext(), ACTION_DELETE, urn.getEntityType()), authorizer, auth, true);
|
||||
|
||||
return RestliUtil.toTask(
|
||||
() -> {
|
||||
@ -961,7 +961,7 @@ public class EntityResource extends CollectionResourceTaskTemplate<String, Entit
|
||||
HttpStatus.S_403_FORBIDDEN, "User is unauthorized to delete entity " + urn);
|
||||
}
|
||||
final OperationContext opContext = OperationContext.asSession(
|
||||
systemOperationContext, RequestContext.builder().buildRestli("deleteTimeseriesAspects", urn.getEntityType()), authorizer, auth, true);
|
||||
systemOperationContext, RequestContext.builder().buildRestli(auth.getActor().toUrnStr(), getContext(), "deleteTimeseriesAspects", urn.getEntityType()), authorizer, auth, true);
|
||||
|
||||
// Construct the filter.
|
||||
List<Criterion> criteria = new ArrayList<>();
|
||||
@ -1017,7 +1017,7 @@ public class EntityResource extends CollectionResourceTaskTemplate<String, Entit
|
||||
HttpStatus.S_403_FORBIDDEN, "User is unauthorized to delete entity " + urnStr);
|
||||
}
|
||||
final OperationContext opContext = OperationContext.asSession(
|
||||
systemOperationContext, RequestContext.builder().buildRestli("deleteReferences", urn.getEntityType()), authorizer, auth, true);
|
||||
systemOperationContext, RequestContext.builder().buildRestli(auth.getActor().toUrnStr(), getContext(), "deleteReferences", urn.getEntityType()), authorizer, auth, true);
|
||||
|
||||
return RestliUtil.toTask(
|
||||
() -> deleteEntityService.deleteReferencesTo(opContext, urn, dryRun),
|
||||
@ -1062,7 +1062,7 @@ public class EntityResource extends CollectionResourceTaskTemplate<String, Entit
|
||||
HttpStatus.S_403_FORBIDDEN, "User is unauthorized to get entity counts.");
|
||||
}
|
||||
OperationContext opContext = OperationContext.asSession(
|
||||
systemOperationContext, RequestContext.builder().buildRestli("getTotalEntityCount", entityName), authorizer, auth, true);
|
||||
systemOperationContext, RequestContext.builder().buildRestli(auth.getActor().toUrnStr(), getContext(), "getTotalEntityCount", entityName), authorizer, auth, true);
|
||||
return RestliUtil.toTask(() -> entitySearchService.docCount(opContext, entityName));
|
||||
}
|
||||
|
||||
@ -1080,7 +1080,7 @@ public class EntityResource extends CollectionResourceTaskTemplate<String, Entit
|
||||
HttpStatus.S_403_FORBIDDEN, "User is unauthorized to get entity counts.");
|
||||
}
|
||||
OperationContext opContext = OperationContext.asSession(
|
||||
systemOperationContext, RequestContext.builder().buildRestli("batchGetTotalEntityCount", entityNames), authorizer, auth, true);
|
||||
systemOperationContext, RequestContext.builder().buildRestli(auth.getActor().toUrnStr(), getContext(), "batchGetTotalEntityCount", entityNames), authorizer, auth, true);
|
||||
return RestliUtil.toTask(
|
||||
() -> new LongMap(searchService.docCountPerEntity(opContext, Arrays.asList(entityNames))));
|
||||
}
|
||||
@ -1103,7 +1103,7 @@ public class EntityResource extends CollectionResourceTaskTemplate<String, Entit
|
||||
HttpStatus.S_403_FORBIDDEN, "User is unauthorized to search.");
|
||||
}
|
||||
OperationContext opContext = OperationContext.asSession(
|
||||
systemOperationContext, RequestContext.builder().buildRestli(ACTION_LIST_URNS, entityName), authorizer, auth, true);
|
||||
systemOperationContext, RequestContext.builder().buildRestli(auth.getActor().toUrnStr(), getContext(), ACTION_LIST_URNS, entityName), authorizer, auth, true);
|
||||
|
||||
log.info("LIST URNS for {} with start {} and count {}", entityName, start, count);
|
||||
return RestliUtil.toTask(() -> {
|
||||
@ -1145,7 +1145,7 @@ public class EntityResource extends CollectionResourceTaskTemplate<String, Entit
|
||||
HttpStatus.S_403_FORBIDDEN, "User is unauthorized to apply retention.");
|
||||
}
|
||||
OperationContext opContext = OperationContext.asSession(
|
||||
systemOperationContext, RequestContext.builder().buildRestli(ACTION_APPLY_RETENTION, resourceSpec.getType()), authorizer, auth, true);
|
||||
systemOperationContext, RequestContext.builder().buildRestli(auth.getActor().toUrnStr(), getContext(), ACTION_APPLY_RETENTION, resourceSpec.getType()), authorizer, auth, true);
|
||||
|
||||
return RestliUtil.toTask(
|
||||
() -> entityService.batchApplyRetention(opContext, start, count, attemptWithVersion, aspectName, urn),
|
||||
@ -1171,7 +1171,7 @@ public class EntityResource extends CollectionResourceTaskTemplate<String, Entit
|
||||
HttpStatus.S_403_FORBIDDEN, "User is unauthorized to search.");
|
||||
}
|
||||
OperationContext opContext = OperationContext.asSession(
|
||||
systemOperationContext, RequestContext.builder().buildRestli(ACTION_FILTER, entityName), authorizer, auth, true);
|
||||
systemOperationContext, RequestContext.builder().buildRestli(auth.getActor().toUrnStr(), getContext(), ACTION_FILTER, entityName), authorizer, auth, true);
|
||||
log.info("FILTER RESULTS for {} with filter {}", entityName, filter);
|
||||
return RestliUtil.toTask(
|
||||
() -> {
|
||||
@ -1206,7 +1206,7 @@ public class EntityResource extends CollectionResourceTaskTemplate<String, Entit
|
||||
HttpStatus.S_403_FORBIDDEN, "User is unauthorized check entity existence: " + urnStr);
|
||||
}
|
||||
OperationContext opContext = OperationContext.asSession(
|
||||
systemOperationContext, RequestContext.builder().buildRestli(ACTION_EXISTS, urn.getEntityType()), authorizer, auth, true);
|
||||
systemOperationContext, RequestContext.builder().buildRestli(auth.getActor().toUrnStr(), getContext(), ACTION_EXISTS, urn.getEntityType()), authorizer, auth, true);
|
||||
log.info("EXISTS for {}", urnStr);
|
||||
final boolean includeRemoved = includeSoftDelete == null || includeSoftDelete;
|
||||
return RestliUtil.toTask(
|
||||
|
||||
@ -79,7 +79,7 @@ public class EntityV2Resource extends CollectionResourceTaskTemplate<String, Ent
|
||||
HttpStatus.S_403_FORBIDDEN, "User is unauthorized to get entity " + urn);
|
||||
}
|
||||
final OperationContext opContext = OperationContext.asSession(
|
||||
systemOperationContext, RequestContext.builder().buildRestli("getEntityV2", urn.getEntityType()), _authorizer, auth, true);
|
||||
systemOperationContext, RequestContext.builder().buildRestli(auth.getActor().toUrnStr(), getContext(), "getEntityV2", urn.getEntityType()), _authorizer, auth, true);
|
||||
|
||||
return RestliUtil.toTask(
|
||||
() -> {
|
||||
@ -123,7 +123,7 @@ public class EntityV2Resource extends CollectionResourceTaskTemplate<String, Ent
|
||||
HttpStatus.S_403_FORBIDDEN, "User is unauthorized to get entities " + urnStrs);
|
||||
}
|
||||
final OperationContext opContext = OperationContext.asSession(
|
||||
systemOperationContext, RequestContext.builder().buildRestli("getEntityV2", urns.stream().map(Urn::getEntityType).collect(Collectors.toList())), _authorizer, auth, true);
|
||||
systemOperationContext, RequestContext.builder().buildRestli(auth.getActor().toUrnStr(), getContext(), "getEntityV2", urns.stream().map(Urn::getEntityType).collect(Collectors.toList())), _authorizer, auth, true);
|
||||
|
||||
if (urns.size() <= 0) {
|
||||
return Task.value(Collections.emptyMap());
|
||||
|
||||
@ -88,7 +88,7 @@ public class EntityVersionedV2Resource
|
||||
"User is unauthorized to get entities " + versionedUrnStrs);
|
||||
}
|
||||
final OperationContext opContext = OperationContext.asSession(
|
||||
systemOperationContext, RequestContext.builder().buildRestli("authorizerChain", urns.stream()
|
||||
systemOperationContext, RequestContext.builder().buildRestli(auth.getActor().toUrnStr(), getContext(), "authorizerChain", urns.stream()
|
||||
.map(Urn::getEntityType).collect(Collectors.toList())), _authorizer, auth, true);
|
||||
|
||||
log.debug("BATCH GET VERSIONED V2 {}", versionedUrnStrs);
|
||||
|
||||
@ -107,7 +107,7 @@ public class OperationsResource extends CollectionResourceTaskTemplate<String, V
|
||||
@ActionParam("gePitEpochMs") @Optional @Nullable Long gePitEpochMs,
|
||||
@ActionParam("lePitEpochMs") @Optional @Nullable Long lePitEpochMs) {
|
||||
return RestliUtil.toTask(
|
||||
() -> Utils.restoreIndices(systemOperationContext,
|
||||
() -> Utils.restoreIndices(systemOperationContext, getContext(),
|
||||
aspectName, urn, urnLike, start, batchSize, limit, gePitEpochMs, lePitEpochMs, _authorizer, _entityService),
|
||||
MetricRegistry.name(this.getClass(), "restoreIndices"));
|
||||
}
|
||||
@ -202,7 +202,7 @@ public class OperationsResource extends CollectionResourceTaskTemplate<String, V
|
||||
HttpStatus.S_403_FORBIDDEN, "User is unauthorized to get index sizes.");
|
||||
}
|
||||
final OperationContext opContext = OperationContext.asSession(
|
||||
systemOperationContext, RequestContext.builder().buildRestli(ACTION_GET_INDEX_SIZES, List.of()), _authorizer, auth, true);
|
||||
systemOperationContext, RequestContext.builder().buildRestli(auth.getActor().toUrnStr(), getContext(), ACTION_GET_INDEX_SIZES, List.of()), _authorizer, auth, true);
|
||||
|
||||
TimeseriesIndicesSizesResult result = new TimeseriesIndicesSizesResult();
|
||||
result.setIndexSizes(
|
||||
@ -232,7 +232,7 @@ public class OperationsResource extends CollectionResourceTaskTemplate<String, V
|
||||
HttpStatus.S_403_FORBIDDEN, "User is unauthorized to truncate timeseries index");
|
||||
}
|
||||
final OperationContext opContext = OperationContext.asSession(
|
||||
systemOperationContext, RequestContext.builder().buildRestli("executeTruncateTimeseriesAspect", entityType), _authorizer, auth, true);
|
||||
systemOperationContext, RequestContext.builder().buildRestli(auth.getActor().toUrnStr(), getContext(), "executeTruncateTimeseriesAspect", entityType), _authorizer, auth, true);
|
||||
|
||||
if (forceDeleteByQuery != null && forceDeleteByQuery.equals(forceReindex)) {
|
||||
return "please only set forceReindex OR forceDeleteByQuery flags";
|
||||
|
||||
@ -13,6 +13,7 @@ import com.linkedin.metadata.entity.EntityService;
|
||||
import com.linkedin.metadata.entity.restoreindices.RestoreIndicesArgs;
|
||||
import com.linkedin.metadata.entity.restoreindices.RestoreIndicesResult;
|
||||
import com.linkedin.restli.common.HttpStatus;
|
||||
import com.linkedin.restli.server.ResourceContext;
|
||||
import com.linkedin.restli.server.RestLiServiceException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@ -32,7 +33,8 @@ public class Utils {
|
||||
private Utils() {}
|
||||
|
||||
public static String restoreIndices(
|
||||
@Nonnull OperationContext systemOperationContext,
|
||||
@Nonnull OperationContext systemOperationContext,
|
||||
@Nonnull ResourceContext resourceContext,
|
||||
@Nonnull String aspectName,
|
||||
@Nullable String urn,
|
||||
@Nullable String urnLike,
|
||||
@ -59,7 +61,7 @@ public class Utils {
|
||||
HttpStatus.S_403_FORBIDDEN, "User is unauthorized to restore indices.");
|
||||
}
|
||||
final OperationContext opContext = OperationContext.asSession(
|
||||
systemOperationContext, RequestContext.builder().buildRestli("restoreIndices", List.of()), authorizer, auth, true);
|
||||
systemOperationContext, RequestContext.builder().buildRestli(auth.getActor().toUrnStr(), resourceContext, "restoreIndices", List.of()), authorizer, auth, true);
|
||||
|
||||
RestoreIndicesArgs args =
|
||||
new RestoreIndicesArgs()
|
||||
|
||||
@ -141,7 +141,7 @@ public class UsageStats extends SimpleResourceTemplate<UsageAggregation> {
|
||||
HttpStatus.S_403_FORBIDDEN, "User is unauthorized to edit entities.");
|
||||
}
|
||||
final OperationContext opContext = OperationContext.asSession(
|
||||
systemOperationContext, RequestContext.builder().buildRestli(ACTION_BATCH_INGEST, urns.stream()
|
||||
systemOperationContext, RequestContext.builder().buildRestli(auth.getActor().toUrnStr(), getContext(), ACTION_BATCH_INGEST, urns.stream()
|
||||
.map(Urn::getEntityType).collect(Collectors.toList())), _authorizer, auth, true);
|
||||
|
||||
for (UsageAggregation agg : buckets) {
|
||||
@ -180,7 +180,7 @@ public class UsageStats extends SimpleResourceTemplate<UsageAggregation> {
|
||||
HttpStatus.S_403_FORBIDDEN, "User is unauthorized to query usage.");
|
||||
}
|
||||
final OperationContext opContext = OperationContext.asSession(
|
||||
systemOperationContext, RequestContext.builder().buildRestli(ACTION_QUERY, resourceUrn.getEntityType()), _authorizer, auth, true);
|
||||
systemOperationContext, RequestContext.builder().buildRestli(auth.getActor().toUrnStr(), getContext(), ACTION_QUERY, resourceUrn.getEntityType()), _authorizer, auth, true);
|
||||
|
||||
return UsageServiceUtil.query(opContext, _timeseriesAspectService, resource, duration, startTime, endTime, maxBuckets);
|
||||
},
|
||||
@ -207,7 +207,7 @@ public class UsageStats extends SimpleResourceTemplate<UsageAggregation> {
|
||||
}
|
||||
|
||||
final OperationContext opContext = OperationContext.asSession(
|
||||
systemOperationContext, RequestContext.builder().buildRestli(ACTION_QUERY_RANGE, resourceUrn.getEntityType()), _authorizer, auth, true);
|
||||
systemOperationContext, RequestContext.builder().buildRestli(auth.getActor().toUrnStr(), getContext(), ACTION_QUERY_RANGE, resourceUrn.getEntityType()), _authorizer, auth, true);
|
||||
|
||||
return RestliUtil.toTask(
|
||||
() -> UsageServiceUtil.queryRange(opContext, _timeseriesAspectService, resource, duration, range), MetricRegistry.name(this.getClass(), "queryRange"));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user