diff --git a/.gitignore b/.gitignore
index f77bee021..177e1bddd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,8 +2,19 @@
.idea
*.iml
*~
+.classpath
+/*/.classpath
+/*/*/.classpath
+.metadata
+/*/.metadata
+/*/*/.metadata
+.project
+.log
+.settings
+/*/*/target
/*/target
/target
+/*/*/build
/*/build
/build
-spark-warehouse
\ No newline at end of file
+spark-warehouse
diff --git a/README.md b/README.md
index 1a13ebf05..451899660 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,2 @@
# dnet-hadoop
+...test
diff --git a/dhp-applications/dhp-mdstore-manager-app/pom.xml b/dhp-applications/dhp-mdstore-manager-app/pom.xml
new file mode 100644
index 000000000..066b33981
--- /dev/null
+++ b/dhp-applications/dhp-mdstore-manager-app/pom.xml
@@ -0,0 +1,92 @@
+
+
+ 4.0.0
+ eu.dnetlib
+ dhp-mdstore-manager-app
+ 1.1.0-SNAPSHOT
+
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.1.3.RELEASE
+
+
+
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ org.springframework.boot
+ spring-boot-starter-json
+
+
+ org.postgresql
+ postgresql
+
+
+ com.vladmihalcea
+ hibernate-types-52
+ 2.3.5
+
+
+ commons-io
+ commons-io
+ 2.6
+
+
+
+
+ io.springfox
+ springfox-swagger2
+ 2.9.2
+
+
+
+ io.springfox
+ springfox-swagger-ui
+ 2.9.2
+
+
+
+
+ junit
+ junit
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+ true
+
+
+
+
+
+
diff --git a/dhp-applications/dhp-mdstore-manager-app/src/main/java/eu/dnetlib/data/mdstore/manager/MDStoreManagerException.java b/dhp-applications/dhp-mdstore-manager-app/src/main/java/eu/dnetlib/data/mdstore/manager/MDStoreManagerException.java
new file mode 100644
index 000000000..6ccd5e5fc
--- /dev/null
+++ b/dhp-applications/dhp-mdstore-manager-app/src/main/java/eu/dnetlib/data/mdstore/manager/MDStoreManagerException.java
@@ -0,0 +1,30 @@
+package eu.dnetlib.data.mdstore.manager;
+
+public class MDStoreManagerException extends Exception{
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -7503316126409002675L;
+
+ public MDStoreManagerException() {
+ super();
+ }
+
+ public MDStoreManagerException(String message, Throwable cause, boolean enableSuppression,
+ boolean writableStackTrace) {
+ super(message, cause, enableSuppression, writableStackTrace);
+ }
+
+ public MDStoreManagerException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public MDStoreManagerException(String message) {
+ super(message);
+ }
+
+ public MDStoreManagerException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/dhp-applications/dhp-mdstore-manager-app/src/main/java/eu/dnetlib/data/mdstore/manager/MainApplication.java b/dhp-applications/dhp-mdstore-manager-app/src/main/java/eu/dnetlib/data/mdstore/manager/MainApplication.java
new file mode 100644
index 000000000..f23b3529b
--- /dev/null
+++ b/dhp-applications/dhp-mdstore-manager-app/src/main/java/eu/dnetlib/data/mdstore/manager/MainApplication.java
@@ -0,0 +1,49 @@
+package eu.dnetlib.data.mdstore.manager;
+
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.context.annotation.Bean;
+
+import springfox.documentation.builders.ApiInfoBuilder;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.service.ApiInfo;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+@SpringBootApplication
+@EnableSwagger2
+@EnableCaching
+public class MainApplication {
+
+ private static final Logger log = LoggerFactory.getLogger(MainApplication.class);
+
+ public static void main(final String[] args) {
+ SpringApplication.run(MainApplication.class, args);
+ }
+
+ @Bean
+ public static Docket newSwaggerDocket() {
+ log.info("Initializing SWAGGER...");
+
+ return new Docket(DocumentationType.SWAGGER_2)
+ .select()
+ .apis(RequestHandlerSelectors.any())
+ .paths(p -> p.startsWith("/api/"))
+ .build().apiInfo(new ApiInfoBuilder()
+ .title("MDStore Manager APIs")
+ .description("APIs documentation")
+ .version("1.1")
+ .contact(ApiInfo.DEFAULT_CONTACT)
+ .license("Apache 2.0")
+ .licenseUrl("http://www.apache.org/licenses/LICENSE-2.0")
+ .build());
+
+ }
+
+
+}
diff --git a/dhp-applications/dhp-mdstore-manager-app/src/main/java/eu/dnetlib/data/mdstore/manager/SwaggerController.java b/dhp-applications/dhp-mdstore-manager-app/src/main/java/eu/dnetlib/data/mdstore/manager/SwaggerController.java
new file mode 100644
index 000000000..b6cfb7dc3
--- /dev/null
+++ b/dhp-applications/dhp-mdstore-manager-app/src/main/java/eu/dnetlib/data/mdstore/manager/SwaggerController.java
@@ -0,0 +1,14 @@
+package eu.dnetlib.data.mdstore.manager;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+@Controller
+public class SwaggerController {
+
+ @RequestMapping(value = { "/", "/apidoc", "/api-doc", "/doc", "/swagger" }, method = RequestMethod.GET)
+ public String apiDoc() {
+ return "redirect:swagger-ui.html";
+ }
+}
diff --git a/dhp-applications/dhp-mdstore-manager-app/src/main/java/eu/dnetlib/data/mdstore/manager/controller/MDStoreController.java b/dhp-applications/dhp-mdstore-manager-app/src/main/java/eu/dnetlib/data/mdstore/manager/controller/MDStoreController.java
new file mode 100644
index 000000000..a0563856e
--- /dev/null
+++ b/dhp-applications/dhp-mdstore-manager-app/src/main/java/eu/dnetlib/data/mdstore/manager/controller/MDStoreController.java
@@ -0,0 +1,79 @@
+package eu.dnetlib.data.mdstore.manager.controller;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import eu.dnetlib.data.mdstore.manager.MDStoreManagerException;
+import eu.dnetlib.data.mdstore.manager.model.MDStore;
+import eu.dnetlib.data.mdstore.manager.model.MDStoreWithInfo;
+import eu.dnetlib.data.mdstore.manager.model.Transaction;
+import eu.dnetlib.data.mdstore.manager.repository.MDStoreRepository;
+import eu.dnetlib.data.mdstore.manager.repository.MDStoreWithInfoRepository;
+import eu.dnetlib.data.mdstore.manager.repository.TransactionRepository;
+
+@RestController
+@RequestMapping("/api/mdstores")
+public class MDStoreController {
+
+ @Autowired
+ private MDStoreRepository mdstoreRepository;
+ @Autowired
+ private TransactionRepository transactionRepository;
+ @Autowired
+ private MDStoreWithInfoRepository mdstoreWithInfoRepository;
+
+ @RequestMapping(value = "/", method = RequestMethod.GET)
+ public final Iterable find() {
+ return mdstoreWithInfoRepository.findAll();
+ }
+
+ @RequestMapping(value = "/identifiers", method = RequestMethod.GET)
+ public final List findIdentifiers() {
+ return mdstoreRepository.findAll().stream().map(MDStore::getId).collect(Collectors.toList());
+ }
+
+ @RequestMapping(value = "/byId/{id}", method = RequestMethod.GET)
+ public final MDStoreWithInfo get(@PathVariable final String id) {
+ return mdstoreWithInfoRepository.findById(id).orElse(null);
+ }
+
+ @RequestMapping(value = "/count", method = RequestMethod.GET)
+ public final long count() {
+ return mdstoreRepository.count();
+ }
+
+ @RequestMapping(value = "/new/{format}/{layout}/{interpretation}", method = RequestMethod.PUT)
+ public MDStoreWithInfo createMDStore(
+ @PathVariable String format,
+ @PathVariable String layout,
+ @PathVariable String interpretation,
+ @RequestParam(required=false) String dsId,
+ @RequestParam(required=false) String apiId) throws MDStoreManagerException {
+ final MDStore md = MDStore.newInstance(dsId, apiId, format, layout, interpretation);
+ mdstoreRepository.save(md);
+
+ final Transaction t = Transaction.newInstance(md.getId());
+ t.setCurrent(true);
+ transactionRepository.save(t);
+
+ return mdstoreWithInfoRepository.findById(md.getId()).orElseThrow(() -> new MDStoreManagerException("MDStore not found"));
+ }
+
+ @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
+ public void delete(@PathVariable final String id) throws MDStoreManagerException {
+ if (transactionRepository.countByMdstoreAndActive(id, true) == 0) {
+ transactionRepository.deleteByMdstore(id);
+ mdstoreRepository.deleteById(id);
+ } else {
+ throw new MDStoreManagerException("Active transactions found on mdstore : " + id);
+ }
+ }
+
+}
diff --git a/dhp-applications/dhp-mdstore-manager-app/src/main/java/eu/dnetlib/data/mdstore/manager/controller/TransactionController.java b/dhp-applications/dhp-mdstore-manager-app/src/main/java/eu/dnetlib/data/mdstore/manager/controller/TransactionController.java
new file mode 100644
index 000000000..d4ae4b1d5
--- /dev/null
+++ b/dhp-applications/dhp-mdstore-manager-app/src/main/java/eu/dnetlib/data/mdstore/manager/controller/TransactionController.java
@@ -0,0 +1,41 @@
+package eu.dnetlib.data.mdstore.manager.controller;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+import eu.dnetlib.data.mdstore.manager.model.Transaction;
+import eu.dnetlib.data.mdstore.manager.repository.TransactionRepository;
+
+@RestController
+@RequestMapping("/api/transactions")
+public class TransactionController {
+
+ @Autowired
+ private TransactionRepository repo;
+
+ @RequestMapping(value = "/", method = RequestMethod.GET)
+ public final List find() {
+ return repo.findAll();
+ }
+
+ @RequestMapping(value = "/identifiers", method = RequestMethod.GET)
+ public final List findIdentifiers() {
+ return repo.findAll().stream().map(Transaction::getId).collect(Collectors.toList());
+ }
+
+ @RequestMapping(value = "/{id}", method = RequestMethod.GET)
+ public final Transaction get(@PathVariable final String id) {
+ return repo.findById(id).orElse(null);
+ }
+
+ @RequestMapping(value = "/count", method = RequestMethod.GET)
+ public final long count() {
+ return repo.count();
+ }
+}
diff --git a/dhp-applications/dhp-mdstore-manager-app/src/main/java/eu/dnetlib/data/mdstore/manager/model/MDStore.java b/dhp-applications/dhp-mdstore-manager-app/src/main/java/eu/dnetlib/data/mdstore/manager/model/MDStore.java
new file mode 100644
index 000000000..797b0784b
--- /dev/null
+++ b/dhp-applications/dhp-mdstore-manager-app/src/main/java/eu/dnetlib/data/mdstore/manager/model/MDStore.java
@@ -0,0 +1,108 @@
+package eu.dnetlib.data.mdstore.manager.model;
+
+import java.io.Serializable;
+import java.util.UUID;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "mdstores")
+public class MDStore implements Serializable {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 3160530489149700055L;
+
+ @Id
+ @Column(name = "id")
+ private String id;
+
+ @Column(name = "format")
+ private String format;
+
+ @Column(name = "layout")
+ private String layout;
+
+
+ @Column(name = "interpretation")
+ private String interpretation;
+
+ @Column(name = "datasource_id")
+ private String datasourceId;
+
+ @Column(name = "api_id")
+ private String apiId ;
+
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getFormat() {
+ return format;
+ }
+
+ public void setFormat(String format) {
+ this.format = format;
+ }
+
+ public String getLayout() {
+ return layout;
+ }
+
+ public void setLayout(String layout) {
+ this.layout = layout;
+ }
+
+ public String getInterpretation() {
+ return interpretation;
+ }
+
+ public void setInterpretation(String interpretation) {
+ this.interpretation = interpretation;
+ }
+
+ public String getDatasourceId() {
+ return datasourceId;
+ }
+
+ public void setDatasourceId(String datasourceId) {
+ this.datasourceId = datasourceId;
+ }
+
+ public String getApiId() {
+ return apiId;
+ }
+
+ public void setApiId(String apiId) {
+ this.apiId = apiId;
+ }
+
+ public static MDStore newInstance(final String format, final String layout, final String interpretation) {
+ return newInstance(null, null, format, layout, interpretation);
+ }
+
+ public static MDStore newInstance(final String dsId, final String apiId, final String format, final String layout, final String interpretation) {
+ final MDStore md = new MDStore();
+ md.setId("md-" + UUID.randomUUID());
+ md.setDatasourceId(dsId);
+ md.setApiId(apiId);
+ md.setFormat(format);
+ md.setLayout(layout);
+ md.setInterpretation(interpretation);
+ return md;
+ }
+
+
+
+
+
+}
diff --git a/dhp-applications/dhp-mdstore-manager-app/src/main/java/eu/dnetlib/data/mdstore/manager/model/MDStoreWithInfo.java b/dhp-applications/dhp-mdstore-manager-app/src/main/java/eu/dnetlib/data/mdstore/manager/model/MDStoreWithInfo.java
new file mode 100644
index 000000000..3f5b59938
--- /dev/null
+++ b/dhp-applications/dhp-mdstore-manager-app/src/main/java/eu/dnetlib/data/mdstore/manager/model/MDStoreWithInfo.java
@@ -0,0 +1,124 @@
+package eu.dnetlib.data.mdstore.manager.model;
+
+import java.io.Serializable;
+import java.util.Date;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+
+@Entity
+@Table(name = "mdstores_with_info")
+public class MDStoreWithInfo implements Serializable {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -8445784770687571492L;
+
+ @Id
+ @Column(name = "id")
+ private String id;
+
+ @Column(name = "format")
+ private String format;
+
+ @Column(name = "layout")
+ private String layout;
+
+ @Column(name = "interpretation")
+ private String interpretation;
+
+ @Column(name = "datasource_id")
+ private String datasourceId;
+
+ @Column(name = "api_id")
+ private String apiId ;
+
+ @Column(name = "current_version")
+ private String currentVersion;
+
+ @Column(name = "lastupdate")
+ @Temporal(TemporalType.TIMESTAMP)
+ private Date lastUpdate;
+
+ @Column(name = "size")
+ private int size;
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getFormat() {
+ return format;
+ }
+
+ public void setFormat(String format) {
+ this.format = format;
+ }
+
+ public String getLayout() {
+ return layout;
+ }
+
+ public void setLayout(String layout) {
+ this.layout = layout;
+ }
+
+ public String getInterpretation() {
+ return interpretation;
+ }
+
+ public void setInterpretation(String interpretation) {
+ this.interpretation = interpretation;
+ }
+
+ public String getDatasourceId() {
+ return datasourceId;
+ }
+
+ public void setDatasourceId(String datasourceId) {
+ this.datasourceId = datasourceId;
+ }
+
+ public String getApiId() {
+ return apiId;
+ }
+
+ public void setApiId(String apiId) {
+ this.apiId = apiId;
+ }
+
+ public String getCurrentVersion() {
+ return currentVersion;
+ }
+
+ public void setCurrentVersion(String currentVersion) {
+ this.currentVersion = currentVersion;
+ }
+
+ public Date getLastUpdate() {
+ return lastUpdate;
+ }
+
+ public void setLastUpdate(Date lastUpdate) {
+ this.lastUpdate = lastUpdate;
+ }
+
+ public int getSize() {
+ return size;
+ }
+
+ public void setSize(int size) {
+ this.size = size;
+ }
+
+
+}
diff --git a/dhp-applications/dhp-mdstore-manager-app/src/main/java/eu/dnetlib/data/mdstore/manager/model/Transaction.java b/dhp-applications/dhp-mdstore-manager-app/src/main/java/eu/dnetlib/data/mdstore/manager/model/Transaction.java
new file mode 100644
index 000000000..cc7100955
--- /dev/null
+++ b/dhp-applications/dhp-mdstore-manager-app/src/main/java/eu/dnetlib/data/mdstore/manager/model/Transaction.java
@@ -0,0 +1,114 @@
+package eu.dnetlib.data.mdstore.manager.model;
+
+import java.io.Serializable;
+import java.util.Date;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+
+@Entity
+@Table(name = "transactions")
+public class Transaction implements Serializable{
+ /**
+ *
+ */
+ private static final long serialVersionUID = -4763494442274298339L;
+
+ @Id
+ @Column(name = "id")
+ private String id;
+
+ @Column(name = "mdstore")
+ private String mdstore;
+
+ @Column(name = "current")
+ private boolean current;
+
+ @Column(name = "active")
+ private boolean active;
+
+ @Column(name = "readcount")
+ private int readCount;
+
+ @Column(name = "lastupdate")
+ @Temporal(TemporalType.TIMESTAMP)
+ private Date lastUpdate;
+
+ @Column(name = "size")
+ private int size;
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getMdstore() {
+ return mdstore;
+ }
+
+ public void setMdstore(String mdstore) {
+ this.mdstore = mdstore;
+ }
+
+ public boolean isCurrent() {
+ return current;
+ }
+
+ public void setCurrent(boolean current) {
+ this.current = current;
+ }
+
+ public boolean isActive() {
+ return active;
+ }
+
+ public void setActive(boolean active) {
+ this.active = active;
+ }
+
+ public int getReadCount() {
+ return readCount;
+ }
+
+ public void setReadCount(int readCount) {
+ this.readCount = readCount;
+ }
+
+ public Date getLastUpdate() {
+ return lastUpdate;
+ }
+
+ public void setLastUpdate(Date lastUpdate) {
+ this.lastUpdate = lastUpdate;
+ }
+
+ public int getSize() {
+ return size;
+ }
+
+ public void setSize(int size) {
+ this.size = size;
+ }
+
+ public static Transaction newInstance(final String mdId) {
+ final Transaction t = new Transaction();
+ t.setId(mdId + "-" + new Date().getTime());
+ t.setMdstore(mdId);
+ t.setLastUpdate(null);
+ t.setActive(false);
+ t.setCurrent(false);
+ t.setReadCount(0);
+ t.setSize(0);
+ return t;
+ }
+
+
+
+}
diff --git a/dhp-applications/dhp-mdstore-manager-app/src/main/java/eu/dnetlib/data/mdstore/manager/repository/MDStoreRepository.java b/dhp-applications/dhp-mdstore-manager-app/src/main/java/eu/dnetlib/data/mdstore/manager/repository/MDStoreRepository.java
new file mode 100644
index 000000000..ab499a3a1
--- /dev/null
+++ b/dhp-applications/dhp-mdstore-manager-app/src/main/java/eu/dnetlib/data/mdstore/manager/repository/MDStoreRepository.java
@@ -0,0 +1,11 @@
+package eu.dnetlib.data.mdstore.manager.repository;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+import eu.dnetlib.data.mdstore.manager.model.MDStore;
+
+@Repository
+public interface MDStoreRepository extends JpaRepository {
+
+}
diff --git a/dhp-applications/dhp-mdstore-manager-app/src/main/java/eu/dnetlib/data/mdstore/manager/repository/MDStoreWithInfoRepository.java b/dhp-applications/dhp-mdstore-manager-app/src/main/java/eu/dnetlib/data/mdstore/manager/repository/MDStoreWithInfoRepository.java
new file mode 100644
index 000000000..3a8608ba2
--- /dev/null
+++ b/dhp-applications/dhp-mdstore-manager-app/src/main/java/eu/dnetlib/data/mdstore/manager/repository/MDStoreWithInfoRepository.java
@@ -0,0 +1,10 @@
+package eu.dnetlib.data.mdstore.manager.repository;
+
+import org.springframework.stereotype.Repository;
+
+import eu.dnetlib.data.mdstore.manager.model.MDStoreWithInfo;
+
+@Repository
+public interface MDStoreWithInfoRepository extends ReadOnlyRepository {
+
+}
diff --git a/dhp-applications/dhp-mdstore-manager-app/src/main/java/eu/dnetlib/data/mdstore/manager/repository/ReadOnlyRepository.java b/dhp-applications/dhp-mdstore-manager-app/src/main/java/eu/dnetlib/data/mdstore/manager/repository/ReadOnlyRepository.java
new file mode 100644
index 000000000..02ba4346c
--- /dev/null
+++ b/dhp-applications/dhp-mdstore-manager-app/src/main/java/eu/dnetlib/data/mdstore/manager/repository/ReadOnlyRepository.java
@@ -0,0 +1,18 @@
+package eu.dnetlib.data.mdstore.manager.repository;
+
+import java.util.Optional;
+
+import org.springframework.data.repository.NoRepositoryBean;
+import org.springframework.data.repository.Repository;
+
+@NoRepositoryBean
+public interface ReadOnlyRepository extends Repository {
+
+ Optional findById(ID id);
+
+ boolean existsById(ID id);
+
+ Iterable findAll();
+
+ long count();
+}
\ No newline at end of file
diff --git a/dhp-applications/dhp-mdstore-manager-app/src/main/java/eu/dnetlib/data/mdstore/manager/repository/TransactionRepository.java b/dhp-applications/dhp-mdstore-manager-app/src/main/java/eu/dnetlib/data/mdstore/manager/repository/TransactionRepository.java
new file mode 100644
index 000000000..e757955bc
--- /dev/null
+++ b/dhp-applications/dhp-mdstore-manager-app/src/main/java/eu/dnetlib/data/mdstore/manager/repository/TransactionRepository.java
@@ -0,0 +1,14 @@
+package eu.dnetlib.data.mdstore.manager.repository;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+import eu.dnetlib.data.mdstore.manager.model.Transaction;
+
+@Repository
+public interface TransactionRepository extends JpaRepository {
+
+ void deleteByMdstore(String id);
+
+ int countByMdstoreAndActive(String id, boolean active);
+}
diff --git a/dhp-applications/dhp-mdstore-manager-app/src/main/resources/application.properties b/dhp-applications/dhp-mdstore-manager-app/src/main/resources/application.properties
new file mode 100644
index 000000000..e72d78cc8
--- /dev/null
+++ b/dhp-applications/dhp-mdstore-manager-app/src/main/resources/application.properties
@@ -0,0 +1,14 @@
+spring.main.banner-mode = console
+logging.level.root = INFO
+
+spring.datasource.url=jdbc:postgresql://localhost:5432/mdstoremanager
+spring.datasource.username=
+spring.datasource.password=
+
+spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect
+
+# Hibernate ddl auto (create, create-drop, validate, update)
+spring.jpa.hibernate.ddl-auto = validate
+spring.jpa.properties.hibernate.hbm2dll.extra_physical_table_types = MATERIALIZED VIEW
+spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
+spring.jpa.open-in-view=true
diff --git a/dhp-applications/dhp-mdstore-manager-app/src/main/resources/schema.sql b/dhp-applications/dhp-mdstore-manager-app/src/main/resources/schema.sql
new file mode 100644
index 000000000..79abc2568
--- /dev/null
+++ b/dhp-applications/dhp-mdstore-manager-app/src/main/resources/schema.sql
@@ -0,0 +1,38 @@
+DROP VIEW IF EXISTS mdstores_with_info;
+DROP TABLE IF EXISTS transactions;
+DROP TABLE IF EXISTS mdstores;
+
+CREATE TABLE mdstores (
+ id text PRIMARY KEY,
+ format text,
+ layout text,
+ interpretation text,
+ datasource_id text,
+ api_id text
+);
+
+CREATE TABLE transactions (
+ id text PRIMARY KEY,
+ mdstore text REFERENCES mdstores(id),
+ current boolean,
+ active boolean,
+ readcount int,
+ lastupdate timestamp,
+ size int
+);
+
+CREATE VIEW mdstores_with_info AS SELECT
+ md.id AS id,
+ md.format AS format,
+ md.layout AS layout,
+ md.interpretation AS interpretation,
+ md.datasource_id AS datasource_id,
+ md.api_id AS api_id,
+ t.id AS current_version,
+ t.lastupdate AS lastupdate,
+ t.size AS size
+FROM
+ mdstores md
+ LEFT OUTER JOIN transactions t ON (md.id = t.mdstore)
+WHERE
+ t.current = TRUE;
diff --git a/dhp-applications/pom.xml b/dhp-applications/pom.xml
new file mode 100644
index 000000000..51d4047ac
--- /dev/null
+++ b/dhp-applications/pom.xml
@@ -0,0 +1,15 @@
+
+
+ 4.0.0
+
+ eu.dnetlib.dhp
+ dhp
+ 1.0.0-SNAPSHOT
+
+ dhp-applications
+ pom
+
+ dhp-mdstore-manager-app
+
+
+
diff --git a/pom.xml b/pom.xml
index c0e104825..1cf33cef0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -23,6 +23,7 @@
dhp-common
dhp-workflows
+ dhp-applications