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.model.document.ProfiledDocument; import org.gcube.application.geoportal.common.model.legacy.Concessione; import org.gcube.application.geoportal.common.model.rest.Configuration; 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.ProfiledDocumentsI; 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 javax.ws.rs.core.Response; import java.io.IOException; import java.rmi.Remote; import java.rmi.RemoteException; import java.util.Iterator; @RequiredArgsConstructor @Slf4j public class DefaultProfiledDocumentsClient implements ProfiledDocumentsI { @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 {}, profile {}) with content {} ", getManagedClass(),profileID, toCreate); Call call = endpoint -> { return 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.get_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 void deleteById(String id) throws RemoteException { deleteById(id,false); } @Override public void deleteById(String id, Boolean force) throws RemoteException { try { log.debug("Deleting ID {}  profile {}  force {} ", id, profileID, force); Call call = endpoint -> { return check(endpoint.path(profileID).path(id). queryParam(InterfaceConstants.Parameters.FORCE,force). request(MediaType.APPLICATION_JSON).delete(),getManagedClass()); }; delegate.make(call); log.info("Deleted ID {}  profile {}  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 {}, profile {})", id, getManagedClass(),profileID); Call call = endpoint -> { return 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 profile {}", profileID); Call call = endpoint -> { return 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); throw new RemoteException("Invalid format for submitted query"); } } @Override public String queryForJSON(QueryRequest request) throws RemoteException { try { log.debug("Querying profile {}  for {}",profileID,request); Call call = endpoint -> { return check(endpoint.path(profileID).path(InterfaceConstants.Methods.QUERY_PATH). request(MediaType.APPLICATION_JSON).get(), 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 {}, profile {}) with request {} ", id, getManagedClass(),profileID, request); Call call = endpoint -> { return check(endpoint.path(profileID).path(id).request(MediaType.APPLICATION_JSON). post(Entity.entity(request, MediaType.APPLICATION_JSON)),getManagedClass()); }; T toReturn = delegate.make(call); log.info("Executed STEP {} on {} [profile {}, 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 { try { log.debug("Registering FileSet on {} (class {}, profile {}) with request {} ", id, getManagedClass(),profileID, req); Call call = endpoint -> { return 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 {} [profile {}, class {}]  with {}", id,profileID,getManagedClass(),req); 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 deleteFileSet(String id, String path, Boolean force) throws RemoteException { try { log.debug("Deleting Fileset for ID {}  [profile {}  , class {}] at {} (force {} )", id, profileID,getManagedClass(),path, force); Call call = endpoint -> { return 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 {}  profile {}  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 updateDocument(String id, Document updatedDocument) throws RemoteException { try { log.debug("Updateing {}  [profile {}  , class {}] with ", id, profileID,getManagedClass(),updatedDocument); Call call = endpoint -> { return 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 {}  profile {}  ", 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); } } protected static R check(Response resp, Class clazz) throws IOException { String resString=resp.readEntity(String.class); if(resp.getStatus()<200||resp.getStatus()>=300) throw new RemoteException("RESP STATUS IS "+resp.getStatus()+". Message : "+resString); if(clazz!=null) return Serialization.read(resString, clazz); else return null; } }