Index: modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/MDStoreUtils.java
===================================================================
--- modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/MDStoreUtils.java	(revision 46516)
+++ modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/MDStoreUtils.java	(nonexistent)
@@ -1,27 +0,0 @@
-package eu.dnetlib.data.mdstore;
-
-import java.util.Comparator;
-import java.util.Date;
-import java.util.function.Function;
-
-import com.mongodb.DBObject;
-import eu.dnetlib.data.mdstore.model.MDStoreTransactionInfo;
-
-/**
- * Created by claudio on 13/03/2017.
- */
-public class MDStoreUtils {
-
-	public static Function<DBObject, String> mdId() {
-		return arg -> (String) arg.get("mdId");
-	}
-
-	public static Comparator<MDStoreTransactionInfo> getComparatorOnDate() {
-		return (o1, o2) -> {
-			final Date d1 = o1.getDate();
-			final Date d2 = o2.getDate();
-			return d1.compareTo(d2);
-		};
-	}
-
-}
Index: modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/RecordParser.java
===================================================================
--- modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/RecordParser.java	(revision 46516)
+++ modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/RecordParser.java	(nonexistent)
@@ -1,79 +0,0 @@
-package eu.dnetlib.data.mdstore;
-
-import java.io.ByteArrayInputStream;
-import java.util.Date;
-import java.util.Stack;
-import java.util.function.Function;
-import javax.xml.stream.XMLInputFactory;
-import javax.xml.stream.XMLStreamConstants;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.XMLStreamReader;
-
-import eu.dnetlib.data.mdstore.model.MDStoreRecord;
-import org.apache.commons.lang3.StringUtils;
-
-/**
- * Created by claudio on 20/03/2017.
- */
-public class RecordParser implements Function<String, MDStoreRecord> {
-
-	public static final String OBJ_IDENTIFIER = "objIdentifier";
-	public static final String IDENTIFIER = "identifier";
-
-	private Long timestamp;
-
-	private XMLInputFactory factory;
-
-	public RecordParser() {
-		factory = XMLInputFactory.newInstance();
-		timestamp = null;
-	}
-
-	public RecordParser(final long timestamp) {
-		factory = XMLInputFactory.newInstance();
-		this.timestamp = timestamp;
-	}
-
-	@Override
-	public MDStoreRecord apply(final String s) {
-		try {
-			final XMLStreamReader parser = factory.createXMLStreamReader(new ByteArrayInputStream(s.getBytes()));
-			final Stack<String> elementStack = new Stack<>();
-			elementStack.push("/");
-
-			final MDStoreRecord res = MDStoreRecord.create()
-					.setBody(s)
-					.setTimestamp(timestamp != null ? timestamp : new Date().getTime());
-
-			System.out.println(res.getTimestamp());
-
-			while (parser.hasNext()) {
-				int event = parser.next();
-
-				if (event == XMLStreamConstants.END_ELEMENT) {
-					elementStack.pop();
-				} else if (event == XMLStreamConstants.START_ELEMENT) {
-					final String localName = parser.getLocalName();
-					elementStack.push(localName);
-
-					if (OBJ_IDENTIFIER.equals(localName)) {
-						parser.next();
-						res.setId(parser.getText().trim());
-
-					} else if (IDENTIFIER.equals(localName)) {
-						if (StringUtils.isBlank(res.getOriginalId())) {
-							parser.next();
-							res.setOriginalId(parser.getText().trim());
-						}
-					}
-					if (StringUtils.isNotBlank(res.getId()) && StringUtils.isNotBlank(res.getOriginalId())) {
-						return res;
-					}
-				}
-			}
-			return res;
-		} catch (XMLStreamException e) {
-			throw new IllegalStateException(e);
-		}
-	}
-}
Index: modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/MDStoreRuntimeException.java
===================================================================
--- modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/MDStoreRuntimeException.java	(revision 46516)
+++ modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/MDStoreRuntimeException.java	(nonexistent)
@@ -1,24 +0,0 @@
-package eu.dnetlib.data.mdstore;
-
-import eu.dnetlib.exceptions.DnetGenericRuntimeException;
-
-/**
- * Created by claudio on 13/03/2017.
- */
-public class MDStoreRuntimeException extends DnetGenericRuntimeException {
-
-	public MDStoreRuntimeException() {
-	}
-
-	public MDStoreRuntimeException(final String message, final Throwable cause) {
-		super(message, cause);
-	}
-
-	public MDStoreRuntimeException(final String message) {
-		super(message);
-	}
-
-	public MDStoreRuntimeException(final Throwable cause) {
-		super(cause);
-	}
-}
Index: modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/MDStoreConstants.java
===================================================================
--- modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/MDStoreConstants.java	(revision 46516)
+++ modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/MDStoreConstants.java	(nonexistent)
@@ -1,34 +0,0 @@
-package eu.dnetlib.data.mdstore;
-
-/**
- * Created by claudio on 20/03/2017.
- */
-public class MDStoreConstants {
-
-	public static final String ID = "id";
-	public static final String INTERNAL_MONGO_ID = "_id";
-	public static final String MDID = "mdId";
-	public static final String METADATA_MANAGER_TABLE = "metadataManager";
-	public static final String CURRENT_ID = "currentId";
-	public static final String EXPIRING = "expiring";
-	public static final String REFRESH = "refresh";
-	public static final String DATE = "date";
-	public static final String TRANSACTIONS = "transactions";
-	public static final String LAST_UPDATE_DATE = "lastUpdateDate";
-	public static final String READ_COUNT = "readCount";
-	public static final String DISCARDED_PREFIX = "discarded-";
-	public static final String BODY = "body";
-	public static final String ORIGINAL_ID = "originalId";
-	public static final String TIMESTAMP = "timestamp";
-
-	public static final String FORMAT = "format";
-	public static final String LAYOUT = "layout";
-	public static final String INTERPRETATION = "interpretation";
-	public static final String SIZE = "size";
-	public static final String METADATA_NAME = "metadata";
-	public static final String TOTAL = "total";
-	public static final String INDEXED = "indexed";
-
-	public static final String ID_SEPARATOR = "/";
-
-}
Index: modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/MDStoreException.java
===================================================================
--- modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/MDStoreException.java	(revision 46516)
+++ modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/MDStoreException.java	(nonexistent)
@@ -1,24 +0,0 @@
-package eu.dnetlib.data.mdstore;
-
-import eu.dnetlib.exceptions.DnetGenericException;
-
-/**
- * Created by claudio on 13/03/2017.
- */
-public class MDStoreException extends DnetGenericException {
-
-	public MDStoreException() {
-	}
-
-	public MDStoreException(final String message, final Throwable cause) {
-		super(message, cause);
-	}
-
-	public MDStoreException(final String message) {
-		super(message);
-	}
-
-	public MDStoreException(final Throwable cause) {
-		super(cause);
-	}
-}
Index: modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/MDStoreProfileManager.java
===================================================================
--- modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/MDStoreProfileManager.java	(revision 46516)
+++ modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/MDStoreProfileManager.java	(nonexistent)
@@ -1,79 +0,0 @@
-package eu.dnetlib.data.mdstore;
-
-import java.io.IOException;
-import java.io.StringWriter;
-import java.io.Writer;
-import java.util.Map;
-
-import com.google.common.collect.Maps;
-import eu.dnetlib.clients.is.InformationServiceClient;
-import eu.dnetlib.miscutils.datetime.DateUtils;
-import eu.dnetlib.msro.controllers.MsroWorkerController;
-import freemarker.template.Configuration;
-import freemarker.template.Template;
-import freemarker.template.TemplateException;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-
-/**
- * Created by claudio on 24/03/2017.
- */
-@Component
-public class MDStoreProfileManager {
-
-	private static final Log log = LogFactory.getLog(MDStoreProfileManager.class);
-
-	@Autowired
-	private InformationServiceClient isClient;
-
-	@Autowired
-	private MsroWorkerController msroWorkerController;
-
-	@Autowired
-	private Configuration freemakerCfg;
-
-	public String registerProfile(String format, String layout, String interpretation) throws MDStoreException {
-
-		final Map<String, Object> input = Maps.newHashMap();
-
-		input.put("serviceId", msroWorkerController.getProfileId());
-		input.put("format", format);
-		input.put("layout", layout);
-		input.put("interpretation", interpretation);
-
-		log.debug(String.format("registering new mdstore profile %s-%s-%s", format, layout, interpretation));
-
-		return isClient.register(processTemplate(input));
-	}
-
-	public void deleteProfile(final String mdId) throws MDStoreException {
-		isClient.deleteProfile(mdId);
-	}
-
-	public void updateSize(final String mdId, final int size) {
-		final String now = DateUtils.now_ISO8601();
-
-		isClient.xupdate("for $x in //RESOURCE_PROFILE[.//RESOURCE_IDENTIFIER/@value = '" + mdId + "']"
-				+ "return update value $x//LAST_STORAGE_DATE with '" + now + "'");
-
-		isClient.xupdate("for $x in //RESOURCE_PROFILE[.//RESOURCE_IDENTIFIER/@value = '" + mdId + "']"
-				+ "return update value $x//NUMBER_OF_RECORDS with '" + size + "'");
-	}
-
-	// HELPERS
-
-	private String processTemplate(final Map<String, Object> input) throws MDStoreException {
-		try(Writer writer = new StringWriter()) {
-			final Template template = freemakerCfg.getTemplate("mdstore.ftl");
-
-			template.process(input, writer);
-
-			return writer.toString();
-		} catch (IOException | TemplateException e) {
-			throw new MDStoreException(e);
-		}
-	}
-
-}
Index: modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/mongo/codec/MDStoreManagerInfoCodec.java
===================================================================
--- modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/mongo/codec/MDStoreManagerInfoCodec.java	(revision 46516)
+++ modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/mongo/codec/MDStoreManagerInfoCodec.java	(nonexistent)
@@ -1,117 +0,0 @@
-package eu.dnetlib.data.mdstore.mongo.codec;
-
-import java.util.Date;
-import java.util.List;
-
-import com.google.common.collect.Lists;
-import eu.dnetlib.data.mdstore.model.MDStoreReadLock;
-import eu.dnetlib.data.mdstore.model.MDStoreManagerInfo;
-import eu.dnetlib.data.mdstore.model.MDStoreTransactionInfo;
-import org.bson.BsonReader;
-import org.bson.BsonType;
-import org.bson.BsonWriter;
-import org.bson.codecs.Codec;
-import org.bson.codecs.DecoderContext;
-import org.bson.codecs.EncoderContext;
-import org.springframework.stereotype.Component;
-
-import static eu.dnetlib.data.mdstore.MDStoreConstants.*;
-
-/**
- * Created by claudio on 22/03/2017.
- */
-@Component
-public class MDStoreManagerInfoCodec implements Codec<MDStoreManagerInfo> {
-
-	@Override
-	public MDStoreManagerInfo decode(final BsonReader reader, final DecoderContext decoderContext) {
-		reader.readStartDocument();
-		reader.readObjectId();
-		final MDStoreManagerInfo i = MDStoreManagerInfo.create()
-				.setMdId(reader.readString(MDID))
-				.setCurrentId(reader.readString(CURRENT_ID))
-				.setReadLocks(decodeReadLocks(reader, decoderContext))
-				.setTransactions(decodeTransactionInfos(reader, decoderContext));
-		reader.readEndDocument();
-		return i;
-	}
-
-	private List<MDStoreReadLock> decodeReadLocks(final BsonReader reader, final DecoderContext decoderContext) {
-		final List<MDStoreReadLock> expiredInfos = Lists.newArrayList();
-		reader.readStartArray();
-		while (reader.readBsonType() != BsonType.END_OF_DOCUMENT) {
-			expiredInfos.add(readExpiredInfo(reader));
-		}
-		reader.readEndArray();
-		return expiredInfos;
-	}
-
-	private MDStoreReadLock readExpiredInfo(final BsonReader reader) {
-		reader.readStartDocument();
-		final MDStoreReadLock i = MDStoreReadLock.create(reader.readString(ID))
-				.setReadCount(reader.readInt32(READ_COUNT))
-				.setLastUpdateDate(new Date(reader.readDateTime(LAST_UPDATE_DATE)));
-		reader.readEndDocument();
-		return i;
-	}
-
-	private List<MDStoreTransactionInfo> decodeTransactionInfos(final BsonReader reader, final DecoderContext decoderContext) {
-		final List<MDStoreTransactionInfo> txInfo = Lists.newArrayList();
-		reader.readStartArray();
-		while (reader.readBsonType() != BsonType.END_OF_DOCUMENT) {
-			txInfo.add(readTransactionInfo(reader));
-		}
-		reader.readEndArray();
-		return txInfo;
-	}
-
-	private MDStoreTransactionInfo readTransactionInfo(final BsonReader reader) {
-		reader.readStartDocument();
-		final MDStoreTransactionInfo i = MDStoreTransactionInfo.create()
-				.setId(reader.readString(ID))
-				.setRefresh(reader.readBoolean(REFRESH))
-				.setDate(new Date(reader.readInt64(DATE)))
-				.setSize(reader.readInt64(SIZE));
-		reader.readEndDocument();
-		return i;
-	}
-
-	@Override
-	public void encode(final BsonWriter writer, final MDStoreManagerInfo value, final EncoderContext encoderContext) {
-		writer.writeStartDocument();
-		writer.writeString(MDID, value.getMdId());
-		writer.writeString(CURRENT_ID, value.getCurrentId());
-
-		writer.writeStartArray(EXPIRING);
-		value.getReadLocks().forEach(e -> encodeReadLock(writer, e));
-		writer.writeEndArray();
-
-		writer.writeStartArray(TRANSACTIONS);
-		value.getTransactions().forEach(t -> encodeTransactionInfo(writer, t));
-		writer.writeEndArray();
-
-		writer.writeEndDocument();
-	}
-
-	public void encodeReadLock(final BsonWriter writer, final MDStoreReadLock value) {
-		writer.writeStartDocument();
-		writer.writeString(ID, value.getId());
-		writer.writeInt32(READ_COUNT, value.getReadCount());
-		writer.writeDateTime(LAST_UPDATE_DATE, value.getLastUpdateDate().getTime());
-		writer.writeEndDocument();
-	}
-
-	private void encodeTransactionInfo(final BsonWriter writer, final MDStoreTransactionInfo value) {
-		writer.writeStartDocument();
-		writer.writeString(ID, value.getId());
-		writer.writeBoolean(REFRESH, value.getRefresh());
-		writer.writeInt64(DATE, value.getDate().getTime());
-		writer.writeInt64(SIZE, value.getSize());
-		writer.writeEndDocument();
-	}
-
-	@Override
-	public Class<MDStoreManagerInfo> getEncoderClass() {
-		return MDStoreManagerInfo.class;
-	}
-}
Index: modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/mongo/codec/MDStoreDescriptionCodec.java
===================================================================
--- modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/mongo/codec/MDStoreDescriptionCodec.java	(revision 46516)
+++ modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/mongo/codec/MDStoreDescriptionCodec.java	(nonexistent)
@@ -1,53 +0,0 @@
-package eu.dnetlib.data.mdstore.mongo.codec;
-
-import eu.dnetlib.data.mdstore.model.MDStoreDescription;
-import org.bson.BsonReader;
-import org.bson.BsonWriter;
-import org.bson.codecs.Codec;
-import org.bson.codecs.DecoderContext;
-import org.bson.codecs.EncoderContext;
-import org.springframework.stereotype.Component;
-
-import static eu.dnetlib.data.mdstore.MDStoreConstants.*;
-
-/**
- * Created by claudio on 20/03/2017.
- */
-@Component
-public class MDStoreDescriptionCodec implements Codec<MDStoreDescription> {
-
-	@Override
-	public MDStoreDescription decode(final BsonReader reader, final DecoderContext decoderContext) {
-		reader.readStartDocument();
-		reader.readObjectId();
-
-		//TODO allow parsing MDStoreDescription(s) where the field order is not the one assumed below.
-		final MDStoreDescription d = MDStoreDescription.create()
-				.setMdId(reader.readString(MDID))
-				.setFormat(reader.readString(FORMAT))
-				.setLayout(reader.readString(LAYOUT))
-				.setInterpretation(reader.readString(INTERPRETATION))
-				.setSize(reader.readInt32(SIZE))
-				.setIndexed(reader.readBoolean(INDEXED));
-		reader.readEndDocument();
-		return d;
-	}
-
-	@Override
-	public void encode(final BsonWriter writer, final MDStoreDescription d, final EncoderContext encoderContext) {
-		writer.writeStartDocument();
-		writer.writeString(MDID, d.getMdId());
-		writer.writeString(FORMAT, d.getFormat());
-		writer.writeString(LAYOUT, d.getLayout());
-		writer.writeString(INTERPRETATION, d.getInterpretation());
-		writer.writeInt32(SIZE, d.getSize());
-		writer.writeBoolean(INDEXED, d.isIndexed());
-		writer.writeEndDocument();
-	}
-
-	@Override
-	public Class<MDStoreDescription> getEncoderClass() {
-		return MDStoreDescription.class;
-	}
-
-}
Index: modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/model/MDStoreTransactionInfo.java
===================================================================
--- modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/model/MDStoreTransactionInfo.java	(revision 46516)
+++ modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/model/MDStoreTransactionInfo.java	(nonexistent)
@@ -1,68 +0,0 @@
-package eu.dnetlib.data.mdstore.model;
-
-import java.util.Date;
-
-/**
- * Created by claudio on 13/03/2017.
- */
-public class MDStoreTransactionInfo {
-
-	private String id;
-	private Boolean refresh;
-	private Date date;
-	private long size;
-
-	public static MDStoreTransactionInfo create() {
-		return new MDStoreTransactionInfo()
-				.setDate(new Date());
-	}
-
-	/**
-	 * @return the date
-	 */
-	public Date getDate() {
-		return date;
-	}
-
-	/**
-	 * @return the id
-	 */
-	public String getId() {
-		return id;
-	}
-
-	/**
-	 * @return the refresh
-	 */
-	public Boolean getRefresh() {
-		return refresh;
-	}
-
-	/**
-	 * @return the size
-	 */
-	public long getSize() {
-		return size;
-	}
-
-	public MDStoreTransactionInfo setId(final String id) {
-		this.id = id;
-		return this;
-	}
-
-	public MDStoreTransactionInfo setRefresh(final Boolean refresh) {
-		this.refresh = refresh;
-		return this;
-	}
-
-	public MDStoreTransactionInfo setDate(final Date date) {
-		this.date = date;
-		return this;
-	}
-
-	public MDStoreTransactionInfo setSize(final long size) {
-		this.size = size;
-		return this;
-	}
-
-}
Index: modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/model/MDStoreDBStatus.java
===================================================================
--- modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/model/MDStoreDBStatus.java	(revision 46516)
+++ modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/model/MDStoreDBStatus.java	(nonexistent)
@@ -1,49 +0,0 @@
-package eu.dnetlib.data.mdstore.model;
-
-public class MDStoreDBStatus {
-
-	private int handledDatastructures;
-	private int usedDiskSpace;
-	private String date;
-
-	public MDStoreDBStatus() {}
-
-	public MDStoreDBStatus(final int handledDatastructures, final int usedDiskSpace, final String date) {
-		this.handledDatastructures = handledDatastructures;
-		this.usedDiskSpace = usedDiskSpace;
-		this.date = date;
-	}
-
-	public int getHandledDatastructures() {
-		return handledDatastructures;
-	}
-
-	public void setHandledDatastructures(final int handledDatastructures) {
-		this.handledDatastructures = handledDatastructures;
-	}
-
-	public int getUsedDiskSpace() {
-		return usedDiskSpace;
-	}
-
-	public void setUsedDiskSpace(final int usedDiskSpace) {
-		this.usedDiskSpace = usedDiskSpace;
-	}
-
-	public String getDate() {
-		return date;
-	}
-
-	public void setDate(final String date) {
-		this.date = date;
-	}
-
-	@Override
-	public String toString() {
-		return "MDStoreDBStatus{" +
-				"handledDatastructures=" + handledDatastructures +
-				", usedDiskSpace=" + usedDiskSpace +
-				", date='" + date + '\'' +
-				'}';
-	}
-}
Index: modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/model/MDStoreManagerInfo.java
===================================================================
--- modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/model/MDStoreManagerInfo.java	(revision 46516)
+++ modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/model/MDStoreManagerInfo.java	(nonexistent)
@@ -1,114 +0,0 @@
-package eu.dnetlib.data.mdstore.model;
-
-import java.time.Duration;
-import java.time.LocalDate;
-import java.time.ZoneId;
-import java.util.Collection;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-
-/**
- * Created by claudio on 13/03/2017.
- */
-public class MDStoreManagerInfo {
-
-	private String mdId;
-	private String currentId;
-
-	private Map<String, MDStoreReadLock> readLockMap = Maps.newHashMap();
-	private Map<String, MDStoreTransactionInfo> transactionMap = Maps.newHashMap();
-
-	public static MDStoreManagerInfo create() {
-		return new MDStoreManagerInfo()
-				.setReadLocks(Lists.newArrayList())
-				.setTransactions(Lists.newArrayList());
-	}
-
-	public MDStoreReadLock getReadLock(final String id) {
-		return readLockMap.get(id);
-	}
-
-	public List<String> getExpired(final int retainDays) {
-		final List<String> res = Lists.newArrayList();
-		readLockMap.entrySet().removeIf(e -> {
-			final MDStoreReadLock info = e.getValue();
-			if (info.getId().equals(getCurrentId())) {
-				return false;
-			} else {
-				if (getExpiringDays(info) >= retainDays) {
-					res.add(info.getId());
-					return true;
-				} else {
-					return false;
-				}
-			}
-		});
-		return res;
-	}
-
-	/**
-	 * Gets the expiring days.
-	 *
-	 * @param info     the value
-	 * @return the expiring days
-	 */
-	private long getExpiringDays(final MDStoreReadLock info) {
-		final Date lastRead = info.getLastUpdateDate();
-		final LocalDate readDate = lastRead.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
-		return Duration.between(LocalDate.now().atTime(0, 0), readDate.atTime(0, 0)).toDays();
-	}
-
-	public String getMdId() {
-		return mdId;
-	}
-
-	public MDStoreManagerInfo setMdId(final String mdId) {
-		this.mdId = mdId;
-		return this;
-	}
-
-	public String getCurrentId() {
-		return currentId;
-	}
-
-	public MDStoreManagerInfo setCurrentId(final String currentId) {
-		this.currentId = currentId;
-		return this;
-	}
-
-	public MDStoreManagerInfo setReadLocks(final List<MDStoreReadLock> readLocks) {
-		readLockMap.clear();
-		readLocks.forEach(r -> readLockMap.put(r.getId(), r));
-		return this;
-	}
-
-	public MDStoreManagerInfo addReadLock(final MDStoreReadLock readLock) {
-		readLockMap.put(readLock.getId(), readLock);
-		return this;
-	}
-
-	public MDStoreManagerInfo addTransaction(final MDStoreTransactionInfo info) {
-		transactionMap.put(info.getId(), info);
-		return this;
-	}
-
-	public MDStoreManagerInfo setTransactions(final List<MDStoreTransactionInfo> transactions) {
-		transactions.clear();
-		transactions.forEach(t -> transactionMap.put(t.getId(), t));
-		return this;
-	}
-
-	public Collection<MDStoreReadLock> getReadLocks() {
-		return readLockMap.values();
-	}
-
-	public Collection<MDStoreTransactionInfo> getTransactions() {
-		return transactionMap.values();
-	}
-
-
-}
Index: modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/model/MDStoreReadLock.java
===================================================================
--- modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/model/MDStoreReadLock.java	(revision 46516)
+++ modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/model/MDStoreReadLock.java	(nonexistent)
@@ -1,67 +0,0 @@
-package eu.dnetlib.data.mdstore.model;
-
-import java.util.Date;
-
-/**
- * Created by claudio on 13/03/2017.
- */
-public class MDStoreReadLock {
-
-	private String id;
-	private int readCount;
-	private Date lastUpdateDate;
-
-	public static MDStoreReadLock create(final String id) {
-		return new MDStoreReadLock()
-				.setId(id)
-				.setReadCount(0)
-				.setLastUpdateDate(new Date());
-	}
-
-	public MDStoreReadLock incrementReadCount() {
-		return modifyReadCount(1);
-	}
-
-	public MDStoreReadLock decrementReadCount() {
-		return modifyReadCount(-1);
-	}
-
-	private MDStoreReadLock modifyReadCount(int v) {
-		setReadCount(getReadCount() + v);
-		setLastUpdateDate(new Date());
-		return this;
-	}
-
-	/**
-	 * @return the lastRead
-	 */
-	public Date getLastUpdateDate() {
-		return lastUpdateDate;
-	}
-
-	/**
-	 * @return the id
-	 */
-	public String getId() {
-		return id;
-	}
-
-	public MDStoreReadLock setId(final String id) {
-		this.id = id;
-		return this;
-	}
-
-	public MDStoreReadLock setLastUpdateDate(final Date lastUpdateDate) {
-		this.lastUpdateDate = lastUpdateDate;
-		return this;
-	}
-
-	public int getReadCount() {
-		return readCount;
-	}
-
-	public MDStoreReadLock setReadCount(final int readCount) {
-		this.readCount = readCount;
-		return this;
-	}
-}
Index: modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/model/MDStoreDescription.java
===================================================================
--- modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/model/MDStoreDescription.java	(revision 46516)
+++ modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/model/MDStoreDescription.java	(nonexistent)
@@ -1,87 +0,0 @@
-package eu.dnetlib.data.mdstore.model;
-
-public class MDStoreDescription {
-
-	private String mdId;
-
-	private String format;
-
-	private String layout;
-
-	private String interpretation;
-
-	private int size;
-
-	private boolean indexed;
-
-	public MDStoreDescription(final String mdId, final String format, final String layout, final String interpretation, final int size, final boolean indexed) {
-		super();
-		this.mdId = mdId;
-		this.format = format;
-		this.layout = layout;
-		this.interpretation = interpretation;
-		this.size = size;
-		this.indexed = indexed;
-	}
-
-	public static MDStoreDescription create() {
-		return new MDStoreDescription();
-	}
-
-	public MDStoreDescription() {}
-
-	public String getMdId() {
-		return mdId;
-	}
-
-	public String getFormat() {
-		return format;
-	}
-
-	public String getLayout() {
-		return layout;
-	}
-
-	public String getInterpretation() {
-		return interpretation;
-	}
-
-	public int getSize() {
-		return size;
-	}
-
-	public boolean isIndexed() {
-		return indexed;
-	}
-
-	public MDStoreDescription setMdId(final String mdId) {
-		this.mdId = mdId;
-		return this;
-	}
-
-	public MDStoreDescription setFormat(final String format) {
-		this.format = format;
-		return this;
-	}
-
-	public MDStoreDescription setLayout(final String layout) {
-		this.layout = layout;
-		return this;
-	}
-
-	public MDStoreDescription setInterpretation(final String interpretation) {
-		this.interpretation = interpretation;
-		return this;
-	}
-
-	public MDStoreDescription setSize(final int size) {
-		this.size = size;
-		return this;
-	}
-
-	public MDStoreDescription setIndexed(final boolean indexed) {
-		this.indexed = indexed;
-		return this;
-	}
-
-}
Index: modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/test/java/eu/dnetlib/data/mdstore/MetadataTest.java
===================================================================
--- modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/test/java/eu/dnetlib/data/mdstore/MetadataTest.java	(nonexistent)
+++ modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/test/java/eu/dnetlib/data/mdstore/MetadataTest.java	(revision 46517)
@@ -0,0 +1,65 @@
+package eu.dnetlib.data.mdstore;
+
+import java.util.List;
+
+import eu.dnetlib.data.mdstore.repository.MetadataRepository;
+import eu.dnetlib.data.mdstore.model.Metadata;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+
+/**
+ * Created by claudio on 30/03/2017.
+ */
+public class MetadataTest extends AbstractMDStoreTest {
+
+	@Autowired
+	private MetadataRepository metadata;
+
+	@Before
+	public void setUp() {
+		metadata.deleteAll();
+	}
+
+	@Test
+	public void testMDStoreMetadata() {
+		Assert.assertNotNull(metadata);
+		Assert.assertEquals(0, metadata.count());
+
+		metadata.save(m("a"));
+
+		Assert.assertEquals(1, metadata.count());
+		Assert.assertNotNull(metadata.findOne("a"));
+
+		final List<Metadata> m = metadata.findByFormatAndLayoutAndInterpretation("f", "l", "i");
+		Assert.assertNotNull(m);
+		Assert.assertEquals(1, m.size());
+	}
+
+	@Test
+	public void testSumOfSize() {
+		metadata.save(m("a"));
+		metadata.save(m("b"));
+		metadata.save(m("c", "f", "l", "i2"));
+
+		Assert.assertEquals(2, metadata.sumOfSize("f", "l", "i"));
+
+		metadata.save(m("d"));
+		Assert.assertEquals(3, metadata.sumOfSize("f", "l", "i"));
+	}
+
+	private Metadata m(final String id) {
+		return m(id, "f", "l", "i");
+	}
+
+	private Metadata m(final String id, final String f, final String l, final String i) {
+		return Metadata.create()
+				.setMdId(id)
+				.setFormat(f)
+				.setLayout(l)
+				.setInterpretation(i)
+				.setSize(1)
+				.setIndexed(true);
+	}
+}
Index: modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/utils/MDStoreUtils.java
===================================================================
--- modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/utils/MDStoreUtils.java	(nonexistent)
+++ modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/utils/MDStoreUtils.java	(revision 46517)
@@ -0,0 +1,27 @@
+package eu.dnetlib.data.mdstore.utils;
+
+import java.util.Comparator;
+import java.util.Date;
+import java.util.function.Function;
+
+import com.mongodb.DBObject;
+import eu.dnetlib.data.mdstore.model.Transaction;
+
+/**
+ * Created by claudio on 13/03/2017.
+ */
+public class MDStoreUtils {
+
+	public static Function<DBObject, String> mdId() {
+		return arg -> (String) arg.get("mdId");
+	}
+
+	public static Comparator<Transaction> getComparatorOnDate() {
+		return (o1, o2) -> {
+			final Date d1 = o1.getDate();
+			final Date d2 = o2.getDate();
+			return d1.compareTo(d2);
+		};
+	}
+
+}
Index: modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/test/java/eu/dnetlib/data/mdstore/TransactionInfoTest.java
===================================================================
--- modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/test/java/eu/dnetlib/data/mdstore/TransactionInfoTest.java	(nonexistent)
+++ modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/test/java/eu/dnetlib/data/mdstore/TransactionInfoTest.java	(revision 46517)
@@ -0,0 +1,54 @@
+package eu.dnetlib.data.mdstore;
+
+import com.google.common.collect.Lists;
+import eu.dnetlib.data.mdstore.model.Transaction;
+import eu.dnetlib.data.mdstore.model.TransactionInfo;
+import eu.dnetlib.data.mdstore.repository.TransactionInfoRepository;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+
+/**
+ * Created by claudio on 30/03/2017.
+ */
+public class TransactionInfoTest extends AbstractMDStoreTest {
+
+	@Autowired
+	private TransactionInfoRepository transaction;
+
+	@Before
+	public void setUp() {
+		transaction.deleteAll();
+	}
+
+	@Test
+	public void testReadWrite() {
+		transaction.save(ti("1", "1"));
+		Assert.assertNotNull(transaction.findOne("1"));
+
+		transaction.save(ti("1", "1"));
+		Assert.assertNotNull(transaction.findOne("1"));
+
+		transaction.save(ti("2", "2"));
+		Assert.assertNotNull(transaction.findOne("1"));
+		Assert.assertEquals(2, Lists.newArrayList(transaction.findAll()).size());
+
+		Assert.assertEquals(0, transaction.findOne("1").getTransactions().size());
+		transaction.addTransaction("1", tx("t1"));
+		Assert.assertEquals(1, transaction.findOne("1").getTransactions().size());
+	}
+
+	private TransactionInfo ti(final String mdId, final String currentId) {
+		return TransactionInfo.create()
+				.setMdId(mdId)
+				.setCurrentId(currentId);
+	}
+
+	private Transaction tx(final String id) {
+		return Transaction.create()
+				.setId(id)
+				.setRefresh(true)
+				.setSize(0);
+	}
+}
Index: modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/MDStoreService.java
===================================================================
--- modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/MDStoreService.java	(revision 46516)
+++ modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/MDStoreService.java	(revision 46517)
@@ -4,6 +4,7 @@
 import java.util.stream.Stream;
 
 import eu.dnetlib.data.mdstore.model.MDStoreRecord;
+import eu.dnetlib.data.mdstore.utils.MDStoreException;
 
 /**
  * Created by claudio on 24/03/2017.
Index: modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/test/java/eu/dnetlib/data/mdstore/MDStoreCodecTest.java
===================================================================
--- modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/test/java/eu/dnetlib/data/mdstore/MDStoreCodecTest.java	(revision 46516)
+++ modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/test/java/eu/dnetlib/data/mdstore/MDStoreCodecTest.java	(revision 46517)
@@ -3,10 +3,10 @@
 import java.util.Date;
 import java.util.List;
 
-import com.google.common.collect.Lists;
 import com.mongodb.client.MongoCollection;
 import com.mongodb.client.model.Filters;
-import eu.dnetlib.data.mdstore.model.*;
+import eu.dnetlib.data.mdstore.model.MDStoreRecord;
+import eu.dnetlib.data.mdstore.utils.MDStoreException;
 import org.bson.codecs.Codec;
 import org.bson.codecs.configuration.CodecRegistry;
 import org.junit.Before;
@@ -13,7 +13,8 @@
 import org.junit.Test;
 import org.springframework.beans.factory.annotation.Autowired;
 
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 
 /**
  * Created by claudio on 22/03/2017.
@@ -57,69 +58,4 @@
 		assertEquals(testRecord.getBody(), findRecord.getBody());
 	}
 
-	@Test
-		public void testMDStoreDescriptionCodec() throws MDStoreException {
-
-		final MongoCollection<MDStoreDescription> test = getCollection(TEST_COLLECTION, MDStoreDescription.class);
-		assertNotNull(test);
-
-		final MDStoreDescription testRecord = MDStoreDescription.create()
-				.setMdId("1")
-				.setFormat("format")
-				.setLayout("layout")
-				.setInterpretation("interpretation")
-				.setSize(0)
-				.setIndexed(true);
-		test.insertOne(testRecord);
-		final MDStoreDescription findRecord = test.find(Filters.eq("mdId", "1")).first();
-
-		assertEquals(testRecord.getMdId(), findRecord.getMdId());
-		assertEquals(testRecord.getFormat(), findRecord.getFormat());
-		assertEquals(testRecord.getLayout(), findRecord.getLayout());
-		assertEquals(testRecord.getInterpretation(), findRecord.getInterpretation());
-		assertEquals(testRecord.getSize(), findRecord.getSize());
-		assertEquals(testRecord.isIndexed(), findRecord.isIndexed());
-	}
-
-	@Test
-	public void testMDStoreManagerInfoCodec() throws MDStoreException {
-
-		final MongoCollection<MDStoreManagerInfo> test = getCollection(TEST_COLLECTION, MDStoreManagerInfo.class);
-		assertNotNull(test);
-
-		final MDStoreManagerInfo testRecord = MDStoreManagerInfo.create()
-				.setMdId("1")
-				.setCurrentId("1")
-				.setReadLocks(Lists.newArrayList(
-						MDStoreReadLock.create("1"),
-						MDStoreReadLock.create("2")))
-				.setTransactions(Lists.newArrayList(
-						MDStoreTransactionInfo.create().setId("1").setRefresh(true).setSize(1),
-						MDStoreTransactionInfo.create().setId("2").setRefresh(true).setSize(1)
-						));
-		test.insertOne(testRecord);
-		final MDStoreManagerInfo findRecord = test.find(Filters.eq("mdId", "1")).first();
-
-		assertEquals(testRecord.getMdId(), findRecord.getMdId());
-		assertEquals(testRecord.getCurrentId(), findRecord.getCurrentId());
-
-		assertEquals(testRecord.getReadLocks().size(), findRecord.getReadLocks().size());
-		for(int i = 0; i < Math.min(testRecord.getReadLocks().size(), findRecord.getReadLocks().size()); i++) {
-			final MDStoreReadLock t = Lists.newArrayList(testRecord.getReadLocks()).get(i);
-			final MDStoreReadLock f = Lists.newArrayList(findRecord.getReadLocks()).get(i);
-			assertEquals(t.getId(), f.getId());
-			assertEquals(t.getLastUpdateDate(), f.getLastUpdateDate());
-			assertEquals(t.getId(), f.getId());
-		}
-		for(int i = 0; i < Math.min(testRecord.getTransactions().size(), findRecord.getTransactions().size()); i++) {
-			final MDStoreTransactionInfo t = Lists.newArrayList(testRecord.getTransactions()).get(i);
-			final MDStoreTransactionInfo f = Lists.newArrayList(findRecord.getTransactions()).get(i);
-			assertEquals(t.getId(), f.getId());
-			assertEquals(t.getSize(), f.getSize());
-			assertEquals(t.getDate(), f.getDate());
-			assertEquals(t.getRefresh(), f.getRefresh());
-		}
-	}
-
-
 }
Index: modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/test/java/eu/dnetlib/data/mdstore/MDStoreServiceTest.java
===================================================================
--- modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/test/java/eu/dnetlib/data/mdstore/MDStoreServiceTest.java	(revision 46516)
+++ modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/test/java/eu/dnetlib/data/mdstore/MDStoreServiceTest.java	(revision 46517)
@@ -3,10 +3,10 @@
 import java.util.stream.Stream;
 
 import com.mongodb.BasicDBObject;
-import com.mongodb.client.model.Filters;
 import eu.dnetlib.data.mdstore.MDStoreService.FeedMode;
-import eu.dnetlib.data.mdstore.model.MDStoreDescription;
 import eu.dnetlib.data.mdstore.mongo.MongoMDStoreService;
+import eu.dnetlib.data.mdstore.utils.MDStoreException;
+import eu.dnetlib.data.mdstore.utils.MDStoreProfileManager;
 import eu.dnetlib.miscutils.iterators.xml.XMLIterator;
 import eu.dnetlib.miscutils.streams.DnetStreamSupport;
 import org.junit.Before;
@@ -14,7 +14,7 @@
 import org.mockito.Mock;
 import org.springframework.beans.factory.annotation.Autowired;
 
-import static eu.dnetlib.data.mdstore.MDStoreConstants.*;
+import static eu.dnetlib.data.mdstore.utils.MDStoreConstants.*;
 import static org.junit.Assert.*;
 import static org.mockito.Mockito.anyString;
 import static org.mockito.Mockito.when;
@@ -45,8 +45,6 @@
 	@Test
 	public void testCreate() throws MDStoreException {
 		final String mdId = mdstoreService.create(FORMAT, LAYOUT, INTERPRETATION);
-		final MDStoreDescription d = getCollection(METADATA_NAME, MDStoreDescription.class).find(Filters.eq(MDID, mdId)).first();
-		assertNotNull(d);
 		assertEquals(1, mdstoreService.list().size());
 		assertEquals(mdId, mdstoreService.list().get(0));
 		assertEquals(0, mdstoreService.size(mdId));
Index: modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/test/resources/application.properties
===================================================================
--- modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/test/resources/application.properties	(revision 46516)
+++ modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/test/resources/application.properties	(revision 46517)
@@ -1,2 +1,3 @@
 msro.worker.mdstore.mongodb.port=27018
 msro.worker.mdstore.skip.prefixes=resolved,metadata
+msro.worker.mdstore.mongodb.dbname=test
Index: modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/mongo/MongoBulkWritesManager.java
===================================================================
--- modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/mongo/MongoBulkWritesManager.java	(revision 46516)
+++ modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/mongo/MongoBulkWritesManager.java	(revision 46517)
@@ -12,33 +12,31 @@
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
-import static eu.dnetlib.data.mdstore.MDStoreConstants.*;
+import static eu.dnetlib.data.mdstore.utils.MDStoreConstants.*;
 
 public class MongoBulkWritesManager {
 
 	private static final Log log = LogFactory.getLog(MongoBulkWritesManager.class);
-	private final boolean discardRecords;
-	private MongoCollection<MDStoreRecord> validCollection;
-	private List<WriteModel<MDStoreRecord>> validBulkOperationList;
+	private MongoCollection<MDStoreRecord> collection;
+	private List<WriteModel<MDStoreRecord>> validBulkOpList;
 
 	private BulkWriteOptions writeOptions;
-	private MongoCollection<MDStoreRecord> discardedCollection;
-	private List<WriteModel<MDStoreRecord>> discardedBulkOperationList;
+	private MongoCollection<MDStoreRecord> discarded;
+	private List<WriteModel<MDStoreRecord>> discardedBulkOpList;
 
 	private int bulkSize;
 
-	public MongoBulkWritesManager(final MongoCollection<MDStoreRecord> collection,
-			final MongoCollection<MDStoreRecord> discardedCollection,
-			final int bulkSize,
-			final boolean discardRecords) {
-		this.validCollection = collection.withWriteConcern(WriteConcern.ACKNOWLEDGED);
-		this.validBulkOperationList = Lists.newArrayList();
+	public MongoBulkWritesManager(
+			final MongoCollection<MDStoreRecord> collection,
+			final MongoCollection<MDStoreRecord> discarded,
+			final int bulkSize) {
+		this.collection = collection.withWriteConcern(WriteConcern.ACKNOWLEDGED);
+		this.validBulkOpList = Lists.newArrayList();
 
-		this.discardedCollection = discardedCollection.withWriteConcern(WriteConcern.ACKNOWLEDGED);
-		this.discardedBulkOperationList = Lists.newArrayList();
+		this.discarded = discarded.withWriteConcern(WriteConcern.ACKNOWLEDGED);
+		this.discardedBulkOpList = Lists.newArrayList();
 
 		this.bulkSize = bulkSize;
-		this.discardRecords = discardRecords;
 		this.writeOptions = new BulkWriteOptions().ordered(false);
 	}
 
@@ -49,31 +47,27 @@
 				if (log.isDebugEnabled()) {
 					log.debug("Saving object" + r.getId());
 				}
-				validBulkOperationList.add(new ReplaceOneModel(new BasicDBObject(ID, r.getId()), r, new UpdateOptions().upsert(true)));
-				if (((validBulkOperationList.size() % bulkSize) == 0) && !validBulkOperationList.isEmpty()) {
-					validCollection.bulkWrite(validBulkOperationList, writeOptions);
-					validBulkOperationList.clear();
+				validBulkOpList.add(new ReplaceOneModel(new BasicDBObject(ID, r.getId()), r, new UpdateOptions().upsert(true)));
+				if (((validBulkOpList.size() % bulkSize) == 0) && !validBulkOpList.isEmpty()) {
+					collection.bulkWrite(validBulkOpList, writeOptions);
+					validBulkOpList.clear();
 				}
 			} else {
-				if (discardRecords) {
-					log.debug("parsed record seems invalid");
-					discardRecord(r);
-				}
+				log.debug("parsed record seems invalid");
+				discardRecord(r);
 			}
 		} catch (Throwable e) {
-			if (discardRecords) {
-				log.debug("unhandled exception: " + e.getMessage());
-				discardRecord(r);
-			}
+			log.debug("unhandled exception: " + e.getMessage());
+			discardRecord(r);
 		}
 	}
 
 	private void discardRecord(final MDStoreRecord MDStoreRecord) {
-		discardedBulkOperationList.add(new InsertOneModel(new BasicDBObject(BODY, MDStoreRecord)));
+		discardedBulkOpList.add(new InsertOneModel(new BasicDBObject(BODY, MDStoreRecord)));
 
-		if (((discardedBulkOperationList.size() % bulkSize) == 0) && !discardedBulkOperationList.isEmpty()) {
-			discardedCollection.bulkWrite(discardedBulkOperationList, writeOptions);
-			discardedBulkOperationList.clear();
+		if (((discardedBulkOpList.size() % bulkSize) == 0) && !discardedBulkOpList.isEmpty()) {
+			discarded.bulkWrite(discardedBulkOpList, writeOptions);
+			discardedBulkOpList.clear();
 		}
 	}
 
@@ -80,17 +74,17 @@
 	public void flushBulks() {
 		//setting to journaled write concern to be sure that when the write returns everything has been flushed to disk (https://docs.mongodb.org/manual/faq/developers/#when-does-mongodb-write-updates-to-disk)
 		//the explicit fsync command can't be run anymore: 'Command failed with error 13: 'fsync may only be run against the admin database.'
-		if (!validBulkOperationList.isEmpty()) {
-			validCollection = getCollectionWithWriteConcern(validCollection, WriteConcern.JOURNALED);
-			validCollection.bulkWrite(validBulkOperationList, writeOptions);
+		if (!validBulkOpList.isEmpty()) {
+			collection = getCollectionWithWriteConcern(collection, WriteConcern.JOURNALED);
+			collection.bulkWrite(validBulkOpList, writeOptions);
 		}
-		if (!discardedBulkOperationList.isEmpty()) {
-			discardedCollection = getCollectionWithWriteConcern(discardedCollection, WriteConcern.ACKNOWLEDGED);
-			discardedCollection.bulkWrite(discardedBulkOperationList, writeOptions);
+		if (!discardedBulkOpList.isEmpty()) {
+			discarded = getCollectionWithWriteConcern(discarded, WriteConcern.ACKNOWLEDGED);
+			discarded.bulkWrite(discardedBulkOpList, writeOptions);
 		}
 		//setting write concern back to ACKNOWLEDGE to avoid the execution of future writes all in Journaled mode
-		validCollection = getCollectionWithWriteConcern(validCollection, WriteConcern.ACKNOWLEDGED);
-		discardedCollection = getCollectionWithWriteConcern(discardedCollection, WriteConcern.ACKNOWLEDGED);
+		collection = getCollectionWithWriteConcern(collection, WriteConcern.ACKNOWLEDGED);
+		discarded = getCollectionWithWriteConcern(discarded, WriteConcern.ACKNOWLEDGED);
 	}
 
 	private MongoCollection<MDStoreRecord> getCollectionWithWriteConcern(MongoCollection<MDStoreRecord> collection, WriteConcern writeConcern) {
Index: modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/mongo/MongoMDStore.java
===================================================================
--- modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/mongo/MongoMDStore.java	(revision 46516)
+++ modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/mongo/MongoMDStore.java	(revision 46517)
@@ -14,11 +14,11 @@
 import com.mongodb.client.MongoCollection;
 import com.mongodb.client.MongoCursor;
 import eu.dnetlib.data.mdstore.MDStore;
-import eu.dnetlib.data.mdstore.MDStoreException;
-import eu.dnetlib.data.mdstore.MDStoreRuntimeException;
-import eu.dnetlib.data.mdstore.model.MDStoreManagerInfo;
-import eu.dnetlib.data.mdstore.model.MDStoreReadLock;
 import eu.dnetlib.data.mdstore.model.MDStoreRecord;
+import eu.dnetlib.data.mdstore.model.ReadLock;
+import eu.dnetlib.data.mdstore.repository.TransactionInfoRepository;
+import eu.dnetlib.data.mdstore.utils.MDStoreException;
+import eu.dnetlib.data.mdstore.utils.MDStoreRuntimeException;
 import eu.dnetlib.miscutils.streams.DnetStreamSupport;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.logging.Log;
@@ -27,7 +27,7 @@
 import org.springframework.data.util.StreamUtils;
 
 import static com.mongodb.client.model.Filters.*;
-import static eu.dnetlib.data.mdstore.MDStoreConstants.*;
+import static eu.dnetlib.data.mdstore.utils.MDStoreConstants.*;
 
 /**
  * Created by claudio on 16/03/2017.
@@ -38,29 +38,20 @@
 	private static final Log log = LogFactory.getLog(MongoMDStore.class);
 
 	private static List<String> indexes = Arrays.asList(ID, TIMESTAMP, ORIGINAL_ID);
-	private final boolean discardRecords;
+
 	private String id;
 	private MongoCollection<MDStoreRecord> recordCollection;
 	private MongoCollection<MDStoreRecord> discardedCollection;
-	private MongoCollection<MDStoreManagerInfo> txManager;
+	private TransactionInfoRepository transaction;
 
 	public MongoMDStore(final String id,
 			final MongoCollection<MDStoreRecord> collection,
 			final MongoCollection<MDStoreRecord> discarded,
-			final MongoCollection<MDStoreManagerInfo> txManager) {
-		this(id, collection, discarded, txManager, true);
-	}
-
-	public MongoMDStore(final String id,
-			final MongoCollection<MDStoreRecord> collection,
-			final MongoCollection<MDStoreRecord> discarded,
-			final MongoCollection<MDStoreManagerInfo> txManager,
-			final boolean discardRecords) {
+			final TransactionInfoRepository transaction) {
 		this.id = id;
 		this.recordCollection = collection;
 		this.discardedCollection = discarded;
-		this.txManager = txManager;
-		this.discardRecords = discardRecords;
+		this.transaction = transaction;
 	}
 
 	@Override
@@ -70,7 +61,7 @@
 		int countStored = 0;
 		final Callable<Integer> writer = () -> {
 			final MongoBulkWritesManager bulkWritesManager =
-					new MongoBulkWritesManager(recordCollection, discardedCollection, BULK_SIZE, discardRecords);
+					new MongoBulkWritesManager(recordCollection, discardedCollection, BULK_SIZE);
 			int count = 0;
 			while (true) {
 				try {
@@ -158,8 +149,7 @@
 	}
 
 	private Stream<MDStoreRecord> doDeliver(final String from, final String until, final String recordFilter) {
-		final MDStoreManagerInfo info = txManager.find(eq(MDID, getId())).first().addReadLock(MDStoreReadLock.create(getId()));
-		txManager.findOneAndReplace(eq(MDID, getId()), info);
+		transaction.addReadLock(getId(), ReadLock.create(getId()));
 		try {
 			ensureIndices();
 			final Bson dateQuery = rangeQuery(parseLong(from), parseLong(until));
Index: modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/mongo/codec/MDStoreRecordCodec.java
===================================================================
--- modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/mongo/codec/MDStoreRecordCodec.java	(revision 46516)
+++ modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/mongo/codec/MDStoreRecordCodec.java	(revision 46517)
@@ -9,7 +9,7 @@
 import org.bson.codecs.EncoderContext;
 import org.springframework.stereotype.Component;
 
-import static eu.dnetlib.data.mdstore.MDStoreConstants.*;
+import static eu.dnetlib.data.mdstore.utils.MDStoreConstants.*;
 
 /**
  * Created by claudio on 20/03/2017.
Index: modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/mongo/MongoMDStoreService.java
===================================================================
--- modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/mongo/MongoMDStoreService.java	(revision 46516)
+++ modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/mongo/MongoMDStoreService.java	(revision 46517)
@@ -1,41 +1,43 @@
 package eu.dnetlib.data.mdstore.mongo;
 
-import java.util.*;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 import javax.annotation.PostConstruct;
 
 import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
 import com.mongodb.BasicDBObject;
-import com.mongodb.BasicDBObjectBuilder;
-import com.mongodb.DBObject;
 import com.mongodb.WriteConcern;
-import com.mongodb.client.AggregateIterable;
 import com.mongodb.client.MongoCollection;
 import com.mongodb.client.MongoDatabase;
 import com.mongodb.client.model.Filters;
 import com.mongodb.client.model.IndexOptions;
 import com.mongodb.client.model.UpdateOptions;
-import eu.dnetlib.data.mdstore.*;
-import eu.dnetlib.data.mdstore.model.MDStoreDescription;
-import eu.dnetlib.data.mdstore.model.MDStoreManagerInfo;
+import eu.dnetlib.data.mdstore.MDStore;
+import eu.dnetlib.data.mdstore.MDStoreService;
 import eu.dnetlib.data.mdstore.model.MDStoreRecord;
-import eu.dnetlib.data.mdstore.model.MDStoreTransactionInfo;
+import eu.dnetlib.data.mdstore.model.Metadata;
+import eu.dnetlib.data.mdstore.model.Transaction;
+import eu.dnetlib.data.mdstore.model.TransactionInfo;
+import eu.dnetlib.data.mdstore.repository.MetadataRepository;
+import eu.dnetlib.data.mdstore.repository.TransactionInfoRepository;
+import eu.dnetlib.data.mdstore.utils.MDStoreException;
+import eu.dnetlib.data.mdstore.utils.MDStoreProfileManager;
+import eu.dnetlib.data.mdstore.utils.MDStoreRuntimeException;
+import eu.dnetlib.data.mdstore.utils.RecordParser;
 import eu.dnetlib.miscutils.streams.DnetStreamSupport;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.bson.Document;
-import org.bson.conversions.Bson;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Component;
 
-import static com.mongodb.client.model.Filters.and;
-import static com.mongodb.client.model.Filters.eq;
-import static eu.dnetlib.data.mdstore.MDStoreConstants.*;
+import static eu.dnetlib.data.mdstore.utils.MDStoreConstants.*;
 
 /**
  * Created by claudio on 24/03/2017.
@@ -59,6 +61,12 @@
 	private MDStoreProfileManager profileManager;
 
 	@Autowired
+	private MetadataRepository metadata;
+
+	@Autowired
+	private TransactionInfoRepository transaction;
+
+	@Autowired
 	private MongoDatabase mongoDatabase;
 
 	@Value("#{'${msro.worker.mdstore.skip.prefixes}'.split(',')}")
@@ -72,35 +80,28 @@
 		log.info("Bootstrap mdstore ...");
 
 		//drop all the stale expiring and the transactions mdstores
-		getMetadata().find().iterator().forEachRemaining(d -> {
-			final Map<String, Object> update = Maps.newHashMap();
-			update.put(EXPIRING, Lists.newArrayList());
-			update.put(TRANSACTIONS, Lists.newArrayList());
-			getTxManager().updateOne(
-					eq(MDID, d.getMdId()),
-					new BasicDBObject("$set", new Document(update)));
-
+		metadata.findAll().forEach(d -> {
+			transaction.bootstrap(d.getMdId());
 			log.debug(String.format("Added %s to Metadata Manager data structure", d.getMdId()));
 		});
 
-		final Set<String> metadataMdIds = getMetadataMdIds();
+		final Set<String> metadataMdIds = Sets.newHashSet(metadata.listMdIds());
 
 		//delete from metadataManager all the mdId(s) that are not in metadata
 		Sets.difference(
-				getMetadataManagerMdIds(),
-				metadataMdIds).forEach(mdId -> getTxManager().findOneAndDelete(eq(MDID, mdId)));
+				Sets.newHashSet(transaction.listMdIds()),
+				metadataMdIds).forEach(mdId -> transaction.delete(mdId));
 
 		//delete all the collections that are not referred by metadataManager.currentId(s)
 		Sets.difference(
-				DnetStreamSupport.stream(getTxManager().find().iterator())
-					.map(txi -> txi.getCurrentId())
-					.collect(Collectors.toSet()),
+				Sets.newHashSet(transaction.listCurrentIds()),
 				metadataMdIds).forEach(name -> {
 						log.info(String.format("dropping collection %s", name));
 						mongoDatabase.getCollection(name).drop();
 					});
 
-		createIndex(MDID, getTxManager(), getMetadata());
+		//TODO check repositories has proper indexes
+		//createIndex(MDID, getTxManager());
 
 		log.info("Bootstrap mdstore complete!");
 	}
@@ -111,11 +112,11 @@
 	public void garbage() {
 		//delete from metadataManager all the mdId(s) that are not in metadata
 		Sets.difference(
-				getMetadataManagerMdIds(),
-				getMetadataMdIds()).forEach(mdId -> getTxManager().findOneAndDelete(eq(MDID, mdId)));
+				Sets.newHashSet(transaction.listMdIds()),
+				getMetadataMdIds()).forEach(mdId -> transaction.delete(mdId));
 
-		final List<MDStoreManagerInfo> txis = Lists.newArrayList();
-		getTxManager().find().iterator().forEachRemaining(txi -> {
+		final List<TransactionInfo> txis = Lists.newArrayList();
+		transaction.findAll().iterator().forEachRemaining(txi -> {
 			final List<String> toDelete = txi.getExpired(expiredDays);
 			if (!toDelete.isEmpty()) {
 				txis.add(txi);
@@ -122,9 +123,7 @@
 				toDelete.forEach(this::doDrop);
 			}
 		});
-		txis.forEach(txi -> {
-			getTxManager().findOneAndReplace(eq(MDID, txi.getMdId()), txi);
-		});
+		transaction.save(txis);
 	}
 
 	@Override
@@ -132,30 +131,36 @@
 		log.debug("Creating new mdstore");
 
 		final String mdId = getProfileManager().registerProfile(format, layout, interpretation);
-		final MDStoreManagerInfo managerInfo = asManagerInfo(mdId);
-		getTxManager().insertOne(managerInfo);
-		getMetadata().insertOne(MDStoreDescription.create()
+		final TransactionInfo tInfo = TransactionInfo.create()
 				.setMdId(mdId)
+				.setCurrentId(createInternalId(mdId));
+
+		transaction.save(tInfo);
+		metadata.save(Metadata.create()
+				.setMdId(mdId)
 				.setFormat(format)
 				.setLayout(layout)
 				.setInterpretation(interpretation)
 				.setSize(0)
 				.setIndexed(true));
-		mongoDatabase.createCollection(managerInfo.getCurrentId());
 
+		mongoDatabase.createCollection(tInfo.getCurrentId());
+		createIndex(ID, mongoDatabase.getCollection(tInfo.getCurrentId()));
+
+		log.info("Created new mdstore: " + mdId);
+
 		return mdId;
 	}
 
 	@Override
 	public void delete(final String mdId) throws MDStoreException {
-		final MongoCollection<MDStoreDescription> metadata = getMetadata();
-
-		final MDStoreManagerInfo dropped = getTxManager().findOneAndDelete(Filters.eq(MDID, mdId));
-		if (dropped == null) {
+		if (!transaction.exists(mdId)) {
 			throw new MDStoreException(String.format("cannot find %s in transaction manager table", mdId));
 		}
-		doDrop(dropped.getCurrentId());
-		metadata.deleteOne(eq(MDID, mdId));
+		final TransactionInfo toDrop = transaction.findOne(mdId);
+		doDrop(toDrop.getCurrentId());
+		transaction.delete(toDrop.getCurrentId());
+		metadata.delete(mdId);
 		getProfileManager().deleteProfile(mdId);
 		log.info("deleted mdId: " + mdId);
 	}
@@ -195,12 +200,16 @@
 
 	@Override
 	public List<String> list() throws MDStoreException {
-		return doListMDStores(new BasicDBObject());
+		return DnetStreamSupport.stream(metadata.findAll().iterator())
+			.map(m -> m.getMdId())
+			.collect(Collectors.toList());
 	}
 
 	@Override
 	public List<String> list(final String format, final String layout, final String interpretation) throws MDStoreException {
-		return doListMDStores(and(eq(FORMAT, format), eq(LAYOUT, layout), eq(INTERPRETATION, interpretation)));
+		return metadata.findByFormatAndLayoutAndInterpretation(format, layout, interpretation).stream()
+				.map(m -> m.getMdId())
+				.collect(Collectors.toList());
 	}
 
 	@Override
@@ -210,28 +219,7 @@
 
 	@Override
 	public int size(final String format, final String layout, final String interpretation) {
-		final MongoCollection<MDStoreDescription> metadata = getMetadata();
-		final BasicDBObject matchObj = (BasicDBObject) BasicDBObjectBuilder
-				.start("$match", BasicDBObjectBuilder.start(FORMAT, format)
-								.add(LAYOUT, layout)
-								.add(INTERPRETATION, interpretation)
-								.get())
-				.get();
-		final BasicDBObject groupObj = (BasicDBObject) BasicDBObjectBuilder
-				.start("$group", BasicDBObjectBuilder.start(INTERNAL_MONGO_ID, "")
-								.add(TOTAL, new BasicDBObject("$sum", "$" + SIZE))
-								.get())
-				.get();
-		final BasicDBObject projectObj = new BasicDBObject("$project", new BasicDBObject(INTERNAL_MONGO_ID, 0).append(TOTAL, 1));
-		final List<BasicDBObject> pipeline = Lists.newArrayList(matchObj, groupObj, projectObj);
-		final AggregateIterable<DBObject> output = metadata.aggregate(pipeline, DBObject.class);
-		final DBObject result = output.first();
-		if (result == null || !result.containsField("total")) {
-			log.debug("No total found");
-			return 0;
-		} else {
-			return (Integer) result.get("total");
-		}
+		return metadata.sumOfSize(format, layout, interpretation);
 	}
 
 	@Override
@@ -238,7 +226,7 @@
 	public void store(final String mdId, final Stream<String> records, final FeedMode feedMode) throws MDStoreException {
 		final boolean refresh = FeedMode.REFRESH.equals(feedMode);
 		final String txId = startTransaction(mdId, refresh);
-		final MDStore mdstore = getMDStore(txId);
+		final MDStore mdstore = getMDStore(mdId, txId);
 		try {
 			if (refresh) {
 				mdstore.truncate();
@@ -245,8 +233,8 @@
 			}
 			mdstore.feed(records.map(new RecordParser()));
 
-			final MDStoreManagerInfo info = getTxManager().find(Filters.eq(MDID, mdId)).first();
-			final Collection<MDStoreTransactionInfo> txs = info.getTransactions();
+			final TransactionInfo info = transaction.findOne(mdId);
+			final Collection<Transaction> txs = info.getTransactions().values();
 			final String oldId = info.getCurrentId();
 
 			if (txs.isEmpty() | !txs.removeIf(tx -> {
@@ -269,13 +257,9 @@
 				throw new MDStoreException("Error, unable to find transaction with Id " + txId);
 			}
 
-			getTxManager().findOneAndReplace(Filters.eq(MDID, info.getMdId()), info);
-
+			transaction.save(info);
 			final int size = mdstore.getSize();
-			getMetadata().updateOne(
-					eq(MDID, mdId),
-					new BasicDBObject("$set", new BasicDBObject(SIZE, size)));
-
+			metadata.updateSize(mdId, size);
 			getProfileManager().updateSize(mdId, size);
 			log.info("Finished feeding mdstore " + mdId + " - new size: " + size);
 		} catch (Throwable e) {
@@ -282,7 +266,7 @@
 			log.error("Error feeding mdstore: " + mdId, e);
 			if (txId != null) {
 				log.error("Dropping transaction : " + txId);
-				dropTransaction(txId, mdId);
+				transaction.dropTransaction(txId, mdId);
 			}
 		}
 	}
@@ -291,42 +275,22 @@
 
 	private String startTransaction(final String mdId, final boolean refresh) throws MDStoreException {
 		log.info("Start transaction for metadata store " + mdId);
-		final MDStoreManagerInfo info = getTxManager().find(Filters.eq(MDID, mdId)).first();
-		final String transactionId = StringUtils.substringBefore(mdId, "_") + "::" + System.currentTimeMillis();
 
+		final TransactionInfo info = transaction.findOne(mdId);
+
 		if (info.getTransactions().size() > getMaxTransactions()) {
 			throw new MDStoreException(
 					String.format("Cannot create more than %s transactions, found: %s, mdId: %s", getMaxTransactions(), info.getTransactions().size(), mdId));
 		}
 
-		info.getTransactions().add(
-				MDStoreTransactionInfo.create()
-						.setId(transactionId)
-						.setRefresh(refresh));
+		final String transactionId = StringUtils.substringBefore(mdId, "_") + "::" + System.currentTimeMillis();
+		transaction.addTransaction(mdId, Transaction.create()
+				.setId(transactionId)
+				.setRefresh(refresh));
 
-		getTxManager().findOneAndReplace(Filters.eq(MDID, info.getMdId()), info);
 		return transactionId;
 	}
 
-	private void dropTransaction(final String mdId, final String idToDrop) throws  MDStoreException {
-		final MDStoreManagerInfo managerInfo = getTxManager().find(Filters.eq(MDID, mdId)).first();
-		managerInfo.getTransactions().removeIf(info -> {
-			if (idToDrop.equals(info.getId())) {
-				doDrop(idToDrop);
-				return true;
-			} else {
-				return false;
-			}
-		});
-		getTxManager().findOneAndReplace(Filters.eq(MDID, managerInfo.getMdId()), managerInfo);
-	}
-
-	private Set<String> getMetadataManagerMdIds() {
-		return DnetStreamSupport.stream(getTxManager().find().iterator())
-				.map(txi -> txi.getMdId())
-				.collect(Collectors.toSet());
-	}
-
 	private Set<String> getMetadataMdIds() {
 		return DnetStreamSupport.stream(mongoDatabase.listCollectionNames().iterator())
 				.filter(name -> skipPrefixes.stream()
@@ -354,22 +318,19 @@
 		}
 	}
 
-	private List<String> doListMDStores(final Bson filter) {
-		return DnetStreamSupport.stream(getMetadata()
-				.find(filter).iterator())
-				.map(MDStoreDescription::getMdId)
-				.collect(Collectors.toList());
-	}
-
-	private MDStore getMDStore(final String mdId) {
-		final MDStoreManagerInfo info = getTxManager().find(Filters.eq(MDID, mdId)).first();
+	private MDStore getMDStore(final String mdId, final String currentId) {
 		return new MongoMDStore(
 				mdId,
-				getRecordCollection(info.getCurrentId()),
-				getRecordCollection(DISCARDED_PREFIX + info.getCurrentId()),
-				getTxManager());
+				getRecordCollection(currentId),
+				getRecordCollection(DISCARDED_PREFIX + currentId),
+				transaction);
 	}
 
+	private MDStore getMDStore(final String id) {
+		final TransactionInfo info = transaction.findOne(id);
+		return getMDStore(id, info.getCurrentId());
+	}
+
 	private void doDrop(final String mdId) {
 		mongoDatabase.getCollection(mdId).drop();
 		mongoDatabase.getCollection(DISCARDED_PREFIX + mdId).drop();
@@ -376,12 +337,6 @@
 		log.debug("deleted collection " + mdId);
 	}
 
-	private MDStoreManagerInfo asManagerInfo(final String mdId) {
-		return MDStoreManagerInfo.create()
-				.setMdId(mdId)
-				.setCurrentId(createInternalId(mdId));
-	}
-
 	private String createInternalId(final String mdId) {
 		String newId = mdId;
 		if (mdId.contains(ID_SEPARATOR)) {
@@ -390,14 +345,6 @@
 		return newId;
 	}
 
-	private MongoCollection<MDStoreManagerInfo> getTxManager() {
-		return mongoDatabase.getCollection(METADATA_MANAGER_TABLE, MDStoreManagerInfo.class);
-	}
-
-	private MongoCollection<MDStoreDescription> getMetadata() {
-		return mongoDatabase.getCollection(METADATA_NAME, MDStoreDescription.class);
-	}
-
 	private MongoCollection<MDStoreRecord> getRecordCollection(final String collectionId) {
 		return mongoDatabase.getCollection(collectionId, MDStoreRecord.class);
 	}
Index: modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/repository/MetadataRepository.java
===================================================================
--- modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/repository/MetadataRepository.java	(nonexistent)
+++ modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/repository/MetadataRepository.java	(revision 46517)
@@ -0,0 +1,15 @@
+package eu.dnetlib.data.mdstore.repository;
+
+import java.util.List;
+
+import eu.dnetlib.data.mdstore.model.Metadata;
+import org.springframework.data.repository.CrudRepository;
+
+/**
+ * Created by claudio on 30/03/2017.
+ */
+public interface MetadataRepository extends CrudRepository<Metadata, String>, MetadataRepositoryCustom {
+
+	List<Metadata> findByFormatAndLayoutAndInterpretation(String format, String layout, String interpretation);
+
+}
Index: modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/repository/TransactionInfoRepository.java
===================================================================
--- modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/repository/TransactionInfoRepository.java	(nonexistent)
+++ modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/repository/TransactionInfoRepository.java	(revision 46517)
@@ -0,0 +1,11 @@
+package eu.dnetlib.data.mdstore.repository;
+
+import eu.dnetlib.data.mdstore.model.TransactionInfo;
+import org.springframework.data.repository.CrudRepository;
+
+/**
+ * Created by claudio on 30/03/2017.
+ */
+public interface TransactionInfoRepository extends CrudRepository<TransactionInfo, String>, TransactionInfoRepositoryCustom {
+
+}
Index: modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/repository/MetadataRepositoryImpl.java
===================================================================
--- modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/repository/MetadataRepositoryImpl.java	(nonexistent)
+++ modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/repository/MetadataRepositoryImpl.java	(revision 46517)
@@ -0,0 +1,61 @@
+package eu.dnetlib.data.mdstore.repository;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+import eu.dnetlib.data.mdstore.model.Metadata;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.core.query.Criteria;
+import org.springframework.data.mongodb.core.query.Query;
+import org.springframework.data.mongodb.core.query.Update;
+
+import static eu.dnetlib.data.mdstore.utils.MDStoreConstants.*;
+import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;
+import static org.springframework.data.mongodb.core.query.Criteria.where;
+
+/**
+ * Created by claudio on 30/03/2017.
+ */
+public class MetadataRepositoryImpl implements MetadataRepositoryCustom {
+
+	private static final Log log = LogFactory.getLog(MetadataRepositoryImpl.class);
+
+	private final MongoTemplate mongoTemplate;
+
+	@Autowired
+	public MetadataRepositoryImpl(MongoTemplate mongoTemplate) {
+		this.mongoTemplate = mongoTemplate;
+	}
+
+	@Override
+	public int sumOfSize(final String format, final String layout, final String interpretation) {
+		log.debug(String.format("calculate size for mdtores %s-%s-%s", format, layout, interpretation));
+		return mongoTemplate.aggregate(newAggregation(
+				match(where(FORMAT).is(format)
+						.and(LAYOUT).is(layout)
+						.and(INTERPRETATION).is(interpretation)),
+				group(FORMAT, LAYOUT, INTERPRETATION).sum(SIZE).as(SIZE),
+				project(SIZE)),
+				Metadata.class,
+				Metadata.class).getUniqueMappedResult().getSize();
+	}
+
+	@Override
+	public void updateSize(final String mdId, final int size) {
+		log.debug(String.format("update size for mdtore %s to %s", mdId, size));
+		mongoTemplate.updateFirst(
+				Query.query(Criteria.where(MDID).is(mdId)),
+				Update.update(SIZE, size),
+				Metadata.class);
+	}
+
+	@Override
+	public List<String> listMdIds() {
+		return mongoTemplate.findAll(Metadata.class).stream()
+				.map(m -> m.getMdId())
+				.collect(Collectors.toList());
+	}
+}
Index: modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/repository/TransactionInfoRepositoryImpl.java
===================================================================
--- modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/repository/TransactionInfoRepositoryImpl.java	(nonexistent)
+++ modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/repository/TransactionInfoRepositoryImpl.java	(revision 46517)
@@ -0,0 +1,89 @@
+package eu.dnetlib.data.mdstore.repository;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+import com.google.common.collect.Maps;
+import eu.dnetlib.data.mdstore.model.ReadLock;
+import eu.dnetlib.data.mdstore.model.Transaction;
+import eu.dnetlib.data.mdstore.model.TransactionInfo;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.mongodb.core.MongoTemplate;
+
+import static eu.dnetlib.data.mdstore.utils.MDStoreConstants.*;
+import static org.springframework.data.mongodb.core.query.Criteria.where;
+import static org.springframework.data.mongodb.core.query.Query.query;
+import static org.springframework.data.mongodb.core.query.Update.update;
+
+/**
+ * Created by claudio on 30/03/2017.
+ */
+public class TransactionInfoRepositoryImpl implements TransactionInfoRepositoryCustom {
+
+	private static final Log log = LogFactory.getLog(TransactionInfoRepositoryImpl.class);
+
+	private final MongoTemplate mongoTemplate;
+
+	@Autowired
+	public TransactionInfoRepositoryImpl(MongoTemplate mongoTemplate) {
+		this.mongoTemplate = mongoTemplate;
+	}
+
+	@Override
+	public void bootstrap(final String mdId) {
+		mongoTemplate.updateFirst(
+				query(where(MDID).is(mdId)),
+				update(READ_LOCKS, Maps.newHashMap()).set(TRANSACTIONS, Maps.newHashMap()),
+				TransactionInfo.class);
+	}
+
+	@Override
+	public List<String> listMdIds() {
+		return mongoTemplate.findAll(TransactionInfo.class).stream()
+				.map(m -> m.getMdId())
+				.collect(Collectors.toList());
+	}
+
+	@Override
+	public List<String> listCurrentIds() {
+		return mongoTemplate.findAll(TransactionInfo.class).stream()
+				.map(m -> m.getCurrentId())
+				.collect(Collectors.toList());
+	}
+
+	@Override
+	public void addTransaction(final String mdId, final Transaction t) {
+		synchronized (this) {
+			final TransactionInfo tInfo = getTransactionInfo(mdId);
+			tInfo.getTransactions().put(t.getId(), t);
+			mongoTemplate.save(tInfo);
+		}
+	}
+
+	@Override
+	public void dropTransaction(final String mdId, final String idToDrop) {
+		synchronized (this) {
+			final TransactionInfo tInfo = getTransactionInfo(mdId);
+			tInfo.getTransactions().remove(idToDrop);
+			mongoTemplate.save(tInfo);
+		}
+	}
+
+	@Override
+	public void addReadLock(final String mdId, final ReadLock r) {
+		synchronized (this) {
+			final TransactionInfo tInfo = getTransactionInfo(mdId);
+			tInfo.getReadLocks().put(r.getId(), r);
+			mongoTemplate.save(tInfo);
+		}
+	}
+
+	private TransactionInfo getTransactionInfo(final String mdId) {
+		return mongoTemplate.findOne(
+				query(where(MDID).is(mdId)),
+				TransactionInfo.class);
+	}
+
+}
Index: modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/repository/MetadataRepositoryCustom.java
===================================================================
--- modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/repository/MetadataRepositoryCustom.java	(nonexistent)
+++ modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/repository/MetadataRepositoryCustom.java	(revision 46517)
@@ -0,0 +1,16 @@
+package eu.dnetlib.data.mdstore.repository;
+
+import java.util.List;
+
+/**
+ * Created by claudio on 30/03/2017.
+ */
+public interface MetadataRepositoryCustom {
+
+	int sumOfSize(String format, String layout, String interpretation);
+
+	void updateSize(String mdId, int size);
+
+	List<String> listMdIds();
+
+}
Index: modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/repository/TransactionInfoRepositoryCustom.java
===================================================================
--- modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/repository/TransactionInfoRepositoryCustom.java	(nonexistent)
+++ modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/repository/TransactionInfoRepositoryCustom.java	(revision 46517)
@@ -0,0 +1,24 @@
+package eu.dnetlib.data.mdstore.repository;
+
+import java.util.List;
+
+import eu.dnetlib.data.mdstore.model.ReadLock;
+import eu.dnetlib.data.mdstore.model.Transaction;
+
+/**
+ * Created by claudio on 30/03/2017.
+ */
+public interface TransactionInfoRepositoryCustom {
+
+	void bootstrap(String mdId);
+
+	List<String> listMdIds();
+
+	List<String> listCurrentIds();
+
+	void addTransaction(String mdId, Transaction t);
+
+	void dropTransaction(final String mdId, final String idToDrop);
+
+	void addReadLock(String mdId, ReadLock r);
+}
Index: modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/model/Metadata.java
===================================================================
--- modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/model/Metadata.java	(nonexistent)
+++ modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/model/Metadata.java	(revision 46517)
@@ -0,0 +1,90 @@
+package eu.dnetlib.data.mdstore.model;
+
+import org.springframework.data.annotation.Id;
+
+public class Metadata {
+
+	@Id
+	private String mdId;
+
+	private String format;
+
+	private String layout;
+
+	private String interpretation;
+
+	private int size;
+
+	private boolean indexed;
+
+	public Metadata(final String mdId, final String format, final String layout, final String interpretation, final int size, final boolean indexed) {
+		super();
+		this.mdId = mdId;
+		this.format = format;
+		this.layout = layout;
+		this.interpretation = interpretation;
+		this.size = size;
+		this.indexed = indexed;
+	}
+
+	public static Metadata create() {
+		return new Metadata();
+	}
+
+	public Metadata() {}
+
+	public String getMdId() {
+		return mdId;
+	}
+
+	public String getFormat() {
+		return format;
+	}
+
+	public String getLayout() {
+		return layout;
+	}
+
+	public String getInterpretation() {
+		return interpretation;
+	}
+
+	public int getSize() {
+		return size;
+	}
+
+	public boolean isIndexed() {
+		return indexed;
+	}
+
+	public Metadata setMdId(final String mdId) {
+		this.mdId = mdId;
+		return this;
+	}
+
+	public Metadata setFormat(final String format) {
+		this.format = format;
+		return this;
+	}
+
+	public Metadata setLayout(final String layout) {
+		this.layout = layout;
+		return this;
+	}
+
+	public Metadata setInterpretation(final String interpretation) {
+		this.interpretation = interpretation;
+		return this;
+	}
+
+	public Metadata setSize(final int size) {
+		this.size = size;
+		return this;
+	}
+
+	public Metadata setIndexed(final boolean indexed) {
+		this.indexed = indexed;
+		return this;
+	}
+
+}
Index: modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/model/TransactionInfo.java
===================================================================
--- modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/model/TransactionInfo.java	(nonexistent)
+++ modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/model/TransactionInfo.java	(revision 46517)
@@ -0,0 +1,106 @@
+package eu.dnetlib.data.mdstore.model;
+
+import java.time.Duration;
+import java.time.LocalDate;
+import java.time.ZoneId;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import org.springframework.data.annotation.Id;
+import org.springframework.data.mongodb.core.index.Indexed;
+
+/**
+ * Created by claudio on 13/03/2017.
+ */
+public class TransactionInfo {
+
+	@Id
+	private String mdId;
+
+	@Indexed
+	private String currentId;
+
+	private Map<String, ReadLock> readLocks;
+	private Map<String, Transaction> transactions;
+
+	public static TransactionInfo create() {
+		return new TransactionInfo()
+				.setReadLocks(Maps.newHashMap())
+				.setTransactions(Maps.newHashMap());
+	}
+
+	public ReadLock getReadLock(final String id) {
+		return readLocks.get(id);
+	}
+
+	public List<String> getExpired(final int retainDays) {
+		final List<String> res = Lists.newArrayList();
+		readLocks.entrySet().removeIf(e -> {
+			final ReadLock info = e.getValue();
+			if (info.getId().equals(getCurrentId())) {
+				return false;
+			} else {
+				if (getExpiringDays(info) >= retainDays) {
+					res.add(info.getId());
+					return true;
+				} else {
+					return false;
+				}
+			}
+		});
+		return res;
+	}
+
+	/**
+	 * Gets the expiring days.
+	 *
+	 * @param info     the value
+	 * @return the expiring days
+	 */
+	private long getExpiringDays(final ReadLock info) {
+		final Date lastRead = info.getLastUpdateDate();
+		final LocalDate readDate = lastRead.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
+		return Duration.between(LocalDate.now().atTime(0, 0), readDate.atTime(0, 0)).toDays();
+	}
+
+	public String getMdId() {
+		return mdId;
+	}
+
+	public TransactionInfo setMdId(final String mdId) {
+		this.mdId = mdId;
+		return this;
+	}
+
+	public String getCurrentId() {
+		return currentId;
+	}
+
+	public TransactionInfo setCurrentId(final String currentId) {
+		this.currentId = currentId;
+		return this;
+	}
+
+	public TransactionInfo setReadLocks(final Map<String, ReadLock> readLocks) {
+		this.readLocks = readLocks;
+		return this;
+	}
+
+	public TransactionInfo setTransactions(final Map<String, Transaction> transactions) {
+		this.transactions = transactions;
+		return this;
+	}
+
+	public Map<String, ReadLock> getReadLocks() {
+		return readLocks;
+	}
+
+	public Map<String, Transaction> getTransactions() {
+		return transactions;
+	}
+
+
+}
Index: modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/model/ReadLock.java
===================================================================
--- modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/model/ReadLock.java	(nonexistent)
+++ modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/model/ReadLock.java	(revision 46517)
@@ -0,0 +1,67 @@
+package eu.dnetlib.data.mdstore.model;
+
+import java.util.Date;
+
+/**
+ * Created by claudio on 13/03/2017.
+ */
+public class ReadLock {
+
+	private String id;
+	private int readCount;
+	private Date lastUpdateDate;
+
+	public static ReadLock create(final String id) {
+		return new ReadLock()
+				.setId(id)
+				.setReadCount(0)
+				.setLastUpdateDate(new Date());
+	}
+
+	public ReadLock incrementReadCount() {
+		return modifyReadCount(1);
+	}
+
+	public ReadLock decrementReadCount() {
+		return modifyReadCount(-1);
+	}
+
+	private ReadLock modifyReadCount(int v) {
+		setReadCount(getReadCount() + v);
+		setLastUpdateDate(new Date());
+		return this;
+	}
+
+	/**
+	 * @return the lastRead
+	 */
+	public Date getLastUpdateDate() {
+		return lastUpdateDate;
+	}
+
+	/**
+	 * @return the id
+	 */
+	public String getId() {
+		return id;
+	}
+
+	public ReadLock setId(final String id) {
+		this.id = id;
+		return this;
+	}
+
+	public ReadLock setLastUpdateDate(final Date lastUpdateDate) {
+		this.lastUpdateDate = lastUpdateDate;
+		return this;
+	}
+
+	public int getReadCount() {
+		return readCount;
+	}
+
+	public ReadLock setReadCount(final int readCount) {
+		this.readCount = readCount;
+		return this;
+	}
+}
Index: modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/model/Transaction.java
===================================================================
--- modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/model/Transaction.java	(nonexistent)
+++ modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/model/Transaction.java	(revision 46517)
@@ -0,0 +1,68 @@
+package eu.dnetlib.data.mdstore.model;
+
+import java.util.Date;
+
+/**
+ * Created by claudio on 13/03/2017.
+ */
+public class Transaction {
+
+	private String id;
+	private Boolean refresh;
+	private Date date;
+	private long size;
+
+	public static Transaction create() {
+		return new Transaction()
+				.setDate(new Date());
+	}
+
+	/**
+	 * @return the date
+	 */
+	public Date getDate() {
+		return date;
+	}
+
+	/**
+	 * @return the id
+	 */
+	public String getId() {
+		return id;
+	}
+
+	/**
+	 * @return the refresh
+	 */
+	public Boolean getRefresh() {
+		return refresh;
+	}
+
+	/**
+	 * @return the size
+	 */
+	public long getSize() {
+		return size;
+	}
+
+	public Transaction setId(final String id) {
+		this.id = id;
+		return this;
+	}
+
+	public Transaction setRefresh(final Boolean refresh) {
+		this.refresh = refresh;
+		return this;
+	}
+
+	public Transaction setDate(final Date date) {
+		this.date = date;
+		return this;
+	}
+
+	public Transaction setSize(final long size) {
+		this.size = size;
+		return this;
+	}
+
+}
Index: modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/model/DBStatus.java
===================================================================
--- modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/model/DBStatus.java	(nonexistent)
+++ modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/model/DBStatus.java	(revision 46517)
@@ -0,0 +1,49 @@
+package eu.dnetlib.data.mdstore.model;
+
+public class DBStatus {
+
+	private int handledDatastructures;
+	private int usedDiskSpace;
+	private String date;
+
+	public DBStatus() {}
+
+	public DBStatus(final int handledDatastructures, final int usedDiskSpace, final String date) {
+		this.handledDatastructures = handledDatastructures;
+		this.usedDiskSpace = usedDiskSpace;
+		this.date = date;
+	}
+
+	public int getHandledDatastructures() {
+		return handledDatastructures;
+	}
+
+	public void setHandledDatastructures(final int handledDatastructures) {
+		this.handledDatastructures = handledDatastructures;
+	}
+
+	public int getUsedDiskSpace() {
+		return usedDiskSpace;
+	}
+
+	public void setUsedDiskSpace(final int usedDiskSpace) {
+		this.usedDiskSpace = usedDiskSpace;
+	}
+
+	public String getDate() {
+		return date;
+	}
+
+	public void setDate(final String date) {
+		this.date = date;
+	}
+
+	@Override
+	public String toString() {
+		return "MDStoreDBStatus{" +
+				"handledDatastructures=" + handledDatastructures +
+				", usedDiskSpace=" + usedDiskSpace +
+				", date='" + date + '\'' +
+				'}';
+	}
+}
Index: modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/utils/MDStoreRuntimeException.java
===================================================================
--- modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/utils/MDStoreRuntimeException.java	(nonexistent)
+++ modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/utils/MDStoreRuntimeException.java	(revision 46517)
@@ -0,0 +1,24 @@
+package eu.dnetlib.data.mdstore.utils;
+
+import eu.dnetlib.exceptions.DnetGenericRuntimeException;
+
+/**
+ * Created by claudio on 13/03/2017.
+ */
+public class MDStoreRuntimeException extends DnetGenericRuntimeException {
+
+	public MDStoreRuntimeException() {
+	}
+
+	public MDStoreRuntimeException(final String message, final Throwable cause) {
+		super(message, cause);
+	}
+
+	public MDStoreRuntimeException(final String message) {
+		super(message);
+	}
+
+	public MDStoreRuntimeException(final Throwable cause) {
+		super(cause);
+	}
+}
Index: modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/utils/MDStoreProfileManager.java
===================================================================
--- modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/utils/MDStoreProfileManager.java	(nonexistent)
+++ modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/utils/MDStoreProfileManager.java	(revision 46517)
@@ -0,0 +1,79 @@
+package eu.dnetlib.data.mdstore.utils;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.Map;
+
+import com.google.common.collect.Maps;
+import eu.dnetlib.clients.is.InformationServiceClient;
+import eu.dnetlib.miscutils.datetime.DateUtils;
+import eu.dnetlib.msro.controllers.MsroWorkerController;
+import freemarker.template.Configuration;
+import freemarker.template.Template;
+import freemarker.template.TemplateException;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+/**
+ * Created by claudio on 24/03/2017.
+ */
+@Component
+public class MDStoreProfileManager {
+
+	private static final Log log = LogFactory.getLog(MDStoreProfileManager.class);
+
+	@Autowired
+	private InformationServiceClient isClient;
+
+	@Autowired
+	private MsroWorkerController msroWorkerController;
+
+	@Autowired
+	private Configuration freemakerCfg;
+
+	public String registerProfile(String format, String layout, String interpretation) throws MDStoreException {
+
+		final Map<String, Object> input = Maps.newHashMap();
+
+		input.put("serviceId", msroWorkerController.getProfileId());
+		input.put("format", format);
+		input.put("layout", layout);
+		input.put("interpretation", interpretation);
+
+		log.debug(String.format("registering new mdstore profile %s-%s-%s", format, layout, interpretation));
+
+		return isClient.register(processTemplate(input));
+	}
+
+	public void deleteProfile(final String mdId) throws MDStoreException {
+		isClient.deleteProfile(mdId);
+	}
+
+	public void updateSize(final String mdId, final int size) {
+		final String now = DateUtils.now_ISO8601();
+
+		isClient.xupdate("for $x in //RESOURCE_PROFILE[.//RESOURCE_IDENTIFIER/@value = '" + mdId + "']"
+				+ "return update value $x//LAST_STORAGE_DATE with '" + now + "'");
+
+		isClient.xupdate("for $x in //RESOURCE_PROFILE[.//RESOURCE_IDENTIFIER/@value = '" + mdId + "']"
+				+ "return update value $x//NUMBER_OF_RECORDS with '" + size + "'");
+	}
+
+	// HELPERS
+
+	private String processTemplate(final Map<String, Object> input) throws MDStoreException {
+		try(Writer writer = new StringWriter()) {
+			final Template template = freemakerCfg.getTemplate("mdstore.ftl");
+
+			template.process(input, writer);
+
+			return writer.toString();
+		} catch (IOException | TemplateException e) {
+			throw new MDStoreException(e);
+		}
+	}
+
+}
Index: modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/utils/MDStoreConstants.java
===================================================================
--- modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/utils/MDStoreConstants.java	(nonexistent)
+++ modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/utils/MDStoreConstants.java	(revision 46517)
@@ -0,0 +1,36 @@
+package eu.dnetlib.data.mdstore.utils;
+
+/**
+ * Created by claudio on 20/03/2017.
+ */
+public class MDStoreConstants {
+
+	public static final String ID = "id";
+	public static final String MDID = "mdId";
+	public static final String METADATA_MANAGER_TABLE = "metadataManager";
+	public static final String CURRENT_ID = "currentId";
+	public static final String EXPIRING = "expiring";
+	public static final String REFRESH = "refresh";
+	public static final String DATE = "date";
+
+	public static final String READ_LOCKS = "readLocks";
+	public static final String TRANSACTIONS = "transactions";
+
+	public static final String LAST_UPDATE_DATE = "lastUpdateDate";
+	public static final String READ_COUNT = "readCount";
+	public static final String DISCARDED_PREFIX = "discarded-";
+	public static final String BODY = "body";
+	public static final String ORIGINAL_ID = "originalId";
+	public static final String TIMESTAMP = "timestamp";
+
+	public static final String FORMAT = "format";
+	public static final String LAYOUT = "layout";
+	public static final String INTERPRETATION = "interpretation";
+	public static final String SIZE = "size";
+	public static final String METADATA_NAME = "metadata";
+
+
+
+	public static final String ID_SEPARATOR = "/";
+
+}
Index: modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/utils/RecordParser.java
===================================================================
--- modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/utils/RecordParser.java	(nonexistent)
+++ modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/utils/RecordParser.java	(revision 46517)
@@ -0,0 +1,79 @@
+package eu.dnetlib.data.mdstore.utils;
+
+import java.io.ByteArrayInputStream;
+import java.util.Date;
+import java.util.Stack;
+import java.util.function.Function;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import eu.dnetlib.data.mdstore.model.MDStoreRecord;
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * Created by claudio on 20/03/2017.
+ */
+public class RecordParser implements Function<String, MDStoreRecord> {
+
+	public static final String OBJ_IDENTIFIER = "objIdentifier";
+	public static final String IDENTIFIER = "identifier";
+
+	private Long timestamp;
+
+	private XMLInputFactory factory;
+
+	public RecordParser() {
+		factory = XMLInputFactory.newInstance();
+		timestamp = null;
+	}
+
+	public RecordParser(final long timestamp) {
+		factory = XMLInputFactory.newInstance();
+		this.timestamp = timestamp;
+	}
+
+	@Override
+	public MDStoreRecord apply(final String s) {
+		try {
+			final XMLStreamReader parser = factory.createXMLStreamReader(new ByteArrayInputStream(s.getBytes()));
+			final Stack<String> elementStack = new Stack<>();
+			elementStack.push("/");
+
+			final MDStoreRecord res = MDStoreRecord.create()
+					.setBody(s)
+					.setTimestamp(timestamp != null ? timestamp : new Date().getTime());
+
+			System.out.println(res.getTimestamp());
+
+			while (parser.hasNext()) {
+				int event = parser.next();
+
+				if (event == XMLStreamConstants.END_ELEMENT) {
+					elementStack.pop();
+				} else if (event == XMLStreamConstants.START_ELEMENT) {
+					final String localName = parser.getLocalName();
+					elementStack.push(localName);
+
+					if (OBJ_IDENTIFIER.equals(localName)) {
+						parser.next();
+						res.setId(parser.getText().trim());
+
+					} else if (IDENTIFIER.equals(localName)) {
+						if (StringUtils.isBlank(res.getOriginalId())) {
+							parser.next();
+							res.setOriginalId(parser.getText().trim());
+						}
+					}
+					if (StringUtils.isNotBlank(res.getId()) && StringUtils.isNotBlank(res.getOriginalId())) {
+						return res;
+					}
+				}
+			}
+			return res;
+		} catch (XMLStreamException e) {
+			throw new IllegalStateException(e);
+		}
+	}
+}
Index: modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/utils/MDStoreException.java
===================================================================
--- modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/utils/MDStoreException.java	(nonexistent)
+++ modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/utils/MDStoreException.java	(revision 46517)
@@ -0,0 +1,24 @@
+package eu.dnetlib.data.mdstore.utils;
+
+import eu.dnetlib.exceptions.DnetGenericException;
+
+/**
+ * Created by claudio on 13/03/2017.
+ */
+public class MDStoreException extends DnetGenericException {
+
+	public MDStoreException() {
+	}
+
+	public MDStoreException(final String message, final Throwable cause) {
+		super(message, cause);
+	}
+
+	public MDStoreException(final String message) {
+		super(message);
+	}
+
+	public MDStoreException(final Throwable cause) {
+		super(cause);
+	}
+}
Index: modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/MDStore.java
===================================================================
--- modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/MDStore.java	(revision 46516)
+++ modules/dnet-springboot-apps/trunk/dnet-simple-aggregation-worker/src/main/java/eu/dnetlib/data/mdstore/MDStore.java	(revision 46517)
@@ -3,6 +3,7 @@
 import java.util.stream.Stream;
 
 import eu.dnetlib.data.mdstore.model.MDStoreRecord;
+import eu.dnetlib.data.mdstore.utils.MDStoreException;
 
 public interface MDStore {
 
