package org.gcube.application.geoportal.client; import lombok.NonNull; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; 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.document.Project; import org.gcube.application.geoportal.common.model.configuration.Configuration; import org.gcube.application.geoportal.common.model.document.access.Access; 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 javax.ws.rs.client.Entity; import javax.ws.rs.client.WebTarget; import javax.ws.rs.core.MediaType; import java.io.IOException; import java.rmi.RemoteException; import java.util.Iterator; @RequiredArgsConstructor @Slf4j public class DefaultDocumentsClient implements Projects { @NonNull protected final ProxyDelegate delegate; @NonNull protected final String profileID; @NonNull protected final Class managedClass; public Class getManagedClass() { return managedClass; } @Override public T createNew(Document toCreate) throws RemoteException { try { log.debug("Creating Profiled Document (class {}, useCaseDescriptor {}) with content {} ", getManagedClass(),profileID, toCreate); Call 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); } } @Override public void deleteById(String id) throws RemoteException { deleteById(id,false); } @Override public void deleteById(String id, Boolean force) throws RemoteException { try { log.debug("Deleting ID {}  useCaseDescriptor {}  force {} ", id, profileID, force); Call 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); } } @Override public T getById(String id) throws RemoteException { try { log.info("Loading Document ID {} (class {}, useCaseDescriptor {})", id, getManagedClass(),profileID); Call 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); } } @Override public Configuration getConfiguration() throws RemoteException { try { log.info("Loading Configuration for useCaseDescriptor {}", profileID); Call 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); } } @Override public Iterator query(QueryRequest request) throws RemoteException { return queryForClass(request,getManagedClass()); } @Override public Iterator queryForClass(QueryRequest request,Class 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"); } } @Override public String queryForJSON(QueryRequest request) throws RemoteException { try { log.debug("Querying useCaseDescriptor {}  for {}",profileID,request); Call 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); } } @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 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); } } @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 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); } } @Override public T deleteFileSet(String id, String path, Boolean force) throws RemoteException { try { log.debug("Deleting Fileset for ID {}  [useCaseDescriptor {}  , class {}] at {} (force {} )", id, profileID,getManagedClass(),path, force); Call call = endpoint -> { return ResponseCommons.check(endpoint.path(profileID).path(InterfaceConstants.Methods.DELETE_FILES_PATH). path(id).queryParam(InterfaceConstants.Parameters.FORCE,force). 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); } } @Override public T forceUnlock(String id) throws RemoteException { try { log.warn("Force Unlock of {} [useCaseDescriptor {} , class {}]", id, profileID,getManagedClass()); Call 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); } } @Override public T setAccessPolicy(String id, Access toSet) throws RemoteException { try { log.info("Setting Access of {} [useCaseDescriptor {} , class {}] as {}", id, profileID,getManagedClass(),toSet); Call 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); } } @Override public T updateDocument(String id, Document updatedDocument) throws RemoteException { try { log.debug("Updateing {} [useCaseDescriptor {} , class {}] with ", id, profileID,getManagedClass(),updatedDocument); Call 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); } } }