Skip to content

Commit

Permalink
Merge pull request #700 from MrCreosote/develop
Browse files Browse the repository at this point in the history
Add method to set admin meta to DAO
  • Loading branch information
MrCreosote authored Oct 23, 2023
2 parents 4272d05 + 5dd0d33 commit 19ec7c0
Show file tree
Hide file tree
Showing 11 changed files with 803 additions and 331 deletions.
4 changes: 4 additions & 0 deletions src/us/kbase/workspace/database/ObjectIDResolvedWS.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

public class ObjectIDResolvedWS {

// TODO JAVADOC
// TODO TEST
// TODO CODE use optionals vs nulls in returns

private final ResolvedWorkspaceID rwsi;
private final String name;
private final Long id;
Expand Down
13 changes: 13 additions & 0 deletions src/us/kbase/workspace/database/WorkspaceDatabase.java
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,19 @@ WorkspaceInformation createWorkspace(WorkspaceUser owner,
Optional<Instant> setWorkspaceMeta(ResolvedWorkspaceID wsid, MetadataUpdate meta)
throws WorkspaceCommunicationException, CorruptWorkspaceDBException;

/** Sets administrative metadata on one or more objects, overwriting existing keys if
* duplicate keys are supplied.
* @param update object identifiers mapped to the metadata update for each object.
* @throws NoSuchObjectException if any of the objects don't exist.
* @throws WorkspaceCommunicationException if a communication error occurs.
* @throws CorruptWorkspaceDBException if the workspace database is corrupt.
* @throws IllegalArgumentException if no metadata is supplied or the
* updated metadata exceeds the allowed size.
*/
void setAdminObjectMeta(Map<ObjectIDResolvedWS, MetadataUpdate> update)
throws NoSuchObjectException, WorkspaceCommunicationException,
CorruptWorkspaceDBException;

/** Clone a workspace.
* @param user the user cloning the workspace
* @param wsid the ID of the workspace to be cloned.
Expand Down
14 changes: 13 additions & 1 deletion src/us/kbase/workspace/database/mongo/Fields.java
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,22 @@ public class Fields {
public static final String VER_TYPE_MINOR_VERSION = "tymin";
public static final String VER_SIZE = "size";
public static final String VER_RVRT = "revert";
public static final String VER_META = "meta";
public static final String VER_COPIED = "copied";
//in 0.3.0, if missing assume no external IDs
public static final String VER_EXT_IDS = "extids";
/*
* Metadata provided by the user and / or automatically extracted from the object, stored
* as a list of dictionaries, each with a key and value field (see below), storing the
* metadata key and metadata value for each metadata key/value pair. It is stored this
* way rather than a simple mapping so that mongo can index the metadata.
*/
public static final String VER_META = "meta";
/*
* Metadata provided by an administrative user, stored the same way as user metadata.
* As of 2023/10/12 administrative metadata is not indexed and there are no plans to index it.
*/
public static final String VER_ADMINMETA = "adminmeta";
// may want a moddate for admin meta in the future? YAGNI for now

// meta document key & value
public static final String META_KEY = "k";
Expand Down
97 changes: 75 additions & 22 deletions src/us/kbase/workspace/database/mongo/MongoWorkspaceDB.java
Original file line number Diff line number Diff line change
Expand Up @@ -700,7 +700,8 @@ private void setCreatedWorkspacePermissions(
@FunctionalInterface
interface DocumentProvider {
Map<String, Object> getDocument()
throws WorkspaceCommunicationException, CorruptWorkspaceDBException;
throws WorkspaceCommunicationException, CorruptWorkspaceDBException,
NoSuchObjectException;
}

@Override
Expand All @@ -709,23 +710,77 @@ public Optional<Instant> setWorkspaceMeta(
final MetadataUpdate meta)
throws WorkspaceCommunicationException, CorruptWorkspaceDBException {
requireNonNull(rwsi, "rwsi");
return setMetadataOnDocument(
meta,
COL_WORKSPACES,
() -> query.queryWorkspace(rwsi, newHashSet(Fields.WS_META)),
new Document(Fields.WS_ID, rwsi.getID()),
Fields.WS_META,
Fields.WS_MODDATE);
try {
return setMetadataOnDocument(
meta,
COL_WORKSPACES,
() -> query.queryWorkspace(rwsi, newHashSet(Fields.WS_META)),
new Document(Fields.WS_ID, rwsi.getID()),
Fields.WS_META,
Fields.WS_MODDATE);
} catch (NoSuchObjectException e) {
throw new RuntimeException("You divided by zero, didn't you, you absolute muppet", e);
}
}



@Override
public void setAdminObjectMeta(final Map<ObjectIDResolvedWS, MetadataUpdate> update)
throws NoSuchObjectException, WorkspaceCommunicationException,
CorruptWorkspaceDBException {
noNulls(requireNonNull(update, "update").keySet(), "null object ID in update");
final Map<ObjectIDResolvedWS, ResolvedObjectID> oids = resolveObjectIDs(update.keySet());
final Set<String> fields = new HashSet<>(Arrays.asList(Fields.VER_ADMINMETA));
for (final ObjectIDResolvedWS oirw: update.keySet()) {
final ResolvedObjectID roi = oids.get(oirw);
try {
setMetadataOnDocument(
update.get(oirw),
COL_WORKSPACE_VERS,
() -> queryVersions(new HashSet<>(Arrays.asList(roi)), fields, false)
.get(roi),
new Document(Fields.VER_WS_ID, roi.getWorkspaceIdentifier().getID())
.append(Fields.VER_ID, roi.getId())
.append(Fields.VER_VER, roi.getVersion()),
Fields.VER_ADMINMETA,
null);
} catch (IllegalArgumentException e) {
final String err;
if (oirw.getVersion() == null) {
err = String.format(
"Error setting metadata on workspace %s id %s, object %s, "
+ "latest version: %s",
oirw.getWorkspaceIdentifier().getName(),
oirw.getWorkspaceIdentifier().getID(),
oirw.getIdentifierString(),
e.getMessage()
);
} else {
err = String.format(
"Error setting metadata on workspace %s id %s, object %s, "
+ "version %s: %s",
oirw.getWorkspaceIdentifier().getName(),
oirw.getWorkspaceIdentifier().getID(),
oirw.getIdentifierString(),
oirw.getVersion(),
e.getMessage()
);
}
throw new IllegalArgumentException(err, e);
}
}
}

private Optional<Instant> setMetadataOnDocument(
final MetadataUpdate newMeta,
final String collection,
final DocumentProvider dp,
final Document identifier,
final String metaField,
final String moddateField)
throws WorkspaceCommunicationException, CorruptWorkspaceDBException {
throws WorkspaceCommunicationException, CorruptWorkspaceDBException,
NoSuchObjectException {
if (newMeta == null || !newMeta.hasUpdate()) {
throw new IllegalArgumentException("No metadata changes provided");
}
Expand Down Expand Up @@ -972,7 +1027,7 @@ public Instant lockWorkspace(final ResolvedWorkspaceID rwsi)
Fields.VER_TYPE_NAME, Fields.VER_TYPE_MAJOR_VERSION, Fields.VER_TYPE_MINOR_VERSION,
Fields.VER_CHKSUM, Fields.VER_SIZE,
Fields.VER_PROV, Fields.VER_REF, Fields.VER_PROVREF,
Fields.VER_COPIED, Fields.VER_META, Fields.VER_EXT_IDS);
Fields.VER_COPIED, Fields.VER_META, Fields.VER_ADMINMETA, Fields.VER_EXT_IDS);

@Override
public CopyResult copyObject(
Expand Down Expand Up @@ -2278,7 +2333,7 @@ private void saveData(
}

private static final Set<String> FLDS_VER_GET_OBJECT = newHashSet(
Fields.VER_VER, Fields.VER_META,
Fields.VER_VER, Fields.VER_META, Fields.VER_ADMINMETA,
Fields.VER_TYPE_NAME, Fields.VER_TYPE_MAJOR_VERSION, Fields.VER_TYPE_MINOR_VERSION,
Fields.VER_SAVEDATE, Fields.VER_SAVEDBY,
Fields.VER_CHKSUM, Fields.VER_SIZE, Fields.VER_PROV,
Expand Down Expand Up @@ -2619,14 +2674,14 @@ private Map<Reference, ObjectReferenceSet> buildReferenceToReferencesMap(
private static final Set<String> FLDS_GETREFOBJ = newHashSet(
Fields.VER_WS_ID, Fields.VER_ID, Fields.VER_VER,
Fields.VER_TYPE_NAME, Fields.VER_TYPE_MAJOR_VERSION, Fields.VER_TYPE_MINOR_VERSION,
Fields.VER_META, Fields.VER_SAVEDATE, Fields.VER_SAVEDBY,
Fields.VER_META, Fields.VER_ADMINMETA, Fields.VER_SAVEDATE, Fields.VER_SAVEDBY,
Fields.VER_CHKSUM, Fields.VER_SIZE,
Fields.VER_PROVREF, Fields.VER_REF);

@Override
public Map<ObjectIDResolvedWS, Set<ObjectInformation>>
getReferencingObjects(final PermissionSet perms,
final Set<ObjectIDResolvedWS> objs)
public Map<ObjectIDResolvedWS, Set<ObjectInformation>> getReferencingObjects(
final PermissionSet perms,
final Set<ObjectIDResolvedWS> objs)
throws NoSuchObjectException, WorkspaceCommunicationException {
final List<Long> wsids = new LinkedList<Long>();
for (final ResolvedWorkspaceID ws: perms.getWorkspaces()) {
Expand Down Expand Up @@ -2927,19 +2982,16 @@ public List<ObjectInformation> getObjectInformation(
Fields.VER_WS_ID, Fields.VER_ID, Fields.VER_VER,
Fields.VER_TYPE_NAME, Fields.VER_TYPE_MAJOR_VERSION, Fields.VER_TYPE_MINOR_VERSION,
Fields.VER_CHKSUM, Fields.VER_SIZE,
Fields.VER_META, Fields.VER_SAVEDATE, Fields.VER_SAVEDBY);
Fields.VER_META, Fields.VER_ADMINMETA, Fields.VER_SAVEDATE, Fields.VER_SAVEDBY);

@Override
public List<ObjectInformation> getObjectHistory(
final ObjectIDResolvedWS oi)
throws NoSuchObjectException, WorkspaceCommunicationException {
final ResolvedObjectID roi = resolveObjectIDs(
new HashSet<ObjectIDResolvedWS>(Arrays.asList(oi))).get(oi);
final ResolvedObjectIDNoVer o =
new ResolvedObjectIDNoVer(roi);
final ResolvedObjectID roi = resolveObjectIDs(new HashSet<>(Arrays.asList(oi))).get(oi);
final ResolvedObjectIDNoVer o = new ResolvedObjectIDNoVer(roi);
final List<Map<String, Object>> versions = queryAllVersions(
new HashSet<ResolvedObjectIDNoVer>(Arrays.asList(o)),
FLDS_VER_OBJ_HIST).get(o);
new HashSet<>(Arrays.asList(o)), FLDS_VER_OBJ_HIST).get(o);
final LinkedList<ObjectInformation> ret =
new LinkedList<ObjectInformation>();
for (final Map<String, Object> v: versions) {
Expand Down Expand Up @@ -2968,6 +3020,7 @@ public Map<ObjectIDResolvedWS, ObjectInformation> getObjectInformation(
if (includeMetadata) {
fields = new HashSet<>(FLDS_VER_META);
fields.add(Fields.VER_META);
fields.add(Fields.VER_ADMINMETA);
} else {
fields = FLDS_VER_META;
}
Expand Down
16 changes: 13 additions & 3 deletions src/us/kbase/workspace/database/mongo/ObjectInfoUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,13 @@ public Map<Map<String, Object>, ObjectInformation> generateObjectInfo(
}

static ObjectInformation generateObjectInfo(
final ResolvedObjectID roi, final Map<String, Object> ver) {
return generateObjectInfo(roi.getWorkspaceIdentifier(), roi.getId(), roi.getName(), ver);
final ResolvedObjectID roi,
final Map<String, Object> ver) {
return generateObjectInfo(
roi.getWorkspaceIdentifier(),
roi.getId(),
roi.getName(),
ver);
}

static ObjectInformation generateObjectInfo(
Expand All @@ -134,6 +139,9 @@ static ObjectInformation generateObjectInfo(
@SuppressWarnings("unchecked")
final List<Map<String, String>> meta =
(List<Map<String, String>>) ver.get(Fields.VER_META);
@SuppressWarnings("unchecked")
final List<Map<String, String>> adminmeta =
(List<Map<String, String>>) ver.get(Fields.VER_ADMINMETA);
final AbsoluteTypeDefId type = new AbsoluteTypeDefId(
new TypeDefName((String) ver.get(Fields.VER_TYPE_NAME)),
(int) ver.get(Fields.VER_TYPE_MAJOR_VERSION),
Expand All @@ -148,8 +156,10 @@ static ObjectInformation generateObjectInfo(
.withWorkspace(rwsi)
.withChecksum((String) ver.get(Fields.VER_CHKSUM))
.withSize((long) ver.get(Fields.VER_SIZE))
.withUserMetadata(meta == null ? null :
.withUserMetadata(
new UncheckedUserMetadata(metaMongoArrayToHash(meta)))
.withAdminUserMetadata(
new UncheckedUserMetadata(metaMongoArrayToHash(adminmeta)))
.build();
}

Expand Down
12 changes: 9 additions & 3 deletions src/us/kbase/workspace/database/mongo/ObjectLister.java
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,14 @@ public List<ObjectInformation> filter(final ResolvedListObjectParameters params)
}
// this method accesses the DB, so we batch calls to it to reduce transport time
final Map<Map<String, Object>, ObjectInformation> objs =
infoUtils.generateObjectInfo(pset, verobjs, params.isShowHidden(),
params.isShowDeleted(), params.isShowOnlyDeleted(),
params.isShowAllVersions(), params.asAdmin()
infoUtils.generateObjectInfo(
pset,
verobjs,
params.isShowHidden(),
params.isShowDeleted(),
params.isShowOnlyDeleted(),
params.isShowAllVersions(),
params.asAdmin()
);
//maintain the ordering from Mongo
final Iterator<Map<String, Object>> veriter = verobjs.iterator();
Expand All @@ -128,6 +133,7 @@ private Document buildProjection(final ResolvedListObjectParameters params) {
FLDS_LIST_OBJ_VER.forEach(field -> projection.put(field, 1));
if (params.isIncludeMetaData()) {
projection.put(Fields.VER_META, 1);
projection.put(Fields.VER_ADMINMETA, 1);
}
return projection;
}
Expand Down
Loading

0 comments on commit 19ec7c0

Please sign in to comment.