Manuele Simi 2009-08-26 01:25:38 +00:00
parent 7e56114be2
commit d25c648d2b
19 changed files with 288 additions and 98 deletions

View File

@ -6,6 +6,12 @@
<environment name="configDir" value="@config.dir@" type="java.lang.String"
override="false" />
<environment name="backupDir" value="existICBackups" type="java.lang.String"
override="false" />
<environment name="scheduledBackupInHours" value="24"
type="java.lang.String" override="false" />
<environment name="sweeperIntervalinMillis" value="120000"
type="java.lang.String" override="false" />

View File

@ -20,11 +20,26 @@
<xsd:import namespace="http://gcube-system.org/namespaces/common/core/types" schemaLocation="../gcube/common/core/types/GCUBETypes.xsd"/>
<xsd:element name="BackupRequest" type="coretypes:VOID"/>
<xsd:element name="VoidRequest" type="coretypes:VOID"/>
<xsd:element name="BackupResponse" type="coretypes:VOID"/>
<xsd:element name="VoidResponse" type="coretypes:VOID"/>
<xsd:element name="XMLStorageUnavailableFaultType">
<xsd:element name="VoidRestoreRequest" type="coretypes:VOID"/>
<xsd:element name="VoidRestoreResponse" type="coretypes:VOID"/>
<!-- FAULTS -->
<xsd:element name="XMLStorageNotAvailableFaultType">
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="corefaults:GCUBEUnrecoverableFault">
<xsd:sequence/>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
<xsd:element name="BackupNotAvailableFaultType">
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="corefaults:GCUBEUnrecoverableFault">
@ -55,21 +70,32 @@
============================================================-->
<wsdl:message name="BackupInputMessage">
<part name="parameters" element="tns:BackupRequest"/>
<part name="parameters" element="tns:VoidRequest"/>
</wsdl:message>
<wsdl:message name="BackupOutputMessage">
<part name="parameters" element="tns:BackupResponse"/>
<part name="parameters" element="tns:VoidResponse"/>
</wsdl:message>
<wsdl:message name="XMLStorageUnavailableFaultTypeMessage">
<part name="fault" element="tns:XMLStorageUnavailableFaultType"/>
<wsdl:message name="RestoreInputMessage">
<part name="parameters" element="tns:VoidRestoreRequest"/>
</wsdl:message>
<wsdl:message name="RestoreOutputMessage">
<part name="parameters" element="tns:VoidRestoreResponse"/>
</wsdl:message>
<wsdl:message name="XMLStorageNotAvailableFaultTypeMessage">
<part name="fault" element="tns:XMLStorageNotAvailableFaultType"/>
</wsdl:message>
<wsdl:message name="BackupFailedFaultTypeMessage">
<part name="fault" element="tns:BackupFailedFaultType"/>
</wsdl:message>
<wsdl:message name="BackupNotAvailableFaultTypeMessage">
<part name="fault" element="tns:BackupNotAvailableFaultType"/>
</wsdl:message>
<!--============================================================
@ -82,27 +108,29 @@
<wsdl:operation name="Backup">
<wsdl:input message="tns:BackupInputMessage"/>
<wsdl:output message="tns:BackupOutputMessage"/>
<wsdl:fault name="fault" message="tns:XMLStorageUnavailableFaultTypeMessage"/>
<wsdl:fault name="fault" message="tns:XMLStorageNotAvailableFaultTypeMessage"/>
<wsdl:fault name="fault2" message="tns:BackupFailedFaultTypeMessage"/>
</wsdl:operation>
<!--
<wsdl:operation name="Restore">
<wsdl:input message="tns:RestoreInputMessage"/>
<wsdl:output message="tns:RestoreOutputMessage"/>
<wsdl:fault name="fault" message="tns:XMLStorageUnavailableFaultTypeMessage"/>
<wsdl:fault name="fault" message="tns:XMLStorageNotAvailableFaultTypeMessage"/>
<wsdl:fault name="fault2" message="tns:BackupNotAvailableFaultTypeMessage"/>
</wsdl:operation>
<!--
<wsdl:operation name="Shutdown">
<wsdl:input message="tns:ShutdownInputMessage"/>
<wsdl:output message="tns:ShutdownOutputMessage"/>
<wsdl:fault name="fault" message="tns:XMLStorageUnavailableFaultTypeMessage"/>
<wsdl:fault name="fault" message="tns:XMLStorageNotAvailableFaultTypeMessage"/>
</wsdl:operation>
<wsdl:operation name="Restart">
<wsdl:input message="tns:RestartInputMessage"/>
<wsdl:output message="tns:RestartOutputMessage"/>
<wsdl:fault name="fault" message="tns:XMLStorageUnavailableFaultTypeMessage"/>
<wsdl:fault name="fault" message="tns:XMLStorageNotAvailableFaultTypeMessage"/>
</wsdl:operation>
-->
</wsdl:portType>

View File

@ -41,7 +41,7 @@ public class ICServiceContext extends GCUBEServiceContext {
/** {@inheritDoc} */
@Override
protected void onReady() throws Exception {
State.initialize();
}
/** {@inheritDoc} */

View File

@ -1,10 +1,13 @@
package org.gcube.informationsystem.collector.impl.porttypes;
import java.io.IOException;
import org.oasis.wsrf.faults.BaseFaultType;
import org.xmldb.api.base.XMLDBException;
import org.gcube.informationsystem.collector.stubs.BackupFailedFaultType;
import org.gcube.informationsystem.collector.stubs.XMLStorageUnavailableFaultType;
import org.gcube.informationsystem.collector.stubs.BackupNotAvailableFaultType;
import org.gcube.informationsystem.collector.stubs.XMLStorageNotAvailableFaultType;
import org.gcube.common.core.contexts.GCUBEServiceContext;
import org.gcube.common.core.porttypes.GCUBEPortType;
import org.gcube.common.core.types.VOID;
@ -29,15 +32,15 @@ public class XMLStorageAccess extends GCUBEPortType {
/**
* Backups the current content of the XMLStorage
* @throws BackupFailedFaultType if the backup fails
* @throws XMLStorageUnavailableFaultType if the XMLStorage is not available (may be corrupted)
* @throws XMLStorageNotAvailableFaultType if the XMLStorage is not available (may be corrupted)
*/
public VOID backup(VOID params) throws BackupFailedFaultType, XMLStorageUnavailableFaultType {
public VOID backup(VOID params) throws BackupFailedFaultType, XMLStorageNotAvailableFaultType {
try {
State.getDataManager().backup();
} catch (XMLDBException e) {
logger.error("Failed to backup", e);
throw new XMLStorageUnavailableFaultType();
throw new XMLStorageNotAvailableFaultType();
} catch (Exception e) {
logger.error("Failed to backup", e);
BackupFailedFaultType fault = new BackupFailedFaultType();
@ -47,6 +50,20 @@ public class XMLStorageAccess extends GCUBEPortType {
return new VOID();
}
public VOID restore(VOID params) throws BackupNotAvailableFaultType, XMLStorageNotAvailableFaultType {
try {
State.getDataManager().restore();
} catch (IOException e) {
logger.error("Failed to backup", e);
BackupNotAvailableFaultType fault = new BackupNotAvailableFaultType();
fault.addFaultDetailString("No valid backup has been found");
throw fault;
}
return new VOID();
}
/**
* Disposes the XMLStorage
@ -54,6 +71,9 @@ public class XMLStorageAccess extends GCUBEPortType {
* @throws BaseFaultType if the shutdown fails
*/
public void dispose() throws BaseFaultType {
//request the backup before to shutdown
this.backup(new VOID());
/*try {
logger.info("Dispose operation invoked");
logger.info("trying to shutdown the storage instances...");

View File

@ -252,8 +252,7 @@ public class AggregatorRegisteredResource extends AggregatorServiceGroupResource
aentry.dispose();
logger.info("Delivered resource stored with success");
} catch (Exception e) {
logger.error("When managing aggregator content:" + e.getMessage());
logger.error("returned exception ", e);
logger.error("An error occurred when managing aggregator content, the resource has NOT be stored successfully", e);
}
}

View File

@ -1,6 +1,7 @@
package org.gcube.informationsystem.collector.impl.xmlstorage.backup;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.util.Calendar;
@ -18,10 +19,16 @@ public class BackupsRootFolder {
private static final long serialVersionUID = 6054398926161291140L;
private final static String backupsRoot = ICServiceContext.getContext().getPersistenceRoot().getAbsolutePath() + File.separator + "backups" + File.separator;
private static String backupDir = (String) ICServiceContext.getContext().getProperty("backupDir", true);
private static GCUBELog logger = new GCUBELog(BackupsRootFolder.class);
static {
if (! new File(backupDir).isAbsolute()) //make it absolute
backupDir = ICServiceContext.getContext().getPersistenceRoot().getAbsolutePath() + File.separator + backupDir + File.separator;
}
/**
* Creates a new backup folder
*
@ -30,7 +37,7 @@ public class BackupsRootFolder {
*/
public static BackupFolder createBackupFolder() throws IOException {
final String backupFolder = backupsRoot + File.separator + buildBackupFolderName();
final String backupFolder = backupDir + File.separator + buildBackupFolderName();
File backup = new File(backupFolder);
if (!backup.mkdirs())
throw new IOException("Unable to create the backup folder");
@ -40,15 +47,16 @@ public class BackupsRootFolder {
@SuppressWarnings("unchecked")
public <T extends BackupFolder> T getLastBackup(Class<T> backupType) throws IOException {
public <T extends BackupFolder> T getLastBackup(Class<T> backupType, FilenameFilter ... filter) throws IOException {
File rootFolder = new File(backupsRoot);
File rootFolder = new File(backupDir);
if (!rootFolder.exists())
throw new IOException("Unable to read the backup folder");
//look for the most recent backup
File[] files = rootFolder.listFiles();
File[] files = (filter != null && filter[0] != null) ? files = rootFolder.listFiles(filter[0]) : rootFolder.listFiles();
long lastModified = 0;
T lastBackup = null;
for (File file : files) {
@ -65,7 +73,7 @@ public class BackupsRootFolder {
if (lastBackup == null)
throw new IOException("Unable to find a valid backup folder");
logger.debug("last backup found in " + lastBackup.getAbsolutePath());
logger.info("last backup found in " + lastBackup.getAbsolutePath());
return lastBackup;
}

View File

@ -1,6 +1,7 @@
package org.gcube.informationsystem.collector.impl.xmlstorage.backup;
import org.gcube.common.core.utils.handlers.GCUBEScheduledHandler;
import org.gcube.common.core.utils.logging.GCUBELog;
/**
* Scheduler for periodic XMLStorage backups
@ -8,32 +9,45 @@ import org.gcube.common.core.utils.handlers.GCUBEScheduledHandler;
* @author Manuele Simi (ISTI-CNR)
*
*/
public abstract class Scheduler extends GCUBEScheduledHandler {
public abstract class Scheduler implements Runnable {
/** scheduler logger */
protected static GCUBELog logger = new GCUBELog(Scheduler.class);
private int intervalInMS = 24 * 3600 * 1000; //default, 1 day
/**
* @param intervalInHours the interval expressed in hours between two backups
*/
public Scheduler(int intervalInHours) {
this.intervalInMS = intervalInHours * 3600 * 1000;
}
public Scheduler() {}
public void run() {
do {
try {
Thread.sleep(this.intervalInMS);
this.doBackup();
} catch (InterruptedException e) {
logger.error("Unable to sleep (yawn)", e);
} catch (Exception e) {
logger.error("Unable to backup", e);
}
} while (Thread.interrupted());
//logger.info("Backup Scheduler was interrupted");
}
/**
* @param interval
* @param mode
* @param handler
* Performs the backup
*
* @throws Exception if the backup fails
*/
public Scheduler(Configuration configuration) {
super(configuration.getInterval(), Mode.EAGER);
}
public class Configuration {
long interval;
/**
* @return the interval
*/
public long getInterval() {
return interval;
}
/**
* @param interval the interval to set
*/
public void setInterval(long interval) {
this.interval = interval;
}
}
}
protected abstract void doBackup() throws Exception;
}

View File

@ -10,7 +10,9 @@ import org.xml.sax.SAXException;
import org.xmldb.api.base.XMLDBException;
import org.gcube.common.core.utils.logging.GCUBELog;
import org.gcube.informationsystem.collector.impl.contexts.ICServiceContext;
import org.gcube.informationsystem.collector.impl.xmlstorage.backup.BackupsRootFolder;
import org.gcube.informationsystem.collector.impl.xmlstorage.backup.Scheduler;
/**
* Data Manager
@ -20,19 +22,21 @@ import org.gcube.informationsystem.collector.impl.xmlstorage.backup.BackupsRootF
*/
public class DataManager extends XMLStorageManager {
private static GCUBELog logger = new GCUBELog(DataManager.class);
private final static GCUBELog logger = new GCUBELog(DataManager.class);
private static ExistScheduler scheduler = null;
/**
* Backups the current content of the XMLStorage
* @throws Exception
*/
public void backup() throws IOException, Exception {
public synchronized void backup() throws IOException, Exception {
//run the eXist's ConsistencyCheckTask
//info: http://www.exist-db.org/backup.html
//source: http://exist.svn.sourceforge.net/viewvc/exist/branches/eXist-stable-1.2/src/org/exist/backup/ExportMain.java?revision=8695&view=markup
logger.info("backup requested");
logger.info("Backup requested");
ConsistencyCheckTask check = new ConsistencyCheckTask();
Properties props = new Properties();
props.setProperty("output", BackupsRootFolder.createBackupFolder().getAbsolutePath()); //The directory to which the backup is written
@ -41,6 +45,7 @@ public class DataManager extends XMLStorageManager {
check.configure(null, props); //configuration is null, since we pass an absolute path as backup folder
check.execute(BrokerPool.getInstance().get(org.exist.security.SecurityManager.SYSTEM_USER));
logger.info("Backup completed");
//alternative backup way
/*Backup backup = new Backup("admin", "admin", BackupsRootFolder.createBackupFolder().getAbsolutePath(), XmldbURI.create(URI + DBBroker.ROOT_COLLECTION));
try {
@ -62,7 +67,9 @@ public class DataManager extends XMLStorageManager {
* @throws ParserConfigurationException
* @throws Exception
*/
public void restore() throws IOException {
public synchronized void restore() throws IOException {
logger.info("Restore requested");
ExistBackupFolder lastBackup = this.getLastBackup();
Restore restore = null;
@ -80,6 +87,7 @@ public class DataManager extends XMLStorageManager {
try {
restore.restore(false, null);
logger.info("Restore completed");
} catch (XMLDBException e) {
logger.error(e);
} catch (SAXException e) {
@ -88,10 +96,32 @@ public class DataManager extends XMLStorageManager {
}
/**
* Retrieves the last backup
* @return the last backup file or folder
* @throws IOException if the backup cannot be found
*/
private ExistBackupFolder getLastBackup() throws IOException {
return new BackupsRootFolder().getLastBackup(ExistBackupFolder.class);
return new BackupsRootFolder().getLastBackup(ExistBackupFolder.class, ExistBackupFolder.getFilter());
}
/**
* Gets the scheduler for automatic and periodic backups of the XMLStorage.<br/>
* Automatic backups are scheduled via the <em>scheduledBackupInHours</em> variable in the service's JNDI.
* If this variable is missing the automatic backups are not performed.
* @return the scheduler or null if no automatic backup was configured
*/
public static Scheduler getScheduler() {
if (scheduler != null)
return scheduler;
String interval = (String) ICServiceContext.getContext().getProperty("scheduledBackupInHours", false);
if (interval == null)
return null; // scheduled backups are not requested
//create a new scheduler if requested
scheduler = new ExistScheduler(Integer.valueOf(interval));
return scheduler;
}
}

View File

@ -1,5 +1,7 @@
package org.gcube.informationsystem.collector.impl.xmlstorage.exist;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import org.gcube.informationsystem.collector.impl.xmlstorage.backup.BackupFolder;
@ -21,11 +23,13 @@ public class ExistBackupFolder extends BackupFolder {
super(pathname);
}
/** {@inheritDoc} */
@Override
protected boolean isValid() {
//TODO: should check the existence of "db/__contents__.xml"
return true;
protected static FilenameFilter getFilter() {
return new FilenameFilter() {
public boolean accept(File dir, String name) {
if ((name.endsWith(".zip") || name.endsWith(".ZIP")))
return true;
//TODO: should check the existence of "db/__contents__.xml" ??
return false;
}};
}
}

View File

@ -2,6 +2,7 @@ package org.gcube.informationsystem.collector.impl.xmlstorage.exist;
import org.gcube.informationsystem.collector.impl.xmlstorage.backup.Scheduler;
/**
* Exist Scheduler for periodic backups
*
@ -10,12 +11,16 @@ import org.gcube.informationsystem.collector.impl.xmlstorage.backup.Scheduler;
*/
public class ExistScheduler extends Scheduler {
/**
* @param configuration
*/
public ExistScheduler(Configuration configuration) {
super(configuration);
/**{@inheritDoc} */
public ExistScheduler(int intervalInHours) {
super(intervalInHours);
}
/**{@inheritDoc} */
@Override
protected void doBackup() throws Exception {
org.gcube.informationsystem.collector.impl.xmlstorage.exist.State.getDataManager().backup();
}
}

View File

@ -1,11 +1,9 @@
package org.gcube.informationsystem.collector.impl.xmlstorage.exist;
import org.gcube.common.core.utils.logging.GCUBELog;
import org.gcube.informationsystem.collector.impl.contexts.ICServiceContext;
import org.gcube.informationsystem.collector.impl.persistence.AggregatorPersistentResource;
import org.globus.wsrf.config.ContainerConfig;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
@ -20,19 +18,20 @@ import java.util.Collections;
public class State {
/**
* Connection to eXist used to store data
* Connection to XMLStorage for data management
*/
private static DataManager storageManager;
private static DataManager dataManager;
/**
* Connection to eXist used to query the database
* Connection to XMLStorage for querying the data
*/
private static QueryManager queryManager;
/**
* Thread that periodically sweeps the database from expired resources
*/
/** Thread that periodically sweeps the XMLStorage from expired resources */
public static Thread sweeperT;
/** Thread that periodically backups the XMLStorage */
public static Thread schedulerT;
/**
* List of recently deleted resources. It is used to avoid the storage of RPs of a deleted
@ -40,7 +39,7 @@ public class State {
*/
public static List<AggregatorPersistentResource> deletedResources = Collections.synchronizedList(new ArrayList<AggregatorPersistentResource>());
private static Log logger = LogFactory.getLog(State.class.getName());
private static GCUBELog logger = new GCUBELog(State.class);
/**
* Initializes the eXist DB connections using during the service life
@ -57,7 +56,7 @@ public class State {
if (Boolean.valueOf((String) ICServiceContext.getContext().getProperty("deleteRPsOnStartup", true))) {
// cleanup the RPs collection
logger.info("deleting all RPs...");
State.storageManager.deleteAllProperties();
State.dataManager.deleteAllProperties();
} else {
logger.info("all RPs previously stored are keept in the storage");
}
@ -67,14 +66,21 @@ public class State {
.getProperty("resourceExpirationTimeInMillis", true)));
State.sweeperT = new Thread(sweeper);
State.sweeperT.start();
//start the scheduler for automatic backups (if any)
org.gcube.informationsystem.collector.impl.xmlstorage.backup.Scheduler scheduler = DataManager.getScheduler();
if (scheduler != null) {
schedulerT = new Thread(scheduler);
schedulerT.start();
}
logger.info("IC service initialization completed");
}
private static void initializeDataManager() throws Exception {
// open the connection used to store resources
State.storageManager = new DataManager();
storageManager.initialize();
State.dataManager = new DataManager();
dataManager.initialize();
}
private static void initializeQueryManager() throws Exception {
@ -87,9 +93,9 @@ public class State {
*
* @return the container base dir
*/
public static String getBaseDirectory() {
return ContainerConfig.getBaseDirectory();
}
// public static String getBaseDirectory() {
// return ContainerConfig.getBaseDirectory();
// }
/**
* Releases all the State resources
@ -98,15 +104,18 @@ public class State {
*/
public static void dispose() throws Exception {
logger.info("Disposing IC service's resources...");
State.storageManager.shutdown();
State.sweeperT.interrupt();
State.schedulerT.interrupt();
State.dataManager.shutdown();
State.queryManager.shutdown();
}
/**
* @return the storageManager
* @return the dataManager
*/
public static DataManager getDataManager() {
return storageManager;
return dataManager;
}
/**
@ -127,6 +136,5 @@ public class State {
logger.debug(keys.nextElement());
}
logger.debug("Exist home: " + System.getProperty("exist.home"));
logger.debug("Class path: " + System.getProperty("java.class.path"));
}
}

View File

@ -171,6 +171,9 @@ public class XMLStorageManager {
logger.error("failed to create collection " + collectionName + "!");
logger.error("" + edb.getCause());
} catch (java.lang.NullPointerException e) {
logger.fatal("the XMLStorage is GONE!! a Restore is needed");
}
return currentCollection;
}

View File

@ -1,4 +1,4 @@
package org.gcube.informationsystem.collector.testsuite;
package org.gcube.informationsystem.collector.stubs.testsuite;
import java.net.URL;
import java.rmi.RemoteException;
@ -9,7 +9,7 @@ import org.gcube.common.core.types.VOID;
import org.gcube.common.core.utils.logging.GCUBEClientLog;
import org.gcube.informationsystem.collector.stubs.BackupFailedFaultType;
import org.gcube.informationsystem.collector.stubs.XMLStorageAccessPortType;
import org.gcube.informationsystem.collector.stubs.XMLStorageUnavailableFaultType;
import org.gcube.informationsystem.collector.stubs.XMLStorageNotAvailableFaultType;
import org.gcube.informationsystem.collector.stubs.service.XMLStorageAccessServiceLocator;
@ -53,7 +53,7 @@ public class BackupTester {
logger.info("Submitting backup request...");
try {
port.backup(new VOID());
} catch (XMLStorageUnavailableFaultType e) {
} catch (XMLStorageNotAvailableFaultType e) {
logger.error("",e);
} catch (BackupFailedFaultType e) {
logger.error("",e);

View File

@ -0,0 +1,65 @@
package org.gcube.informationsystem.collector.stubs.testsuite;
import java.net.URL;
import java.rmi.RemoteException;
import org.gcube.common.core.contexts.GCUBERemotePortTypeContext;
import org.gcube.common.core.scope.GCUBEScope;
import org.gcube.common.core.types.VOID;
import org.gcube.common.core.utils.logging.GCUBEClientLog;
import org.gcube.informationsystem.collector.stubs.BackupNotAvailableFaultType;
import org.gcube.informationsystem.collector.stubs.XMLStorageAccessPortType;
import org.gcube.informationsystem.collector.stubs.XMLStorageNotAvailableFaultType;
import org.gcube.informationsystem.collector.stubs.service.XMLStorageAccessServiceLocator;
/**
* Tester for <em>Restore</em> operation of the
* <em>gcube/informationsystem/collector/XMLStorageAccess</em> portType
*
* @author Manuele Simi (ISTI-CNR)
*
*/
public class RestoreTester {
private static GCUBEClientLog logger = new GCUBEClientLog(RestoreTester.class);
/**
* @param args
* <ol>
* <li> IC host
* <li> IC port
* <li> Caller Scope
* </ol>
*/
public static void main(String[] args) {
/*if (args.length != 3) {
logger.fatal("Usage: RestoreTester <host> <port> <Scope>");
return;
}*/
//final String portTypeURI = "http://" + args[0] + ":" + args[1] + "/wsrf/services/gcube/informationsystem/collector/XMLStorageAccess";
final String portTypeURI = "http://node10.d.d4science.research-infrastructures.eu:8080/wsrf/services/gcube/informationsystem/collector/XMLStorageAccess";
XMLStorageAccessPortType port = null;
try {
port = new XMLStorageAccessServiceLocator().getXMLStorageAccessPortTypePort(new URL(portTypeURI));
port = GCUBERemotePortTypeContext.getProxy(port, GCUBEScope.getScope("/CNRPrivate"));
} catch (Exception e) {
e.printStackTrace();
}
logger.info("Submitting restore request...");
try {
port.restore(new VOID());
} catch (XMLStorageNotAvailableFaultType e) {
logger.error("",e);
} catch (BackupNotAvailableFaultType e) {
logger.error("",e);
} catch (RemoteException e) {
logger.error("",e);
}
}
}

View File

@ -1,4 +1,4 @@
package org.gcube.informationsystem.collector.testsuite;
package org.gcube.informationsystem.collector.stubs.testsuite;
/**
* TODO: Manuele, don't forget to add a comment for this new type!!

View File

@ -1,4 +1,4 @@
package org.gcube.informationsystem.collector.testsuite;
package org.gcube.informationsystem.collector.stubs.testsuite;
import java.io.BufferedReader;