gcube-cms-suite/geoportal-client/src/main/java/org/gcube/application/geoportal/client/DefaultDocumentsClient.java

588 lines
19 KiB
Java
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package org.gcube.application.geoportal.client;
import java.io.IOException;
import java.rmi.RemoteException;
import java.util.Iterator;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.bson.Document;
import org.gcube.application.geoportal.client.utils.Serialization;
import org.gcube.application.geoportal.common.faults.InvalidRequestException;
import org.gcube.application.geoportal.common.model.configuration.Configuration;
import org.gcube.application.geoportal.common.model.document.Project;
import org.gcube.application.geoportal.common.model.document.access.Access;
import org.gcube.application.geoportal.common.model.document.relationships.RelationshipNavigationObject;
import org.gcube.application.geoportal.common.model.rest.CreateRelationshipRequest;
import org.gcube.application.geoportal.common.model.rest.DeleteRelationshipRequest;
import org.gcube.application.geoportal.common.model.rest.QueryRequest;
import org.gcube.application.geoportal.common.model.rest.RegisterFileSetRequest;
import org.gcube.application.geoportal.common.model.rest.StepExecutionRequest;
import org.gcube.application.geoportal.common.rest.InterfaceConstants;
import org.gcube.application.geoportal.common.rest.Projects;
import org.gcube.common.clients.Call;
import org.gcube.common.clients.delegates.ProxyDelegate;
import org.glassfish.jersey.client.HttpUrlConnectorProvider;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
/**
* Instantiates a new default documents client.
*
* @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it
*
* May 2, 2023
* @param <T> the generic type
*/
/**
* Instantiates a new default documents client.
*
* @param delegate the delegate
* @param profileID the profile ID
* @param managedClass the managed class
*/
@RequiredArgsConstructor
@Slf4j
public class DefaultDocumentsClient<T extends Project> implements Projects<T> {
@NonNull
protected final ProxyDelegate<WebTarget> delegate;
@NonNull
protected final String profileID;
@NonNull
protected final Class<T> managedClass;
/**
* Gets the managed class.
*
* @return the managed class
*/
public Class<T> getManagedClass() {
return managedClass;
}
/**
* Creates the new.
*
* @param toCreate the to create
* @return the t
* @throws RemoteException the remote exception
*/
@Override
public T createNew(Document toCreate) throws RemoteException {
try {
log.debug("Creating Profiled Document (class {}, useCaseDescriptor {}) with content {} ", getManagedClass(),
profileID, toCreate);
Call<WebTarget, T> call = endpoint -> {
return ResponseCommons.check(endpoint.path(profileID).request(MediaType.APPLICATION_JSON)
.post(Entity.entity(toCreate, MediaType.APPLICATION_JSON)), getManagedClass());
};
T toReturn = delegate.make(call);
log.info("Registered {} profiled {} ", toReturn.getId(), profileID);
return toReturn;
} catch (RemoteException e) {
log.error("Unexpected error ", e);
throw e;
} catch (Exception e) {
log.error("Unexpected error ", e);
throw new RemoteException("Unexpected Error", e);
}
}
/**
* Delete by id.
*
* @param id the id
* @throws RemoteException the remote exception
*/
@Override
public void deleteById(String id) throws RemoteException {
deleteById(id, false);
}
/**
* Delete by id.
*
* @param id the id
* @param force the force
* @throws RemoteException the remote exception
*/
@Override
public void deleteById(String id, Boolean force) throws RemoteException {
try {
log.debug("Deleting ID {}  useCaseDescriptor {}  force {} ", id, profileID, force);
Call<WebTarget, T> call = endpoint -> {
return ResponseCommons
.check(endpoint.path(profileID).path(id).queryParam(InterfaceConstants.Parameters.FORCE, force)
.request(MediaType.APPLICATION_JSON).delete(), null);
};
delegate.make(call);
log.info("Deleted ID {}  useCaseDescriptor {}  force {} ", id, profileID, force);
} catch (RemoteException e) {
log.error("Unexpected error ", e);
throw e;
} catch (Exception e) {
log.error("Unexpected error ", e);
throw new RemoteException("Unexpected Error", e);
}
}
/**
* Gets the by id.
*
* @param id the id
* @return the by id
* @throws RemoteException the remote exception
*/
@Override
public T getById(String id) throws RemoteException {
try {
log.info("Loading Document ID {} (class {}, useCaseDescriptor {})", id, getManagedClass(), profileID);
Call<WebTarget, T> call = endpoint -> {
return ResponseCommons.check(
endpoint.path(profileID).path(id).request(MediaType.APPLICATION_JSON).get(), getManagedClass());
};
return delegate.make(call);
} catch (RemoteException e) {
log.error("Unexpected error ", e);
throw e;
} catch (Exception e) {
log.error("Unexpected error ", e);
throw new RemoteException("Unexpected Error", e);
}
}
/**
* Gets the configuration.
*
* @return the configuration
* @throws RemoteException the remote exception
*/
@Override
public Configuration getConfiguration() throws RemoteException {
try {
log.info("Loading Configuration for useCaseDescriptor {}", profileID);
Call<WebTarget, Configuration> call = endpoint -> {
return ResponseCommons.check(endpoint.path(profileID)
.path(InterfaceConstants.Methods.CONFIGURATION_PATH).request(MediaType.APPLICATION_JSON).get(),
Configuration.class);
};
return delegate.make(call);
} catch (RemoteException e) {
log.error("Unexpected error ", e);
throw e;
} catch (Exception e) {
log.error("Unexpected error ", e);
throw new RemoteException("Unexpected Error", e);
}
}
/**
* Query.
*
* @param request the request
* @return the iterator
* @throws RemoteException the remote exception
*/
@Override
public Iterator<T> query(QueryRequest request) throws RemoteException {
return queryForClass(request, getManagedClass());
}
/**
* Query for class.
*
* @param <C> the generic type
* @param request the request
* @param clazz the clazz
* @return the iterator
* @throws RemoteException the remote exception
*/
@Override
public <C> Iterator<C> queryForClass(QueryRequest request, Class<C> clazz) throws RemoteException {
String jsonString = queryForJSON(request);
log.debug("Deserializing query Result as {} ", clazz);
try {
return Serialization.readCollection(jsonString, clazz);
} catch (IOException e) {
log.error("Unable to deserialize result as " + clazz, e);
log.debug("Query request was {} ", request);
log.debug("Query result was {} ", jsonString);
throw new RemoteException("Invalid format for submitted query");
}
}
/**
* Query for JSON.
*
* @param request the request
* @return the string
* @throws RemoteException the remote exception
*/
@Override
public String queryForJSON(QueryRequest request) throws RemoteException {
try {
log.debug("Querying useCaseDescriptor {}  for {}", profileID, request);
Call<WebTarget, String> call = endpoint -> {
return ResponseCommons.check(endpoint.path(profileID).path(InterfaceConstants.Methods.QUERY_PATH)
.request(MediaType.APPLICATION_JSON).post(Entity.entity(request, MediaType.APPLICATION_JSON)),
String.class);
};
return delegate.make(call);
} catch (RemoteException e) {
log.error("Unexpected error ", e);
throw e;
} catch (Exception e) {
log.error("Unexpected error ", e);
throw new RemoteException("Unexpected Error", e);
}
}
/**
* Perform step.
*
* @param id the id
* @param request the request
* @return the t
* @throws RemoteException the remote exception
*/
@Override
public T performStep(String id, StepExecutionRequest request) throws RemoteException {
try {
log.debug("Executing step on {} (class {}, useCaseDescriptor {}) with request {} ", id, getManagedClass(),
profileID, request);
Call<WebTarget, T> call = endpoint -> {
return ResponseCommons.check(endpoint.path(profileID).path(InterfaceConstants.Methods.STEP).path(id)
.request(MediaType.APPLICATION_JSON).post(Entity.entity(request, MediaType.APPLICATION_JSON)),
getManagedClass());
};
T toReturn = delegate.make(call);
log.info("Executed STEP {} on {} [useCaseDescriptor {}, class {}] ", request.getStepID(), id, profileID,
getManagedClass());
return toReturn;
} catch (RemoteException e) {
log.error("Unexpected error ", e);
throw e;
} catch (Exception e) {
log.error("Unexpected error ", e);
throw new RemoteException("Unexpected Error", e);
}
}
/**
* Register file set.
*
* @param id the id
* @param req the req
* @return the t
* @throws RemoteException the remote exception
* @throws InvalidRequestException the invalid request exception
*/
@Override
public T registerFileSet(String id, RegisterFileSetRequest req) throws RemoteException, InvalidRequestException {
try {
log.debug("Registering FileSet on {} (class {}, useCaseDescriptor {}) with request {} ", id,
getManagedClass(), profileID, req);
req.validate();
Call<WebTarget, T> call = endpoint -> {
return ResponseCommons.check(endpoint.path(profileID)
.path(InterfaceConstants.Methods.REGISTER_FILES_PATH).path(id)
.request(MediaType.APPLICATION_JSON).post(Entity.entity(req, MediaType.APPLICATION_JSON)),
getManagedClass());
};
T toReturn = delegate.make(call);
log.info("Registered FileSet on {} [useCaseDescriptor {}, class {}]  with {}", id, profileID,
getManagedClass(), req);
return toReturn;
} catch (InvalidRequestException e) {
log.error("Invalid Request ", e);
throw e;
} catch (RemoteException e) {
log.error("Unexpected error ", e);
throw e;
} catch (Exception e) {
log.error("Unexpected error ", e);
throw new RemoteException("Unexpected Error", e);
}
}
/**
* Delete file set.
*
* @param id the id
* @param path the path
* @param force the force
* @param ignoreErrors the ignore errors
* @return the t
* @throws RemoteException the remote exception
*/
@Override
public T deleteFileSet(String id, String path, Boolean force, Boolean ignoreErrors) throws RemoteException {
try {
log.debug(
"Deleting Fileset for ID {}  [useCaseDescriptor {}  , class {}] at {} (force {} ) (ignoreErrors {} )",
id, profileID, getManagedClass(), path, force, ignoreErrors);
Call<WebTarget, T> call = endpoint -> {
return ResponseCommons.check(endpoint.path(profileID).path(InterfaceConstants.Methods.DELETE_FILES_PATH)
.path(id).queryParam(InterfaceConstants.Parameters.FORCE, force)
.queryParam(InterfaceConstants.Parameters.IGNORE_ERRORS, ignoreErrors)
.request(MediaType.APPLICATION_JSON).post(Entity.entity(path, MediaType.APPLICATION_JSON)),
getManagedClass());
};
T toReturn = delegate.make(call);
log.info("Deleted ID {}  useCaseDescriptor {}  force {} ", id, profileID, force);
return toReturn;
} catch (RemoteException e) {
log.error("Unexpected error ", e);
throw e;
} catch (Exception e) {
log.error("Unexpected error ", e);
throw new RemoteException("Unexpected Error", e);
}
}
/**
* Force unlock.
*
* @param id the id
* @return the t
* @throws RemoteException the remote exception
*/
@Override
public T forceUnlock(String id) throws RemoteException {
try {
log.warn("Force Unlock of {} [useCaseDescriptor {} , class {}]", id, profileID, getManagedClass());
Call<WebTarget, T> call = endpoint -> {
return ResponseCommons.check(endpoint.path(profileID).path(InterfaceConstants.Methods.FORCE_UNLOCK)
.path(id).request(MediaType.APPLICATION_JSON).put(Entity.json("")), getManagedClass());
};
T toReturn = delegate.make(call);
log.info("Unlocked ID {} useCaseDescriptor {}", id, profileID);
return toReturn;
} catch (RemoteException e) {
log.error("Unexpected error ", e);
throw e;
} catch (Exception e) {
log.error("Unexpected error ", e);
throw new RemoteException("Unexpected Error", e);
}
}
/**
* Sets the access policy.
*
* @param id the id
* @param toSet the to set
* @return the t
* @throws RemoteException the remote exception
*/
@Override
public T setAccessPolicy(String id, Access toSet) throws RemoteException {
try {
log.info("Setting Access of {} [useCaseDescriptor {} , class {}] as {}", id, profileID, getManagedClass(),
toSet);
Call<WebTarget, T> call = endpoint -> {
return ResponseCommons.check(
endpoint.path(profileID).path(InterfaceConstants.Methods.SET_PROJECT_ACCESS_POLICY).path(id)
.request(MediaType.APPLICATION_JSON).put(Entity.json(toSet)),
getManagedClass());
};
T toReturn = delegate.make(call);
log.debug("Updated Access of ID {} useCaseDescriptor {}", id, profileID);
return toReturn;
} catch (RemoteException e) {
log.error("Unexpected error ", e);
throw e;
} catch (Exception e) {
log.error("Unexpected error ", e);
throw new RemoteException("Unexpected Error", e);
}
}
/**
* Update document.
*
* @param id the id
* @param updatedDocument the updated document
* @return the t
* @throws RemoteException the remote exception
*/
@Override
public T updateDocument(String id, Document updatedDocument) throws RemoteException {
try {
log.debug("Updating {} [useCaseDescriptor {} , class {}] with ", id, profileID, getManagedClass(),
updatedDocument);
Call<WebTarget, T> call = endpoint -> {
return ResponseCommons.check(endpoint.path(profileID).path(id).request(MediaType.APPLICATION_JSON)
.put(Entity.entity(updatedDocument, MediaType.APPLICATION_JSON)), getManagedClass());
};
T toReturn = delegate.make(call);
log.info("Updated ID {} useCaseDescriptor {}", id, profileID);
return toReturn;
} catch (RemoteException e) {
log.error("Unexpected error ", e);
throw e;
} catch (Exception e) {
log.error("Unexpected error ", e);
throw new RemoteException("Unexpected Error", e);
}
}
/**
* Patch document. Added by Francesco Mangiacrapa
*
* @param id the id
* @param path the path
* @param updatedDocument the updated document
* @return the t
* @throws RemoteException the remote exception
*/
@Override
public T patchDocument(String id, String path, Document updatedDocument) throws RemoteException {
try {
log.debug("Patching {} [useCaseDescriptor {} , class {}] with ", id, profileID, getManagedClass(),
updatedDocument);
Call<WebTarget, T> call = endpoint -> {
WebTarget webTarget = endpoint.path(profileID).path(id);
webTarget.queryParam(InterfaceConstants.Parameters.PATH, path);
webTarget.property(HttpUrlConnectorProvider.SET_METHOD_WORKAROUND, true);
Response response = webTarget.request(MediaType.APPLICATION_JSON).method("PATCH",
Entity.entity(updatedDocument, MediaType.APPLICATION_JSON));
return ResponseCommons.check(response, getManagedClass());
};
T toReturn = delegate.make(call);
log.info("Updated ID {} useCaseDescriptor {}", id, profileID);
return toReturn;
} catch (RemoteException e) {
log.error("Unexpected error ", e);
throw e;
} catch (Exception e) {
log.error("Unexpected error ", e);
throw new RemoteException("Unexpected Error", e);
}
}
/**
* Sets the relation.
*
* @param request the request
* @return the project
* @throws RemoteException the remote exception
*/
@Override
public Project setRelation(CreateRelationshipRequest request) throws RemoteException {
try {
log.debug("Setting relationship {}:{} --{}--> {}:{}", profileID, request.getProjectId(),
request.getRelationshipId(), request.getTargetUCD(), request.getTargetId());
Call<WebTarget, T> call = endpoint -> {
return ResponseCommons.check(endpoint.path(profileID).path(InterfaceConstants.Methods.RELATIONSHIP)
.path(request.getProjectId()).path(request.getRelationshipId())
.queryParam(InterfaceConstants.Parameters.TARGET_ID, request.getTargetId())
.queryParam(InterfaceConstants.Parameters.TARGET_UCD, request.getTargetUCD())
.request(MediaType.APPLICATION_JSON).put(Entity.json("")), getManagedClass());
};
T toReturn = delegate.make(call);
log.info("Set relationship {}:{} --{}--> {}:{}", profileID, request.getProjectId(),
request.getRelationshipId(), request.getTargetUCD(), request.getTargetId());
return toReturn;
} catch (RemoteException e) {
log.error("Unexpected error ", e);
throw e;
} catch (Exception e) {
log.error("Unexpected error ", e);
throw new RemoteException("Unexpected Error", e);
}
}
/**
* Delete relation.
*
* @param request the request
* @return the project
* @throws RemoteException the remote exception
*/
@Override
public Project deleteRelation(DeleteRelationshipRequest request) throws RemoteException {
try {
log.debug("Deleting relationship {}:{} --{}--> {}:{}", profileID, request.getProjectId(),
request.getRelationshipId(), request.getTargetUCD(), request.getTargetId());
Call<WebTarget, T> call = endpoint -> {
return ResponseCommons.check(endpoint.path(profileID).path(InterfaceConstants.Methods.RELATIONSHIP)
.path(request.getProjectId()).path(request.getRelationshipId())
.queryParam(InterfaceConstants.Parameters.TARGET_ID, request.getTargetId())
.queryParam(InterfaceConstants.Parameters.TARGET_UCD, request.getTargetUCD())
.request(MediaType.APPLICATION_JSON).delete(), getManagedClass());
};
T toReturn = delegate.make(call);
log.info("Deleted relationship {}:{} --{}--> {}:{}", profileID, request.getProjectId(),
request.getRelationshipId(), request.getTargetUCD(), request.getTargetId());
return toReturn;
} catch (RemoteException e) {
log.error("Unexpected error ", e);
throw e;
} catch (Exception e) {
log.error("Unexpected error ", e);
throw new RemoteException("Unexpected Error", e);
}
}
/**
* Gets the relationship chain.
*
* @param id the id
* @param relationId the relation id
* @return the relationship chain
* @throws RemoteException the remote exception
*/
@Override
public Iterator<RelationshipNavigationObject> getRelationshipChain(String id, String relationId)
throws RemoteException {
return getRelationshipChain(id, relationId, null);
}
/**
* Gets the relationship chain.
*
* @param id the id
* @param relationId the relation id
* @param deep the deep
* @return the relationship chain
* @throws RemoteException the remote exception
*/
@Override
public Iterator<RelationshipNavigationObject> getRelationshipChain(String id, String relationId, Boolean deep)
throws RemoteException {
try {
log.debug("Get relationship chain ID {} for {} [useCaseDescriptor {} , class {}]", relationId, id,
profileID, getManagedClass());
Call<WebTarget, Iterator<RelationshipNavigationObject>> call = endpoint -> {
WebTarget target = endpoint.path(profileID).path(InterfaceConstants.Methods.RELATIONSHIP).path(id)
.path(relationId);
if (deep != null)
target = target.queryParam(InterfaceConstants.Parameters.DEEP, deep);
String jsonChain = ResponseCommons.check(target.request(MediaType.APPLICATION_JSON).get(),
String.class);
return Serialization.readCollection(jsonChain, RelationshipNavigationObject.class);
};
return delegate.make(call);
} catch (RemoteException e) {
log.error("Unexpected error ", e);
throw e;
} catch (Exception e) {
log.error("Unexpected error ", e);
throw new RemoteException("Unexpected Error", e);
}
}
}