Cleanup unused snapshot resources for corp users & groups

This commit is contained in:
Kerem Sahin 2020-03-03 15:37:00 -08:00
parent a8f6016543
commit 970a003cc3
10 changed files with 3 additions and 568 deletions

View File

@ -44,7 +44,7 @@ the application directly from command line after a successful [build](#build):
### Get user
```
➜ curl -H 'X-RestLi-Protocol-Version:2.0.0' -H 'X-RestLi-Method: get' 'http://localhost:8080/corpUsers/($params:(),name:fbar)/snapshot/($params:(),aspectVersions:List((aspect:com.linkedin.identity.CorpUserInfo,version:0)))' | jq
➜ curl 'http://localhost:8080/corpUsers?action=getSnapshot' -X POST -H 'X-RestLi-Protocol-Version:2.0.0' --data '{"urn": "urn:li:corpuser:fbar"}' -v
{
"urn": "urn:li:corpuser:fbar",
"aspects": [

View File

@ -95,38 +95,7 @@
} ]
} ],
"entity" : {
"path" : "/corpGroups/{corpGroup}",
"subresources" : [ {
"annotations" : {
"createOnly" : {
"value" : [ "urn" ]
},
"deprecated" : {
"doc" : "Use corresponding action methods in /corpGroups"
}
},
"name" : "snapshot",
"namespace" : "com.linkedin.identity.corpgroup",
"path" : "/corpGroups/{corpGroup}/snapshot",
"schema" : "com.linkedin.metadata.snapshot.CorpGroupSnapshot",
"doc" : "Rest.li entry point: /corpGroups/{corpGroupKey}/snapshot\n\ngenerated from: com.linkedin.identity.rest.resources.CorpGroupsSnapshot",
"collection" : {
"identifier" : {
"name" : "snapshotId",
"type" : "com.linkedin.metadata.snapshot.SnapshotKey",
"params" : "com.linkedin.restli.common.EmptyRecord"
},
"supports" : [ "create", "get" ],
"methods" : [ {
"method" : "create"
}, {
"method" : "get"
} ],
"entity" : {
"path" : "/corpGroups/{corpGroup}/snapshot/{snapshotId}"
}
}
} ]
"path" : "/corpGroups/{corpGroup}"
}
}
}

View File

@ -133,36 +133,6 @@
"path" : "/corpUsers/{corpUser}/editableInfo/{editableInfoId}"
}
}
}, {
"annotations" : {
"createOnly" : {
"value" : [ "urn" ]
},
"deprecated" : {
"doc" : "Use corresponding action methods in /corpUsers"
}
},
"name" : "snapshot",
"namespace" : "com.linkedin.identity.corpuser",
"path" : "/corpUsers/{corpUser}/snapshot",
"schema" : "com.linkedin.metadata.snapshot.CorpUserSnapshot",
"doc" : "Rest.li entry point: /corpUsers/{corpUserKey}/snapshot\n\ngenerated from: com.linkedin.identity.rest.resources.CorpUsersSnapshot",
"collection" : {
"identifier" : {
"name" : "snapshotId",
"type" : "com.linkedin.metadata.snapshot.SnapshotKey",
"params" : "com.linkedin.restli.common.EmptyRecord"
},
"supports" : [ "create", "get" ],
"methods" : [ {
"method" : "create"
}, {
"method" : "get"
} ],
"entity" : {
"path" : "/corpUsers/{corpUser}/snapshot/{snapshotId}"
}
}
} ]
}
}

View File

@ -129,20 +129,6 @@
"optional" : true
} ]
}, "com.linkedin.identity.CorpGroupInfo", "com.linkedin.identity.CorpGroupKey", {
"type" : "record",
"name" : "AspectVersion",
"namespace" : "com.linkedin.metadata.aspect",
"doc" : "A tuple of a specific metadata aspect and its version.",
"fields" : [ {
"name" : "aspect",
"type" : "string",
"doc" : "The FQCN of the metadata aspect, e.g. com.linkedin.common.Ownership"
}, {
"name" : "version",
"type" : "long",
"doc" : "The version of the metadata aspect"
} ]
}, {
"type" : "typeref",
"name" : "CorpGroupAspect",
"namespace" : "com.linkedin.metadata.aspect",
@ -285,19 +271,6 @@
},
"doc" : "The list of metadata aspects associated with the LdapUser. Depending on the use case, this can either be all, or a selection, of supported aspects."
} ]
}, {
"type" : "record",
"name" : "SnapshotKey",
"namespace" : "com.linkedin.metadata.snapshot",
"doc" : "The Key for a metadata Snapshot.",
"fields" : [ {
"name" : "aspectVersions",
"type" : {
"type" : "array",
"items" : "com.linkedin.metadata.aspect.AspectVersion"
},
"doc" : "A list of metadata aspects in the Snapshot and their versions"
} ]
}, {
"type" : "record",
"name" : "EmptyRecord",
@ -405,38 +378,7 @@
} ]
} ],
"entity" : {
"path" : "/corpGroups/{corpGroup}",
"subresources" : [ {
"annotations" : {
"createOnly" : {
"value" : [ "urn" ]
},
"deprecated" : {
"doc" : "Use corresponding action methods in /corpGroups"
}
},
"name" : "snapshot",
"namespace" : "com.linkedin.identity.corpgroup",
"path" : "/corpGroups/{corpGroup}/snapshot",
"schema" : "com.linkedin.metadata.snapshot.CorpGroupSnapshot",
"doc" : "Rest.li entry point: /corpGroups/{corpGroupKey}/snapshot\n\ngenerated from: com.linkedin.identity.rest.resources.CorpGroupsSnapshot",
"collection" : {
"identifier" : {
"name" : "snapshotId",
"type" : "com.linkedin.metadata.snapshot.SnapshotKey",
"params" : "com.linkedin.restli.common.EmptyRecord"
},
"supports" : [ "create", "get" ],
"methods" : [ {
"method" : "create"
}, {
"method" : "get"
} ],
"entity" : {
"path" : "/corpGroups/{corpGroup}/snapshot/{snapshotId}"
}
}
} ]
"path" : "/corpGroups/{corpGroup}"
}
}
}

View File

@ -176,20 +176,6 @@
}
}
} ]
}, {
"type" : "record",
"name" : "AspectVersion",
"namespace" : "com.linkedin.metadata.aspect",
"doc" : "A tuple of a specific metadata aspect and its version.",
"fields" : [ {
"name" : "aspect",
"type" : "string",
"doc" : "The FQCN of the metadata aspect, e.g. com.linkedin.common.Ownership"
}, {
"name" : "version",
"type" : "long",
"doc" : "The version of the metadata aspect"
} ]
}, {
"type" : "typeref",
"name" : "CorpUserAspect",
@ -333,19 +319,6 @@
},
"doc" : "The list of metadata aspects associated with the CorpUser. Depending on the use case, this can either be all, or a selection, of supported aspects."
} ]
}, {
"type" : "record",
"name" : "SnapshotKey",
"namespace" : "com.linkedin.metadata.snapshot",
"doc" : "The Key for a metadata Snapshot.",
"fields" : [ {
"name" : "aspectVersions",
"type" : {
"type" : "array",
"items" : "com.linkedin.metadata.aspect.AspectVersion"
},
"doc" : "A list of metadata aspects in the Snapshot and their versions"
} ]
}, {
"type" : "record",
"name" : "EmptyRecord",
@ -491,36 +464,6 @@
"path" : "/corpUsers/{corpUser}/editableInfo/{editableInfoId}"
}
}
}, {
"annotations" : {
"createOnly" : {
"value" : [ "urn" ]
},
"deprecated" : {
"doc" : "Use corresponding action methods in /corpUsers"
}
},
"name" : "snapshot",
"namespace" : "com.linkedin.identity.corpuser",
"path" : "/corpUsers/{corpUser}/snapshot",
"schema" : "com.linkedin.metadata.snapshot.CorpUserSnapshot",
"doc" : "Rest.li entry point: /corpUsers/{corpUserKey}/snapshot\n\ngenerated from: com.linkedin.identity.rest.resources.CorpUsersSnapshot",
"collection" : {
"identifier" : {
"name" : "snapshotId",
"type" : "com.linkedin.metadata.snapshot.SnapshotKey",
"params" : "com.linkedin.restli.common.EmptyRecord"
},
"supports" : [ "create", "get" ],
"methods" : [ {
"method" : "create"
}, {
"method" : "get"
} ],
"entity" : {
"path" : "/corpUsers/{corpUser}/snapshot/{snapshotId}"
}
}
} ]
}
}

View File

@ -1,52 +0,0 @@
package com.linkedin.identity.client;
import com.linkedin.common.urn.CorpGroupUrn;
import com.linkedin.identity.CorpGroupKey;
import com.linkedin.identity.corpgroup.SnapshotRequestBuilders;
import com.linkedin.metadata.restli.BaseClient;
import com.linkedin.metadata.snapshot.CorpGroupSnapshot;
import com.linkedin.metadata.snapshot.SnapshotKey;
import com.linkedin.r2.RemoteInvocationException;
import com.linkedin.restli.client.Client;
import com.linkedin.restli.client.CreateIdRequest;
import com.linkedin.restli.client.GetRequest;
import com.linkedin.restli.common.ComplexResourceKey;
import com.linkedin.restli.common.EmptyRecord;
import javax.annotation.Nonnull;
public class CorpGroupSnapshots extends BaseClient {
private static final SnapshotRequestBuilders SNAPSHOT_REQUEST_BUILDERS = new SnapshotRequestBuilders();
public CorpGroupSnapshots(@Nonnull Client restliClient) {
super(restliClient);
}
@Nonnull
public CorpGroupSnapshot get(@Nonnull CorpGroupUrn urn, @Nonnull SnapshotKey snapshotKey)
throws RemoteInvocationException {
GetRequest<CorpGroupSnapshot> getRequest = SNAPSHOT_REQUEST_BUILDERS.get()
.corpGroupKey(new ComplexResourceKey<>(toCorpGroupKey(urn), new EmptyRecord()))
.id(new ComplexResourceKey<>(snapshotKey, new EmptyRecord()))
.build();
return _client.sendRequest(getRequest).getResponseEntity();
}
@Nonnull
public SnapshotKey create(@Nonnull CorpGroupUrn urn, @Nonnull CorpGroupSnapshot snapshot)
throws RemoteInvocationException {
CreateIdRequest<ComplexResourceKey<SnapshotKey, EmptyRecord>, CorpGroupSnapshot> createRequest =
SNAPSHOT_REQUEST_BUILDERS.create()
.corpGroupKey(new ComplexResourceKey<>(toCorpGroupKey(urn), new EmptyRecord()))
.input(snapshot)
.build();
return _client.sendRequest(createRequest).getResponseEntity().getId().getKey();
}
private CorpGroupKey toCorpGroupKey(CorpGroupUrn urn) {
return new CorpGroupKey().setName(urn.getGroupNameEntity());
}
}

View File

@ -1,69 +0,0 @@
package com.linkedin.identity.rest.resources;
import com.linkedin.common.urn.CorpGroupUrn;
import com.linkedin.identity.CorpGroupKey;
import com.linkedin.metadata.aspect.CorpGroupAspect;
import com.linkedin.metadata.dao.BaseLocalDAO;
import com.linkedin.metadata.dao.EbeanLocalDAO;
import com.linkedin.metadata.restli.BaseSnapshotResource;
import com.linkedin.metadata.snapshot.CorpGroupSnapshot;
import com.linkedin.metadata.snapshot.SnapshotKey;
import com.linkedin.parseq.Task;
import com.linkedin.restli.common.ComplexResourceKey;
import com.linkedin.restli.common.EmptyRecord;
import com.linkedin.restli.common.validation.CreateOnly;
import com.linkedin.restli.server.CreateResponse;
import com.linkedin.restli.server.PathKeys;
import com.linkedin.restli.server.annotations.PathKeysParam;
import com.linkedin.restli.server.annotations.RestLiCollection;
import com.linkedin.restli.server.annotations.RestMethod;
import javax.annotation.Nonnull;
import javax.inject.Inject;
import javax.inject.Named;
import lombok.extern.slf4j.Slf4j;
/**
* Rest.li entry point: /corpGroups/{corpGroupKey}/snapshot
*
* @deprecated Use corresponding action methods in /corpGroups
*/
@Slf4j
@RestLiCollection(name = "snapshot", namespace = "com.linkedin.identity.corpgroup", parent = CorpGroups.class)
@CreateOnly({"urn"})
public class CorpGroupsSnapshot extends BaseSnapshotResource<CorpGroupUrn, CorpGroupSnapshot, CorpGroupAspect> {
private static final String CORPGROUP_KEY = CorpGroups.class.getAnnotation(RestLiCollection.class).keyName();
public CorpGroupsSnapshot() {
super(CorpGroupSnapshot.class, CorpGroupAspect.class);
}
@Inject
@Named("corpGroupDao")
private EbeanLocalDAO localDAO;
@Override
@RestMethod.Create
public Task<CreateResponse> create(@Nonnull CorpGroupSnapshot snapshot) {
return super.create(snapshot);
}
@Override
@RestMethod.Get
public Task<CorpGroupSnapshot> get(@Nonnull ComplexResourceKey<SnapshotKey, EmptyRecord> snapshotKey) {
return super.get(snapshotKey);
}
@Nonnull
@Override
protected BaseLocalDAO<CorpGroupAspect, CorpGroupUrn> getLocalDAO() {
return localDAO;
}
@Nonnull
@Override
protected CorpGroupUrn getUrn(@PathKeysParam @Nonnull PathKeys keys) {
return new CorpGroupUrn(keys.<ComplexResourceKey<CorpGroupKey, EmptyRecord>>get(CORPGROUP_KEY).getKey().getName());
}
}

View File

@ -1,69 +0,0 @@
package com.linkedin.identity.rest.resources;
import com.linkedin.common.urn.CorpuserUrn;
import com.linkedin.identity.CorpUserKey;
import com.linkedin.metadata.aspect.CorpUserAspect;
import com.linkedin.metadata.dao.BaseLocalDAO;
import com.linkedin.metadata.dao.EbeanLocalDAO;
import com.linkedin.metadata.restli.BaseSnapshotResource;
import com.linkedin.metadata.snapshot.CorpUserSnapshot;
import com.linkedin.metadata.snapshot.SnapshotKey;
import com.linkedin.parseq.Task;
import com.linkedin.restli.common.ComplexResourceKey;
import com.linkedin.restli.common.EmptyRecord;
import com.linkedin.restli.common.validation.CreateOnly;
import com.linkedin.restli.server.CreateResponse;
import com.linkedin.restli.server.PathKeys;
import com.linkedin.restli.server.annotations.PathKeysParam;
import com.linkedin.restli.server.annotations.RestLiCollection;
import com.linkedin.restli.server.annotations.RestMethod;
import javax.annotation.Nonnull;
import javax.inject.Inject;
import javax.inject.Named;
import lombok.extern.slf4j.Slf4j;
/**
* Rest.li entry point: /corpUsers/{corpUserKey}/snapshot
*
* @deprecated Use corresponding action methods in /corpUsers
*/
@Slf4j
@RestLiCollection(name = "snapshot", namespace = "com.linkedin.identity.corpuser", parent = CorpUsers.class)
@CreateOnly({"urn"})
public class CorpUsersSnapshot extends BaseSnapshotResource<CorpuserUrn, CorpUserSnapshot, CorpUserAspect> {
private static final String CORPUSER_KEY = CorpUsers.class.getAnnotation(RestLiCollection.class).keyName();
public CorpUsersSnapshot() {
super(CorpUserSnapshot.class, CorpUserAspect.class);
}
@Inject
@Named("corpUserDao")
private EbeanLocalDAO localDAO;
@Override
@RestMethod.Create
public Task<CreateResponse> create(@Nonnull CorpUserSnapshot corpUserSnapshot) {
return super.create(corpUserSnapshot);
}
@Override
@RestMethod.Get
public Task<CorpUserSnapshot> get(@Nonnull ComplexResourceKey<SnapshotKey, EmptyRecord> snapshotKey) {
return super.get(snapshotKey);
}
@Nonnull
@Override
protected BaseLocalDAO<CorpUserAspect, CorpuserUrn> getLocalDAO() {
return localDAO;
}
@Nonnull
@Override
protected CorpuserUrn getUrn(@PathKeysParam @Nonnull PathKeys keys) {
return new CorpuserUrn(keys.<ComplexResourceKey<CorpUserKey, EmptyRecord>>get(CORPUSER_KEY).getKey().getName());
}
}

View File

@ -1,104 +0,0 @@
package com.linkedin.identity.rest.resources;
import com.linkedin.common.AuditStamp;
import com.linkedin.common.CorpGroupUrnArray;
import com.linkedin.common.CorpuserUrnArray;
import com.linkedin.common.urn.CorpGroupUrn;
import com.linkedin.common.urn.CorpuserUrn;
import com.linkedin.identity.CorpGroupInfo;
import com.linkedin.metadata.aspect.CorpGroupAspect;
import com.linkedin.metadata.aspect.CorpGroupAspectArray;
import com.linkedin.metadata.dao.BaseLocalDAO;
import com.linkedin.metadata.restli.BaseSnapshotResource;
import com.linkedin.metadata.snapshot.CorpGroupSnapshot;
import com.linkedin.parseq.BaseEngineTest;
import com.linkedin.restli.server.CreateResponse;
import com.linkedin.restli.server.PathKeys;
import com.linkedin.restli.server.ResourceContext;
import javax.annotation.Nonnull;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import static org.mockito.Mockito.*;
import static org.testng.Assert.*;
public class CorpGroupsSnapshotTest extends BaseEngineTest {
private BaseLocalDAO<CorpGroupAspect, CorpGroupUrn> _mockLocalDAO;
private CorpGroupUrn corpGroupUrn = new CorpGroupUrn("foo");
class CorpGroupSnapshotResource extends BaseSnapshotResource<CorpGroupUrn, CorpGroupSnapshot, CorpGroupAspect> {
public CorpGroupSnapshotResource() {
super(CorpGroupSnapshot.class, CorpGroupAspect.class);
}
@Nonnull
@Override
protected BaseLocalDAO<CorpGroupAspect, CorpGroupUrn> getLocalDAO() {
return _mockLocalDAO;
}
@Nonnull
@Override
protected CorpGroupUrn getUrn(@Nonnull PathKeys entityPathKeys) {
return corpGroupUrn;
}
@Override
public ResourceContext getContext() {
return mock(ResourceContext.class);
}
}
@BeforeMethod
public void setup() {
_mockLocalDAO = mock(BaseLocalDAO.class);
}
@Test
public void testCreate() {
CorpGroupSnapshotResource resource = new CorpGroupSnapshotResource();
CorpGroupSnapshot snapshot = new CorpGroupSnapshot();
CorpGroupAspect aspect = new CorpGroupAspect();
CorpGroupInfo info = new CorpGroupInfo();
info.setEmail("foo-dev@linkedin.com");
CorpuserUrnArray admins = new CorpuserUrnArray();
CorpuserUrn admin1 = new CorpuserUrn("admin1");
admins.add(admin1);
CorpuserUrnArray members = new CorpuserUrnArray();
CorpuserUrn member1 = new CorpuserUrn("member1");
CorpuserUrn member2 = new CorpuserUrn("member2");
members.add(member1);
members.add(member2);
CorpGroupUrnArray groups = new CorpGroupUrnArray();
CorpGroupUrn group1 = new CorpGroupUrn("group1");
CorpGroupUrn group2 = new CorpGroupUrn("group2");
CorpGroupUrn group3 = new CorpGroupUrn("group3");
groups.add(group1);
groups.add(group2);
groups.add(group3);
info.setAdmins(admins);
info.setMembers(members);
info.setGroups(groups);
aspect.setCorpGroupInfo(info);
CorpGroupAspectArray arr = new CorpGroupAspectArray();
arr.add(aspect);
snapshot.setAspects(arr);
CreateResponse response = runAndWait(resource.create(snapshot));
assertFalse(response.hasError());
verify(_mockLocalDAO, times(1)).add(eq(corpGroupUrn), eq(info), any(AuditStamp.class));
}
}

View File

@ -1,95 +0,0 @@
package com.linkedin.identity.rest.resources;
import com.linkedin.common.AuditStamp;
import com.linkedin.common.urn.CorpuserUrn;
import com.linkedin.identity.CorpUserInfo;
import com.linkedin.metadata.aspect.AspectVersion;
import com.linkedin.metadata.aspect.AspectVersionArray;
import com.linkedin.metadata.aspect.CorpUserAspect;
import com.linkedin.metadata.aspect.CorpUserAspectArray;
import com.linkedin.metadata.dao.BaseLocalDAO;
import com.linkedin.metadata.dao.utils.ModelUtils;
import com.linkedin.metadata.restli.BaseSnapshotResource;
import com.linkedin.metadata.snapshot.CorpUserSnapshot;
import com.linkedin.metadata.snapshot.SnapshotKey;
import com.linkedin.parseq.BaseEngineTest;
import com.linkedin.restli.server.CreateResponse;
import com.linkedin.restli.server.PathKeys;
import com.linkedin.restli.server.ResourceContext;
import javax.annotation.Nonnull;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import static org.mockito.Mockito.*;
import static org.testng.Assert.*;
public class CorpUsersSnapshotTest extends BaseEngineTest {
private BaseLocalDAO<CorpUserAspect, CorpuserUrn> _mockLocalDAO;
private CorpuserUrn corpUserUrn = new CorpuserUrn("foo");
class CorpUserSnapshotResource extends BaseSnapshotResource<CorpuserUrn, CorpUserSnapshot, CorpUserAspect> {
public CorpUserSnapshotResource() {
super(CorpUserSnapshot.class, CorpUserAspect.class);
}
@Nonnull
@Override
protected BaseLocalDAO<CorpUserAspect, CorpuserUrn> getLocalDAO() {
return _mockLocalDAO;
}
@Nonnull
@Override
protected CorpuserUrn getUrn(@Nonnull PathKeys entityPathKeys) {
return corpUserUrn;
}
@Override
public ResourceContext getContext() {
return mock(ResourceContext.class);
}
}
@BeforeMethod
public void setup() {
_mockLocalDAO = mock(BaseLocalDAO.class);
}
@Test
public void testCreate() {
CorpUserSnapshotResource resource = new CorpUserSnapshotResource();
CorpUserSnapshot snapshot = new CorpUserSnapshot();
CorpUserInfo info = new CorpUserInfo();
info.setFirstName("hang");
info.setLastName("zhang");
info.setActive(true);
CorpUserAspect aspect = new CorpUserAspect();
aspect.setCorpUserInfo(info);
CorpUserAspectArray arr = new CorpUserAspectArray();
arr.add(aspect);
snapshot.setAspects(arr);
snapshot.setUrn(corpUserUrn);
SnapshotKey sKey = new SnapshotKey();
AspectVersionArray array = new AspectVersionArray();
AspectVersion v = new AspectVersion();
v.setAspect(ModelUtils.getAspectName(CorpUserInfo.class));
v.setVersion(0L);
array.add(v);
sKey.setAspectVersions(array);
CreateResponse response = runAndWait(resource.create(snapshot));
assertFalse(response.hasError());
verify(_mockLocalDAO, times(1)).add(eq(corpUserUrn), eq(info), any(AuditStamp.class));
}
}