feat(openapi): restore Timeline OpenAPIv1 and deprecations (#10768)

This commit is contained in:
david-leifker 2024-06-24 16:13:53 -05:00 committed by GitHub
parent 567811353d
commit d494e352ed
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 104 additions and 3 deletions

View File

@ -24,6 +24,10 @@ This file documents any backwards-incompatible changes in DataHub and assists pe
### Deprecations
- OpenAPI v1: OpenAPI v1 is collectively defined as all endpoints which are not prefixed with `/v2` or `/v3`. The v1 endpoints
will be deprecated in no less than 6 months. Endpoints will be replaced with equivalents in the `/v2` or `/v3` APIs.
No loss of functionality expected unless explicitly mentioned in Breaking Changes.
### Other Notable Changes
## 0.13.3

View File

@ -31,7 +31,7 @@ import io.datahubproject.openapi.dto.UrnResponseMap;
import io.datahubproject.openapi.generated.EntityResponse;
import io.datahubproject.openapi.v1.entities.EntitiesController;
import io.datahubproject.openapi.v1.relationships.RelationshipsController;
import io.datahubproject.openapi.v2.controller.TimelineController;
import io.datahubproject.openapi.v2.controller.TimelineControllerV2;
import io.datahubproject.test.metadata.context.TestOperationContexts;
import java.util.Arrays;
import java.util.Map;
@ -126,7 +126,7 @@ public class OpenAPIEntityTestConfiguration {
return entitiesController;
}
@MockBean public TimelineController timelineController;
@MockBean public TimelineControllerV2 timelineControllerV2;
@MockBean public RelationshipsController relationshipsController;

View File

@ -55,6 +55,10 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/*
Use v2 or v3 controllers instead
*/
@Deprecated
@RestController
@RequestMapping("/entities/v1")
@Slf4j

View File

@ -41,6 +41,10 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/*
Use v2 or v3 controllers instead
*/
@Deprecated
@RestController
@RequiredArgsConstructor
@RequestMapping("/relationships/v1")

View File

@ -0,0 +1,89 @@
package io.datahubproject.openapi.v1.timeline;
import com.datahub.authentication.Authentication;
import com.datahub.authentication.AuthenticationContext;
import com.datahub.authorization.AuthUtil;
import com.datahub.authorization.AuthorizerChain;
import com.datahub.authorization.ConjunctivePrivilegeGroup;
import com.datahub.authorization.DisjunctivePrivilegeGroup;
import com.datahub.authorization.EntitySpec;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.google.common.collect.ImmutableList;
import com.linkedin.common.urn.Urn;
import com.linkedin.metadata.authorization.PoliciesConfig;
import com.linkedin.metadata.timeline.TimelineService;
import com.linkedin.metadata.timeline.data.ChangeCategory;
import com.linkedin.metadata.timeline.data.ChangeTransaction;
import io.datahubproject.openapi.exception.UnauthorizedException;
import io.swagger.v3.oas.annotations.tags.Tag;
import java.net.URISyntaxException;
import java.util.List;
import java.util.Set;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/*
Use v2 or v3 controllers instead
*/
@Deprecated
@RestController
@AllArgsConstructor
@RequestMapping("/timeline/v1")
@Tag(
name = "Timeline",
description =
"An API for retrieving historical updates to entities and their related documentation.")
public class TimelineControllerV1 {
private final TimelineService _timelineService;
private final AuthorizerChain _authorizerChain;
@Value("${authorization.restApiAuthorization:false}")
private Boolean restApiAuthorizationEnabled;
/**
* @param rawUrn
* @param startTime
* @param endTime
* @param raw
* @param categories
* @return
* @throws URISyntaxException
* @throws JsonProcessingException
*/
@GetMapping(path = "/{urn}", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<List<ChangeTransaction>> getTimeline(
@PathVariable("urn") String rawUrn,
@RequestParam(name = "startTime", defaultValue = "-1") long startTime,
@RequestParam(name = "endTime", defaultValue = "0") long endTime,
@RequestParam(name = "raw", defaultValue = "false") boolean raw,
@RequestParam(name = "categories") Set<ChangeCategory> categories)
throws URISyntaxException, JsonProcessingException {
// Make request params when implemented
String startVersionStamp = null;
String endVersionStamp = null;
Urn urn = Urn.createFromString(rawUrn);
Authentication authentication = AuthenticationContext.getAuthentication();
String actorUrnStr = authentication.getActor().toUrnStr();
EntitySpec resourceSpec = new EntitySpec(urn.getEntityType(), rawUrn);
DisjunctivePrivilegeGroup orGroup =
new DisjunctivePrivilegeGroup(
ImmutableList.of(
new ConjunctivePrivilegeGroup(
ImmutableList.of(PoliciesConfig.GET_TIMELINE_PRIVILEGE.getType()))));
if (restApiAuthorizationEnabled
&& !AuthUtil.isAuthorized(_authorizerChain, actorUrnStr, orGroup, resourceSpec)) {
throw new UnauthorizedException(actorUrnStr + " is unauthorized to edit entities.");
}
return ResponseEntity.ok(
_timelineService.getTimeline(
urn, categories, startTime, endTime, startVersionStamp, endVersionStamp, raw));
}
}

View File

@ -36,7 +36,7 @@ import org.springframework.web.bind.annotation.RestController;
name = "Timeline",
description =
"An API for retrieving historical updates to entities and their related documentation.")
public class TimelineController {
public class TimelineControllerV2 {
private final TimelineService _timelineService;
private final AuthorizerChain _authorizerChain;