mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 05:07:41 +00:00
GUACAMOLE-462: Allow individual records to be identified and retrieved directly.
This commit is contained in:
@@ -100,6 +100,17 @@ public class ModeledActivityRecord implements ActivityRecord {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getIdentifier() {
|
||||||
|
|
||||||
|
Integer id = model.getRecordID();
|
||||||
|
if (id == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return id.toString();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UUID getUUID() {
|
public UUID getUUID() {
|
||||||
|
|
||||||
|
@@ -78,6 +78,21 @@ public interface ActivityRecord extends ReadableAttributes {
|
|||||||
*/
|
*/
|
||||||
public boolean isActive();
|
public boolean isActive();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the unique identifier assigned to this record, if any. If this
|
||||||
|
* record is not uniquely identifiable, this may be null. If provided, this
|
||||||
|
* unique identifier MUST be unique across all {@link ActivityRecord}
|
||||||
|
* objects within the same {@link ActivityRecordSet}.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* The unique identifier assigned to this record, or null if this
|
||||||
|
* record has no such identifier.
|
||||||
|
*/
|
||||||
|
public default String getIdentifier() {
|
||||||
|
UUID uuid = getUUID();
|
||||||
|
return uuid != null ? uuid.toString() : null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a UUID that uniquely identifies this record. If provided, this
|
* Returns a UUID that uniquely identifies this record. If provided, this
|
||||||
* UUID MUST be deterministic and unique across all {@link ActivityRecord}
|
* UUID MUST be deterministic and unique across all {@link ActivityRecord}
|
||||||
|
@@ -57,6 +57,30 @@ public interface ActivityRecordSet<RecordType extends ActivityRecord> {
|
|||||||
*/
|
*/
|
||||||
Collection<RecordType> asCollection() throws GuacamoleException;
|
Collection<RecordType> asCollection() throws GuacamoleException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the record having the given unique identifier, if records within
|
||||||
|
* this set have unique identifiers. If records within this set do not have
|
||||||
|
* defined unique identifiers, this function has no effect.
|
||||||
|
*
|
||||||
|
* @param identifier
|
||||||
|
* The unique identifier of the record to retrieve.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* The record having the given unique identifier, or null if there is
|
||||||
|
* no such record.
|
||||||
|
*
|
||||||
|
* @throws GuacamoleException
|
||||||
|
* If an error occurs while retrieving the record.
|
||||||
|
*/
|
||||||
|
default RecordType get(String identifier) throws GuacamoleException {
|
||||||
|
return asCollection().stream()
|
||||||
|
.filter((record) -> {
|
||||||
|
String recordIdentifier = record.getIdentifier();
|
||||||
|
return recordIdentifier != null && recordIdentifier.equals(identifier);
|
||||||
|
})
|
||||||
|
.findFirst().orElse(null);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the subset of records which contain the given value. The
|
* Returns the subset of records which contain the given value. The
|
||||||
* properties and semantics involved with determining whether a particular
|
* properties and semantics involved with determining whether a particular
|
||||||
|
@@ -122,6 +122,17 @@ public abstract class DecoratingActivityRecordSet<RecordType extends ActivityRec
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RecordType get(String string) throws GuacamoleException {
|
||||||
|
|
||||||
|
RecordType record = super.get(string);
|
||||||
|
if (record != null)
|
||||||
|
return decorate(record);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ActivityRecordSet<RecordType> sort(SortableProperty property,
|
public ActivityRecordSet<RecordType> sort(SortableProperty property,
|
||||||
boolean desc) throws GuacamoleException {
|
boolean desc) throws GuacamoleException {
|
||||||
|
@@ -81,6 +81,11 @@ public class DelegatingActivityRecord implements ActivityRecord {
|
|||||||
return record.isActive();
|
return record.isActive();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getIdentifier() {
|
||||||
|
return record.getIdentifier();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UUID getUUID() {
|
public UUID getUUID() {
|
||||||
return record.getUUID();
|
return record.getUUID();
|
||||||
|
@@ -59,6 +59,11 @@ public class DelegatingActivityRecordSet<RecordType extends ActivityRecord>
|
|||||||
return recordSet;
|
return recordSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RecordType get(String identifier) throws GuacamoleException {
|
||||||
|
return recordSet.get(identifier);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<RecordType> asCollection() throws GuacamoleException {
|
public Collection<RecordType> asCollection() throws GuacamoleException {
|
||||||
return recordSet.asCollection();
|
return recordSet.asCollection();
|
||||||
|
@@ -96,6 +96,7 @@ public class APIActivityRecord {
|
|||||||
this.remoteHost = record.getRemoteHost();
|
this.remoteHost = record.getRemoteHost();
|
||||||
this.username = record.getUsername();
|
this.username = record.getUsername();
|
||||||
this.active = record.isActive();
|
this.active = record.isActive();
|
||||||
|
this.identifier = record.getIdentifier();
|
||||||
this.uuid = record.getUUID();
|
this.uuid = record.getUUID();
|
||||||
this.attributes = record.getAttributes();
|
this.attributes = record.getAttributes();
|
||||||
|
|
||||||
@@ -164,6 +165,18 @@ public class APIActivityRecord {
|
|||||||
return active;
|
return active;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the unique identifier assigned to this record, if any. If this
|
||||||
|
* record is not uniquely identifiable, this may be null.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* The unique identifier assigned to this record, or null if this
|
||||||
|
* record has no such identifier.
|
||||||
|
*/
|
||||||
|
public String getIdentifier() {
|
||||||
|
return identifier;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a UUID that uniquely identifies this record. If not implemented
|
* Returns a UUID that uniquely identifies this record. If not implemented
|
||||||
* by the extension exposing this history record, this may be null.
|
* by the extension exposing this history record, this may be null.
|
||||||
|
@@ -19,7 +19,9 @@
|
|||||||
|
|
||||||
package org.apache.guacamole.rest.history;
|
package org.apache.guacamole.rest.history;
|
||||||
|
|
||||||
|
import java.util.function.Function;
|
||||||
import javax.ws.rs.Consumes;
|
import javax.ws.rs.Consumes;
|
||||||
|
import javax.ws.rs.GET;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
import javax.ws.rs.PathParam;
|
import javax.ws.rs.PathParam;
|
||||||
import javax.ws.rs.Produces;
|
import javax.ws.rs.Produces;
|
||||||
@@ -42,14 +44,37 @@ public class ActivityRecordResource {
|
|||||||
*/
|
*/
|
||||||
private final ActivityRecord record;
|
private final ActivityRecord record;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The REST API object representing the ActivityRecord being exposed.
|
||||||
|
*/
|
||||||
|
private final APIActivityRecord externalRecord;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new ActivityRecordResource which exposes the given record.
|
* Creates a new ActivityRecordResource which exposes the given record.
|
||||||
*
|
*
|
||||||
* @param record
|
* @param record
|
||||||
* The ActivityRecord that should be exposed.
|
* The ActivityRecord that should be exposed.
|
||||||
|
*
|
||||||
|
* @param externalRecord
|
||||||
|
* The REST API object representing the ActivityRecord being exposed.
|
||||||
*/
|
*/
|
||||||
public ActivityRecordResource(ActivityRecord record) {
|
public ActivityRecordResource(ActivityRecord record,
|
||||||
|
APIActivityRecord externalRecord) {
|
||||||
this.record = record;
|
this.record = record;
|
||||||
|
this.externalRecord = externalRecord;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the record represented by this ActivityRecordResource, in a
|
||||||
|
* format intended for interchange.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* The record that this ActivityRecordResource represents, in a format
|
||||||
|
* intended for interchange.
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
public APIActivityRecord getRecord() {
|
||||||
|
return externalRecord;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -21,7 +21,6 @@ package org.apache.guacamole.rest.history;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
|
||||||
import javax.ws.rs.Consumes;
|
import javax.ws.rs.Consumes;
|
||||||
import javax.ws.rs.GET;
|
import javax.ws.rs.GET;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
@@ -29,7 +28,6 @@ import javax.ws.rs.PathParam;
|
|||||||
import javax.ws.rs.Produces;
|
import javax.ws.rs.Produces;
|
||||||
import javax.ws.rs.QueryParam;
|
import javax.ws.rs.QueryParam;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
import org.apache.guacamole.GuacamoleClientException;
|
|
||||||
import org.apache.guacamole.GuacamoleException;
|
import org.apache.guacamole.GuacamoleException;
|
||||||
import org.apache.guacamole.GuacamoleResourceNotFoundException;
|
import org.apache.guacamole.GuacamoleResourceNotFoundException;
|
||||||
import org.apache.guacamole.net.auth.ActivityRecord;
|
import org.apache.guacamole.net.auth.ActivityRecord;
|
||||||
@@ -176,70 +174,28 @@ public abstract class ActivityRecordSetResource<InternalRecordType extends Activ
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves record having the given UUID from among the list of activity
|
* Retrieves record having the given identifier from among the set of
|
||||||
* records stored within the underlying ActivityRecordSet which match the
|
* activity records stored within the underlying ActivityRecordSet.
|
||||||
* given, arbitrary criteria. If specified, the returned records will also
|
|
||||||
* be sorted according to the given sort predicates. As the number of
|
|
||||||
* activity records retrieved at any given time may be limited by the
|
|
||||||
* extension providing those records, the sorting and search criteria may
|
|
||||||
* impact whether the record having a particular UUID can be located, even
|
|
||||||
* if it is known that the record exists.
|
|
||||||
*
|
*
|
||||||
* @param uuid
|
* @param identifier
|
||||||
* The UUID of the record to retrieve.
|
* The unique identifier of the record to retrieve.
|
||||||
*
|
|
||||||
* @param requiredContents
|
|
||||||
* The set of strings that each must occur somewhere within the
|
|
||||||
* relevant records, whether within the associated username,
|
|
||||||
* the name of some associated object (such as a connection), or any
|
|
||||||
* associated date. If non-empty, any record not matching each of the
|
|
||||||
* strings within the collection will not be considered.
|
|
||||||
*
|
|
||||||
* @param sortPredicates
|
|
||||||
* A list of predicates to apply while sorting the relevant records,
|
|
||||||
* describing the properties involved and the sort order for those
|
|
||||||
* properties.
|
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* The record having the given UUID which matches the provided
|
* A resource representing the record having the given identifier.
|
||||||
* criteria.
|
|
||||||
*
|
*
|
||||||
* @throws GuacamoleException
|
* @throws GuacamoleException
|
||||||
* If an error occurs while applying the given filter criteria or
|
* If an error occurs while locating the requested record, or if the
|
||||||
* sort predicates, or if the requested record cannot be found.
|
* requested record cannot be found.
|
||||||
*/
|
*/
|
||||||
@Path("{uuid}")
|
@Path("{identifier}")
|
||||||
public ActivityRecordResource getRecord(@PathParam("uuid") String uuid,
|
public ActivityRecordResource getRecord(@PathParam("identifier") String identifier)
|
||||||
@QueryParam("contains") List<String> requiredContents,
|
throws GuacamoleException {
|
||||||
@QueryParam("order") List<APISortPredicate> sortPredicates)
|
|
||||||
throws GuacamoleException {
|
|
||||||
|
|
||||||
// Parse UUID from provided string
|
InternalRecordType record = history.get(identifier);
|
||||||
UUID parsedUUID;
|
if (record == null)
|
||||||
try {
|
throw new GuacamoleResourceNotFoundException("Not found: \"" + identifier + "\"");
|
||||||
parsedUUID = UUID.fromString(uuid);
|
|
||||||
}
|
|
||||||
catch (IllegalArgumentException e) {
|
|
||||||
throw new GuacamoleClientException("Invalid UUID.", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply search/sort criteria
|
return new ActivityRecordResource(record, toExternalRecord(record));
|
||||||
applyCriteria(requiredContents, sortPredicates);
|
|
||||||
|
|
||||||
// Locate record having given UUID among all visible records
|
|
||||||
for (InternalRecordType record : history.asCollection()) {
|
|
||||||
|
|
||||||
// Ignore records lacking any UUID
|
|
||||||
UUID recordUUID = record.getUUID();
|
|
||||||
if (recordUUID == null)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (recordUUID.equals(parsedUUID))
|
|
||||||
return new ActivityRecordResource(record);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new GuacamoleResourceNotFoundException("No such history entry.");
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user