Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/controllers/RepositoryController.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/controllers/RepositoryController.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/controllers/RepositoryController.java	(revision 61527)
@@ -0,0 +1,277 @@
+package eu.dnetlib.repo.manager.controllers;
+
+import eu.dnetlib.domain.data.Repository;
+import eu.dnetlib.domain.data.RepositoryInterface;
+import eu.dnetlib.repo.manager.domain.*;
+import eu.dnetlib.repo.manager.domain.dto.User;
+import eu.dnetlib.repo.manager.exception.ResourceNotFoundException;
+import eu.dnetlib.repo.manager.service.RepositoryService;
+import eu.dnetlib.repo.manager.service.security.AuthorizationService;
+import eu.dnetlib.repo.manager.utils.JsonUtils;
+import io.swagger.annotations.Api;
+import org.apache.log4j.Logger;
+import org.json.JSONException;
+import org.mitre.openid.connect.model.OIDCAuthenticationToken;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.access.prepost.PostAuthorize;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.web.bind.annotation.*;
+
+import javax.ws.rs.core.Response;
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+@RestController
+@RequestMapping(value = "/repositories")
+@Api(description = "Repository API", tags = {"repositories"})
+public class RepositoryController {
+
+    private static final Logger logger = Logger.getLogger(RepositoryController.class);
+
+    private final RepositoryService repositoryService;
+    private final AuthorizationService authorizationService;
+
+    @Autowired
+    RepositoryController(RepositoryService repositoryService,
+                         AuthorizationService authorizationService) {
+        this.repositoryService = repositoryService;
+        this.authorizationService = authorizationService;
+    }
+
+    @RequestMapping(value = "/countries", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    public Country[] getCountries() {
+        return repositoryService.getCountries();
+    }
+
+    @RequestMapping(value = "/getRepositoriesByCountry/{country}/{mode}", method = RequestMethod.GET,
+            produces = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    public List<RepositorySnippet> getRepositoriesByCountry(@PathVariable("country") String country,
+                                                            @PathVariable("mode") String mode,
+                                                            @RequestParam(value = "managed", required = false) Boolean managed) throws JSONException, IOException {
+        return repositoryService.getRepositoriesByCountry(country, mode, managed);
+    }
+
+    @RequestMapping(value = "/snippets/user", method = RequestMethod.GET,
+            produces = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    @PreAuthorize("hasAuthority('REGISTERED_USER')")
+    public List<RepositorySnippet> getRepositoriesSnippetsOfUser() throws Exception {
+        return repositoryService.getRepositoriesSnippetsOfUser("0", "100");
+    }
+
+    @RequestMapping(value = "/searchRegisteredRepositories/{page}/{size}", method = RequestMethod.GET,
+            produces = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    @PreAuthorize("hasAuthority('SUPER_ADMINISTRATOR') or hasAuthority('CONTENT_PROVIDER_DASHBOARD_ADMINISTRATOR')")
+    public List<RepositorySnippet> searchRegisteredRepositories(@RequestParam(name = "country", required = false) String country,
+                                                                @RequestParam(name = "typology", required = false) String typology,
+                                                                @RequestParam(name = "englishName", required = false) String englishName,
+                                                                @RequestParam(name = "officialName", required = false) String officialName,
+                                                                @RequestParam("requestSortBy") String requestSortBy,
+                                                                @RequestParam("order") String order,
+                                                                @PathVariable("page") int page,
+                                                                @PathVariable("size") int pageSize) throws Exception {
+
+        return repositoryService.searchRegisteredRepositories(country, typology, englishName, officialName, requestSortBy, order, page, pageSize);
+    }
+
+    @RequestMapping(value = "/getRepositoryById/{id}", method = RequestMethod.GET,
+            produces = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    @PostAuthorize("hasAnyAuthority('SUPER_ADMINISTRATOR', 'CONTENT_PROVIDER_DASHBOARD_ADMINISTRATOR') or @authorizationService.isMemberOf(#id) or (returnObject.registeredBy=='null' and hasAuthority('REGISTERED_USER'))")
+    public Repository getRepositoryById(@PathVariable("id") String id) throws JSONException, ResourceNotFoundException {
+        Repository repo = repositoryService.getRepositoryById(id);
+
+        if (repo != null)
+            logger.info("Returning repository " + repo.getId() + " registered by " + repo.getRegisteredBy());
+        else
+            logger.info("Requested repository " + id + " not found");
+        return repo;
+    }
+
+    @RequestMapping(value = "/getRepositoryAggregations/{id}", method = RequestMethod.GET,
+            produces = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    public List<AggregationDetails> getRepositoryAggregations(@PathVariable("id") String id) throws JSONException {
+        return repositoryService.getRepositoryAggregations(id, 0, 20);
+    }
+
+    @RequestMapping(value = "/getRepositoryAggregationsByYear/{id}", method = RequestMethod.GET,
+            produces = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    public Map<String, List<AggregationDetails>> getRepositoryAggregationsByYear(@PathVariable("id") String id) throws JSONException {
+        return repositoryService.getRepositoryAggregationsByYear(id);
+    }
+
+    @RequestMapping(value = "/getRepositoriesByName/{name:.+}/{page}/{size}/", method = RequestMethod.GET,
+            produces = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    public List<Repository> getRepositoriesByName(@PathVariable("name") String name,
+                                                  @PathVariable("page") String page,
+                                                  @PathVariable("size") String size) throws JSONException {
+        return repositoryService.getRepositoriesByName(name, page, size);
+    }
+
+    @RequestMapping(value = "/getRepositoryInterface/{id}", method = RequestMethod.GET,
+            produces = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    @PostAuthorize("hasAuthority('SUPER_ADMINISTRATOR') or hasAuthority('CONTENT_PROVIDER_DASHBOARD_ADMINISTRATOR') or @authorizationService.isMemberOf(#id) or (@repositoryService.getRepositoryById(#id).registeredBy=='null' and hasAuthority('REGISTERED_USER'))")
+    public List<RepositoryInterface> getRepositoryInterface(@PathVariable("id") String id) throws JSONException {
+        return repositoryService.getRepositoryInterface(id);
+    }
+
+    @RequestMapping(value = "/addRepository", method = RequestMethod.POST,
+            consumes = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+//    @PreAuthorize("hasAuthority('SUPER_ADMINISTRATOR') or hasAuthority('CONTENT_PROVIDER_DASHBOARD_ADMINISTRATOR') or (hasAuthority(@authorizationService.convertRepoIdToRoleId(#repository.id)) or hasAuthority(@authorizationService.convertRepoIdToRoleId(returnObject.id)))")
+    @PreAuthorize("hasAuthority('SUPER_ADMINISTRATOR') or hasAuthority('CONTENT_PROVIDER_DASHBOARD_ADMINISTRATOR') or hasAuthority('REGISTERED_USER')")
+    public Repository addRepository(@RequestParam("datatype") String datatype,
+                                    @RequestBody Repository repository) throws Exception {
+
+        return repositoryService.addRepository(datatype, repository);
+    }
+
+    @RequestMapping(value = "/getDnetCountries", method = RequestMethod.GET,
+            produces = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    public List<String> getDnetCountries() {
+        return repositoryService.getDnetCountries();
+    }
+
+    @RequestMapping(value = "/getTypologies", method = RequestMethod.GET,
+            produces = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    public List<String> getTypologies() {
+        return repositoryService.getTypologies();
+    }
+
+    @RequestMapping(value = "/getTimezones", method = RequestMethod.GET,
+            produces = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    public List<Timezone> getTimezones() {
+        return repositoryService.getTimezones();
+    }
+
+    @RequestMapping(value = "/updateRepository", method = RequestMethod.POST,
+            consumes = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    @PreAuthorize("hasAuthority('SUPER_ADMINISTRATOR') or hasAuthority('CONTENT_PROVIDER_DASHBOARD_ADMINISTRATOR') or @authorizationService.isMemberOf(#repository.id)")
+    public Repository updateRepository(@RequestBody Repository repository, Authentication authentication) throws Exception {
+        return repositoryService.updateRepository(repository, authentication);
+    }
+
+    @RequestMapping(value = "/deleteInterface/", method = RequestMethod.DELETE)
+    @PreAuthorize("@authorizationService.isMemberOf(#id)")
+    public void deleteRepositoryInterface(@RequestParam("id") String id,
+                                          @RequestParam("registeredBy") String registeredBy) {
+        repositoryService.deleteRepositoryInterface(id, registeredBy);
+    }
+
+    @RequestMapping(value = "/addInterface", method = RequestMethod.POST,
+            consumes = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    @PreAuthorize("hasAuthority('SUPER_ADMINISTRATOR') or hasAuthority('CONTENT_PROVIDER_DASHBOARD_ADMINISTRATOR') or @authorizationService.isMemberOf(#id)")
+    public RepositoryInterface addRepositoryInterface(@RequestParam("datatype") String datatype,
+                                                      @RequestParam("id") String id,
+                                                      @RequestParam("registeredBy") String registeredBy,
+                                                      @RequestParam(value = "comment", required = false) String comment,
+                                                      @RequestBody RepositoryInterface repositoryInterface) throws Exception {
+        return repositoryService.addRepositoryInterface(datatype, id, registeredBy, comment, repositoryInterface);
+    }
+
+    @RequestMapping(value = "/getUrlsOfUserRepos/{page}/{size}/", method = RequestMethod.GET,
+            produces = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    @PreAuthorize("hasAuthority('REGISTERED_USER')")
+    public List<String> getUrlsOfUserRepos(@PathVariable("page") String page, @PathVariable("size") String size) {
+        return repositoryService.getUrlsOfUserRepos(((OIDCAuthenticationToken) SecurityContextHolder.getContext().getAuthentication()).getUserInfo().getEmail(), page, size);
+    }
+
+    @RequestMapping(value = "/getDatasourceVocabularies/{mode}", method = RequestMethod.GET,
+            produces = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    public List<String> getDatasourceVocabularies(@PathVariable("mode") String mode) {
+        return repositoryService.getDatasourceVocabularies(mode);
+    }
+
+    @RequestMapping(value = "/getCompatibilityClasses/{mode}", method = RequestMethod.GET,
+            produces = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    public Map<String, String> getCompatibilityClasses(@PathVariable("mode") String mode) {
+
+        return repositoryService.getCompatibilityClasses(mode);
+    }
+
+    @RequestMapping(value = "/getDatasourceClasses/{mode}", method = RequestMethod.GET,
+            produces = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    public Map<String, String> getDatasourceClasses(@PathVariable("mode") String mode) {
+        return repositoryService.getDatasourceClasses(mode);
+    }
+
+    @RequestMapping(value = "/getMetricsInfoForRepository/{id}", method = RequestMethod.GET,
+            produces = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    public MetricsInfo getMetricsInfoForRepository(@PathVariable("id") String id) throws RepositoryServiceException {
+        return repositoryService.getMetricsInfoForRepository(id);
+    }
+
+    @RequestMapping(value = "/getListLatestUpdate/{mode}", method = RequestMethod.GET,
+            produces = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    public Map<String, String> getListLatestUpdate(@PathVariable("mode") String mode) throws JSONException {
+        return repositoryService.getListLatestUpdate(mode);
+    }
+
+    @RequestMapping(value = "/updateRepositoryInterface", method = RequestMethod.POST,
+            consumes = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    @PreAuthorize("hasAuthority('SUPER_ADMINISTRATOR') or hasAuthority('CONTENT_PROVIDER_DASHBOARD_ADMINISTRATOR') or @authorizationService.isMemberOf(#id)")
+    public RepositoryInterface updateRepositoryInterface(@RequestParam("id") String id,
+                                                         @RequestParam("registeredBy") String registeredBy,
+                                                         @RequestParam(value = "comment", required = false) String comment,
+                                                         @RequestBody RepositoryInterface repositoryInterface) throws Exception {
+        return repositoryService.updateRepositoryInterface(id, registeredBy, comment, repositoryInterface);
+    }
+
+
+    ///////////////////////////////////////////////////////////////////////////////////////////////////////////
+    ///////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * Get all the admins of the repository
+     */
+    @RequestMapping(method = RequestMethod.GET, path = "{id}/admins")
+    @PreAuthorize("hasAnyAuthority('SUPER_ADMINISTRATOR', 'CONTENT_PROVIDER_DASHBOARD_ADMINISTRATOR') or @authorizationService.isMemberOf(#id)")
+    public ResponseEntity<List<User>> getAdminsOfARepo(@PathVariable("id") String id) {
+        return new ResponseEntity<>(authorizationService.getAdminsOfRepo(id), HttpStatus.OK);
+    }
+
+    /**
+     * Subscribe to repo by email
+     */
+    @RequestMapping(method = RequestMethod.POST, path = "{id}/admins")
+    @PreAuthorize("hasAnyAuthority('SUPER_ADMINISTRATOR', 'CONTENT_PROVIDER_DASHBOARD_ADMINISTRATOR') or @authorizationService.isMemberOf(#id)")
+    public Response subscribeByEmail(@PathVariable("id") String id, @RequestBody String email) throws ResourceNotFoundException {
+        authorizationService.addAdmin(id, email);
+        return Response.status(HttpStatus.OK.value()).entity(JsonUtils.createResponse("Role has been assigned").toString()).type(javax.ws.rs.core.MediaType.APPLICATION_JSON).build();
+    }
+
+    /**
+     * Unsubscribe from repo by email
+     */
+    @RequestMapping(method = RequestMethod.DELETE, path = "{id}/admins/{email:.+}")
+    @PreAuthorize("hasAnyAuthority('SUPER_ADMINISTRATOR', 'CONTENT_PROVIDER_DASHBOARD_ADMINISTRATOR') or @authorizationService.isMemberOf(#id)")
+    public ResponseEntity<Void> unsubscribeByEmail(@PathVariable("id") String id, @PathVariable("email") String email) throws ResourceNotFoundException {
+        authorizationService.removeAdmin(id, email);
+        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
+    }
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/StatsService.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/StatsService.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/StatsService.java	(revision 61527)
@@ -0,0 +1,9 @@
+package eu.dnetlib.repo.manager.service;
+
+import java.util.Map;
+
+
+public interface StatsService {
+
+    Map getStatistics() ;
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/controllers/PiWikController.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/controllers/PiWikController.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/controllers/PiWikController.java	(revision 61527)
@@ -0,0 +1,182 @@
+package eu.dnetlib.repo.manager.controllers;
+
+import eu.dnetlib.domain.data.PiwikInfo;
+import eu.dnetlib.repo.manager.domain.OrderByField;
+import eu.dnetlib.repo.manager.domain.OrderByType;
+import eu.dnetlib.repo.manager.domain.Paging;
+import eu.dnetlib.repo.manager.domain.RepositoryServiceException;
+import eu.dnetlib.repo.manager.service.PiWikServiceImpl;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import org.apache.log4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.io.FileSystemResource;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+
+@RestController
+@RequestMapping(value = "/piwik")
+@Api(description = "Piwik API",  tags = {"piwik"})
+public class PiWikController {
+
+    private static final Logger LOGGER = Logger
+            .getLogger(PiWikController.class);
+
+    @Autowired
+    private PiWikServiceImpl piWikService;
+
+    @RequestMapping(value = "/getPiwikSiteForRepo/{repositoryId}" , method = RequestMethod.GET,produces = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    @PreAuthorize("hasAnyAuthority('SUPER_ADMINISTRATOR', 'CONTENT_PROVIDER_DASHBOARD_ADMINISTRATOR') or @authorizationService.isMemberOf(#repositoryId) or (@repositoryService.getRepositoryById(#repositoryId).registeredBy=='null' and hasAuthority('REGISTERED_USER'))")
+    public PiwikInfo getPiwikSiteForRepo(@PathVariable("repositoryId") String repositoryId) {
+        return piWikService.getPiwikSiteForRepo(repositoryId);
+    }
+
+    @RequestMapping(value = "/savePiwikInfo" , method = RequestMethod.POST,produces = MediaType.APPLICATION_JSON_VALUE)
+    @PreAuthorize("hasAnyAuthority('SUPER_ADMINISTRATOR', 'CONTENT_PROVIDER_DASHBOARD_ADMINISTRATOR') or @authorizationService.isMemberOf(#piwikInfo.repositoryId) or (@repositoryService.getRepositoryById(#piwikInfo.repositoryId).registeredBy=='null' and hasAuthority('REGISTERED_USER'))")
+    public PiwikInfo savePiwikInfo(@RequestBody PiwikInfo piwikInfo) {
+        return piWikService.savePiwikInfo(piwikInfo);
+    }
+
+    @RequestMapping(value = "/getPiwikSitesForRepos" , method = RequestMethod.GET,produces = MediaType.APPLICATION_JSON_VALUE)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "from", dataType = "number", paramType = "query"),
+            @ApiImplicitParam(name = "quantity", dataType = "number", paramType = "query"),
+            @ApiImplicitParam(name = "order", dataType = "eu.dnetlib.repo.manager.domain.OrderByType", paramType = "query"),
+            @ApiImplicitParam(name = "orderField", dataType = "eu.dnetlib.repo.manager.domain.OrderByField", paramType = "query"),
+            @ApiImplicitParam(name = "searchField", dataType = "string", paramType = "query"),
+    })
+    public Paging<PiwikInfo> getPiwikSitesForRepos(
+            @RequestParam(value = "from",required=false,defaultValue = "0") int from,
+            @RequestParam(value = "quantity",required=false,defaultValue = "100") int quantity,
+            @RequestParam(value = "order",required=false,defaultValue = "DSC") OrderByType orderType,
+            @RequestParam(value = "orderField", required = false, defaultValue = "REPOSITORY_NAME") OrderByField orderField,
+            @RequestParam(value = "searchField", required = false, defaultValue = "") String searchField
+
+    ){
+        Paging<PiwikInfo> results = new Paging<>();
+        List<PiwikInfo> returning = piWikService.getPiwikSitesForRepos(orderField,orderType,from,quantity,searchField);
+        results.setFrom(from);
+        results.setTo(from + returning.size());
+        results.setTotal(piWikService.getPiwikSitesTotals(searchField));
+        results.setResults(returning);
+        return results;
+    }
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "from", dataType = "number", paramType = "query"),
+            @ApiImplicitParam(name = "quantity", dataType = "number", paramType = "query"),
+            @ApiImplicitParam(name = "order", dataType = "eu.dnetlib.repo.manager.domain.OrderByType", paramType = "query"),
+            @ApiImplicitParam(name = "searchField", dataType = "eu.dnetlib.repo.manager.domain.OrderByField", paramType = "query"),
+            @ApiImplicitParam(name = "orderField", dataType = "string", paramType = "query"),
+    })
+    @RequestMapping(value = "/getPiwikSitesForRepos/csv" , method = RequestMethod.GET,produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
+    @ResponseBody
+    public FileSystemResource getPiwikSitesForReposToCsv(
+            @RequestParam(value = "from",required=false,defaultValue = "0") int from,
+            @RequestParam(value = "quantity",required=false,defaultValue = "10000") int quantity,
+            @RequestParam(value = "order",required=false,defaultValue = "DSC") OrderByType orderType,
+            @RequestParam(value = "orderField", required = false, defaultValue = "REPOSITORY_NAME") OrderByField orderField,
+            @RequestParam(value = "searchField", required = false, defaultValue = "") String searchField,
+            HttpServletResponse response,
+            HttpServletRequest request
+    ) throws IOException {
+
+        Path p = Files.createTempFile("exportingCsv-", new Date().toString());
+        List<PiwikInfo> returning = piWikService.getPiwikSitesForRepos(orderField,orderType,0,10000,searchField);
+        try (PrintWriter writer = new PrintWriter(p.toFile())) {
+
+            StringBuilder sb = new StringBuilder();
+            sb.append(" Repository ID , Repository name, Country, Site ID, Authentication token, Creation date, Requestor full name, Requestor email, Validated, Validation date, Comment \n");
+
+            for(PiwikInfo piwikInfo : returning){
+                sb.append(
+                        (piwikInfo.getRepositoryId() == null ? "," : piwikInfo.getRepositoryId()+ ",")+
+                                (piwikInfo.getRepositoryName() == null ? "," : piwikInfo.getRepositoryName()+ ",")+
+                                (piwikInfo.getCountry() == null ? "," : piwikInfo.getCountry()+ ",")+
+                                (piwikInfo.getSiteId() == null ? "," : piwikInfo.getSiteId()+ ",") +
+                                (piwikInfo.getAuthenticationToken() == null ? "," : piwikInfo.getAuthenticationToken()+ ",")+
+                                (piwikInfo.getCreationDate() == null ? "," : piwikInfo.getCreationDate().toString()+ ",") +
+                                (piwikInfo.getRequestorName() == null ? "," : piwikInfo.getRequestorName()+ ",") +
+                                (piwikInfo.getRequestorEmail() == null ? "," : piwikInfo.getRequestorEmail()+ ",")+
+                                piwikInfo.isValidated() + "," +
+                                (piwikInfo.getValidationDate() == null ? "," : piwikInfo.getValidationDate().toString()+ ",") +
+                                (piwikInfo.getComment() == null ? "\n" : piwikInfo.getComment()+ "\n")
+
+                );
+            }
+            writer.write(sb.toString());
+
+        } catch (FileNotFoundException e) {
+            LOGGER.error(e.getMessage());
+        }
+
+
+        String mimeType = request.getServletContext().getMimeType(p.toFile().getAbsolutePath());
+        if (mimeType == null) {
+            mimeType = "application/octet-stream";
+        }
+        response.setContentType(mimeType);
+        response.setContentLength((int) p.toFile().length());
+
+
+        String headerKey = "Content-Disposition";
+        SimpleDateFormat sdfDate = new SimpleDateFormat("ddMMyyyy");//dd/MM/yyyy
+        Date now = new Date();
+        String strDate = sdfDate.format(now);
+        String headerValue = String.format("attachment; filename=\"csv-%s.csv\"",
+                strDate);
+        response.setHeader(headerKey, headerValue);
+
+
+        return new FileSystemResource(p.toFile());
+
+    }
+
+
+    @RequestMapping(value = "/approvePiwikSite/{repositoryId}" , method = RequestMethod.GET)
+    @ResponseBody
+    @PreAuthorize("hasAuthority('SUPER_ADMINISTRATOR') or hasAuthority('CONTENT_PROVIDER_DASHBOARD_ADMINISTRATOR')")
+    public ResponseEntity<Object> approvePiwikSite(@PathVariable("repositoryId") String repositoryId) {
+        return piWikService.approvePiwikSite(repositoryId);
+    }
+
+    @RequestMapping(value = "/getOpenaireId/{repositoryId}" , method = RequestMethod.GET,produces = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    @PreAuthorize("hasAnyAuthority('SUPER_ADMINISTRATOR', 'CONTENT_PROVIDER_DASHBOARD_ADMINISTRATOR') or @authorizationService.isMemberOf(#repositoryId) or (@repositoryService.getRepositoryById(#repositoryId).registeredBy=='null' and hasAuthority('REGISTERED_USER'))")
+    public String getOpenaireId(@PathVariable("repositoryId") String repositoryId){
+        return piWikService.getOpenaireId(repositoryId);
+    }
+
+    @RequestMapping(value = "/markPiwikSiteAsValidated/{repositoryId}" , method = RequestMethod.POST,
+            consumes = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    @PreAuthorize("hasAuthority('SUPER_ADMINISTRATOR') or hasAuthority('CONTENT_PROVIDER_DASHBOARD_ADMINISTRATOR')")
+    public ResponseEntity<Object> markPiwikSiteAsValidated(@PathVariable("repositoryId") String repositoryId) throws RepositoryServiceException {
+        return piWikService.markPiwikSiteAsValidated(repositoryId);
+    }
+
+    @RequestMapping(value = "/enableMetricsForRepository", method = RequestMethod.POST,
+            consumes = MediaType.APPLICATION_JSON_VALUE)
+    @PreAuthorize("hasAuthority('SUPER_ADMINISTRATOR') or hasAuthority('CONTENT_PROVIDER_DASHBOARD_ADMINISTRATOR') or (hasAuthority('REGISTERED_USER') and #piwikInfo.requestorEmail == authentication.userInfo.email)")
+    public PiwikInfo enableMetricsForRepository(@RequestParam("officialName") String officialName,
+                                                @RequestParam("repoWebsite") String repoWebsite,
+                                                @RequestBody PiwikInfo piwikInfo) throws RepositoryServiceException {
+        return piWikService.enableMetricsForRepository(officialName, repoWebsite, piwikInfo);
+    }
+
+
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/DashboardService.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/DashboardService.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/DashboardService.java	(revision 61527)
@@ -0,0 +1,14 @@
+package eu.dnetlib.repo.manager.service;
+
+import eu.dnetlib.repo.manager.domain.RepositorySummaryInfo;
+import org.json.JSONException;
+import org.springframework.web.bind.annotation.PathVariable;
+
+import java.util.List;
+
+public interface DashboardService {
+
+    List<RepositorySummaryInfo> getRepositoriesSummaryInfo(@PathVariable("userEmail") String userEmail,
+                                                           @PathVariable("page") String page,
+                                                           @PathVariable("size") String size) throws JSONException;
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/controllers/PrometheusController.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/controllers/PrometheusController.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/controllers/PrometheusController.java	(revision 61527)
@@ -0,0 +1,55 @@
+package eu.dnetlib.repo.manager.controllers;
+
+import eu.dnetlib.repo.manager.service.PiWikService;
+import io.micrometer.core.instrument.binder.jvm.DiskSpaceMetrics;
+import io.micrometer.core.instrument.binder.jvm.JvmGcMetrics;
+import io.micrometer.core.instrument.binder.jvm.JvmMemoryMetrics;
+import io.micrometer.core.instrument.binder.jvm.JvmThreadMetrics;
+import io.micrometer.core.instrument.binder.system.ProcessorMetrics;
+import io.micrometer.core.instrument.binder.system.UptimeMetrics;
+import io.micrometer.prometheus.PrometheusConfig;
+import io.micrometer.prometheus.PrometheusMeterRegistry;
+import io.prometheus.client.exporter.common.TextFormat;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.io.File;
+
+
+@RestController
+@RequestMapping("/actuator/prometheus")
+public class PrometheusController { // TODO: remove this with migration to Spring Boot 2
+
+    private final PiWikService piWikService;
+
+    @Autowired
+    public PrometheusController(PiWikService piWikService) {
+        this.piWikService = piWikService;
+    }
+
+    @RequestMapping(method = RequestMethod.GET, path = "", produces = MediaType.TEXT_PLAIN_VALUE)
+    public String getPiwikMetrics() {
+        PrometheusMeterRegistry registry = new PrometheusMeterRegistry(PrometheusConfig.DEFAULT);
+        registry.counter("total").increment(piWikService.getTotal());
+        registry.counter("validated").increment(piWikService.getValidated(true));
+
+        return registry.scrape(TextFormat.CONTENT_TYPE_004);
+    }
+
+    @RequestMapping(method = RequestMethod.GET, path = "metrics", produces = MediaType.TEXT_PLAIN_VALUE)
+    public String getMetrics() {
+        PrometheusMeterRegistry registry = new PrometheusMeterRegistry(PrometheusConfig.DEFAULT);
+        new JvmThreadMetrics().bindTo(registry);
+        new JvmGcMetrics().bindTo(registry);
+        new JvmMemoryMetrics().bindTo(registry);
+        new DiskSpaceMetrics(new File("/")).bindTo(registry);
+        new ProcessorMetrics().bindTo(registry); // metrics related to the CPU stats
+        new UptimeMetrics().bindTo(registry);
+
+        return registry.scrape(TextFormat.CONTENT_TYPE_004);
+    }
+
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/customHystrixCommands/AggregatorsHystrixCommand.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/customHystrixCommands/AggregatorsHystrixCommand.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/customHystrixCommands/AggregatorsHystrixCommand.java	(revision 61527)
@@ -0,0 +1,48 @@
+package eu.dnetlib.repo.manager.service.customHystrixCommands;
+
+import com.netflix.hystrix.HystrixCommand;
+import com.netflix.hystrix.HystrixCommandGroupKey;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.client.RestTemplate;
+import org.springframework.web.util.UriComponents;
+import org.springframework.web.util.UriComponentsBuilder;
+
+import java.util.Map;
+
+public class AggregatorsHystrixCommand extends HystrixCommand<String> {
+
+    RestTemplate restTemplate;
+    String baseAddress;
+
+    public AggregatorsHystrixCommand(String baseAddress, RestTemplate restTemplate) {
+        super(HystrixCommandGroupKey.Factory.asKey("StatisticsGroup"));
+        this.baseAddress = baseAddress;
+        this.restTemplate = restTemplate;
+    }
+
+    @Override
+    protected String run() throws Exception {
+        String url = baseAddress + "/resources" +
+                "?query= " +
+                " oaftype exact datasource and " +
+                " ( datasourcetypename exact Institutional Repository Aggregator " +
+                "     or datasourcetypename exact Publication Repository Aggregator )";
+
+        UriComponents uriComponents = UriComponentsBuilder
+                .fromHttpUrl(url)
+                .queryParam("page", 0)
+                .queryParam("size", 0)
+                .queryParam("format", "json")
+                .build().encode();
+
+        ResponseEntity rs = restTemplate.exchange(uriComponents.toUri(), HttpMethod.GET, null, Map.class);
+        Map metadata = (Map) ((Map) rs.getBody()).get("meta");
+        return String.valueOf(metadata.get("total"));
+    }
+
+    @Override
+    protected String getFallback() {
+        return null;
+    }
+}
\ No newline at end of file
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/controllers/UserController.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/controllers/UserController.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/controllers/UserController.java	(revision 61527)
@@ -0,0 +1,25 @@
+package eu.dnetlib.repo.manager.controllers;
+
+import eu.dnetlib.repo.manager.service.UserServiceImpl;
+import io.swagger.annotations.Api;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping(value = "/user")
+@Api(description = "User API",  tags = {"user"})
+public class UserController {
+
+    @Autowired
+    private UserServiceImpl userService;
+
+    @RequestMapping(value = "/login" , method = RequestMethod.GET)
+    @PreAuthorize("hasAuthority('REGISTERED_USER')")
+    public ResponseEntity<Object> login() {
+        return userService.login();
+    }
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/customHystrixCommands/LastYearUsageStatsHystrixCommand.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/customHystrixCommands/LastYearUsageStatsHystrixCommand.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/customHystrixCommands/LastYearUsageStatsHystrixCommand.java	(revision 61527)
@@ -0,0 +1,52 @@
+package eu.dnetlib.repo.manager.service.customHystrixCommands;
+
+import com.netflix.hystrix.HystrixCommand;
+import com.netflix.hystrix.HystrixCommandGroupKey;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.client.RestTemplate;
+import org.springframework.web.util.UriComponents;
+import org.springframework.web.util.UriComponentsBuilder;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class LastYearUsageStatsHystrixCommand extends HystrixCommand<Map> {
+
+    RestTemplate restTemplate;
+    String usagestatsBaseAddress;
+
+    public LastYearUsageStatsHystrixCommand(String usagestatsBaseAddress,RestTemplate restTemplate) {
+        super(HystrixCommandGroupKey.Factory.asKey("StatisticsGroup"));
+        this.usagestatsBaseAddress = usagestatsBaseAddress;
+        this.restTemplate = restTemplate;
+    }
+
+    @Override
+    protected Map run() throws Exception {
+        UriComponents uriComponents = UriComponentsBuilder
+                .fromHttpUrl(usagestatsBaseAddress + "/totals")
+                .build().encode();
+
+        ResponseEntity rs = restTemplate.exchange(uriComponents.toUri(), HttpMethod.GET,null,Map.class);
+
+        List yearly_stats = (List) ((Map)rs.getBody()).get("yearly_stats");
+        Map lastYear = (Map) yearly_stats.get(yearly_stats.size()-1);
+        Integer downloads = (Integer) lastYear.get("downloads");
+        Integer views = (Integer) lastYear.get("views");
+        Integer year = (Integer) lastYear.get("year");
+
+        Map<String,Object> usagestats = new HashMap<>();
+        usagestats.put("number",String.valueOf(downloads+views));
+        usagestats.put("year",year);
+
+        return usagestats;
+    }
+
+    @Override
+    protected Map getFallback() {
+        return null;
+    }
+
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/controllers/UserRoleController.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/controllers/UserRoleController.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/controllers/UserRoleController.java	(revision 61527)
@@ -0,0 +1,110 @@
+package eu.dnetlib.repo.manager.controllers;
+
+import eu.dnetlib.repo.manager.domain.dto.Role;
+import eu.dnetlib.repo.manager.service.aai.registry.AaiRegistryService;
+import eu.dnetlib.repo.manager.service.security.AuthoritiesUpdater;
+import eu.dnetlib.repo.manager.service.security.AuthorizationService;
+import eu.dnetlib.repo.manager.service.security.RoleMappingService;
+import eu.dnetlib.repo.manager.utils.JsonUtils;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.util.Collection;
+
+@RestController
+@RequestMapping(value = "/role-management")
+@Api(description = "Role Management", value = "role-management")
+public class UserRoleController {
+
+    private final AaiRegistryService aaiRegistryService;
+    private final AuthoritiesUpdater authoritiesUpdater;
+    private final RoleMappingService roleMappingService;
+    private final AuthorizationService authorizationService;
+
+    @Autowired
+    UserRoleController(AaiRegistryService aaiRegistryService,
+                       AuthoritiesUpdater authoritiesUpdater,
+                       RoleMappingService roleMappingService,
+                       AuthorizationService authorizationService) {
+        this.aaiRegistryService = aaiRegistryService;
+        this.authoritiesUpdater = authoritiesUpdater;
+        this.roleMappingService = roleMappingService;
+        this.authorizationService = authorizationService;
+    }
+
+    /**
+     * Get the role with the given id.
+     **/
+    @RequestMapping(method = RequestMethod.GET, path = "/role/{id}")
+//    @PreAuthorize("hasAnyAuthority('REGISTERED_USER', 'SUPER_ADMINISTRATOR', 'CONTENT_PROVIDER_DASHBOARD_ADMINISTRATOR')")
+    public Response getRole(@RequestParam(value = "type", defaultValue = "datasource") String type, @PathVariable("id") String id) {
+        int roleId = aaiRegistryService.getCouId(type, id);
+        return Response.status(HttpStatus.OK.value()).entity(JsonUtils.createResponse("Role id is: " + roleId).toString()).type(MediaType.APPLICATION_JSON).build();
+    }
+
+    /**
+     * Create a new role with the given name and description.
+     **/
+    @RequestMapping(method = RequestMethod.POST, path = "/role")
+    @PreAuthorize("hasAnyAuthority('SUPER_ADMINISTRATOR')")
+    public Response createRole(@RequestBody Role role) {
+        aaiRegistryService.createRole(role);
+        return Response.status(HttpStatus.OK.value()).entity(JsonUtils.createResponse("Role has been created").toString()).type(MediaType.APPLICATION_JSON).build();
+    }
+
+    /**
+     * Subscribe to a type(Community, etc.) with id(ee, egi, etc.)
+     */
+    @ApiOperation(value = "subscribe")
+    @RequestMapping(method = RequestMethod.POST, path = "/subscribe/{type}/{id}")
+    @PreAuthorize("hasAnyAuthority('SUPER_ADMINISTRATOR', 'CONTENT_PROVIDER_DASHBOARD_ADMINISTRATOR')")
+    public Response subscribe(@PathVariable("type") String type, @PathVariable("id") String id) {
+        Integer coPersonId = aaiRegistryService.getCoPersonIdByIdentifier();
+        if (coPersonId == null) {
+            coPersonId = aaiRegistryService.getCoPersonIdByEmail();
+        }
+        Integer couId = aaiRegistryService.getCouId(type, id);
+        if (couId != null) {
+            Integer role = aaiRegistryService.getRoleId(coPersonId, couId);
+            aaiRegistryService.assignMemberRole(coPersonId, couId, role);
+
+            // Add role to current authorities
+            authoritiesUpdater.addRole(roleMappingService.convertRepoIdToAuthority(id));
+
+            return Response.status(HttpStatus.OK.value()).entity(JsonUtils.createResponse("Role has been assigned").toString()).type(MediaType.APPLICATION_JSON).build();
+        } else {
+            return Response.status(HttpStatus.NOT_FOUND.value()).entity(JsonUtils.createResponse("Role has not been found").toString()).type(MediaType.APPLICATION_JSON).build();
+        }
+    }
+    /////////////////////////////////////////////////////////////////////////////////////////////
+    /////////////////////////////////////////////////////////////////////////////////////////////
+
+    @RequestMapping(method = RequestMethod.GET, path = "/users/couid/{id}")
+    @PreAuthorize("hasAnyAuthority('SUPER_ADMINISTRATOR', 'CONTENT_PROVIDER_DASHBOARD_ADMINISTRATOR')")
+    public ResponseEntity<String> getUsersByCouId(@PathVariable("id") Integer id) {
+//        calls.getUserByCoId()
+        return ResponseEntity.ok(aaiRegistryService.getUsersByCouId(id).toString());
+    }
+
+
+    @RequestMapping(method = RequestMethod.GET, path = "/users/{email}/roles")
+    @PreAuthorize("hasAnyAuthority('SUPER_ADMINISTRATOR', 'CONTENT_PROVIDER_DASHBOARD_ADMINISTRATOR') or hasAuthority('REGISTERED_USER') and authentication.userInfo.email==#email")
+    public ResponseEntity<Collection<String>> getRolesByEmail(@PathVariable("email") String email) {
+        return ResponseEntity.ok(authorizationService.getUserRoles(email));
+    }
+
+
+    @RequestMapping(method = RequestMethod.GET, path = "/user/roles/my")
+    @PreAuthorize("hasAuthority('REGISTERED_USER')")
+    public ResponseEntity<Collection<String>> getRoleNames() {
+        return ResponseEntity.ok(authorizationService.getUserRoles());
+    }
+
+}
\ No newline at end of file
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/customHystrixCommands/JournalHystrixCommand.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/customHystrixCommands/JournalHystrixCommand.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/customHystrixCommands/JournalHystrixCommand.java	(revision 61527)
@@ -0,0 +1,48 @@
+package eu.dnetlib.repo.manager.service.customHystrixCommands;
+
+import com.netflix.hystrix.HystrixCommand;
+import com.netflix.hystrix.HystrixCommandGroupKey;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.client.RestTemplate;
+import org.springframework.web.util.UriComponents;
+import org.springframework.web.util.UriComponentsBuilder;
+
+import java.util.Map;
+
+public class JournalHystrixCommand extends HystrixCommand<String> {
+
+    RestTemplate restTemplate;
+    private String baseAddress;
+
+    public JournalHystrixCommand(String baseAddress, RestTemplate restTemplate) {
+        super(HystrixCommandGroupKey.Factory.asKey("StatisticsGroup"));
+        this.baseAddress = baseAddress;
+        this.restTemplate = restTemplate;
+    }
+
+    @Override
+    protected String run() throws Exception {
+        String url = baseAddress+"/resources"+
+                "?query= " +
+                " oaftype exact datasource and " +
+                " datasourcetypename exact Journal";
+
+        UriComponents uriComponents = UriComponentsBuilder
+                .fromHttpUrl(url)
+                .queryParam("page", 0)
+                .queryParam("size", 0)
+                .queryParam("format", "json")
+                .build().encode();
+
+        ResponseEntity rs = restTemplate.exchange(uriComponents.toUri(), HttpMethod.GET, null, Map.class);
+        Map metadata = (Map) ((Map) rs.getBody()).get("meta");
+        return String.valueOf(metadata.get("total"));
+    }
+
+    @Override
+    protected String getFallback() {
+        return null;
+    }
+
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/controllers/BrokerController.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/controllers/BrokerController.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/controllers/BrokerController.java	(revision 61527)
@@ -0,0 +1,126 @@
+package eu.dnetlib.repo.manager.controllers;
+
+import eu.dnetlib.repo.manager.domain.BrokerException;
+import eu.dnetlib.repo.manager.domain.Term;
+import eu.dnetlib.repo.manager.domain.broker.*;
+import eu.dnetlib.repo.manager.service.BrokerServiceImpl;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiParam;
+import org.json.JSONException;
+import org.mitre.openid.connect.model.OIDCAuthenticationToken;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.web.bind.annotation.*;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+@RestController
+@RequestMapping(value = "/broker")
+@Api(description = "Broker API",  tags = {"broker"})
+public class BrokerController{
+
+    @Autowired
+    private BrokerServiceImpl brokerService;
+
+    @RequestMapping(value = "/getDatasourcesOfUser" , method = RequestMethod.GET,
+            produces = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    @PreAuthorize("hasAuthority('REGISTERED_USER')")
+    public DatasourcesBroker getDatasourcesOfUser(
+                                           @RequestParam("includeShared")
+                                           @ApiParam(value = "Include shared datasources", required = true , defaultValue = "false") String includeShared,
+                                           @RequestParam("includeByOthers")
+                                           @ApiParam(value = "Include datasources of other", required = true,defaultValue = "false") String includeByOthers) throws JSONException {
+        return brokerService.getDatasourcesOfUser(((OIDCAuthenticationToken) SecurityContextHolder.getContext().getAuthentication()).getUserInfo().getEmail(), includeShared, includeByOthers);
+    }
+
+    @RequestMapping(value = "/getTopicsForDatasource/{datasourceName:.+}" ,
+            method = RequestMethod.GET,
+            produces = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    public List<BrowseEntry> getTopicsForDatasource(@PathVariable("datasourceName")  String datasourceName) throws BrokerException{
+        return brokerService.getTopicsForDatasource(datasourceName);
+    }
+
+    @RequestMapping(value = "/advancedShowEvents/{page}/{size}" ,
+            method = RequestMethod.POST,
+            produces = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    @PreAuthorize("hasAuthority('REGISTERED_USER')")
+    public EventsPage advancedShowEvents(@PathVariable("page") String page,
+                                  @PathVariable("size") String size,
+                                  @RequestBody AdvQueryObject advQueryObject) throws BrokerException, JSONException ,IOException{
+        return brokerService.advancedShowEvents(page, size, advQueryObject);
+    }
+
+    @RequestMapping(value = "/showEvents/{datasourceName:.+}/{topic}/{page}" ,
+            method = RequestMethod.GET,
+            produces = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    @PreAuthorize("hasAuthority('REGISTERED_USER')")
+    public EventsPage showEvents(@RequestParam("datasourceName") String datasourceName,
+                          @RequestParam("topic") String topic,
+                          @RequestParam("page") String page,
+                          @RequestParam("size") String size) throws BrokerException, JSONException{
+        return brokerService.showEvents(datasourceName, topic, page, size);
+    }
+
+    @RequestMapping(value = "/getSimpleSubscriptionsOfUser" ,
+            method = RequestMethod.GET,
+            produces = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    @PreAuthorize("hasAuthority('REGISTERED_USER')")
+    public Map<String, List<SimpleSubscriptionDesc>> getSimpleSubscriptionsOfUser() throws BrokerException{
+        return brokerService.getSimpleSubscriptionsOfUser(((OIDCAuthenticationToken) SecurityContextHolder.getContext().getAuthentication()).getUserInfo().getEmail());
+    }
+
+    @RequestMapping(value = "/subscribe" , method = RequestMethod.POST,
+            consumes = MediaType.APPLICATION_JSON_VALUE,
+            produces = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    @PreAuthorize("hasAuthority('REGISTERED_USER') ")
+    public Subscription subscribe(@RequestBody OpenaireSubscription obj) throws BrokerException{
+        return brokerService.subscribe(obj);
+    }
+
+    @RequestMapping(value = "/unsubscribe/{subscriptionId}" , method = RequestMethod.POST,
+            consumes = MediaType.APPLICATION_JSON_VALUE,
+            produces = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    @PreAuthorize("hasAuthority('REGISTERED_USER')")
+    public ResponseEntity<Object> unsubscribe(@PathVariable("subscriptionId") String subscriptionId) throws BrokerException{
+        return brokerService.unsubscribe(subscriptionId);
+    }
+
+    @RequestMapping(value = "/getSubscription/{subscriptionId}" , method = RequestMethod.GET,
+            produces = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    @PreAuthorize("hasAuthority('REGISTERED_USER')")
+    public Subscription getSubscription(@PathVariable("subscriptionId") String subscriptionId) throws BrokerException{
+        return brokerService.getSubscription(subscriptionId);
+    }
+
+
+    @RequestMapping(value = "/getDnetTopics" , method = RequestMethod.GET,
+            produces = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    public Map<String, Term> getDnetTopics() throws BrokerException{
+        return brokerService.getDnetTopics();
+    }
+
+    @RequestMapping(value = "/getNotificationsBySubscriptionId/{subscriptionId}/{page}/{size}" , method = RequestMethod.GET
+            ,produces = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    @PreAuthorize("hasAuthority('REGISTERED_USER')")
+    public EventsPage getNotificationsBySubscriptionId(@PathVariable("subscriptionId") String subscriptionId,
+                                                @PathVariable("page") String page,
+                                                @PathVariable("size") String size) throws BrokerException{
+        return brokerService.getNotificationsBySubscriptionId(subscriptionId, page, size);
+    }
+
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/customHystrixCommands/LiteratureHystrixCommand.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/customHystrixCommands/LiteratureHystrixCommand.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/customHystrixCommands/LiteratureHystrixCommand.java	(revision 61527)
@@ -0,0 +1,49 @@
+package eu.dnetlib.repo.manager.service.customHystrixCommands;
+
+import com.netflix.hystrix.HystrixCommand;
+import com.netflix.hystrix.HystrixCommandGroupKey;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.client.RestTemplate;
+import org.springframework.web.util.UriComponents;
+import org.springframework.web.util.UriComponentsBuilder;
+
+import java.util.Map;
+
+public class LiteratureHystrixCommand extends HystrixCommand<String> {
+
+    RestTemplate restTemplate;
+    private String baseAddress;
+
+    public LiteratureHystrixCommand(String baseAddress , RestTemplate restTemplate) {
+        super(HystrixCommandGroupKey.Factory.asKey("StatisticsGroup"));
+        this.baseAddress = baseAddress;
+        this.restTemplate = restTemplate;
+    }
+
+    @Override
+    protected String run() throws Exception {
+        String url = baseAddress+"/resources"+
+                "?query= " +
+                " oaftype exact datasource and " +
+                " ( datasourcetypename exact Institutional Repository  " +
+                "     or datasourcetypename exact Publication Repository )";
+
+        UriComponents uriComponents = UriComponentsBuilder
+                .fromHttpUrl(url)
+                .queryParam("page", 0)
+                .queryParam("size", 0)
+                .queryParam("format", "json")
+                .build().encode();
+
+        ResponseEntity rs = restTemplate.exchange(uriComponents.toUri(), HttpMethod.GET, null, Map.class);
+        Map metadata = (Map) ((Map) rs.getBody()).get("meta");
+        return String.valueOf(metadata.get("total"));
+    }
+
+    @Override
+    protected String getFallback() {
+        return null;
+    }
+
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/controllers/ValidatorController.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/controllers/ValidatorController.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/controllers/ValidatorController.java	(revision 61527)
@@ -0,0 +1,128 @@
+package eu.dnetlib.repo.manager.controllers;
+
+import eu.dnetlib.api.functionality.ValidatorServiceException;
+import eu.dnetlib.domain.functionality.validator.JobForValidation;
+import eu.dnetlib.domain.functionality.validator.RuleSet;
+import eu.dnetlib.domain.functionality.validator.StoredJob;
+import eu.dnetlib.repo.manager.domain.InterfaceInformation;
+import eu.dnetlib.repo.manager.domain.ValidationServiceException;
+import eu.dnetlib.repo.manager.exception.ResourceNotFoundException;
+import eu.dnetlib.repo.manager.service.EmailUtils;
+import eu.dnetlib.repo.manager.service.ValidatorServiceImpl;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiParam;
+import org.json.JSONException;
+import org.mitre.openid.connect.model.OIDCAuthenticationToken;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+
+@RestController
+@RequestMapping(value = "/validator")
+@Api(description = "Validator API",  tags = {"validator"})
+public class ValidatorController {
+
+    @Autowired
+    private ValidatorServiceImpl validatorService;
+
+    @Autowired
+    private EmailUtils emailUtils;
+
+    @RequestMapping(value = "/submitJobForValidation",method = RequestMethod.POST,
+            consumes = MediaType.APPLICATION_JSON_VALUE,
+            produces = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    @PreAuthorize("hasAuthority('REGISTERED_USER') and #jobForValidation.userEmail == authentication.userInfo.email")
+    public JobForValidation submitJobForValidation(@RequestBody JobForValidation jobForValidation) throws ValidatorServiceException {
+        return validatorService.submitJobForValidation(jobForValidation);
+    }
+
+    @RequestMapping(value = "/reSubmitJobForValidation/{jobId}",method = RequestMethod.POST,
+            consumes = MediaType.APPLICATION_JSON_VALUE,
+            produces = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    @PreAuthorize("hasAuthority('REGISTERED_USER')")
+    public ResponseEntity<Object> reSubmitJobForValidation(@PathVariable("jobId") String jobId) throws JSONException, ValidatorServiceException {
+        return validatorService.reSubmitJobForValidation(((OIDCAuthenticationToken) SecurityContextHolder.getContext().getAuthentication()).getUserInfo().getEmail(), jobId);
+    }
+
+    @RequestMapping(value = "/getRuleSets/{mode}" , method = RequestMethod.GET,produces = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    public List<RuleSet> getRuleSets(@PathVariable("mode") String mode) {
+        return validatorService.getRuleSets(mode);
+    }
+
+    @RequestMapping(value = "/getSetsOfRepository" , method = RequestMethod.GET,produces = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    public List<String> getSetsOfRepository(@RequestParam(value = "url", required = true) String url) {
+        return validatorService.getSetsOfRepository(url);
+    }
+
+    @RequestMapping(value = "/identifyRepository" , method = RequestMethod.GET,produces = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    public boolean identifyRepo(@RequestParam(value = "url", required = true) String url) {
+        return validatorService.identifyRepo(url);
+    }
+
+    @RequestMapping(value = "/getRuleSet/{acronym}" , method = RequestMethod.GET,produces = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    public RuleSet getRuleSet(@PathVariable("acronym") String acronym) {
+        return validatorService.getRuleSet(acronym);
+    }
+
+    @RequestMapping(value = "/getStoredJobsNew" , method = RequestMethod.GET,produces = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    @PreAuthorize("hasAuthority('REGISTERED_USER')")
+    public List<StoredJob> getStoredJobsNew(@RequestParam(value = "jobType", required = false)
+                                            @ApiParam(value = "Equals to filter job type on validation history page") String jobType,
+                                            @RequestParam("offset") @ApiParam(value = "Page number", required = true) String offset,
+                                            @RequestParam(value = "limit", required = false,defaultValue = "10") @ApiParam(value = "Null value") String limit,
+                                            @RequestParam(value = "dateFrom", required = false) @ApiParam(value = "Null value") String dateFrom,
+                                            @RequestParam(value = "dateTo", required = false) @ApiParam(value = "Null value") String dateTo,
+                                            @RequestParam("validationStatus") @ApiParam(value = "Equals to filter validation jobs", required = true) String validationStatus
+                                            ) throws ValidatorServiceException {
+        return validatorService.getStoredJobsNew(((OIDCAuthenticationToken) SecurityContextHolder.getContext().getAuthentication()).getUserInfo().getEmail(), jobType, offset, limit, dateFrom, dateTo, validationStatus);
+    }
+
+    @RequestMapping(value = "/getStoredJobsTotalNumberNew" , method = RequestMethod.GET,produces = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    public int getStoredJobsTotalNumberNew(String user, String jobType, String validationStatus) throws  ValidatorServiceException {
+        return validatorService.getStoredJobsTotalNumberNew(user, jobType, validationStatus);
+    }
+
+    @RequestMapping(value = "/getInterfaceInformation" , method = RequestMethod.GET,produces = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    public InterfaceInformation getInterfaceInformation(@RequestParam(value = "baseUrl") String baseUrl) throws ValidationServiceException {
+        return validatorService.getInterfaceInformation(baseUrl);
+    }
+
+    @RequestMapping(value = "/validationSummary/{repoId}" , method = RequestMethod.GET,produces = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    public List<StoredJob> getInterfaceInformation(@PathVariable(value = "repoId") String repoId, @RequestParam(name = "size", defaultValue = "20") int size ) throws ValidatorServiceException, ResourceNotFoundException, JSONException {
+        return validatorService.getJobsSummary(repoId,size);
+    }
+
+
+    @RequestMapping(value = "/complete" , method = RequestMethod.POST,  produces = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    public void validationCompleted(
+        @RequestParam(value = "interfaceId") String interfaceId,
+        @RequestParam(value = "repoId") String repoId,
+        @RequestParam(value = "jobId") String jobId,
+        @RequestParam(value = "issuerEmail") String issuerEmail,
+        @RequestParam(value = "isUpdate") boolean isUpdate,
+        @RequestParam(value = "isSuccess") boolean isSuccess,
+        @RequestParam(value = "scoreUsage") int scoreUsage,
+        @RequestParam(value = "scoreContent") int scoreContent) throws Exception {
+
+        emailUtils.sendUponJobCompletion(repoId,interfaceId,scoreUsage,scoreContent,isSuccess,isUpdate,issuerEmail, jobId);
+    }
+
+
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/SushiliteService.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/SushiliteService.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/SushiliteService.java	(revision 61527)
@@ -0,0 +1,23 @@
+package eu.dnetlib.repo.manager.service;
+
+import eu.dnetlib.usagestats.sushilite.domain.ReportResponseWrapper;
+import org.json.JSONException;
+
+
+public interface SushiliteService {
+
+
+    ReportResponseWrapper getReportResults(String page,
+                                           String pageSize,
+                                           String Report,
+                                           String Release,
+                                           String RequestorID,
+                                           String BeginDate,
+                                           String EndDate,
+                                           String RepositoryIdentifier,
+                                           String ItemIdentifier,
+                                           String ItemDataType,
+                                           String Granularity,
+                                           String Pretty) throws JSONException;
+
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/controllers/DashboardController.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/controllers/DashboardController.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/controllers/DashboardController.java	(revision 61527)
@@ -0,0 +1,94 @@
+package eu.dnetlib.repo.manager.controllers;
+
+import eu.dnetlib.repo.manager.domain.*;
+import eu.dnetlib.repo.manager.service.BrokerService;
+import eu.dnetlib.repo.manager.service.DashboardService;
+import eu.dnetlib.repo.manager.service.PiWikService;
+import eu.dnetlib.repo.manager.service.RepositoryService;
+import io.swagger.annotations.Api;
+import org.json.JSONException;
+import org.mitre.openid.connect.model.OIDCAuthenticationToken;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@RestController
+@RequestMapping(value = "/dashboard")
+@Api(description = "Dashboard API",  tags = {"dashboard"})
+public class DashboardController {
+
+    @Autowired
+    private DashboardService dashboardService;
+
+    @Autowired
+    private RepositoryService repositoryService;
+
+    @Autowired
+    private BrokerService brokerService;
+
+    @Autowired
+    private PiWikService piWikService;
+
+    @RequestMapping(value = "/getRepositoriesSummary/{page}/{size}" , method = RequestMethod.GET,
+            produces = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    @PreAuthorize("hasAuthority('REGISTERED_USER')")
+    public List<RepositorySummaryInfo> getRepositoriesSummaryInfo(
+                                                                  @PathVariable("page") String page,
+                                                                  @PathVariable("size") String size) throws JSONException {
+        return dashboardService.getRepositoriesSummaryInfo(((OIDCAuthenticationToken) SecurityContextHolder.getContext().getAuthentication()).getUserInfo().getEmail(), page, size);
+    }
+
+    @RequestMapping(value = "/collectionMonitorSummary/{repoId}" , method = RequestMethod.GET,
+            produces = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    @PreAuthorize("hasAuthority('REGISTERED_USER')")
+    public CollectionMonitorSummary getCollectionMonitorSummary(
+            @PathVariable("repoId") String repoId,
+            @RequestParam(name = "size", required = false, defaultValue = "20") int size) throws JSONException {
+
+        List<AggregationDetails> aggregationDetails = repositoryService.getRepositoryAggregations(repoId,0,size);
+        CollectionMonitorSummary collectionMonitorSummary = new CollectionMonitorSummary();
+        collectionMonitorSummary.setAggregationDetails(aggregationDetails);
+        size=0;
+        do {
+            aggregationDetails = repositoryService.getRepositoryAggregations(repoId,size,size+50);
+            for(AggregationDetails aggregationDetail : aggregationDetails){
+                if(aggregationDetail.getIndexedVersion()){
+                    collectionMonitorSummary.setLastIndexedVersion(aggregationDetail);
+                    break;
+                }
+            }
+            size+=30;
+        }while (aggregationDetails.size() != 0 && collectionMonitorSummary.getLastIndexedVersion()==null);
+
+        return collectionMonitorSummary;
+    }
+
+    @RequestMapping(value = "/usageSummary/{repoId}" , method = RequestMethod.GET,
+            produces = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    @PreAuthorize("hasAuthority('REGISTERED_USER')")
+    public UsageSummary getUsageSummary(
+            @PathVariable("repoId") String repoId
+    ) throws RepositoryServiceException {
+        return new UsageSummary(repositoryService.getMetricsInfoForRepository(repoId), piWikService.getPiwikSiteForRepo(repoId));
+    }
+
+    @RequestMapping(value = "/brokerSummary/{ds_name}" , method = RequestMethod.GET,
+            produces = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    @PreAuthorize("hasAuthority('REGISTERED_USER')")
+    public BrokerSummary getBrokerSummary(
+            @PathVariable("ds_name") String datasourceName) throws BrokerException {
+        return new BrokerSummary(brokerService.getSimpleSubscriptionsOfUser( ((OIDCAuthenticationToken) SecurityContextHolder.getContext().getAuthentication()).getUserInfo().getEmail()), brokerService.getTopicsForDatasource(datasourceName));
+    }
+
+
+
+
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/config/OpenAIREAuthoritiesMapper.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/config/OpenAIREAuthoritiesMapper.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/config/OpenAIREAuthoritiesMapper.java	(revision 61527)
@@ -0,0 +1,48 @@
+package eu.dnetlib.repo.manager.config;
+
+import com.google.gson.JsonArray;
+import com.nimbusds.jwt.JWT;
+import eu.dnetlib.repo.manager.service.security.AuthoritiesMapper;
+import org.apache.log4j.Logger;
+import org.mitre.openid.connect.client.OIDCAuthoritiesMapper;
+import org.mitre.openid.connect.model.UserInfo;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.stereotype.Component;
+
+import java.util.*;
+
+@ComponentScan
+@Component
+public class OpenAIREAuthoritiesMapper implements OIDCAuthoritiesMapper {
+
+    private static final Logger logger = Logger.getLogger(OpenAIREAuthoritiesMapper.class);
+
+    @Value("${services.repo-manager.adminEmail}")
+    String adminEmail;
+
+    @Override
+    public Collection<? extends GrantedAuthority> mapAuthorities(JWT jwtToken, UserInfo userInfo) {
+        JsonArray entitlements = null;
+        Set<GrantedAuthority> authorities = new HashSet<>();
+        if (userInfo != null && userInfo.getSource() != null) {
+            if (userInfo.getSource().getAsJsonArray("edu_person_entitlements") != null) {
+                entitlements = userInfo.getSource().getAsJsonArray("edu_person_entitlements");
+            } else if (userInfo.getSource().getAsJsonArray("eduperson_entitlement") != null) {
+                entitlements = userInfo.getSource().getAsJsonArray("eduperson_entitlement");
+            }
+            logger.debug("user info: " + userInfo + "\nentitlements: " + entitlements);
+
+            // FIXME: delete this if statement when super administrators are set
+            if (userInfo.getEmail() != null && userInfo.getEmail().equals(adminEmail)) {
+                authorities.add(new SimpleGrantedAuthority("SUPER_ADMINISTRATOR"));
+            }
+
+            authorities.addAll(AuthoritiesMapper.map(entitlements));
+        }
+        return authorities;
+    }
+}
+
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/security/RoleMappingService.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/security/RoleMappingService.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/security/RoleMappingService.java	(revision 61527)
@@ -0,0 +1,74 @@
+package eu.dnetlib.repo.manager.service.security;
+
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+
+import java.util.Collection;
+
+public interface RoleMappingService {
+
+    /**
+     * @param fullName
+     * @param prefix
+     * @return
+     */
+    String getRepoNameWithoutType(String fullName, String prefix);
+
+    /**
+     * @param roleId Role Id
+     * @return Converts {@param roleId} to a repo Id.
+     */
+    String getRepoIdByRoleId(String roleId);
+
+    /**
+     *
+     * @param roleIds Collection of roles
+     * @return Converts {@param roleIds} to a repo Ids.
+     */
+    Collection<String> getRepoIdsByRoleIds(Collection<String> roleIds);
+
+    /**
+     * @param repoId Repository Id
+     * @return Converts {@param repoId} to a role Id.
+     */
+    String getRoleIdByRepoId(String repoId);
+
+    /**
+     * @param repoIds Collection of Repository Ids
+     * @return Converts {@param repoIds} to role Ids.
+     */
+    Collection<String> getRoleIdsByRepoIds(Collection<String> repoIds);
+
+    /**
+     * @param authorityId Authority Id
+     * @return Converts {@param authorityId} to repo Id.
+     */
+    String convertAuthorityIdToRepoId(String authorityId);
+
+    /**
+     * @param authority Granted authority
+     * @return Converts {@param authority} to repo Id.
+     */
+    String convertAuthorityToRepoId(GrantedAuthority authority);
+
+    /**
+     * @param repoId Repository Id
+     * @return
+     */
+    String convertRepoIdToAuthorityId(String repoId);
+
+    /**
+     * @param repoId Repository Id
+     * @return Converts {@param repoId} to {@link String} role id url encoded ($ -> %24)
+     * // TODO: remove role encoding and perform url decoding when mapping authorities. (Must be performed in all OpenAIRE projects because of Redis)
+     */
+    String convertRepoIdToEncodedAuthorityId(String repoId);
+
+    /**
+     * @param repoId Repository Id
+     * @return Converts {@param repoId} to {@link SimpleGrantedAuthority} with the role url encoded ($ -> %24)
+     * // TODO: remove role encoding and perform url decoding when mapping authorities. (Must be performed in all OpenAIRE projects because of Redis)
+     */
+    SimpleGrantedAuthority convertRepoIdToAuthority(String repoId);
+
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/controllers/MonitorController.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/controllers/MonitorController.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/controllers/MonitorController.java	(revision 61527)
@@ -0,0 +1,59 @@
+package eu.dnetlib.repo.manager.controllers;
+
+import eu.dnetlib.api.functionality.ValidatorServiceException;
+import eu.dnetlib.domain.functionality.validator.StoredJob;
+import eu.dnetlib.repo.manager.domain.JobsOfUser;
+import eu.dnetlib.repo.manager.service.MonitorServiceImpl;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiParam;
+import org.apache.log4j.Logger;
+import org.json.JSONException;
+import org.mitre.openid.connect.model.OIDCAuthenticationToken;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@RequestMapping(value = "/monitor")
+@Api(description = "Monitor API",  tags = {"monitor"})
+public class MonitorController {
+
+    private static final Logger LOGGER = Logger
+            .getLogger(MonitorController.class);
+
+    @Autowired
+    private MonitorServiceImpl monitorService;
+
+    @RequestMapping(value = "/getJobsOfUser" , method = RequestMethod.GET,
+            produces = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    @PreAuthorize("hasAuthority('REGISTERED_USER')")
+    public JobsOfUser getJobsOfUser(@RequestParam(value = "jobType", required = false)
+                                    @ApiParam(value = "Equals to filter job type on validation history page") String jobType,
+                                    @RequestParam("offset") @ApiParam(value = "Page number", required = true) String offset,
+                                    @RequestParam(value = "limit", required = false,defaultValue = "10") @ApiParam(value = "Null value") String limit,
+                                    @RequestParam(value = "dateFrom", required = false) @ApiParam(value = "Null value") String dateFrom,
+                                    @RequestParam(value = "dateTo", required = false) @ApiParam(value = "Null value") String dateTo,
+                                    @RequestParam("validationStatus") @ApiParam(value = "Equals to filter validation jobs", required = false) String validationStatus,
+                                    @RequestParam("includeJobsTotal") @ApiParam(value = "Always true", required = true) String includeJobsTotal) throws JSONException, ValidatorServiceException {
+        return monitorService.getJobsOfUser(((OIDCAuthenticationToken) SecurityContextHolder.getContext().getAuthentication()).getUserInfo().getEmail(), jobType, offset, limit, dateFrom, dateTo, validationStatus, includeJobsTotal);
+    }
+
+    @RequestMapping(value = "/getJobsOfUserPerValidationStatus" , method = RequestMethod.GET,produces = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    @PreAuthorize("hasAuthority('REGISTERED_USER')")
+    public int getJobsOfUserPerValidationStatus(@RequestBody String jobType,
+                                                @RequestBody String validationStatus) throws JSONException {
+        return monitorService.getJobsOfUserPerValidationStatus(((OIDCAuthenticationToken) SecurityContextHolder.getContext().getAuthentication()).getUserInfo().getEmail(), jobType, validationStatus);
+    }
+
+    @RequestMapping(value = "/getJobSummary" , method = RequestMethod.GET,produces = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    public StoredJob getJobSummary(@RequestParam String jobId,
+                                   @RequestParam String groupBy) throws JSONException {
+        return monitorService.getJobSummary(jobId, groupBy);
+    }
+
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/security/AuthoritiesUpdater.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/security/AuthoritiesUpdater.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/security/AuthoritiesUpdater.java	(revision 61527)
@@ -0,0 +1,98 @@
+package eu.dnetlib.repo.manager.service.security;
+
+import org.apache.log4j.Logger;
+import org.mitre.openid.connect.model.OIDCAuthenticationToken;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.context.SecurityContext;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.oauth2.common.exceptions.UnauthorizedClientException;
+import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
+import org.springframework.session.ExpiringSession;
+import org.springframework.session.FindByIndexNameSessionRepository;
+import org.springframework.stereotype.Service;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Map;
+
+
+@Service
+public class AuthoritiesUpdater extends HttpSessionSecurityContextRepository {
+
+    private static final Logger logger = Logger.getLogger(AuthoritiesUpdater.class);
+
+    @Autowired
+    FindByIndexNameSessionRepository sessions;
+
+    public void update(String email, Collection<? extends GrantedAuthority> authorities) {
+        if (sessions != null) {
+            Map<String, ExpiringSession> map = sessions.
+                    findByIndexNameAndIndexValue(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, email);
+            if (map != null) {
+                logger.debug(map.values().toArray().length);
+                for (ExpiringSession session : map.values()) {
+                    logger.debug(session.getId());
+                    if (!session.isExpired()) {
+                        SecurityContext securityContext = session.getAttribute(SPRING_SECURITY_CONTEXT_KEY);
+                        Authentication authentication = securityContext.getAuthentication();
+                        if (authentication instanceof OIDCAuthenticationToken) {
+                            OIDCAuthenticationToken authOIDC = (OIDCAuthenticationToken) authentication;
+                            logger.debug(authorities);
+                            securityContext.setAuthentication(new OIDCAuthenticationToken(authOIDC.getSub(), authOIDC.getIssuer(),
+                                    authOIDC.getUserInfo(), authorities, authOIDC.getIdToken(),
+                                    authOIDC.getAccessTokenValue(), authOIDC.getRefreshTokenValue()));
+                            logger.debug("Update authorities");
+                            session.setAttribute(SPRING_SECURITY_CONTEXT_KEY, securityContext);
+                            sessions.save(session);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    public void update(String email, Update update) {
+        Collection<? extends GrantedAuthority> authorities = update.authorities(SecurityContextHolder.getContext().getAuthentication().getAuthorities());
+        this.update(email, authorities);
+    }
+
+    public void addRole(String email, GrantedAuthority role) {
+        this.update(email, old -> {
+            HashSet<GrantedAuthority> authorities = new HashSet<>(old);
+            authorities.add(role);
+            return authorities;
+        });
+    }
+
+    public void addRole(GrantedAuthority role) {
+        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
+        if (auth instanceof OIDCAuthenticationToken) {
+            OIDCAuthenticationToken oidcAuth = (OIDCAuthenticationToken) auth;
+            this.addRole(oidcAuth.getUserInfo().getEmail(), role);
+        } else {
+            throw new UnauthorizedClientException("User auth is not instance of OIDCAuthenticationToken");
+        }
+    }
+
+    public void removeRole(String email, GrantedAuthority role) {
+        this.update(email, old -> {
+            HashSet<GrantedAuthority> authorities = new HashSet<>(old);
+            authorities.remove(role);
+            return authorities;
+        });
+    }
+
+    public void removeRole(GrantedAuthority role) {
+        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
+        if (auth instanceof OIDCAuthenticationToken) {
+            OIDCAuthenticationToken oidcAuth = (OIDCAuthenticationToken) auth;
+            this.removeRole(oidcAuth.getUserInfo().getEmail(), role);
+        }
+    }
+
+    public interface Update {
+        Collection<? extends GrantedAuthority> authorities(Collection<? extends GrantedAuthority> old);
+    }
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/config/GlobalSecurityConfiguration.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/config/GlobalSecurityConfiguration.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/config/GlobalSecurityConfiguration.java	(revision 61527)
@@ -0,0 +1,19 @@
+package eu.dnetlib.repo.manager.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
+import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration;
+import org.springframework.web.multipart.commons.CommonsMultipartResolver;
+
+@Configuration
+@EnableGlobalMethodSecurity(prePostEnabled = true,proxyTargetClass = true)
+public class GlobalSecurityConfiguration extends GlobalMethodSecurityConfiguration {
+
+    @Bean
+    public CommonsMultipartResolver multipartResolver(){
+        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
+        multipartResolver.setMaxUploadSize(268435456);
+        return multipartResolver;
+    }
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/controllers/SushiliteController.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/controllers/SushiliteController.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/controllers/SushiliteController.java	(revision 61527)
@@ -0,0 +1,39 @@
+package eu.dnetlib.repo.manager.controllers;
+
+import eu.dnetlib.repo.manager.service.SushiliteServiceImpl;
+import eu.dnetlib.usagestats.sushilite.domain.ReportResponseWrapper;
+import io.swagger.annotations.Api;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@RequestMapping(value = "/sushilite")
+@Api(description = "Sushi-Lite API",  tags = {"sushilite"})
+public class SushiliteController {
+
+
+    @Autowired
+    private SushiliteServiceImpl sushiliteService;
+
+    @RequestMapping(value = "/getReportResults/{page}/{pageSize}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    @PreAuthorize("hasAuthority('REGISTERED_USER')")
+    public ReportResponseWrapper getReportResults(@PathVariable("page") String page,
+                                                  @PathVariable("pageSize") String pageSize,
+                                                  @RequestParam(value = "Report") String Report,
+                                                  @RequestParam(value = "Release",defaultValue="4") String Release,
+                                                  @RequestParam(value = "RequestorID",required=false,defaultValue="anonymous") String RequestorID,
+                                                  @RequestParam(value = "BeginDate",required=false,defaultValue="") String BeginDate,
+                                                  @RequestParam(value = "EndDate",required=false,defaultValue="") String EndDate,
+                                                  @RequestParam(value = "RepositoryIdentifier") String RepositoryIdentifier,
+                                                  @RequestParam(value = "ItemIdentifier",required=false,defaultValue="") String ItemIdentifier,
+                                                  @RequestParam(value = "ItemDataType",required=false,defaultValue="") String ItemDataType,
+                                                  @RequestParam(value = "Granularity") String Granularity,
+                                                  @RequestParam(value = "Pretty",required=false,defaultValue="") String Pretty) {
+
+           return sushiliteService.getReportResults(page, pageSize, Report, Release, RequestorID, BeginDate, EndDate, RepositoryIdentifier, ItemIdentifier, ItemDataType, Granularity, Pretty);
+    }
+
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/controllers/StatsController.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/controllers/StatsController.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/controllers/StatsController.java	(revision 61527)
@@ -0,0 +1,28 @@
+package eu.dnetlib.repo.manager.controllers;
+
+import eu.dnetlib.repo.manager.service.StatsServiceImpl;
+import io.swagger.annotations.Api;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Map;
+
+@RestController
+@RequestMapping(value = "/stats")
+@Api(description = "Stats API",  tags = {"statistics"})
+public class StatsController {
+
+    @Autowired
+    private StatsServiceImpl statsService;
+
+    @RequestMapping(value = "/getStatistics" , method = RequestMethod.GET,
+            produces = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    public Map getStatistics(){
+       return statsService.getStatistics();
+    }
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/config/ActuatorConfig.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/config/ActuatorConfig.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/config/ActuatorConfig.java	(revision 61527)
@@ -0,0 +1,39 @@
+package eu.dnetlib.repo.manager.config;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.actuate.autoconfigure.EndpointAutoConfiguration;
+import org.springframework.boot.actuate.autoconfigure.HealthIndicatorAutoConfiguration;
+import org.springframework.boot.actuate.autoconfigure.PublicMetricsAutoConfiguration;
+import org.springframework.boot.actuate.endpoint.MetricsEndpoint;
+import org.springframework.boot.actuate.endpoint.mvc.EndpointHandlerMapping;
+import org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter;
+import org.springframework.boot.actuate.endpoint.mvc.MvcEndpoint;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+import org.springframework.web.servlet.config.annotation.EnableWebMvc;
+
+import java.util.Collection;
+
+@Configuration
+@EnableWebMvc
+@Import({
+        EndpointAutoConfiguration.class,
+        PublicMetricsAutoConfiguration.class,
+//        HealthIndicatorAutoConfiguration.class
+})
+
+public class ActuatorConfig { // TODO: remove this with migration to Spring Boot 2
+
+    @Bean
+    @Autowired
+    public EndpointHandlerMapping endpointHandlerMapping(Collection<? extends MvcEndpoint> endpoints) {
+        return new EndpointHandlerMapping(endpoints);
+    }
+
+    @Bean
+    @Autowired
+    public EndpointMvcAdapter metricsEndPoint(MetricsEndpoint delegate) {
+        return new EndpointMvcAdapter(delegate);
+    }
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/controllers/GenericControllerAdvice.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/controllers/GenericControllerAdvice.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/controllers/GenericControllerAdvice.java	(revision 61527)
@@ -0,0 +1,67 @@
+package eu.dnetlib.repo.manager.controllers;
+
+
+import eu.dnetlib.api.functionality.ValidatorServiceException;
+import eu.dnetlib.repo.manager.domain.BrokerException;
+import eu.dnetlib.repo.manager.exception.EndPointException;
+import eu.dnetlib.repo.manager.exception.ResourceNotFoundException;
+import eu.dnetlib.repo.manager.exception.ServerError;
+import org.apache.log4j.LogManager;
+import org.apache.log4j.Logger;
+import org.json.JSONException;
+import org.springframework.core.Ordered;
+import org.springframework.core.annotation.Order;
+import org.springframework.http.HttpStatus;
+import org.springframework.security.access.AccessDeniedException;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.ResponseStatus;
+
+import javax.servlet.http.HttpServletRequest;
+import java.net.UnknownHostException;
+
+
+@ControllerAdvice
+@Order(Ordered.HIGHEST_PRECEDENCE)
+public class GenericControllerAdvice {
+
+    private Logger logger = LogManager.getLogger(GenericControllerAdvice.class);
+
+
+    @ResponseStatus(HttpStatus.NOT_FOUND)
+    @ExceptionHandler(ResourceNotFoundException.class)
+    @ResponseBody
+    public ServerError securityException(HttpServletRequest req, Exception ex) {
+        return new ServerError(req.getRequestURL().toString(),ex);
+    }
+
+    @ResponseStatus(HttpStatus.FORBIDDEN)
+    @ExceptionHandler(AccessDeniedException.class)
+    @ResponseBody
+    public ServerError accessDeniedException(HttpServletRequest req, Exception ex) {
+        return new ServerError(req.getRequestURL().toString(),ex);
+    }
+
+    @ResponseStatus(HttpStatus.NOT_FOUND)
+    @ExceptionHandler(UnknownHostException.class)
+    @ResponseBody
+    public ServerError unknownHostException(HttpServletRequest req, Exception ex) {
+        return new ServerError(req.getRequestURL().toString(),ex);
+    }
+
+    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
+    @ExceptionHandler({JSONException.class,BrokerException.class,ValidatorServiceException.class})
+    @ResponseBody
+    public ServerError internalException(HttpServletRequest req, Exception ex) {
+        return new ServerError(req.getRequestURL().toString(),ex);
+    }
+
+    @ResponseStatus(HttpStatus.GATEWAY_TIMEOUT)
+    @ExceptionHandler(EndPointException.class)
+    @ResponseBody
+    public ServerError endPointException(HttpServletRequest req, Exception ex) {
+        return new ServerError(req.getRequestURL().toString(),ex);
+    }
+
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/config/Config.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/config/Config.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/config/Config.java	(revision 61527)
@@ -0,0 +1,75 @@
+package eu.dnetlib.repo.manager.config;
+
+import org.apache.log4j.Logger;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.*;
+import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
+import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
+import org.springframework.session.web.http.CookieSerializer;
+import org.springframework.session.web.http.DefaultCookieSerializer;
+import org.springframework.web.client.RestTemplate;
+
+import javax.annotation.PostConstruct;
+
+@Configuration
+@EnableRedisHttpSession
+@PropertySource(value = {"classpath:application.properties"} )
+@ComponentScan(basePackages = {
+        "org.eurocris.openaire.cris.validator.service",
+        "eu.dnetlib.repo.manager.*"})
+public class Config {
+
+    private static Logger LOGGER = Logger.getLogger(Config.class);
+
+    @Value("${redis.host}")
+    private String host;
+
+    @Value("${redis.port:6379}")
+    private String port;
+
+    @Value("${redis.password}")
+    private String password;
+
+    @Value("${aai.mode}")
+    private String aai_mode;
+
+    @PostConstruct
+    private void init(){
+        LOGGER.info(String.format("Redis : %s Port : %s Password : %s",host,port,password));
+    }
+
+    @Bean
+    public JedisConnectionFactory connectionFactory() {
+        LOGGER.info(String.format("Redis : %s Port : %s Password : %s",host,port,password));
+        JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory();
+        jedisConnectionFactory.setHostName(host);
+        jedisConnectionFactory.setPort(Integer.parseInt(port));
+        jedisConnectionFactory.setUsePool(true);
+        if(password != null) jedisConnectionFactory.setPassword(password);
+        return jedisConnectionFactory;
+    }
+
+    @Bean
+    public CookieSerializer cookieSerializer() {
+        DefaultCookieSerializer serializer = new DefaultCookieSerializer();
+        serializer.setCookieName("openAIRESession");
+        serializer.setCookiePath("/");
+        if(aai_mode.equalsIgnoreCase("production") || aai_mode.equalsIgnoreCase("beta"))
+            serializer.setDomainName(".openaire.eu");
+//        serializer.setDomainName(".athenarc.gr");
+        LOGGER.info("Serializer : " + serializer);
+        return serializer;
+    }
+
+    @Bean
+    public RestTemplate restTemplate() {
+        RestTemplate restTemplate = new RestTemplate();
+        restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
+        HttpHeaders httpHeaders = new HttpHeaders();
+        httpHeaders.set("Content-Type", "application/json");
+        return restTemplate;
+    }
+
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/controllers/RestTemplateResponseErrorHandler.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/controllers/RestTemplateResponseErrorHandler.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/controllers/RestTemplateResponseErrorHandler.java	(revision 61527)
@@ -0,0 +1,34 @@
+package eu.dnetlib.repo.manager.controllers;
+
+import eu.dnetlib.repo.manager.exception.EndPointException;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.client.ClientHttpResponse;
+import org.springframework.stereotype.Component;
+import org.springframework.web.client.ResponseErrorHandler;
+
+import java.io.IOException;
+
+import static org.springframework.http.HttpStatus.Series.CLIENT_ERROR;
+import static org.springframework.http.HttpStatus.Series.SERVER_ERROR;
+
+@Component
+public class RestTemplateResponseErrorHandler implements ResponseErrorHandler {
+
+    @Override
+    public boolean hasError(ClientHttpResponse httpResponse) throws IOException {
+        return (httpResponse.getStatusCode().series() == CLIENT_ERROR
+                || httpResponse.getStatusCode().series() == SERVER_ERROR);
+    }
+
+    @Override
+    public void handleError(ClientHttpResponse httpResponse) throws IOException {
+
+        if (httpResponse.getStatusCode().series() == HttpStatus.Series.SERVER_ERROR) {
+            throw new EndPointException();
+        } else if (httpResponse.getStatusCode().series() == HttpStatus.Series.CLIENT_ERROR) {
+            if (httpResponse.getStatusCode() == HttpStatus.NOT_FOUND) {
+                throw new IOException();
+            }
+        }
+    }
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/config/DatasourceConfiguration.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/config/DatasourceConfiguration.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/config/DatasourceConfiguration.java	(revision 61527)
@@ -0,0 +1,59 @@
+package eu.dnetlib.repo.manager.config;
+
+import org.apache.commons.dbcp.BasicDataSource;
+import org.apache.log4j.Logger;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.jdbc.datasource.DataSourceTransactionManager;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+@Configuration
+@EnableTransactionManagement
+public class DatasourceConfiguration {
+
+    private static Logger LOGGER = Logger.getLogger(DatasourceConfiguration.class);
+
+    @Value("${repomanager.db.driverClassName}")
+    private String driverClassname;
+
+    @Value("${repomanager.db.url}")
+    private String URL;
+
+    @Value("${repomanager.db.username}")
+    private String username;
+
+    @Value("${repomanager.db.password}")
+    private String password;
+
+    @Bean
+    public BasicDataSource dataSource(){
+        BasicDataSource basicDataSource = new BasicDataSource();
+        basicDataSource.setDriverClassName(driverClassname);
+        basicDataSource.setUrl(URL);
+        basicDataSource.setUsername(username);
+        basicDataSource.setPassword(password);
+        basicDataSource.setMaxIdle(10);
+        basicDataSource.setMaxActive(100);
+        basicDataSource.setMaxWait(1000);
+        basicDataSource.setValidationQuery("SELECT 1;");
+        basicDataSource.setTestOnBorrow(true);
+        basicDataSource.setTestOnReturn(true);
+        basicDataSource.setTestWhileIdle(true);
+        basicDataSource.setTimeBetweenEvictionRunsMillis(1200000);
+        basicDataSource.setMinEvictableIdleTimeMillis(1800000);
+        basicDataSource.setMinEvictableIdleTimeMillis(5);
+        basicDataSource.setPoolPreparedStatements(true);
+        basicDataSource.setDefaultAutoCommit(true);
+
+        return basicDataSource;
+    }
+
+    @Bean
+    public DataSourceTransactionManager txManager(){
+        DataSourceTransactionManager txManager = new DataSourceTransactionManager();
+        txManager.setDataSource(dataSource());
+        return txManager;
+    }
+
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/PiWikService.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/PiWikService.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/PiWikService.java	(revision 61527)
@@ -0,0 +1,34 @@
+package eu.dnetlib.repo.manager.service;
+
+
+import eu.dnetlib.domain.data.PiwikInfo;
+import eu.dnetlib.repo.manager.domain.OrderByField;
+import eu.dnetlib.repo.manager.domain.OrderByType;
+import eu.dnetlib.repo.manager.domain.RepositoryServiceException;
+import org.springframework.http.ResponseEntity;
+
+import java.util.List;
+
+
+public interface PiWikService {
+
+    PiwikInfo getPiwikSiteForRepo(String repositoryId);
+
+    PiwikInfo savePiwikInfo(PiwikInfo piwikInfo);
+
+    List<PiwikInfo> getPiwikSitesForRepos(OrderByField orderByField, OrderByType orderByType, int from, int quantity, String searchField);
+
+    int getPiwikSitesTotals(String searchField);
+
+    ResponseEntity<Object> approvePiwikSite(String repositoryId);
+
+    String getOpenaireId(String repositoryid);
+
+    ResponseEntity<Object> markPiwikSiteAsValidated(String repositoryId) throws RepositoryServiceException;
+
+    PiwikInfo enableMetricsForRepository(String officialName, String repoWebsite, PiwikInfo piwikInfo) throws RepositoryServiceException;
+
+    Integer getTotal();
+
+    Integer getValidated(boolean validated);
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/utils/DatasourceManagerClient.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/utils/DatasourceManagerClient.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/utils/DatasourceManagerClient.java	(revision 61527)
@@ -0,0 +1,5 @@
+package eu.dnetlib.repo.manager.utils;
+
+public class DatasourceManagerClient {
+    //
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/utils/HttpUtils.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/utils/HttpUtils.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/utils/HttpUtils.java	(revision 61527)
@@ -0,0 +1,99 @@
+package eu.dnetlib.repo.manager.utils;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.log4j.Logger;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.*;
+import org.springframework.stereotype.Component;
+import org.springframework.web.client.RestTemplate;
+
+import java.nio.charset.Charset;
+import java.util.Map;
+
+@Component
+public class HttpUtils {
+
+    private static final Logger logger = Logger.getLogger(HttpUtils.class);
+
+    @Value("${aai.registry.url}")
+    private String registryUrl;
+
+    @Value("${aai.registry.authentication.username}")
+    private String user;
+
+    @Value("${aai.registry.authentication.password}")
+    private String password;
+
+    public JsonElement post(String path, JsonObject body) {
+        RestTemplate restTemplate = new RestTemplate();
+        HttpHeaders headers = createHeaders(user, password);
+        headers.setContentType(MediaType.APPLICATION_JSON);
+        HttpEntity<String> request = new HttpEntity<>(body.toString(), headers);
+        ResponseEntity<String> responseEntity = restTemplate.exchange(registryUrl + path, HttpMethod.POST, request, String.class);
+        return getResponseEntityAsJsonElement(responseEntity);
+    }
+
+    public JsonElement put(String path, JsonObject body) {
+        RestTemplate restTemplate = new RestTemplate();
+        HttpHeaders headers = createHeaders(user, password);
+        headers.setContentType(MediaType.APPLICATION_JSON);
+        HttpEntity<String> request = new HttpEntity<>(body.toString(), headers);
+        ResponseEntity<String> responseEntity = restTemplate.exchange(registryUrl + path, HttpMethod.PUT, request, String.class);
+        return getResponseEntityAsJsonElement(responseEntity);
+    }
+
+    public JsonElement get(String path, Map<String, String> params) {
+        RestTemplate restTemplate = new RestTemplate();
+        String url = registryUrl + path + ((params != null) ? createParams(params) : null);
+        ResponseEntity<String> responseEntity = restTemplate.exchange
+                (url, HttpMethod.GET, new HttpEntity<>(createHeaders(user, password)), String.class);
+        return getResponseEntityAsJsonElement(responseEntity);
+    }
+
+    public JsonElement delete(String path) {
+        RestTemplate restTemplate = new RestTemplate();
+        String url = registryUrl + path;
+        ResponseEntity<String> responseEntity = restTemplate.exchange
+                (url, HttpMethod.DELETE, new HttpEntity<>(createHeaders(user, password)), String.class);
+        return getResponseEntityAsJsonElement(responseEntity);
+    }
+
+
+    private String createParams(Map<String, String> params) {
+        StringBuilder ret = new StringBuilder("?");
+        int count = 0;
+        for (Map.Entry<String, String> param : params.entrySet()) {
+            ret.append(param.getKey()).append("=").append(param.getValue());
+            count++;
+            if (count != params.entrySet().size()) {
+                ret.append("&");
+            }
+        }
+        return ret.toString();
+    }
+
+    private HttpHeaders createHeaders(String username, String password) {
+        return new HttpHeaders() {{
+            String auth = username + ":" + password;
+            byte[] encodedAuth = Base64.encodeBase64(
+                    auth.getBytes(Charset.forName("US-ASCII")));
+            String authHeader = "Basic " + new String(encodedAuth);
+            set("Authorization", authHeader);
+        }};
+    }
+
+    private JsonElement getResponseEntityAsJsonElement(ResponseEntity<String> responseEntity) {
+        if (responseEntity != null && responseEntity.getBody() != null) {
+            logger.info(responseEntity.getBody());
+            try {
+                return new JsonParser().parse(responseEntity.getBody());
+            } catch (Exception e) {
+                logger.warn("Could not parse response body", e);
+            }
+        }
+        return null;
+    }
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/utils/OaiTools.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/utils/OaiTools.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/utils/OaiTools.java	(revision 61527)
@@ -0,0 +1,148 @@
+package eu.dnetlib.repo.manager.utils;
+
+import org.apache.log4j.Logger;
+import org.dom4j.io.DOMWriter;
+import org.w3c.dom.Document;
+import se.kb.oai.pmh.*;
+
+import javax.net.ssl.*;
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+public class OaiTools {
+
+	{
+		disableSslVerification();
+	}
+
+	private static Logger LOGGER = Logger.getLogger(OaiTools.class);
+
+	public static List<String> getSetsOfRepo(String baseUrl) throws Exception {
+		try {
+			LOGGER.debug("Getting sets of repository " + baseUrl);
+			OaiPmhServer harvester = new OaiPmhServer(baseUrl);
+			SetsList setList = harvester.listSets();
+			ResumptionToken token = setList.getResumptionToken();
+			List<Set> sets = new ArrayList<Set>();
+			sets.addAll(setList.asList());
+			while (token != null) {
+				setList = harvester.listSets(token);
+				token = setList.getResumptionToken();
+				sets.addAll(setList.asList());
+			}
+
+			List<String> ret = new ArrayList<String>();
+			for (Set set : sets) {
+				ret.add(set.getSpec().trim());
+			}
+			if (ret.size() > 0 )
+				Collections.sort(ret);
+			return ret;
+
+		} catch (Exception e) {
+			LOGGER.error("Error getting sets of repository " + baseUrl, e);
+			return new ArrayList<String>();
+			//throw e;
+		}
+	}
+
+	public static boolean identifyRepository(String baseUrl) throws Exception {
+		LOGGER.debug("sending identify request to repo " + baseUrl);
+
+		OaiPmhServer harvester = new OaiPmhServer(baseUrl);
+
+		if (baseUrl.trim().isEmpty()) {
+			return false;
+		}
+
+		try {
+			Identification identification = harvester.identify();
+			DOMWriter d4Writer = new DOMWriter();
+			Document d = d4Writer.write(identification.getResponse());
+
+			return verifyIdentify(d);
+		} catch (Exception e) {
+			LOGGER.debug("Error verifying identify response", e);
+			throw e;
+		}
+	}
+
+	private static boolean verifyIdentify(Document doc) throws XPathExpressionException {
+		NamespaceContext ctx = new NamespaceContext() {
+			public String getNamespaceURI(String prefix) {
+				String uri;
+				if (prefix.equals("oai"))
+					uri = "http://www.openarchives.org/OAI/2.0/";
+				else
+					uri = null;
+				return uri;
+			}
+
+			// Dummy implementation - not used!
+			public Iterator<String> getPrefixes(String val) {
+				return null;
+			}
+
+			// Dummy implemenation - not used!
+			public String getPrefix(String uri) {
+				return null;
+			}
+		};
+
+		// Now the XPath expression
+
+		String xpathStr = "//oai:OAI-PMH/oai:Identify";
+		XPathFactory xpathFact = XPathFactory.newInstance();
+		XPath xpath = xpathFact.newXPath();
+		xpath.setNamespaceContext(ctx);
+		String result = xpath.evaluate(xpathStr, doc);
+
+		return (result != null && !result.equals(""));
+	}
+
+	private static void disableSslVerification() {
+		try
+		{
+			LOGGER.debug("disabling ssl verification");
+			// Create a trust manager that does not validate certificate chains
+			TrustManager[] trustAllCerts = new TrustManager[] {new X509TrustManager() {
+				public X509Certificate[] getAcceptedIssuers() {
+					return null;
+				}
+				public void checkClientTrusted(X509Certificate[] certs, String authType) {
+				}
+				public void checkServerTrusted(X509Certificate[] certs, String authType) {
+				}
+			}
+			};
+
+			// Install the all-trusting trust manager
+			SSLContext sc = SSLContext.getInstance("SSL");
+			sc.init(null, trustAllCerts, new java.security.SecureRandom());
+			HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
+
+			// Create all-trusting host name verifier
+			HostnameVerifier allHostsValid = new HostnameVerifier() {
+				public boolean verify(String hostname, SSLSession session) {
+					return true;
+				}
+			};
+
+			// Install the all-trusting host verifier
+			HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
+		} catch (NoSuchAlgorithmException e) {
+			LOGGER.error("disabling ssl verification", e);
+		} catch (KeyManagementException e) {
+			LOGGER.error("error while disabling ssl verification", e);
+		}
+	}
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/EmailUtilsImpl.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/EmailUtilsImpl.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/EmailUtilsImpl.java	(revision 61527)
@@ -0,0 +1,905 @@
+package eu.dnetlib.repo.manager.service;
+
+import eu.dnetlib.domain.data.PiwikInfo;
+import eu.dnetlib.domain.data.Repository;
+import eu.dnetlib.domain.data.RepositoryInterface;
+import eu.dnetlib.domain.functionality.validator.JobForValidation;
+import eu.dnetlib.repo.manager.config.CascadingPropertyLoader;
+import eu.dnetlib.repo.manager.domain.ValidationServiceException;
+import eu.dnetlib.utils.MailLibrary;
+import org.apache.log4j.Logger;
+import org.mitre.openid.connect.model.OIDCAuthenticationToken;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+
+@Component("emailUtils")
+public class EmailUtilsImpl implements EmailUtils {
+
+    private static Logger LOGGER = Logger.getLogger(EmailUtilsImpl.class);
+
+    private List<String> specialRecipients = new ArrayList<String>();
+    private boolean override = false, logonly = false;
+    private String overrideEmail = null, from = null;
+
+    private final MailLibrary mailLibrary;
+    private final CascadingPropertyLoader pLoader;
+    private final RepositoryService repositoryService;
+
+    @Value("${services.repo-manager.baseUrl}")
+    private String baseUrl;
+
+    @Value("${services.repo-manager.adminEmail}")
+    private String adminEmail;
+
+    @Value("${services.repomanager.usagestats.adminEmail}")
+    private String usageStatsAdminEmail;
+
+    @Value("${services.provide.adminEmail}")
+    private String provideAdminEmail;
+
+    @Value("${validator.results.url}")
+    private String valBaseUrl;
+
+    @Autowired
+    EmailUtilsImpl(MailLibrary mailLibrary, CascadingPropertyLoader pLoader,
+                   RepositoryService repositoryService) {
+        this.mailLibrary = mailLibrary;
+        this.pLoader = pLoader;
+        this.repositoryService = repositoryService;
+    }
+
+
+    @PostConstruct
+    public void init(){
+        System.out.println("url -> " + this.baseUrl);
+    }
+
+
+    @Override
+    public void reportException(Exception exception) {
+        Writer writer = new StringWriter();
+        PrintWriter printWriter = new PrintWriter(writer);
+        exception.printStackTrace(printWriter);
+
+        List<String> recipients = new ArrayList<String>();
+
+        try {
+            recipients.add(this.adminEmail);
+            String message = "An exception has occurred:\n"+writer.toString();
+            String subject = "Automatic Bug Report";
+            this.sendMail(recipients, subject, message, false, null);
+        } catch (Exception e) {
+            LOGGER.error("Error sending error report", e);
+        }
+    }
+
+    @Override
+    public void sendAdministratorRequestToEnableMetrics(PiwikInfo piwikInfo) throws Exception {
+
+        try {
+            String subject = "[OpenAIRE-Usage Statistics] New request to enable usage statistics";
+
+            String message = "Dear administrator,\n" +
+                    "\n" +
+                    "we have received a request to enable the OpenAIRE usage statistics for the following repository \n" +
+                    "\n" +
+                    "Repository - " + piwikInfo.getRepositoryName() + ", " + piwikInfo.getCountry() + " (" + piwikInfo.getRepositoryId() + ")\n" +
+                    "Requestor - " + piwikInfo.getRequestorName() + ", " + piwikInfo.getRequestorEmail() + "\n" +
+                    "Matomo ID - " + piwikInfo.getSiteId() + "\n" +
+                    "Authentication token - " + piwikInfo.getAuthenticationToken() + "\n" +
+                    "\n" +
+                    "For more information about this request, go here: \n" +
+                    this.baseUrl + "/admin/metrics\n" +
+                    "\n" +
+                    "Best,\n" +
+                    "The OpenAIRE team";
+
+            this.sendMail(this.usageStatsAdminEmail, subject, message, false, null);
+
+        } catch (Exception e) {
+            LOGGER.error("Error while sending request to enable metrics email to administrator: " + this.usageStatsAdminEmail, e);
+            throw e;
+        }
+    }
+
+    @Override
+    public void sendUserRequestToEnableMetrics(PiwikInfo piwikInfo) throws Exception {
+
+        try {
+            String subject = "[OpenAIRE-Usage Statistics] Your request to enable usage statistics";
+
+            String message = "Dear " + piwikInfo.getRequestorName() + ",\n" +
+                    "\n" +
+                    "we have received your request to enable the OpenAIRE usage statistics for your repository\n" +
+                    "\n" +
+                    "Repository - " + piwikInfo.getRepositoryName() + ", " + piwikInfo.getCountry() + " (" + piwikInfo.getRepositoryId() + ")\n" +
+                    "Matomo ID - " + piwikInfo.getSiteId() + "\n" +
+                    "Authentication token - " + piwikInfo.getAuthenticationToken() + "\n" +
+                    "\n" +
+                    "In order to enable the usage statistics, you must install the OpenAIRE's tracking code in your repository software. " +
+                    "OpenAIRE's usage statistics service tracking code is maintained on Github as a patch for various versions of DSpace " +
+                    "(https://github.com/openaire/OpenAIRE-Piwik-DSpace) and as an Eprints plugin for version 3 " +
+                    "(https://github.com/openaire/EPrints-OAPiwik). In case the platform is different from DSpace or EPrints please contact " +
+                    "the OpenAIRE team in repositoryusagestats@openaire.eu in order to find a solution.\n" +
+                    "\n" +
+                    "For more information about your request and configuration details, go here: \n" +
+                    this.baseUrl + "/getImpact/instructions/" + piwikInfo.getRepositoryId() + "\n" +
+                    "\n" +
+                    "Once you have finished configuring your repository or if you have any questions, please notify the OpenAIRE team by sending \n" +
+                    "an email to repositoryusagestats@openaire.eu\n" +
+                    "\n" +
+                    "Best,\n" +
+                    "The OpenAIRE team";
+
+            this.sendMail(piwikInfo.getRequestorEmail(), subject, message, false, null);
+
+        } catch (Exception e) {
+            LOGGER.error("Error while sending request to enable metrics email to user: " + piwikInfo.getRequestorEmail(), e);
+            throw e;
+        }
+    }
+
+    @Override
+    public void sendAdministratorMetricsEnabled(PiwikInfo piwikInfo) throws Exception {
+
+        try {
+            String subject = "[OpenAIRE-Usage Statistics] Usage statistics have been enabled";
+
+            String message = "Dear administrator,\n" +
+                    "\n" +
+                    "The installation and configuration of OpenAIRE's tracking code for the following repository " +
+                    "has been completed and validated and the usage statistics have been enabled in OpenAIRE.\n" +
+                    "\n" +
+                    "Repository - " + piwikInfo.getRepositoryName() + ", " + piwikInfo.getCountry() + " (" + piwikInfo.getRepositoryId() + ")\n" +
+                    "Requestor - " + piwikInfo.getRequestorName() + ", " + piwikInfo.getRequestorEmail() + "\n" +
+                    "Piwik ID - " + piwikInfo.getSiteId() + "\n" +
+                    "Authentication token - " + piwikInfo.getAuthenticationToken() + "\n" +
+                    "\n" +
+                    "Best,\n" +
+                    "The OpenAIRE team";
+
+            this.sendMail(this.usageStatsAdminEmail, subject, message, false, null);
+
+        } catch (Exception e) {
+            LOGGER.error("Error while sending metrics enabled notification email to administator: " + this.usageStatsAdminEmail, e);
+            throw e;
+        }
+    }
+
+    @Override
+    public void sendUserMetricsEnabled(PiwikInfo piwikInfo) throws Exception {
+
+        try {
+            String subject = "[OpenAIRE-Usage Statistics] Usage statistics have been enabled";
+
+            String message = "Dear " + piwikInfo.getRequestorName() + ",\n" +
+                    "\n" +
+                    "The installation and configuration of OpenAIRE's tracking code for your repository \"" + piwikInfo.getRepositoryName() +
+                    "\" has been completed and validated and the usage statistics have been enabled in OpenAIRE.\n" +
+                    "\n" +
+                    "You can preview the statistics in your repository's dashboard: \n" +
+                    this.baseUrl + "/getImpact/" + piwikInfo.getRepositoryId() + "\n" +
+                    "\n" +
+                    " For more information and questions, you can contact the openaire support team by sending an email to " +
+                    "repositoryusagestats@openaire.eu\n" +
+                    "\n" +
+                    "Best,\n" +
+                    "The OpenAIRE team";
+
+            this.sendMail(piwikInfo.getRequestorEmail(), subject, message, false, null);
+
+        } catch (Exception e) {
+            LOGGER.error("Error while sending metrics enabled notification email to user: " + piwikInfo.getRequestorEmail(), e);
+            throw e;
+        }
+    }
+
+    @Override
+    public void sendAdminRegistrationEmail(Repository repository, Authentication authentication) throws Exception {
+        try {
+            String subject = "OpenAIRE content provider registration for " +
+                    repository.getDatasourceType() + "[" + repository.getOfficialName() + "]";
+
+            String message = "Dear administrator" + ",\n" +
+                    "\n" +
+                    "We received a request to register the " + repository.getDatasourceType() + "[" + repository.getOfficialName() + "]" +
+                    " to the OpenAIRE compliant list of content providers. " +
+                    "\n\n" +
+                    "User Contact: " + authentication.getName() + " (" + ((OIDCAuthenticationToken) authentication).getUserInfo().getEmail() + ")" +
+                    "\n\n" +
+                    "Please do not reply to this message\n" +
+                    "This message has been generated automatically.\n\n" +
+                    "Regards,\n" +
+                    "the OpenAIRE technical team\n";
+
+            this.sendMail(this.provideAdminEmail, subject, message, false, null);
+
+        } catch (Exception e) {
+            LOGGER.error("Error while sending registration notification email to the administrator", e);
+            throw e;
+        }
+    }
+
+    @Override
+    public void sendUserRegistrationEmail(Repository repository, Authentication authentication) throws Exception {
+        try {
+            String subject = "OpenAIRE content provider registration for " +
+                    repository.getDatasourceType() + "[" + repository.getOfficialName() + "]";
+
+//            String message = "Dear " + ((OIDCAuthenticationToken) authentication).getUserInfo().getName() + ",\n" +
+            String message = "Dear "+SecurityContextHolder.getContext().getAuthentication().getName()+",\n" +
+                    "\n" +
+                    "We received a request to register the " + repository.getDatasourceType() + "[" + repository.getOfficialName() + "]" +
+                    " to the OpenAIRE compliant list of content providers. " +
+                    "\n\n" +
+                    "Please do not reply to this message\n" +
+                    "This message has been generated automatically.\n\n" +
+                    "If you have any questions, write to 'helpdesk@openaire.eu'. \n\n" +
+                    "Regards,\n" +
+                    "the OpenAIRE technical team\n";
+
+            this.sendMail(repository.getRegisteredBy(), subject, message, false, null);
+
+        } catch (Exception e) {
+            LOGGER.error("Error while sending registration notification email to user: " + repository.getRegisteredBy(), e);
+            throw e;
+        }
+    }
+
+    @Override
+    public void sendAdminRegisterInterfaceEmail(Repository repository, String comment, RepositoryInterface repositoryInterface, Authentication authentication) throws Exception {
+        try {
+            String subject = "OpenAIRE new interface registration request started for " +
+                    repository.getDatasourceType() + "[" + repository.getOfficialName() + "]";
+
+            String message = "Dear administrator" + ",\n" +
+                    "\n" +
+                    "We received a request to add the following interface: \n\n" +
+                    "Base URL: " + repositoryInterface.getBaseUrl() + "\n" +
+                    "Set: " + repositoryInterface.getAccessSet() + "\n" +
+                    "Guidelines: " + repositoryInterface.getDesiredCompatibilityLevel() + "\n\n" +
+                    "to " + repository.getDatasourceType() + "[" + repository.getOfficialName() + "].\n";
+
+            if (comment != null)
+                message += "\nThe users comment was '" + comment + "'\n";
+
+            message += "A validation process for this interface against the OpenAIRE guidelines compatibility " +
+                    "has been started. You will be informed in another message once the process is finished." +
+                    "\n\n" +
+                    "User Contact: " + authentication.getName() + " (" + ((OIDCAuthenticationToken) authentication).getUserInfo().getEmail() + ")" +
+                    "\n\n" +
+                    "Please do not reply to this message\n" +
+                    "This message has been generated automatically.\n\n" +
+                    "Regards,\n" +
+                    "the OpenAIRE technical team\n";
+
+            this.sendMail(this.provideAdminEmail, subject, message, false, null);
+
+        } catch (Exception e) {
+            LOGGER.error("Error while sending registration of interface notification email to the administrator", e);
+            throw e;
+        }
+    }
+
+    @Override
+    public void sendUserRegisterInterfaceEmail(Repository repository, String comment, RepositoryInterface repositoryInterface, Authentication authentication) throws Exception {
+        try {
+            String subject = "OpenAIRE new interface registration request started for " +
+                    repository.getDatasourceType() + "[" + repository.getOfficialName() + "]";
+
+            String message = "Dear "+SecurityContextHolder.getContext().getAuthentication().getName()+",\n" +
+                    "\n" +
+                    "We received a request to add the following interface: \n\n" +
+                    "Base URL: " + repositoryInterface.getBaseUrl() + "\n" +
+                    "Set: " + repositoryInterface.getAccessSet() + "\n" +
+                    "Guidelines: " + repositoryInterface.getDesiredCompatibilityLevel() + "\n\n" +
+                    "to " + repository.getDatasourceType() + "[" + repository.getOfficialName() + "].\n";
+
+            if (comment != null) {
+                message += "\n Your comment was '" + comment + "'\n";
+            }
+
+            message += "A validation process for this interface against the OpenAIRE guidelines compatibility " +
+                    "has been started. You will be informed in another message once the process is finished." +
+                    "\n\n" +
+                    "Please do not reply to this message\n" +
+                    "This message has been generated automatically.\n\n" +
+                    "Regards,\n" +
+                    "the OpenAIRE technical team\n";
+
+            this.sendMail(repository.getRegisteredBy(), subject, message, false, null);
+
+        } catch (Exception e) {
+            LOGGER.error("Error while sending registration of interface notification email to user: " + repository.getRegisteredBy(), e);
+            throw e;
+        }
+    }
+
+    @Override
+    public void sendUserRegistrationResultsSuccessEmail(String issuerEmail, String jobId, RepositoryInterface repositoryInterface, Repository repository, Authentication authentication) throws Exception {
+        try {
+            String subject = "OpenAIRE new interface registration request - results (success) for " +
+                    repository.getDatasourceType() + "[" + repository.getOfficialName() + "]";
+
+//            String message = "Dear " + ((OIDCAuthenticationToken) authentication).getUserInfo().getName() + ",\n" +
+            String message = "Dear user,\n" +
+                    "\n" +
+                    "the compatibility test on " + "[" + repository.getOfficialName() + "]" +
+                    " was successful and the datasource type \""+ repository.getDatasourceType()  + "\" will be prepared for aggregation in OpenAIRE."+
+                    "\n\n" +
+                    "Please note that it usually takes about 3-4 weeks until a data source is indexed and it’s metadata visible on openaire.eu.\n\n" +
+                    "Registration identifier in OpenAIRE: "+ repository.getNamespacePrefix()+
+                    "\nOfficial Name:" + repository.getOfficialName() +
+                    "\n\nBase URL: "+ repositoryInterface.getBaseUrl() +
+                    "\n\nValidation Set: " + repositoryInterface.getAccessSet() +
+                    "\n\nGuidelines: "+ repositoryInterface.getDesiredCompatibilityLevel() +
+                    "\n\nYou can review the validation results here.\n" + valBaseUrl + "" + jobId +
+                    "\n\n\nPlease do not reply to this email\n"+
+                    "This message has been generated manually\n\n"+
+                    "If you have any questions, write to 'helpdesk@openaire.eu'. \n\n" +
+                    "Regards,\n" +
+                    "the OpenAIRE technical team\n";
+
+            this.sendMail(repository.getRegisteredBy(), subject, message, false, null);
+
+        } catch (Exception e) {
+            LOGGER.error("Error while sending registration notification email to user: " + repository.getRegisteredBy(), e);
+            throw e;
+        }
+    }
+
+    @Override
+    public void sendAdminRegistrationResultsSuccessEmail(String issuerEmail, String jobId,RepositoryInterface repositoryInterface, Repository repository, Authentication authentication) throws Exception {
+        try {
+            String subject = "OpenAIRE new interface registration request - results (success) for " +
+                    repository.getDatasourceType() + "[" + repository.getOfficialName() + "]";
+
+            String message = "Dear admin ,\n" +
+                    "\n" +
+                    "the compatibility test on " + "[" + repository.getOfficialName() + "]" +
+                    " was successful and the datasource type \""+ repository.getDatasourceType()  + "\" will be prepared for aggregation in OpenAIRE."+
+                    "\n\n" +
+                    "Please note that it usually takes about 3-4 weeks until a data source is indexed and it’s metadata visible on openaire.eu.\n\n" +
+                    "Registration identifier in OpenAIRE: "+ repository.getNamespacePrefix()+
+                    "\nOfficial Name:" + repository.getOfficialName() +
+                    "\n\nBase URL: "+ repositoryInterface.getBaseUrl() +
+                    "\n\nValidation Set: " + repositoryInterface.getAccessSet() +
+                    "\n\nGuidelines: "+ repositoryInterface.getDesiredCompatibilityLevel() +
+                    "\n\nUser Contact:"+ issuerEmail +""+
+                    "\n\nYou can review the validation results here.\n" + valBaseUrl + "" + jobId +
+                    "\n\n\nPlease do not reply to this email\n"+
+                    "This message has been generated manually\n\n"+
+                    "If you have any questions, write to 'helpdesk@openaire.eu'. \n\n" +
+                    "Regards,\n" +
+                    "the OpenAIRE technical team\n";
+
+            this.sendMail(this.provideAdminEmail, subject, message, false, null);
+
+        } catch (Exception e) {
+            LOGGER.error("Error while sending registration notification email to user: " + repository.getRegisteredBy(), e);
+            throw e;
+        }
+    }
+
+    @Override
+    public void sendUserRegistrationResultsFailureEmail(String jobId, RepositoryInterface repositoryInterface, Repository repository, Authentication authentication) throws Exception {
+        try {
+            String subject = "OpenAIRE new interface registration request - results (failure) for " +
+                    repository.getDatasourceType() + "[" + repository.getOfficialName() + "]";
+            //            String message = "Dear " + ((OIDCAuthenticationToken) authentication).getUserInfo().getName() + ",\n" +
+            String message = "Dear user,\n" +
+                    "\n" +
+                    "the compatibility test on " + "[" + repository.getOfficialName() + "]" +
+                    " was not successful and the registration process was interrupted."+
+                    "\n\n" +
+                    "We will check what caused the problem and get back to you within a couple of days.\n\n" +
+                    "Registration identifier in OpenAIRE: "+ repository.getNamespacePrefix()+
+                    "\nOfficial Name:" + repository.getOfficialName() +
+                    "\n\nBase URL: "+ repositoryInterface.getBaseUrl() +
+                    "\n\nValidation Set: " + repositoryInterface.getAccessSet() +
+                    "\n\nGuidelines: "+ repositoryInterface.getDesiredCompatibilityLevel() +
+                    "\n\nYou can review the validation results here.\n" + valBaseUrl + "" + jobId +
+                    "\n\n\nPlease do not reply to this email\n"+
+                    "This message has been generated manually\n\n"+
+                    "If you have any questions, write to 'helpdesk@openaire.eu'. \n\n" +
+                    "Regards,\n" +
+                    "the OpenAIRE technical team\n";
+
+            this.sendMail(repository.getRegisteredBy(), subject, message, false, null);
+
+        } catch (Exception e) {
+            LOGGER.error("Error while sending registration notification email to user: " + repository.getRegisteredBy(), e);
+            throw e;
+        }
+    }
+
+    @Override
+    public void sendAdminRegistrationResultsFailureEmail(String issuerEmail, String jobId, RepositoryInterface repositoryInterface, Repository repository, Authentication authentication) throws Exception {
+        try {
+            String subject = "OpenAIRE new interface registration request - results (failure) for " +
+                    repository.getDatasourceType() + "[" + repository.getOfficialName() + "]";
+
+            String message = "Dear admin,\n" +
+                    "\n" +
+                    "the compatibility test on " + "[" + repository.getOfficialName() + "]" +
+                    " was not successful and the registration process was interrupted."+
+                    "\n\n" +
+                    "We will check what caused the problem and get back to you within a couple of days.\n\n" +
+                    "Registration identifier in OpenAIRE: "+ repository.getNamespacePrefix()+
+                    "\nOfficial Name:" + repository.getOfficialName() +
+                    "\n\nBase URL: "+ repositoryInterface.getBaseUrl() +
+                    "\n\nValidation Set: " + repositoryInterface.getAccessSet() +
+                    "\n\nGuidelines: "+ repositoryInterface.getDesiredCompatibilityLevel() +
+                    "\n\nUser Contact:"+ issuerEmail +""+
+                    "\n\nYou can review the validation results here.\n" + valBaseUrl + "" + jobId +
+                    "\n\n\nPlease do not reply to this email\n"+
+                    "This message has been generated manually\n\n"+
+                    "If you have any questions, write to 'helpdesk@openaire.eu'. \n\n" +
+                    "Regards,\n" +
+                    "the OpenAIRE technical team\n";
+
+            this.sendMail(this.provideAdminEmail, subject, message, false, null);
+
+        } catch (Exception e) {
+            LOGGER.error("Error while sending registration notification email to user: " + repository.getRegisteredBy(), e);
+            throw e;
+        }
+    }
+
+    @Override
+    public void sendUserUpdateResultsSuccessEmail(String issuer, String jobId, RepositoryInterface repositoryInterface, Repository repository, Authentication authentication) throws Exception {
+        try {
+            String subject = "OpenAIRE interface update request - results (success) for " +
+                    repository.getDatasourceType() + "[" + repository.getOfficialName() + "]";
+
+            //            String message = "Dear " + ((OIDCAuthenticationToken) authentication).getUserInfo().getName() + ",\n" +
+            String message = "Dear user,\n" +
+                    "\n" +
+                    "the compatibility test on [" + repository.getOfficialName()+"] has been successful\n\n" +
+                    "We will check your transmitted information and adjust the aggregation settings accordingly. Please note that it usually takes about 3-4 weeks until the changes are visible on openaire.eu."+"\n\n" +
+                    "Registration identifier in OpenAIRE: "+ repository.getNamespacePrefix()+
+                    "\nOfficial Name:" + repository.getOfficialName() +
+                    "\n\nBase URL: "+ repositoryInterface.getBaseUrl() +
+                    "\n\nValidation Set: " + repositoryInterface.getAccessSet() +
+                    "\n\nGuidelines: "+ repositoryInterface.getDesiredCompatibilityLevel() +
+                    "\n\nYou can review the validation results here.\n" + valBaseUrl + "" + jobId +
+                    "\n\n\nPlease do not reply to this email\n"+
+                    "This message has been generated manually\n\n"+
+                    "If you have any questions, write to 'helpdesk@openaire.eu'. \n\n" +
+                    "Regards,\n" +
+                    "the OpenAIRE technical team\n";
+
+            this.sendMail(issuer, subject, message, false, null);
+
+        } catch (Exception e) {
+            LOGGER.error("Error while sending registration notification email to the administrator", e);
+            throw e;
+        }
+    }
+
+    @Override
+    public void sendAdminUpdateResultsSuccessEmail(String issuerEmail, String jobId, RepositoryInterface repositoryInterface, Repository repository, Authentication authentication) throws Exception {
+            try {
+                String subject = "OpenAIRE interface update request - results (success) for " +
+                        repository.getDatasourceType() + "[" + repository.getOfficialName() + "]";
+
+                String message = "Dear admin,\n" +
+                        "\n" +
+                        "the compatibility test on [" + repository.getOfficialName()+"] has been successful\n\n" +
+                        "We will check your transmitted information and adjust the aggregation settings accordingly. Please note that it usually takes about 3-4 weeks until the changes are visible on openaire.eu."+"\n\n" +
+                        "Registration identifier in OpenAIRE: "+ repository.getNamespacePrefix()+
+                        "\nOfficial Name:" + repository.getOfficialName() +
+                        "\n\nBase URL: "+ repositoryInterface.getBaseUrl() +
+                        "\n\nValidation Set: " + repositoryInterface.getAccessSet() +
+                        "\n\nGuidelines: "+ repositoryInterface.getDesiredCompatibilityLevel() +
+                        "\n\nUser Contact:"+ issuerEmail +""+
+                        "\n\nYou can review the validation results here.\n" + valBaseUrl + "" + jobId +
+                        "\n\n\nPlease do not reply to this email\n"+
+                        "This message has been generated manually\n\n"+
+                        "If you have any questions, write to 'helpdesk@openaire.eu'. \n\n" +
+                        "Regards,\n" +
+                        "the OpenAIRE technical team\n";
+
+                this.sendMail(this.provideAdminEmail, subject, message, false, null);
+
+            } catch (Exception e) {
+                LOGGER.error("Error while sending registration notification email to the administrator", e);
+                throw e;
+            }
+    }
+
+    @Override
+    public void sendUserUpdateResultsFailureEmail(String issuer, String jobId, RepositoryInterface repositoryInterface, Repository repository, Authentication authentication) throws Exception {
+        try {
+            String subject = "OpenAIRE interface update request - results (failure) for " +
+                    repository.getDatasourceType() + "[" + repository.getOfficialName() + "]";
+
+            //            String message = "Dear " + ((OIDCAuthenticationToken) authentication).getUserInfo().getName() + ",\n" +
+            String message = "Dear user,\n" +
+                    "\n" +
+                    "the compatibility test on " + "[" + repository.getOfficialName() + "]" +
+                    " was not successful."+
+                    "\n\n" +
+                    "WWe will check your transmitted information to see what caused the problem and get back to you within a couple of days.\n\n" +
+                    "Registration identifier in OpenAIRE: "+ repository.getNamespacePrefix()+
+                    "\nOfficial Name:" + repository.getOfficialName() +
+                    "\n\nBase URL: "+ repositoryInterface.getBaseUrl() +
+                    "\n\nValidation Set: " + repositoryInterface.getAccessSet() +
+                    "\n\nGuidelines: "+ repositoryInterface.getDesiredCompatibilityLevel() +
+                    "\n\nYou can review the validation results here.\n" + valBaseUrl + "" + jobId +
+                    "\n\n\nPlease do not reply to this email\n"+
+                    "This message has been generated manually\n\n"+
+                    "If you have any questions, write to 'helpdesk@openaire.eu'. \n\n" +
+                    "Regards,\n" +
+                    "the OpenAIRE technical team\n";
+
+            this.sendMail(issuer, subject, message, false, null);
+
+        } catch (Exception e) {
+            LOGGER.error("Error while sending registration notification email to user: " + repository.getRegisteredBy(), e);
+            throw e;
+        }
+    }
+
+    @Override
+    public void sendAdminUpdateResultsFailureEmail(String issuerEmail, String jobId, RepositoryInterface repositoryInterface, Repository repository, Authentication authentication) throws Exception {
+        try {
+            String subject = "OpenAIRE interface update request - results (failure) for " +
+                    repository.getDatasourceType() + "[" + repository.getOfficialName() + "]";
+
+            String message = "Dear admin,\n" +
+                    "\n" +
+                    "the compatibility test on " + "[" + repository.getOfficialName() + "]" +
+                    " was not successful."+
+                    "\n\n" +
+                    "WWe will check your transmitted information to see what caused the problem and get back to you within a couple of days.\n\n" +
+                    "Registration identifier in OpenAIRE: "+ repository.getNamespacePrefix()+
+                    "\nOfficial Name:" + repository.getOfficialName() +
+                    "\n\nBase URL: "+ repositoryInterface.getBaseUrl() +
+                    "\n\nValidation Set: " + repositoryInterface.getAccessSet() +
+                    "\n\nGuidelines: "+ repositoryInterface.getDesiredCompatibilityLevel() +
+                    "\n\nUser Contact:"+ issuerEmail +""+
+                    "\n\nYou can review the validation results here.\n" + valBaseUrl + "" + jobId +
+                    "\n\n\nPlease do not reply to this email\n"+
+                    "This message has been generated manually\n\n"+
+                    "If you have any questions, write to 'helpdesk@openaire.eu'. \n\n" +
+                    "Regards,\n" +
+                    "the OpenAIRE technical team\n";
+
+            this.sendMail(this.provideAdminEmail, subject, message, false, null);
+
+        } catch (Exception e) {
+            LOGGER.error("Error while sending registration notification email to user: " + repository.getRegisteredBy(), e);
+            throw e;
+        }
+    }
+
+    @Override
+    public void sendUserValidationResults(String issuer, String jobId, RepositoryInterface repositoryInterface, Repository repository, Authentication authentication) throws Exception {
+        try {
+            String subject = "OpenAIRE validator - Test results ";
+
+            //            String message = "Dear " + ((OIDCAuthenticationToken) authentication).getUserInfo().getName() + ",\n" +
+            String message = "Dear user,\n" +
+                    "\n" +
+                    "the validation request you have submitted has finished. You can retrieve the results by following this url: "+ valBaseUrl+"" + jobId+" .\n\n" +
+                    "Please do not reply to this message.\n" +
+                    "This message has been generated automatically.\n" +
+                    "If you have any questions, write to 'helpdesk@openaire.eu'. \n\n" +
+                    "Regards,\n" +
+                    "the OpenAIRE technical team\n";
+
+            this.sendMail(issuer, subject, message, false, null);
+
+        } catch (Exception e) {
+            LOGGER.error("Error while sending validation submission notification email to user: " + issuer, e);
+            throw e;
+        }
+    }
+
+    @Override
+    public void sendAdminValidationResults(String issuer, String jobId, RepositoryInterface repositoryInterface, Repository repository, Authentication authentication) throws Exception {
+        try {
+            String subject = "OpenAIRE validator - Test results ";
+
+            String message = "Dear admin,\n" +
+                    "\n" +
+                    "a validation request has finished. You can retrieve the results by following this url: "+ valBaseUrl+"" + jobId+" .\n\n" +
+                    "\n\nUser Contact:"+ issuer +""+
+                    "Please do not reply to this message.\n" +
+                    "This message has been generated automatically.\n" +
+                    "If you have any questions, write to 'helpdesk@openaire.eu'. \n\n" +
+                    "Regards,\n" +
+                    "the OpenAIRE technical team\n";
+
+            this.sendMail(this.provideAdminEmail, subject, message, false, null);
+
+        } catch (Exception e) {
+            LOGGER.error("Error while sending validation submission notification email to user: " + issuer, e);
+            throw e;
+        }
+    }
+
+    @Override
+    public void sendAdminGeneralFailure(String issuer, String jobId, RepositoryInterface repositoryInterface, Repository repository, Authentication authentication) throws Exception {
+        try {
+            String subject = "OpenAIRE validator - job failure";
+
+            String message = "Dear admin,\n" +
+                    "\n" +
+                    "the validation job that was automatically submitted for the update/registration of the interface "+repositoryInterface.getId()+" ("+repositoryInterface.getBaseUrl()+", "+repositoryInterface.getAccessSet()+") of the repository "+repository.getId()+" ("+repository.getOfficialName()+") failed to complete." +
+                    "This message has been generated automatically.\n\n" +
+                    "Regards,\n" +
+                    "the OpenAIRE technical team\n";
+
+            this.sendMail(this.provideAdminEmail, subject, message, false, null);
+
+        } catch (Exception e) {
+            LOGGER.error("Error while sending validation submission notification email to user: " + issuer, e);
+            throw e;
+        }
+    }
+
+    @Override
+    public void sendAdminUpdateRepositoryInfoEmail(Repository repository, Authentication authentication) throws Exception {
+        try {
+            String subject = "OpenAIRE content provider update information for " +
+                    repository.getDatasourceType() + "[" + repository.getOfficialName() + "]";
+
+            String message = "Dear administrator" + ",\n" +
+                    "\n" +
+                    "We received a request to update the basic information for " + repository.getDatasourceType() + "[" + repository.getOfficialName() + "].\n\n" +
+                    "Please do not reply to this message\n" +
+                    "This message has been generated automatically.\n\n" +
+                    "Regards,\n" +
+                    "the OpenAIRE technical team\n";
+
+            this.sendMail(this.provideAdminEmail, subject, message, false, null);
+
+        } catch (Exception e) {
+            LOGGER.error("Error while sending registration notification email to the administrator", e);
+            throw e;
+        }
+    }
+
+    @Override
+    public void sendUserUpdateRepositoryInfoEmail(Repository repository, Authentication authentication) throws Exception {
+        try {
+            String subject = "OpenAIRE content provider update information for " +
+                    repository.getDatasourceType() + "[" + repository.getOfficialName() + "]";
+
+            //            String message = "Dear " + ((OIDCAuthenticationToken) authentication).getUserInfo().getName() + ",\n" +
+            String message = "Dear user,\n" +
+                    "\n" +
+                    "We received a request to update the basic information for " + repository.getDatasourceType() + "[" + repository.getOfficialName() + "].\n\n" +
+                    "Please do not reply to this message\n" +
+                    "This message has been generated automatically.\n\n" +
+                    "If you have any questions, write to 'helpdesk@openaire.eu'. \n\n" +
+                    "Regards,\n" +
+                    "the OpenAIRE technical team\n";
+
+            this.sendMail(repository.getRegisteredBy(), subject, message, false, null);
+
+        } catch (Exception e) {
+            LOGGER.error("Error while sending registration notification email to user: " + repository.getRegisteredBy(), e);
+            throw e;
+        }
+    }
+
+    @Override
+    public void sendAdminUpdateInterfaceEmail(Repository repository, String comment, RepositoryInterface repositoryInterface, Authentication authentication) throws Exception {
+        try {
+            String subject = "OpenAIRE interface update request started for " +
+                    repository.getDatasourceType() + "[" + repository.getOfficialName() + "]";
+
+            String message = "Dear administrator" + ",\n" +
+                    "\n" +
+                    "We received a request to update the following interface: \n\n" +
+                    "Base URL: " + repositoryInterface.getBaseUrl() + "\n" +
+                    "Set: " + repositoryInterface.getAccessSet() + "\n" +
+                    "Guidelines: " + repositoryInterface.getDesiredCompatibilityLevel() + "\n\n" +
+                    "for " + repository.getDatasourceType() + "[" + repository.getOfficialName() + "].\n";
+
+            if (comment != null)
+                message += "\nThe users comment was '" + comment + "'\n";
+
+            message += "A new iteration process of the validation against the OpenAIRE guidelines compatibility has been started.\n\n" +
+                    "User Contact: " + authentication.getName() + " (" + ((OIDCAuthenticationToken) authentication).getUserInfo().getEmail() + ")" +
+                    "\n\n" +
+                    "Please do not reply to this message\n" +
+                    "This message has been generated automatically.\n\n" +
+                    "Regards,\n" +
+                    "the OpenAIRE technical team\n";
+
+            this.sendMail(this.provideAdminEmail, subject, message, false, null);
+
+        } catch (Exception e) {
+            LOGGER.error("Error while sending registration notification email to the administrator", e);
+            throw e;
+        }
+    }
+
+    @Override
+    public void sendUserUpdateInterfaceEmail(Repository repository, String comment, RepositoryInterface repositoryInterface, Authentication authentication) throws Exception {
+        try {
+            String subject = "OpenAIRE interface update request started for " +
+                    repository.getDatasourceType() + "[" + repository.getOfficialName() + "]";
+
+            //            String message = "Dear " + ((OIDCAuthenticationToken) authentication).getUserInfo().getName() + ",\n" +
+            String message = "Dear user,\n" +
+                    "\n" +
+                    "We received a request to update the following interface: \n\n" +
+                    "Base URL: " + repositoryInterface.getBaseUrl() + "\n" +
+                    "Set: " + repositoryInterface.getAccessSet() + "\n" +
+                    "Guidelines: " + repositoryInterface.getDesiredCompatibilityLevel() + "\n\n" +
+                    "for " + repository.getDatasourceType() + "[" + repository.getOfficialName() + "].\n";
+
+            if (comment != null) {
+                message += "\n Your comment was '" + comment + "'\n";
+            }
+
+            message += "A new iteration process of the validation against the OpenAIRE guidelines compatibility has been started.\n\n" +
+                    "Please do not reply to this message\n" +
+                    "This message has been generated automatically.\n\n" +
+                    "If you have any questions, write to 'helpdesk@openaire.eu'. \n\n" +
+                    "Regards,\n" +
+                    "the OpenAIRE technical team\n";
+
+            this.sendMail(repository.getRegisteredBy(), subject, message, false, null);
+
+        } catch (Exception e) {
+            LOGGER.error("Error while sending registration notification email to user: " + repository.getRegisteredBy(), e);
+            throw e;
+        }
+    }
+
+    @Override
+    public void sendSubmitJobForValidationEmail(Authentication authentication, JobForValidation jobForValidation) throws Exception {
+        try {
+            String subject = "OpenAIRE validator - Test submission ";
+
+            //            String message = "Dear " + ((OIDCAuthenticationToken) authentication).getUserInfo().getName() + ",\n" +
+            String message = "Dear user,\n" +
+                    "\n" +
+                    "The validation request you have submitted has started.\n" +
+                    "Please do not reply to this message.\n" +
+                    "This message has been generated automatically.\n" +
+                    "If you have any questions, write to 'helpdesk@openaire.eu'. \n\n" +
+                    "Regards,\n" +
+                    "the OpenAIRE technical team\n";
+
+            this.sendMail(jobForValidation.getUserEmail(), subject, message, false, null);
+
+        } catch (Exception e) {
+            LOGGER.error("Error while sending validation submission notification email to user: " + jobForValidation.getUserEmail(), e);
+            throw e;
+        }
+    }
+
+    @Override
+    public void sendUponJobCompletion(
+            String repoId,
+            String repoInterfaceId,
+            int scoreUsage,
+            int scoreContent,
+            boolean isSuccess,
+            boolean isUpdate,
+            String issuerEmail,
+            String jobId) throws Exception {
+        List<RepositoryInterface> repositoryInterfaces = repositoryService.getRepositoryInterface(repoId);
+        if(repositoryInterfaces.size()==0)
+            throw new ValidationServiceException("Repository interface with id \""+repoInterfaceId+"\" not found",ValidationServiceException.ErrorCode.GENERAL_ERROR);
+
+        RepositoryInterface repositoryInterface = repositoryInterfaces.stream().filter( repoInterface -> repoInterface.getId().equals(repoInterfaceId)).collect(Collectors.toList()).get(0);
+        Repository repository = repositoryService.getRepositoryById(repoId);
+
+        if(!isUpdate){
+            if(isSuccess){
+                if(scoreContent>=50 && scoreUsage >= 50){
+                    this.sendUserRegistrationResultsSuccessEmail(issuerEmail,jobId,repositoryInterface,repository, SecurityContextHolder.getContext().getAuthentication());
+                    this.sendAdminRegistrationResultsSuccessEmail(issuerEmail,jobId,repositoryInterface,repository,SecurityContextHolder.getContext().getAuthentication());
+                }else{
+                    this.sendUserRegistrationResultsFailureEmail(jobId,repositoryInterface,repository, SecurityContextHolder.getContext().getAuthentication());
+                    this.sendAdminRegistrationResultsFailureEmail(issuerEmail,jobId,repositoryInterface,repository,SecurityContextHolder.getContext().getAuthentication());
+                }
+            }else{
+                this.sendAdminGeneralFailure(issuerEmail,jobId,repositoryInterface,repository,SecurityContextHolder.getContext().getAuthentication());
+            }
+        }else{
+            if(isSuccess){
+                if(scoreContent>=50 && scoreUsage >= 50){
+                    this.sendUserUpdateResultsSuccessEmail(issuerEmail,jobId,repositoryInterface,repository, SecurityContextHolder.getContext().getAuthentication());
+                    this.sendAdminUpdateResultsSuccessEmail(issuerEmail,jobId,repositoryInterface,repository, SecurityContextHolder.getContext().getAuthentication());
+                }else{
+                    this.sendUserUpdateResultsFailureEmail(issuerEmail,jobId,repositoryInterface,repository, SecurityContextHolder.getContext().getAuthentication());
+                    this.sendAdminUpdateResultsFailureEmail(issuerEmail,jobId,repositoryInterface,repository, SecurityContextHolder.getContext().getAuthentication());
+                }
+            }else{
+                this.sendAdminGeneralFailure(issuerEmail,jobId,repositoryInterface,repository,SecurityContextHolder.getContext().getAuthentication());
+            }
+        }
+
+    }
+
+
+    private void sendMail(String email, String subject, String message, boolean sendToSpecial, List<String> repoAdminMails) throws Exception {
+        ArrayList<String> to = new ArrayList<String>();
+        to.add(email);
+        this.sendMail(to,subject,message,sendToSpecial,repoAdminMails);
+    }
+
+    public void sendMail(List<String> recipients, String subject, String message, boolean sendToSpecial, List<String> repoAdminMails) throws Exception {
+
+        try {
+            if (sendToSpecial) {
+                recipients.addAll(this.specialRecipients);
+            }
+
+            if (repoAdminMails != null)
+                recipients.addAll(repoAdminMails);
+
+            if (this.override) {
+                recipients.clear();
+                recipients.add(overrideEmail);
+            }
+            if (!logonly)
+                mailLibrary.sendEmail(recipients.toArray(new String[]{}), subject, message);
+            LOGGER.debug("Sending mail to Recipients: " + recipients + " Subject: " + subject + " Message: " + message);
+        } catch (Exception e) {
+            LOGGER.error("Error sending mail to Recipients: " + recipients + " Subject: " + subject + " Message: " + message, e);
+            throw new Exception(e);
+        }
+    }
+
+    private String getEmailProperty(String key) {
+        return pLoader.getProperties().getProperty(key);
+    }
+
+    public void setSpecialRecipients(String specialRecipients) {
+        String[] recps = specialRecipients.split(",");
+
+        for (String recp : recps) {
+            recp = recp.trim();
+
+            this.specialRecipients.add(recp);
+        }
+    }
+
+
+    public void setOverride(boolean override) {
+        this.override = override;
+    }
+
+    public void setOverrideEmail(String overrideEmail) {
+        this.overrideEmail = overrideEmail;
+    }
+
+    public String getFrom() {
+        return from;
+    }
+
+    public void setFrom(String from) {
+        this.from = from;
+    }
+
+    public boolean isLogonly() {
+        return logonly;
+    }
+
+    public void setLogonly(boolean logonly) {
+        this.logonly = logonly;
+    }
+
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/utils/CrisValidatorUtils.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/utils/CrisValidatorUtils.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/utils/CrisValidatorUtils.java	(revision 61527)
@@ -0,0 +1,83 @@
+package eu.dnetlib.repo.manager.utils;
+
+import eu.dnetlib.domain.functionality.validator.JobResultEntry;
+import eu.dnetlib.domain.functionality.validator.StoredJob;
+import org.eurocris.openaire.cris.validator.model.Job;
+import org.eurocris.openaire.cris.validator.model.RuleResults;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+public class CrisValidatorUtils {
+
+    private static final DateFormat DATE_FORMATTER = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+    private static final DateFormat DURATION_FORMATTER = new SimpleDateFormat("HH 'hours' mm 'min' ss 'sec'");
+
+    public static StoredJob convertJobToStoredJob(Job job) {
+        StoredJob sj = new StoredJob();
+        sj.setId(job.getId().hashCode());
+        sj.setValidationStatus(job.getStatus());
+        if (job.getDateFinished() != null) {
+            sj.setEnded(DATE_FORMATTER.format(job.getDateFinished()));
+            sj.setDuration(DURATION_FORMATTER.format(new Date(job.getDateFinished().getTime() - job.getDateStarted().getTime())));
+        } else {
+            sj.setEnded("-");
+            sj.setDuration("-");
+        }
+        sj.setStarted(DATE_FORMATTER.format(job.getDateStarted()));
+
+        sj.setUserEmail(job.getUser());
+        sj.setCris(true);
+        sj.setBaseUrl(job.getUrl());
+        sj.setValidationType("CU");
+        sj.setJobType("CRIS Validation");
+        sj.setGuidelinesShortName("For CRIS Managers 1.1");
+        sj.setValidationSet("-");
+
+        // Set status
+        sj.setValidationStatus(job.getStatus());
+        sj.setUsageJobStatus(job.getUsageJobStatus());
+        sj.setContentJobStatus(job.getContentJobStatus());
+
+        // Set scores
+//            sj.setFilteredScores(); // TODO what is this?
+        sj.setContentJobScore(job.getContentScore());
+        sj.setUsageJobScore(job.getUsageScore());
+
+        sj.setResultEntries(CrisValidatorUtils.crisResultsToJobEntries(job));
+        sj.setRecordsTested(job.getRecordsTested());
+
+        return sj;
+    }
+
+    public static List<JobResultEntry> crisResultsToJobEntries(Job crisJob) {
+        List<JobResultEntry> jobResultEntries = new ArrayList<>();
+        for (RuleResults ruleResults : crisJob.getRuleResults()) {
+            JobResultEntry jobResultEntry = new JobResultEntry();
+            jobResultEntry.setName(ruleResults.getRule().getName());
+            jobResultEntry.setRuleId(ruleResults.getRule().getId());
+            jobResultEntry.setDescription(ruleResults.getRule().getDescription());
+            jobResultEntry.setMandatory(true);
+            jobResultEntry.setWeight(Math.round(ruleResults.getRule().getWeight()));
+            jobResultEntry.setType(ruleResults.getRule().getType());
+            jobResultEntry.setHasErrors(false);
+            if (ruleResults.getCount() == 0) {
+                jobResultEntry.setSuccesses("-");
+            } else {
+                jobResultEntry.setSuccesses(ruleResults.getCount() - ruleResults.getFailed() + "/" + ruleResults.getCount());
+            }
+            if (ruleResults.getErrorMessages() != null && !ruleResults.getErrorMessages().isEmpty()) {
+                jobResultEntry.setErrors(ruleResults.getErrorMessages());
+                jobResultEntry.setHasErrors(true);
+            }
+            jobResultEntries.add(jobResultEntry);
+        }
+        return jobResultEntries;
+    }
+
+    private CrisValidatorUtils() {
+    }
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/EmailUtils.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/EmailUtils.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/EmailUtils.java	(revision 61527)
@@ -0,0 +1,78 @@
+package eu.dnetlib.repo.manager.service;
+
+import eu.dnetlib.domain.data.PiwikInfo;
+import eu.dnetlib.domain.data.Repository;
+import eu.dnetlib.domain.data.RepositoryInterface;
+import eu.dnetlib.domain.functionality.validator.JobForValidation;
+import org.springframework.security.core.Authentication;
+
+public interface EmailUtils {
+
+
+    void reportException(Exception exception);
+
+    void sendAdministratorRequestToEnableMetrics(PiwikInfo piwikInfo) throws Exception;
+
+    void sendUserRequestToEnableMetrics(PiwikInfo piwikInfo) throws Exception;
+
+    void sendAdministratorMetricsEnabled(PiwikInfo piwikInfo) throws Exception;
+
+    void sendUserMetricsEnabled(PiwikInfo piwikInfo) throws Exception;
+
+    /****USER REGISTRATION REQUEST EMAILS****/
+    void sendAdminRegistrationEmail(Repository repository, Authentication authentication) throws Exception;
+
+    void sendUserRegistrationEmail(Repository repository, Authentication authentication) throws Exception;
+
+    void sendAdminRegisterInterfaceEmail(Repository repository, String comment, RepositoryInterface repositoryInterface, Authentication authentication) throws Exception;
+
+    void sendUserRegisterInterfaceEmail(Repository repository, String comment, RepositoryInterface repositoryInterface, Authentication authentication) throws Exception;
+
+    /****SUCCESSFUL REGISTRATION RESULTS EMAILS****/
+    void sendUserRegistrationResultsSuccessEmail(String issuerEmail, String jobId,RepositoryInterface repositoryInterface, Repository repository, Authentication authentication) throws Exception;
+
+    void sendAdminRegistrationResultsSuccessEmail(String issuerEmail, String jobId,RepositoryInterface repositoryInterface, Repository repository, Authentication authentication) throws Exception;
+
+    /****FAILURE REGISTRATION RESULTS EMAILS****/
+    void sendUserRegistrationResultsFailureEmail(String jobId,RepositoryInterface repositoryInterface, Repository repository, Authentication authentication) throws Exception;
+
+    void sendAdminRegistrationResultsFailureEmail(String issuerEmail, String jobId,RepositoryInterface repositoryInterface, Repository repository, Authentication authentication) throws Exception;
+
+    /****SUCCESSFUL UPDATE RESULTS EMAILS****/
+    void sendUserUpdateResultsSuccessEmail(String issuer, String jobId,RepositoryInterface repositoryInterface, Repository repository, Authentication authentication) throws Exception;
+
+    void sendAdminUpdateResultsSuccessEmail(String issuerEmail, String jobId,RepositoryInterface repositoryInterface, Repository repository, Authentication authentication) throws Exception;
+
+    /****FAILURE UPDATE RESULTS EMAILS****/
+    void sendUserUpdateResultsFailureEmail(String issuer, String jobId,RepositoryInterface repositoryInterface, Repository repository, Authentication authentication) throws Exception;
+
+    void sendAdminUpdateResultsFailureEmail(String issuerEmail, String jobId,RepositoryInterface repositoryInterface, Repository repository, Authentication authentication) throws Exception;
+
+    /****VALIDATION OF CONTENT PROVIDER EMAILS****/
+    void sendUserValidationResults(String issuer,String jobId,RepositoryInterface repositoryInterface, Repository repository, Authentication authentication) throws Exception;
+
+    void sendAdminValidationResults(String issuer,String jobId,RepositoryInterface repositoryInterface, Repository repository, Authentication authentication) throws Exception;
+
+    /****GENERAL FAILURE OF VALIDATOR****/
+    void sendAdminGeneralFailure(String issuer,String jobId,RepositoryInterface repositoryInterface, Repository repository, Authentication authentication) throws Exception;
+
+
+    void sendAdminUpdateRepositoryInfoEmail(Repository repository, Authentication authentication) throws Exception;
+
+    void sendUserUpdateRepositoryInfoEmail(Repository repository, Authentication authentication) throws Exception;
+
+    void sendAdminUpdateInterfaceEmail(Repository repository, String comment, RepositoryInterface repositoryInterface, Authentication authentication) throws Exception;
+
+    void sendUserUpdateInterfaceEmail(Repository repository, String comment, RepositoryInterface repositoryInterface, Authentication authentication) throws Exception;
+
+    void sendSubmitJobForValidationEmail(Authentication authentication, JobForValidation jobForValidation) throws Exception;
+
+    void sendUponJobCompletion(String repoId,
+                               String repoInterfaceId,
+                               int scoreUsage,
+                               int scoreContent,
+                               boolean isSuccess,
+                               boolean isUpdate,
+                               String issuerEmail,
+                               String jobId) throws Exception;
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/RepositorySnippet.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/RepositorySnippet.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/RepositorySnippet.java	(revision 61527)
@@ -0,0 +1,142 @@
+package eu.dnetlib.repo.manager.domain;
+
+
+import eu.dnetlib.domain.data.PiwikInfo;
+
+import java.util.Date;
+
+public class RepositorySnippet {
+
+    // Do not refactor names to keep compatibility with external api.
+    private String id;
+    private String officialname;
+    private String englishname;
+    private String websiteurl;
+    private String typology;
+    private String registeredby;
+    private Organization[] organizations;
+    private String registrationdate;
+    private String logoUrl;
+    private String description;
+    private String fullTextDownload;
+    private String consentTermsOfUse;
+    private Date consentTermsOfUseDate;
+
+
+    private PiwikInfo piwikInfo;
+
+    public RepositorySnippet() {
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getOfficialname() {
+        return officialname;
+    }
+
+    public void setOfficialname(String officialname) {
+        this.officialname = officialname;
+    }
+
+    public String getEnglishname() {
+        return englishname;
+    }
+
+    public void setEnglishname(String englishname) {
+        this.englishname = englishname;
+    }
+
+    public String getWebsiteurl() {
+        return websiteurl;
+    }
+
+    public void setWebsiteurl(String websiteurl) {
+        this.websiteurl = websiteurl;
+    }
+
+    public String getRegisteredby() {
+        return registeredby;
+    }
+
+    public void setRegisteredby(String registeredby) {
+        this.registeredby = registeredby;
+    }
+
+    public String getTypology() {
+        return typology;
+    }
+
+    public void setTypology(String typology) {
+        this.typology = typology;
+    }
+
+    public Organization[] getOrganizations() {
+        return organizations;
+    }
+
+    public void setOrganizations(Organization[] organizations) {
+        this.organizations = organizations;
+    }
+
+    public String getRegistrationdate() {
+        return registrationdate;
+    }
+
+    public void setRegistrationdate(String registrationdate) {
+        this.registrationdate = registrationdate;
+    }
+
+    public PiwikInfo getPiwikInfo() {
+        return piwikInfo;
+    }
+
+    public void setPiwikInfo(PiwikInfo piwikInfo) {
+        this.piwikInfo = piwikInfo;
+    }
+
+    public String getLogoUrl() {
+        return logoUrl;
+    }
+
+    public void setLogoUrl(String logoUrl) {
+        this.logoUrl = logoUrl;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public String getFullTextDownload() {
+        return fullTextDownload;
+    }
+
+    public void setFullTextDownload(String fullTextDownload) {
+        this.fullTextDownload = fullTextDownload;
+    }
+
+    public String getConsentTermsOfUse() {
+        return consentTermsOfUse;
+    }
+
+    public void setConsentTermsOfUse(String consentTermsOfUse) {
+        this.consentTermsOfUse = consentTermsOfUse;
+    }
+
+    public Date getConsentTermsOfUseDate() {
+        return consentTermsOfUseDate;
+    }
+
+    public void setConsentTermsOfUseDate(Date consentTermsOfUseDate) {
+        this.consentTermsOfUseDate = consentTermsOfUseDate;
+    }
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/broker/DatasourcesBroker.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/broker/DatasourcesBroker.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/broker/DatasourcesBroker.java	(revision 61527)
@@ -0,0 +1,40 @@
+package eu.dnetlib.repo.manager.domain.broker;
+
+
+import eu.dnetlib.repo.manager.domain.Tuple;
+
+import java.util.List;
+
+/**
+ * Created by stefanos on 31/10/2016.
+ */
+public class DatasourcesBroker   {
+
+    private List<Tuple<BrowseEntry, String>> datasourcesOfUser;
+    private List<Tuple<BrowseEntry, String>> sharedDatasources;
+    private List<Tuple<BrowseEntry, String>> datasourcesOfOthers;
+
+    public List<Tuple<BrowseEntry, String>> getDatasourcesOfUser() {
+        return datasourcesOfUser;
+    }
+
+    public void setDatasourcesOfUser(List<Tuple<BrowseEntry, String>> datasourcesOfUser) {
+        this.datasourcesOfUser = datasourcesOfUser;
+    }
+
+    public List<Tuple<BrowseEntry, String>> getSharedDatasources() {
+        return sharedDatasources;
+    }
+
+    public void setSharedDatasources(List<Tuple<BrowseEntry, String>> sharedDatasources) {
+        this.sharedDatasources = sharedDatasources;
+    }
+
+    public List<Tuple<BrowseEntry, String>> getDatasourcesOfOthers() {
+        return datasourcesOfOthers;
+    }
+
+    public void setDatasourcesOfOthers(List<Tuple<BrowseEntry, String>> datasourcesOfOthers) {
+        this.datasourcesOfOthers = datasourcesOfOthers;
+    }
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/Constants.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/Constants.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/Constants.java	(revision 61527)
@@ -0,0 +1,45 @@
+package eu.dnetlib.repo.manager.domain;
+
+
+
+/**
+ * Created by nikonas on 23/12/15.
+ */
+
+public class Constants{
+
+    public static final String MODE_LOCAL = "local";
+    public static final String MODE_DNET = "dnet";
+    public static final String MODE_LDAP = "ldap";
+    public static final String ENV_LAREFERENCIA = "lareferencia";
+
+    public static final String ENV_MINCYT = "mincyt";
+    public static final String ENV_OPENAIRE_PRODUCTION = "openaire-production";
+    public static final String ENV_OPENAIRE_BETA = "openaire-beta";
+    public static final String ENV_DEVELOPMENT = "development";
+    public static final String LATITUDE_PATTERN = "^(\\+|-)?(?:90(?:(?:\\.0{1,6})?)|(?:[0-9]|[1-8][0-9])(?:(?:\\.[0-9]{1,6})?))$";
+
+    public static final String LONGITUDE_PATTERN = "^(\\+|-)?(?:180(?:(?:\\.0{1,6})?)|(?:[0-9]|[1-9][0-9]|1[0-7][0-9])(?:(?:\\.[0-9]{1,6})?))$";
+    public static final String EMAIL_PATTERN = "^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$";
+
+
+    public static final String REPOSITORY_MODE_OPENDOAR = "opendoar";
+    public static final String REPOSITORY_MODE_RE3DATA = "re3data";
+    public static final String REPOSITORY_MODE_JOURNAL = "journal";
+    public static final String REPOSITORY_MODE_AGGREGATOR = "aggregator";
+    public static final String REPOSITORY_MODE_ALL = "all";
+
+    public static final String VALIDATION_MODE_LITERATURE = "literature";
+    public static final String VALIDATION_MODE_DATA = "data";
+    public static final String VALIDATION_MODE_CRIS = "cris";
+    public static final String VALIDATION_MODE_FAIR = "fair";
+
+    public static final String VALIDATION_JOB_TYPE_COMPATIBILITY_TEST = "Compatibility Test";
+    public static final String VALIDATION_JOB_TYPE_REGISTRATION_REQUEST = "Registration Request";
+    public static final String VALIDATION_JOB_TYPE_WORKFLOW_REQUEST = "Workflow Request";
+
+    public static final String VALIDATION_JOB_STATUS_SUCCESSFUL = "successful";
+    public static final String VALIDATION_JOB_STATUS_FAILED = "failed";
+    public static final String VALIDATION_JOB_STATUS_ONGOING = "ongoing";
+
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/broker/BrowseEntry.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/broker/BrowseEntry.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/broker/BrowseEntry.java	(revision 61527)
@@ -0,0 +1,40 @@
+package eu.dnetlib.repo.manager.domain.broker;
+
+/**
+ * Created by stefanos on 26/10/2016.
+ */
+public class BrowseEntry implements Comparable<BrowseEntry>{
+
+    private String value;
+    private Long size;
+
+    public BrowseEntry() {
+    }
+
+    public BrowseEntry(final String value, final Long size) {
+        this.value = value;
+        this.size = size;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+
+    public Long getSize() {
+        return size;
+    }
+
+    public void setSize(Long size) {
+        this.size = size;
+    }
+
+    @Override
+    public int compareTo(final BrowseEntry bv) {
+        return Long.compare(getSize(), bv.getSize());
+    }
+
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/PiWikServiceImpl.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/PiWikServiceImpl.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/PiWikServiceImpl.java	(revision 61527)
@@ -0,0 +1,230 @@
+package eu.dnetlib.repo.manager.service;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import eu.dnetlib.domain.data.PiwikInfo;
+import eu.dnetlib.domain.data.Repository;
+import eu.dnetlib.repo.manager.domain.OrderByField;
+import eu.dnetlib.repo.manager.domain.OrderByType;
+import eu.dnetlib.repo.manager.domain.RepositoryServiceException;
+import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.log4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.dao.EmptyResultDataAccessException;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.core.RowMapper;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.stereotype.Service;
+
+import javax.sql.DataSource;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URL;
+import java.net.URLEncoder;
+import java.sql.Types;
+import java.util.List;
+import java.util.Map;
+
+@Service("piwikService")
+public class PiWikServiceImpl implements PiWikService {
+
+    @Autowired
+    private DataSource dataSource;
+
+
+    @Value("${services.repomanager.analyticsURL}")
+    private String analyticsURL;
+
+
+    @Autowired
+    private RepositoryService repositoryService;
+
+    @Autowired
+    @Qualifier("emailUtils")
+    private EmailUtils emailUtils;
+
+    private static final Logger LOGGER = Logger
+            .getLogger(PiWikServiceImpl.class);
+
+    private final static String GET_PIWIK_SITE = "select repositoryid, siteid, authenticationtoken, creationdate, requestorname, requestoremail, validated, validationdate, comment, repositoryname, country from piwik_site where repositoryid = ?;";
+
+    private final static String INSERT_PIWIK_INFO = "insert into piwik_site (repositoryid, siteid, creationdate, requestorname, requestoremail, validated, repositoryname, country, authenticationtoken) values (?, ?, now(), ?, ?, ?, ?, ?, ?)";
+
+    private final static String GET_PIWIK_SITES = "select  repositoryid, siteid, authenticationtoken, creationdate, requestorname, requestoremail, validated, validationdate, comment, repositoryname, country from piwik_site ";
+
+    private final static String GET_PIWIK_SITES_TOTAL = "select count(*) as totals from piwik_site ";
+
+    private final static String APPROVE_PIWIK_SITE = "update piwik_site set validated=true, validationdate=now() where repositoryid = ?;";
+
+    private RowMapper<PiwikInfo> piwikRowMapper = (rs, i) -> new PiwikInfo(rs.getString("repositoryid"), getOpenaireId(rs.getString("repositoryid")), rs.getString("repositoryname"), rs.getString("country"),
+            rs.getString("siteid"), rs.getString("authenticationtoken"), rs.getTimestamp("creationdate"), rs.getString("requestorname"), rs.getString("requestoremail"),
+            rs.getBoolean("validated"), rs.getTimestamp("validationdate"), rs.getString("comment"));
+
+
+    @Override
+    public PiwikInfo getPiwikSiteForRepo(String repositoryId) {
+        try {
+            return new JdbcTemplate(dataSource).queryForObject(GET_PIWIK_SITE, new String[]{repositoryId}, new int[]{Types.VARCHAR}, piwikRowMapper);
+        } catch (EmptyResultDataAccessException e) {
+            return null;
+        }
+    }
+
+    @Override
+    @PreAuthorize("hasAuthority('SUPER_ADMINISTRATOR') or hasAuthority('CONTENT_PROVIDER_DASHBOARD_ADMINISTRATOR') or (hasAuthority('REGISTERED_USER') and #piwikInfo.requestorEmail == authentication.userInfo.email)")
+    public PiwikInfo savePiwikInfo(PiwikInfo piwikInfo) {
+        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
+        jdbcTemplate.update(INSERT_PIWIK_INFO, new Object[]{piwikInfo.getRepositoryId(), piwikInfo.getSiteId(), piwikInfo.getRequestorName(),
+                        piwikInfo.getRequestorEmail(), piwikInfo.isValidated(), piwikInfo.getRepositoryName(), piwikInfo.getCountry(), piwikInfo.getAuthenticationToken()},
+                new int[]{Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.BOOLEAN, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR});
+        return piwikInfo;
+    }
+
+    @Override
+    public List<PiwikInfo> getPiwikSitesForRepos(OrderByField orderByField, OrderByType orderByType, int from, int quantity, String searchField) {
+        try {
+            String finalizedQuery = GET_PIWIK_SITES + " where (" +
+                    " repositoryid ilike ? " +
+                    " or siteid ilike ?" +
+                    " or requestorname ilike ?" +
+                    " or requestoremail ilike ?" +
+                    " or comment ilike ?" +
+                    " or repositoryname ilike ?" +
+                    " or country ilike ?"
+                    + ") order by " + orderByField + " " + orderByType + " offset ? limit ?";
+
+            return new JdbcTemplate(dataSource).query(finalizedQuery, preparedStatement -> {
+                preparedStatement.setString(1, "%" + searchField + "%");
+                preparedStatement.setString(2, "%" + searchField + "%");
+                preparedStatement.setString(3, "%" + searchField + "%");
+                preparedStatement.setString(4, "%" + searchField + "%");
+                preparedStatement.setString(5, "%" + searchField + "%");
+                preparedStatement.setString(6, "%" + searchField + "%");
+                preparedStatement.setString(7, "%" + searchField + "%");
+                preparedStatement.setInt(8, from);
+                preparedStatement.setInt(9, quantity);
+            }, piwikRowMapper);
+        } catch (EmptyResultDataAccessException e) {
+            return null;
+        }
+
+    }
+
+    @Override
+    public int getPiwikSitesTotals(String searchField) {
+        try {
+            String finalizedQuery = GET_PIWIK_SITES_TOTAL + " where (" +
+                    " repositoryid ilike ? " +
+                    " or siteid ilike ?" +
+                    " or requestorname ilike ?" +
+                    " or requestoremail ilike ?" +
+                    " or comment ilike ?" +
+                    " or repositoryname ilike ?" +
+                    " or country ilike ?)";
+
+            return new JdbcTemplate(dataSource).query(finalizedQuery, preparedStatement -> {
+                preparedStatement.setString(1, "%" + searchField + "%");
+                preparedStatement.setString(2, "%" + searchField + "%");
+                preparedStatement.setString(3, "%" + searchField + "%");
+                preparedStatement.setString(4, "%" + searchField + "%");
+                preparedStatement.setString(5, "%" + searchField + "%");
+                preparedStatement.setString(6, "%" + searchField + "%");
+                preparedStatement.setString(7, "%" + searchField + "%");
+            }, rowMapper -> {
+                rowMapper.next();
+                return rowMapper.getInt("totals");
+            });
+        } catch (EmptyResultDataAccessException e) {
+            return 0;
+        }
+    }
+
+    @Override
+    @PreAuthorize("hasAuthority('SUPER_ADMINISTRATOR') or hasAuthority('CONTENT_PROVIDER_DASHBOARD_ADMINISTRATOR')")
+    public ResponseEntity<Object> approvePiwikSite(String repositoryId) {
+        new JdbcTemplate(dataSource).update(APPROVE_PIWIK_SITE, new Object[]{repositoryId}, new int[]{Types.VARCHAR});
+        return new ResponseEntity<>("OK", HttpStatus.OK);
+    }
+
+    @Override
+    public String getOpenaireId(String repositoryId) {
+        if (repositoryId != null && repositoryId.contains("::"))
+            return repositoryId.split("::")[0] + "::" + DigestUtils.md5Hex(repositoryId.split("::")[1]);
+        return null;
+    }
+
+    @Override
+    @PreAuthorize("hasAuthority('SUPER_ADMINISTRATOR') or hasAuthority('CONTENT_PROVIDER_DASHBOARD_ADMINISTRATOR')")
+    public ResponseEntity<Object> markPiwikSiteAsValidated(String repositoryId) throws RepositoryServiceException {
+        try {
+            approvePiwikSite(repositoryId);
+
+            PiwikInfo piwikInfo = getPiwikSiteForRepo(repositoryId);
+            emailUtils.sendAdministratorMetricsEnabled(piwikInfo);
+            emailUtils.sendUserMetricsEnabled(piwikInfo);
+
+        } catch (EmptyResultDataAccessException e) {
+            LOGGER.error("Error while approving piwik site: ", e);
+            emailUtils.reportException(e);
+            throw new RepositoryServiceException("General error", RepositoryServiceException.ErrorCode.GENERAL_ERROR);
+        } catch (Exception e) {
+            LOGGER.error("Error while sending email to administrator or user about the enabling of metrics", e);
+            emailUtils.reportException(e);
+        }
+        return new ResponseEntity<>("OK", HttpStatus.OK);
+    }
+
+    @Override
+    @PreAuthorize("hasAuthority('SUPER_ADMINISTRATOR') or hasAuthority('CONTENT_PROVIDER_DASHBOARD_ADMINISTRATOR') or (hasAuthority('REGISTERED_USER') and #piwikInfo.requestorEmail == authentication.userInfo.email)")
+    public PiwikInfo enableMetricsForRepository(String officialName,
+                                                String repoWebsite,
+                                                PiwikInfo piwikInfo) throws RepositoryServiceException {
+        try {
+            String URL = analyticsURL + "siteName=" + URLEncoder.encode(officialName, "UTF-8") + "&url="
+                    + URLEncoder.encode(repoWebsite, "UTF-8");
+            Map map = new ObjectMapper().readValue(new URL(URL), Map.class);
+            String siteId = null;
+            if (map.get("value") != null) {
+                siteId = map.get("value").toString();
+            }
+            piwikInfo.setSiteId(siteId);
+
+            savePiwikInfo(piwikInfo);
+
+            Repository repository = repositoryService.getRepositoryById(piwikInfo.getRepositoryId());
+            repository.setPiwikInfo(piwikInfo);
+
+            repositoryService.updateRepository(repository, SecurityContextHolder.getContext().getAuthentication());
+
+            emailUtils.sendAdministratorRequestToEnableMetrics(piwikInfo);
+            emailUtils.sendUserRequestToEnableMetrics(piwikInfo);
+        } catch (UnsupportedEncodingException uee) {
+            LOGGER.error("Error while creating piwikScript URL", uee);
+            emailUtils.reportException(uee);
+            throw new RepositoryServiceException("login.generalError", RepositoryServiceException.ErrorCode.GENERAL_ERROR);
+        } catch (IOException ioe) {
+            LOGGER.error("Error while creating piwik site", ioe);
+            emailUtils.reportException(ioe);
+            throw new RepositoryServiceException("login.generalError", RepositoryServiceException.ErrorCode.GENERAL_ERROR);
+        } catch (Exception e) {
+            LOGGER.error("Error while sending email to administrator or user about the request to enable metrics", e);
+            emailUtils.reportException(e);
+        }
+        return piwikInfo;
+    }
+
+    @Override
+    public Integer getTotal() {
+        return new JdbcTemplate(dataSource).queryForObject(GET_PIWIK_SITES_TOTAL, new Object[]{}, Integer.class);
+    }
+
+    @Override
+    public Integer getValidated(boolean validated) {
+        String finalizedQuery = GET_PIWIK_SITES_TOTAL + " where validated = ?";
+        return new JdbcTemplate(dataSource).queryForObject(finalizedQuery, new Object[]{validated}, Integer.class);
+    }
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/ValidatorService.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/ValidatorService.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/ValidatorService.java	(revision 61527)
@@ -0,0 +1,45 @@
+package eu.dnetlib.repo.manager.service;
+
+import eu.dnetlib.api.functionality.ValidatorServiceException;
+import eu.dnetlib.domain.functionality.validator.JobForValidation;
+import eu.dnetlib.domain.functionality.validator.RuleSet;
+import eu.dnetlib.domain.functionality.validator.StoredJob;
+import eu.dnetlib.repo.manager.domain.InterfaceInformation;
+import eu.dnetlib.repo.manager.domain.ValidationServiceException;
+import eu.dnetlib.repo.manager.exception.ResourceNotFoundException;
+import org.json.JSONException;
+import org.springframework.http.ResponseEntity;
+
+import java.util.List;
+
+
+
+public interface ValidatorService {
+
+
+    JobForValidation submitJobForValidation(JobForValidation jobForValidation) throws ValidatorServiceException;
+
+    ResponseEntity<Object> reSubmitJobForValidation(String email, String jobId) throws JSONException, ValidatorServiceException;
+
+    List<RuleSet> getRuleSets(String mode);
+
+    List<String> getSetsOfRepository(String url);
+
+    boolean identifyRepo(String url);
+
+    RuleSet getRuleSet(String acronym);
+
+    List<StoredJob> getStoredJobsNew(String user,
+                                     String jobType,
+                                     String offset,
+                                     String limit,
+                                     String dateFrom,
+                                     String dateTo,
+                                     String validationStatus) throws ValidatorServiceException;
+
+    int getStoredJobsTotalNumberNew(String user, String jobType, String validationStatus) throws ValidatorServiceException;
+
+    InterfaceInformation getInterfaceInformation(String baseUrl) throws ValidationServiceException;
+
+    List<StoredJob> getJobsSummary(String repoId, int limit) throws ValidatorServiceException, ResourceNotFoundException, JSONException;
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/broker/MapConditions.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/broker/MapConditions.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/broker/MapConditions.java	(revision 61527)
@@ -0,0 +1,52 @@
+package eu.dnetlib.repo.manager.domain.broker;
+
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by stefanos on 17/3/2017.
+ */
+public class MapConditions   {
+
+    private String field;
+    private MapValueType fieldType;
+    private ConditionOperator operator;
+    private List<ConditionParams> listParams = new ArrayList<>();
+
+    public MapConditions() {
+    }
+
+    public String getField() {
+        return field;
+    }
+
+    public void setField(String field) {
+        this.field = field;
+    }
+
+    public MapValueType getFieldType() {
+        return fieldType;
+    }
+
+    public void setFieldType(MapValueType fieldType) {
+        this.fieldType = fieldType;
+    }
+
+    public ConditionOperator getOperator() {
+        return operator;
+    }
+
+    public void setOperator(ConditionOperator operator) {
+        this.operator = operator;
+    }
+
+    public List<ConditionParams> getListParams() {
+        return listParams;
+    }
+
+    public void setListParams(List<ConditionParams> listParams) {
+        this.listParams = listParams;
+    }
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/broker/AdvQueryObject.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/broker/AdvQueryObject.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/broker/AdvQueryObject.java	(revision 61527)
@@ -0,0 +1,99 @@
+package eu.dnetlib.repo.manager.domain.broker;
+
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class AdvQueryObject   {
+
+    private String datasource = "";
+    private String topic = "";
+    private List<String> titles = new ArrayList<>();
+    private List<String> subjects = new ArrayList<>();
+    private List<String> authors = new ArrayList<>();
+    private List<Range> dates = new ArrayList<>();
+    private Range trust = new Range("0", "1");
+
+    private long page = 0;
+
+    public AdvQueryObject() {
+    }
+
+    public AdvQueryObject(String datasource, String topic, List<String> titles, List<String> subjects, List<String> authors,
+                          List<Range> dates, Range trust, long page) {
+        this.datasource = datasource;
+        this.topic = topic;
+        this.titles = titles;
+        this.subjects = subjects;
+        this.authors = authors;
+        this.dates = dates;
+        this.trust = trust;
+        this.page = page;
+    }
+
+    public String getDatasource() {
+        return datasource;
+    }
+
+    public void setDatasource(String datasource) {
+        this.datasource = datasource;
+    }
+
+    public String getTopic() {
+        return topic;
+    }
+
+    public void setTopic(String topic) {
+        this.topic = topic;
+    }
+
+    public List<String> getTitles() {
+        return titles;
+    }
+
+    public void setTitles(List<String> titles) {
+        this.titles = titles;
+    }
+
+    public List<String> getSubjects() {
+        return subjects;
+    }
+
+    public void setSubjects(List<String> subjects) {
+        this.subjects = subjects;
+    }
+
+    public List<String> getAuthors() {
+        return authors;
+    }
+
+    public void setAuthors(List<String> authors) {
+        this.authors = authors;
+    }
+
+    public List<Range> getDates() {
+        return dates;
+    }
+
+    public void setDates(List<Range> dates) {
+        this.dates = dates;
+    }
+
+    public Range getTrust() {
+        return trust;
+    }
+
+    public void setTrust(Range trust) {
+        this.trust = trust;
+    }
+
+    public long getPage() {
+        return page;
+    }
+
+    public void setPage(long page) {
+        this.page = page;
+    }
+}
+
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/broker/NotificationMode.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/broker/NotificationMode.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/broker/NotificationMode.java	(revision 61527)
@@ -0,0 +1,10 @@
+package eu.dnetlib.repo.manager.domain.broker;
+
+
+
+/**
+ * Created by stefanos on 10-Mar-17.
+ */
+public enum NotificationMode   {
+    MOCK, EMAIL
+}
\ No newline at end of file
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/MonitorService.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/MonitorService.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/MonitorService.java	(revision 61527)
@@ -0,0 +1,29 @@
+package eu.dnetlib.repo.manager.service;
+
+import eu.dnetlib.api.functionality.ValidatorServiceException;
+import eu.dnetlib.domain.functionality.validator.StoredJob;
+import eu.dnetlib.repo.manager.domain.JobsOfUser;
+import org.json.JSONException;
+
+
+public interface MonitorService {
+
+
+    JobsOfUser getJobsOfUser(String user,
+                             String jobType,
+                             String offset,
+                             String limit,
+                             String dateFrom,
+                             String dateTo,
+                             String validationStatus,
+                             String includeJobsTotal) throws JSONException, ValidatorServiceException;
+
+    int getJobsOfUserPerValidationStatus(String user,
+                                         String jobType,
+                                         String validationStatus) throws JSONException;
+
+
+    StoredJob getJobSummary(String jobId,
+                            String groupBy) throws JSONException;
+
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/broker/MapValueType.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/broker/MapValueType.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/broker/MapValueType.java	(revision 61527)
@@ -0,0 +1,9 @@
+package eu.dnetlib.repo.manager.domain.broker;
+
+
+/**
+ * Created by stefanos on 17/3/2017.
+ */
+public enum MapValueType {
+    STRING, INTEGER, FLOAT, DATE, BOOLEAN, LIST_STRING, LIST_INTEGER, LIST_FLOAT, LIST_DATE, LIST_BOOLEAN;
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/WizardState.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/WizardState.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/WizardState.java	(revision 61527)
@@ -0,0 +1,9 @@
+package eu.dnetlib.repo.manager.domain;
+
+
+
+/**
+ * Created by stefania on 2/10/16.
+ */
+public class WizardState   {
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/BrokerException.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/BrokerException.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/BrokerException.java	(revision 61527)
@@ -0,0 +1,17 @@
+package eu.dnetlib.repo.manager.domain;
+
+
+/**
+ * Created by stefanos on 27-Oct-16.
+ */
+public class BrokerException extends Exception {
+
+    public BrokerException(Throwable th) {
+        super(th);
+    }
+
+    public BrokerException() {
+    }
+
+
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/StatsServiceImpl.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/StatsServiceImpl.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/StatsServiceImpl.java	(revision 61527)
@@ -0,0 +1,50 @@
+package eu.dnetlib.repo.manager.service;
+
+import eu.dnetlib.repo.manager.service.customHystrixCommands.*;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.RestTemplate;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@Service("statsService")
+public class StatsServiceImpl implements StatsService {
+
+    @Autowired
+    RestTemplate restTemplate;
+
+    @Value("${search.api.baseAddress}")
+    private String baseAddress;
+    @Value("${search.api.usagestats}")
+    private String usagestatsBaseAddress;
+    @Value("${search.api.usageEvents}")
+    private String usagestatsEvents;
+
+    @Override
+    public Map getStatistics()  {
+
+        UsageStatsTotalHystrixCommand usageStatsTotalHystrixCommand = new UsageStatsTotalHystrixCommand(usagestatsEvents,restTemplate);
+        DataRepositoriesHystrixCommand dataRepositoriesHystrixCommand = new DataRepositoriesHystrixCommand(baseAddress,restTemplate);
+        AggregatorsHystrixCommand aggregatorsHystrixCommand = new AggregatorsHystrixCommand(baseAddress,restTemplate);
+        LiteratureHystrixCommand literatureHystrixCommand = new LiteratureHystrixCommand(baseAddress,restTemplate);
+        JournalHystrixCommand journalHystrixCommand = new JournalHystrixCommand(baseAddress,restTemplate);
+        PublicationHystrixCommand publicationHystrixCommand = new PublicationHystrixCommand(baseAddress,restTemplate);
+        DatasetsHystrixCommand datasetsHystrixCommand = new DatasetsHystrixCommand(baseAddress,restTemplate);
+        SoftwareHystrixCommand softwareHystrixCommand = new SoftwareHystrixCommand(baseAddress,restTemplate);
+        LastYearUsageStatsHystrixCommand lastYearUsageStatsHystrixCommand = new LastYearUsageStatsHystrixCommand(usagestatsBaseAddress,restTemplate);
+
+        Map<String,Object> stats = new HashMap<>();
+        stats.put("aggregators",aggregatorsHystrixCommand.execute());
+        stats.put("dataRepositories",dataRepositoriesHystrixCommand.execute());
+        stats.put("literature",literatureHystrixCommand.execute());
+        stats.put("journal",journalHystrixCommand.execute());
+        stats.put("publications",publicationHystrixCommand.execute());
+        stats.put("datasets",datasetsHystrixCommand.execute());
+        stats.put("software",softwareHystrixCommand.execute());
+        stats.put("lastYearUsagestats", lastYearUsageStatsHystrixCommand.execute());
+        stats.put("usagestats",usageStatsTotalHystrixCommand.execute());
+        return stats;
+    }
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/customHystrixCommands/DatasetsHystrixCommand.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/customHystrixCommands/DatasetsHystrixCommand.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/customHystrixCommands/DatasetsHystrixCommand.java	(revision 61527)
@@ -0,0 +1,44 @@
+package eu.dnetlib.repo.manager.service.customHystrixCommands;
+
+import com.netflix.hystrix.HystrixCommand;
+import com.netflix.hystrix.HystrixCommandGroupKey;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.client.RestTemplate;
+import org.springframework.web.util.UriComponents;
+import org.springframework.web.util.UriComponentsBuilder;
+
+import java.util.Map;
+
+public class DatasetsHystrixCommand extends HystrixCommand<String> {
+
+    RestTemplate restTemplate;
+    String baseAddress;
+
+    public DatasetsHystrixCommand(String baseAddress,RestTemplate restTemplate) {
+        super(HystrixCommandGroupKey.Factory.asKey("StatisticsGroup"));
+        this.restTemplate = restTemplate;
+        this.baseAddress = baseAddress;
+    }
+
+    @Override
+    protected String run() throws Exception {
+        String url = baseAddress+"/datasets/count";
+
+        UriComponents uriComponents = UriComponentsBuilder
+                .fromHttpUrl(url)
+                .queryParam("page", 0)
+                .queryParam("size", 0)
+                .queryParam("format", "json")
+                .build().encode();
+
+        ResponseEntity rs = restTemplate.exchange(uriComponents.toUri(), HttpMethod.GET, null, Map.class);
+        Map metadata = (Map) (rs.getBody());
+        return String.valueOf(metadata.get("total"));
+    }
+
+    @Override
+    protected String getFallback() {
+        return null;
+    }
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/RepositoryServiceImpl.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/RepositoryServiceImpl.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/RepositoryServiceImpl.java	(revision 61527)
@@ -0,0 +1,1087 @@
+package eu.dnetlib.repo.manager.service;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import eu.dnetlib.api.functionality.ValidatorServiceException;
+import eu.dnetlib.domain.data.Repository;
+import eu.dnetlib.domain.data.RepositoryInterface;
+import eu.dnetlib.domain.enabling.Vocabulary;
+import eu.dnetlib.domain.functionality.validator.JobForValidation;
+import eu.dnetlib.repo.manager.domain.*;
+import eu.dnetlib.repo.manager.domain.dto.Role;
+import eu.dnetlib.repo.manager.exception.ResourceNotFoundException;
+import eu.dnetlib.repo.manager.service.aai.registry.AaiRegistryService;
+import eu.dnetlib.repo.manager.service.security.AuthoritiesUpdater;
+import eu.dnetlib.repo.manager.service.security.AuthorizationService;
+import eu.dnetlib.repo.manager.service.security.RoleMappingService;
+import eu.dnetlib.repo.manager.utils.Converter;
+import gr.uoa.di.driver.enabling.vocabulary.VocabularyLoader;
+import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.log4j.Logger;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.mitre.openid.connect.model.OIDCAuthenticationToken;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.core.ParameterizedTypeReference;
+import org.springframework.http.*;
+import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.HttpClientErrorException;
+import org.springframework.web.client.RestClientException;
+import org.springframework.web.client.RestTemplate;
+import org.springframework.web.util.UriComponents;
+import org.springframework.web.util.UriComponentsBuilder;
+
+import javax.annotation.PostConstruct;
+import java.io.IOException;
+import java.sql.Timestamp;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Collectors;
+
+@Service("repositoryService")
+public class RepositoryServiceImpl implements RepositoryService {
+
+    private static final Logger LOGGER = Logger.getLogger(RepositoryServiceImpl.class);
+
+    private final AuthorizationService authorizationService;
+    private final RoleMappingService roleMappingService;
+    private final AaiRegistryService registryCalls;
+    private final AuthoritiesUpdater authoritiesUpdater;
+    private final RestTemplate restTemplate;
+    private final VocabularyLoader vocabularyLoader;
+    private final PiWikService piWikService;
+    private final EmailUtils emailUtils;
+    private final ValidatorService validatorService;
+
+    @Value("${api.baseAddress}")
+    private String baseAddress;
+
+    @Value("${services.repo-manager.adminEmail}")
+    private String adminEmail;
+
+    @Value("${services.repomanager.usageStatisticsDiagramsBaseURL}")
+    private String usageStatisticsDiagramsBaseURL;
+
+    @Value("${services.repomanager.usageStatisticsNumbersBaseURL}")
+    private String usageStatisticsNumbersBaseURL;
+
+
+    private static final Map<String, List<String>> dataSourceClass = new HashMap<>();
+    private static final Map<String, String> invertedDataSourceClass = new HashMap<>();
+
+
+    private final String[] vocabularyNames = {"dnet:countries", "dnet:datasource_typologies", "dnet:compatibilityLevel"};
+    private final Map<String, Vocabulary> vocabularyMap = new ConcurrentHashMap<>();
+    private final Map<String, String> countriesMap = new HashMap<>();
+    private final Map<String, String> inverseCountriesMap = new HashMap<>();
+
+    private HttpHeaders httpHeaders;
+
+    @Autowired
+    public RepositoryServiceImpl(AuthorizationService authorizationService,
+                                 RoleMappingService roleMappingService,
+                                 AaiRegistryService registryCalls,
+                                 AuthoritiesUpdater authoritiesUpdater,
+                                 VocabularyLoader vocabularyLoader,
+                                 RestTemplate restTemplate,
+                                 @Lazy EmailUtils emailUtils,
+                                 @Lazy ValidatorService validatorService,
+                                 @Lazy PiWikService piWikService) {
+        this.authorizationService = authorizationService;
+        this.roleMappingService = roleMappingService;
+        this.registryCalls = registryCalls;
+        this.authoritiesUpdater = authoritiesUpdater;
+        this.vocabularyLoader = vocabularyLoader;
+        this.piWikService = piWikService;
+        this.emailUtils = emailUtils;
+        this.validatorService = validatorService;
+        this.restTemplate = restTemplate;
+    }
+
+    private String getAuthenticatedUserEmail() {
+        OIDCAuthenticationToken authenticationToken = (OIDCAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
+        return authenticationToken.getUserInfo().getEmail();
+    }
+
+
+    @PostConstruct
+    private void init() {
+        LOGGER.debug("Initialization method of repository api!");
+        LOGGER.debug("Updated version!");
+
+        dataSourceClass.put("opendoar", Arrays.asList("pubsrepository::institutional", "pubsrepository::thematic", "pubsrepository::unknown", "pubsrepository::mock"));
+        dataSourceClass.put("re3data", Collections.singletonList("datarepository::unknown"));
+        dataSourceClass.put("journal", Collections.singletonList("pubsrepository::journal"));
+        dataSourceClass.put("aggregator", Arrays.asList("aggregator::pubsrepository::institutional", "aggregator::pubsrepository::journals", "aggregator::datarepository", "aggregator::pubsrepository::unknown"));
+
+        invertedDataSourceClass.put("pubsrepository::institutional", "opendoar");
+        invertedDataSourceClass.put("pubsrepository::thematic", "opendoar");
+        invertedDataSourceClass.put("pubsrepository::unknown", "opendoar");
+        invertedDataSourceClass.put("pubsrepository::mock", "opendoar");
+        invertedDataSourceClass.put("datarepository::unknown", "re3data");
+        invertedDataSourceClass.put("pubsrepository::journal", "journal");
+        invertedDataSourceClass.put("aggregator::pubsrepository::institutional", "aggregator");
+        invertedDataSourceClass.put("aggregator::pubsrepository::journals", "aggregator");
+        invertedDataSourceClass.put("aggregator::datarepository", "aggregator");
+        invertedDataSourceClass.put("aggregator::pubsrepository::unknown", "aggregator");
+
+
+        httpHeaders = new HttpHeaders();
+        httpHeaders.setContentType(MediaType.APPLICATION_JSON_UTF8);
+
+        for (String vocName : vocabularyNames) {
+            vocabularyMap.put(vocName, vocabularyLoader.getVocabulary(vocName, Locale.ENGLISH, Locale.ROOT));
+        }
+
+        Country[] countries = getCountries();
+        for (Country c : countries) {
+            countriesMap.put(c.getName(), c.getCode());
+            inverseCountriesMap.put(c.getCode(), c.getName());
+        }
+
+
+    }
+
+    @Override
+    public Country[] getCountries() {
+        UriComponents uriComponents = UriComponentsBuilder
+                .fromHttpUrl(baseAddress + "/ds/countries")
+                .build().encode();
+        return restTemplate.getForObject(uriComponents.toUri(), Country[].class);
+    }
+    
+    // FIXME: with the new roles of the users the "requestFilter.setRegisteredby(userEmail)" can no longer be used
+    //  and the "requestFilter.setId(repoId)" should return only one result at a time, thus,
+    //  another way for paging must be implemented.
+    @Override
+    public List<Repository> getRepositories(List<String> ids) throws JSONException {
+        return getRepositories(ids, 0, 10);
+    }
+
+    // FIXME: with the new roles of the users the "requestFilter.setRegisteredby(userEmail)" can no longer be used
+    //  and the "requestFilter.setId(repoId)" should return only one result at a time, thus,
+    //  another way for paging must be implemented.
+    @Override
+    public List<Repository> getRepositories(List<String> ids, int page, int size) throws JSONException {
+        List<Repository> repos = new ArrayList<>();
+        LOGGER.debug("Retreiving repositories with ids : " + String.join(", ", ids));
+        UriComponents uriComponents = searchDatasource(Integer.toString(Math.abs(page)), Integer.toString(Math.abs(size)));
+        RequestFilter requestFilter = new RequestFilter();
+
+        try {
+            for (String repoId : ids) {
+                requestFilter.setId(repoId);
+                String rs = restTemplate.postForObject(uriComponents.toUri(), requestFilter, String.class);
+
+                repos.addAll(Converter.jsonToRepositoryList(new JSONObject(rs)));
+            }
+        } catch (JSONException e) {
+            LOGGER.debug("Exception on getRepositoriesOfUser", e);
+            emailUtils.reportException(e);
+            throw e;
+        }
+
+        for (Repository r : repos)
+            r.setPiwikInfo(piWikService.getPiwikSiteForRepo(r.getId()));
+        return repos;
+    }
+
+    // FIXME: with the new roles of the users the "requestFilter.setRegisteredby(userEmail)" can no longer be used
+    //  and the "requestFilter.setId(repoId)" should return only one result at a time, thus,
+    //  another way for paging must be implemented.
+    @Override
+    public List<RepositorySnippet> getRepositoriesSnippets(List<String> ids) throws Exception {
+        return getRepositoriesSnippets(ids, 0, 10);
+    }
+
+    // FIXME: with the new roles of the users the "requestFilter.setRegisteredby(userEmail)" can no longer be used
+    //  and the "requestFilter.setId(repoId)" should return only one result at a time, thus,
+    //  another way for paging must be implemented.
+    @Override
+    public List<RepositorySnippet> getRepositoriesSnippets(List<String> ids, int page, int size) throws Exception {
+        List<RepositorySnippet> resultSet = new ArrayList<>();
+        ObjectMapper mapper = new ObjectMapper();
+
+        // here page should be 0
+        UriComponents uriComponents = searchSnipperDatasource(Integer.toString(Math.abs(page)), Integer.toString(Math.abs(size)));
+        RequestFilter requestFilter = new RequestFilter();
+
+        try {
+            for (String repoId : ids) {
+                requestFilter.setId(repoId);
+
+                String rs = restTemplate.postForObject(uriComponents.toUri(), requestFilter, String.class);
+                JSONArray jsonArray = (JSONArray) new JSONObject(rs).get("datasourceInfo");
+                resultSet.addAll(mapper.readValue(String.valueOf(jsonArray),
+                        mapper.getTypeFactory().constructCollectionType(List.class, RepositorySnippet.class)));
+            }
+        } catch (Exception e) {
+            LOGGER.debug("Exception on getRepositoriesSnippetOfUser", e);
+            throw e;
+        }
+
+        LOGGER.debug("resultSet:" + resultSet);
+        resultSet.parallelStream().forEach(repositorySnippet -> {
+            repositorySnippet.setPiwikInfo(piWikService.getPiwikSiteForRepo(repositorySnippet.getId()));
+        });
+        return resultSet;
+    }
+
+
+    @Override
+    public List<RepositorySnippet> getRepositoriesByCountry(String country,
+                                                            String mode,
+                                                            Boolean managed) throws JSONException, IOException {
+
+        LOGGER.debug("Getting repositories by country!");
+        int page = 0;
+        int size = 100;
+        List<RepositorySnippet> resultSet = new ArrayList<>();
+        ObjectMapper mapper = new ObjectMapper();
+
+        String filterKey = "UNKNOWN";
+        if (mode.equalsIgnoreCase("opendoar"))
+            filterKey = "openaire____::opendoar";
+        else if (mode.equalsIgnoreCase("re3data"))
+            filterKey = "openaire____::re3data";
+
+
+        LOGGER.debug("Country code equals : " + country);
+        LOGGER.debug("Filter mode equals : " + filterKey);
+
+        UriComponents uriComponents = searchSnipperDatasource(String.valueOf(page), String.valueOf(size));
+        RequestFilter requestFilter = new RequestFilter();
+        requestFilter.setCountry(country);
+        requestFilter.setCollectedfrom(filterKey);
+
+        try {
+            String rs = restTemplate.postForObject(uriComponents.toUri(), requestFilter, String.class);
+            JSONArray jsonArray = (JSONArray) new JSONObject(rs).get("datasourceInfo");
+            while (jsonArray.length() > 0) {
+                resultSet.addAll(mapper.readValue(String.valueOf(jsonArray),
+                        mapper.getTypeFactory().constructCollectionType(List.class, RepositorySnippet.class)));
+                page += 1;
+                uriComponents = searchSnipperDatasource(String.valueOf(page), String.valueOf(size));
+                rs = restTemplate.postForObject(uriComponents.toUri(), requestFilter, String.class);
+                jsonArray = (JSONArray) new JSONObject(rs).get("datasourceInfo");
+            }
+            return resultSet;
+        } catch (Exception e) {
+            LOGGER.debug("Exception on getRepositoriesByCountry", e);
+            emailUtils.reportException(e);
+            throw e;
+        }
+    }
+
+    public List<RepositorySnippet> searchRegisteredRepositories(String country, String typology, String englishName,
+                                                                String officialName, String requestSortBy, String order, int page, int pageSize) throws Exception {
+
+        LOGGER.debug("Searching registered repositories");
+
+        List<RepositorySnippet> resultSet = new ArrayList<>();
+        ObjectMapper mapper = new ObjectMapper();
+
+        UriComponents uriComponents = searchRegisteredDatasource(requestSortBy, order, Integer.toString(page), Integer.toString(pageSize));
+
+        RequestFilter requestFilter = new RequestFilter();
+        requestFilter.setCountry(country);
+        requestFilter.setTypology(typology);
+        requestFilter.setOfficialname(officialName);
+        requestFilter.setEnglishname(englishName);
+
+        try {
+            String rs = restTemplate.postForObject(uriComponents.toUri(), requestFilter, String.class);
+            JSONArray jsonArray = (JSONArray) new JSONObject(rs).get("datasourceInfo");
+
+            resultSet.addAll(mapper.readValue(String.valueOf(jsonArray), mapper.getTypeFactory().constructCollectionType(List.class, RepositorySnippet.class)));
+
+            return resultSet;
+        } catch (Exception e) {
+            LOGGER.error("Error searching registered datasources", e);
+            throw e;
+        }
+    }
+
+    private Repository updateRepositoryInfo(Repository r) throws JSONException {
+
+        /*
+         * from datasource class
+         * we get the datasource type form the inverted map
+         * */
+        r.setDatasourceType(getRepositoryType(r.getDatasourceClass()));
+        r.setInterfaces(this.getRepositoryInterface(r.getId()));
+        r.setPiwikInfo(piWikService.getPiwikSiteForRepo(r.getId()));
+        r.setCountryName(getCountryName(r.getCountryCode()));
+        return r;
+    }
+
+
+    private Collection<Repository> getRepositoriesByMode(String mode, List<Repository> rs) {
+
+        List<Repository> reps = new ArrayList<>();
+        for (Repository r : rs) {
+            if (r.getCollectedFrom() != null && r.getCollectedFrom().equals(mode))
+                reps.add(r);
+
+        }
+        return reps;
+    }
+
+    @Override
+    public List<Repository> getRepositoriesOfUser(String page, String size) throws JSONException {
+        String userEmail = ((OIDCAuthenticationToken) SecurityContextHolder.getContext().getAuthentication()).getUserInfo().getEmail();
+        LOGGER.debug("Retreiving repositories of authenticated user : " + userEmail);
+        Collection<String> repoIds = roleMappingService.getRepoIdsByRoleIds(authorizationService.getUserRoles());
+        return getRepositories(new ArrayList<>(repoIds));
+    }
+
+    @Override
+    public List<Repository> getRepositoriesOfUser(String userEmail, String page, String size) throws JSONException {
+        LOGGER.debug("Retreiving repositories of authenticated user : " + userEmail);
+        Collection<String> repoIds = roleMappingService.getRepoIdsByRoleIds(authorizationService.getUserRoles(userEmail));
+        return getRepositories(new ArrayList<>(repoIds));
+    }
+
+    @Override
+    public List<RepositorySnippet> getRepositoriesSnippetsOfUser(String page, String size) throws Exception {
+        Collection<String> repoIds = roleMappingService.getRepoIdsByRoleIds(authorizationService.getUserRoles());
+        return getRepositoriesSnippets(new ArrayList<>(repoIds));
+    }
+
+    @Override
+    public List<RepositorySnippet> getRepositoriesSnippetsOfUser(String userEmail, String page, String size) throws Exception {
+        Collection<String> repoIds = roleMappingService.getRepoIdsByRoleIds(authorizationService.getUserRoles(userEmail));
+        return getRepositoriesSnippets(new ArrayList<>(repoIds));
+    }
+
+    @Override
+    public RepositorySnippet getRepositorySnippetById(String id) throws JSONException, ResourceNotFoundException {
+
+        LOGGER.debug("Retreiving repositories with id : " + id);
+        RepositorySnippet repo = null;
+        UriComponents uriComponents = searchSnipperDatasource("0", "100");
+        RequestFilter requestFilter = new RequestFilter();
+        requestFilter.setId(id);
+
+        try {
+            String rs = restTemplate.postForObject(uriComponents.toUri(), requestFilter, String.class);
+            JSONArray jsonArray = (JSONArray) new JSONObject(rs).get("datasourceInfo");
+
+            if (jsonArray.length() == 0)
+                throw new ResourceNotFoundException();
+
+            repo = Converter.jsonToRepositorySnippetObject(jsonArray.getJSONObject(0));
+            return repo;
+        } catch (JSONException e) {
+            LOGGER.debug("Exception on getRepositoryById", e);
+            emailUtils.reportException(e);
+            throw e;
+        }
+
+    }
+
+    @Override
+    public Repository getRepositoryById(String id) throws JSONException, ResourceNotFoundException {
+
+        LOGGER.debug("Retreiving repositories with id : " + id);
+        Repository repo = null;
+        UriComponents uriComponents = searchDatasource("0", "100");
+        RequestFilter requestFilter = new RequestFilter();
+        requestFilter.setId(id);
+
+        try {
+            String rs = restTemplate.postForObject(uriComponents.toUri(), requestFilter, String.class);
+            JSONArray jsonArray = (JSONArray) new JSONObject(rs).get("datasourceInfo");
+
+            if (jsonArray.length() == 0)
+                throw new ResourceNotFoundException();
+
+            repo = Converter.jsonToRepositoryObject(jsonArray.getJSONObject(0));
+            return updateRepositoryInfo(repo);
+        } catch (JSONException e) {
+            LOGGER.debug("Exception on getRepositoryById", e);
+            emailUtils.reportException(e);
+            throw e;
+        }
+
+    }
+
+
+    @Override
+    public List<AggregationDetails> getRepositoryAggregations(String id, int from, int size) throws JSONException {
+
+        LOGGER.debug("Retreiving aggregations for repository with id : " + id);
+        UriComponents uriComponents = searchDatasource(from + "", size + "");
+        RequestFilter requestFilter = new RequestFilter();
+        requestFilter.setId(id);
+
+        List<AggregationDetails> aggregationHistory = new ArrayList<>();
+
+        try {
+            long start = System.currentTimeMillis();
+            String rs = restTemplate.postForObject(uriComponents.toUri(), requestFilter, String.class);
+            long end = System.currentTimeMillis();
+
+            System.out.println("Aggregations request through rest template took " + (end - start) + "ms");
+            JSONObject repository = new JSONObject(rs);
+
+            if (repository.getJSONArray("datasourceInfo").length() == 0)
+                return aggregationHistory;
+
+            start = System.currentTimeMillis();
+            aggregationHistory.addAll(Converter.getAggregationHistoryFromJson(repository.getJSONArray("datasourceInfo").getJSONObject(0)));
+            end = System.currentTimeMillis();
+
+            System.out.println("Getting aggregations history from json " + (end - start) + "ms");
+            return aggregationHistory.size() == 0 ? aggregationHistory : aggregationHistory.stream()
+                    .sorted(Comparator.comparing(AggregationDetails::getDate).reversed())
+                    .limit(size)
+                    .collect(Collectors.toList());
+        } catch (JSONException e) {
+            LOGGER.debug("Exception on getRepositoryAggregations", e);
+            emailUtils.reportException(e);
+            throw e;
+        }
+
+    }
+
+    @Override
+    public Map<String, List<AggregationDetails>> getRepositoryAggregationsByYear(String id) throws JSONException {
+        LOGGER.debug("Retreiving aggregations (by year) for repository with id : " + id);
+        UriComponents uriComponents = searchDatasource("0", "100");
+        RequestFilter requestFilter = new RequestFilter();
+        requestFilter.setId(id);
+
+        List<AggregationDetails> aggregationHistory = new ArrayList<>();
+        Map<String, List<AggregationDetails>> aggregationByYear = new HashMap<>();
+        try {
+            String rs = restTemplate.postForObject(uriComponents.toUri(), requestFilter, String.class);
+            JSONObject repository = new JSONObject(rs);
+
+            if (repository.getJSONArray("datasourceInfo").length() == 0)
+                return aggregationByYear;
+
+            aggregationHistory.addAll(Converter.getAggregationHistoryFromJson(repository.getJSONArray("datasourceInfo").getJSONObject(0)));
+            return aggregationHistory.size() == 0 ? aggregationByYear : createYearMap(aggregationHistory);
+
+        } catch (JSONException e) {
+            LOGGER.debug("Exception on getRepositoryAggregations", e);
+            emailUtils.reportException(e);
+            throw e;
+        }
+    }
+
+    private Map<String, List<AggregationDetails>> createYearMap(List<AggregationDetails> aggregationHistory) {
+        Map<String, List<AggregationDetails>> aggregationByYear;
+        aggregationHistory = aggregationHistory.stream()
+                .sorted(Comparator.comparing(AggregationDetails::getDate).reversed())
+                .collect(Collectors.toList());
+
+        return aggregationHistory.stream()
+                .collect(Collectors.groupingBy(AggregationDetails::getYear));
+    }
+
+
+    @Override
+    public List<Repository> getRepositoriesByName(String name,
+                                                  String page,
+                                                  String size) throws JSONException {
+
+        LOGGER.debug("Retreiving  repositories with official name : " + name);
+        UriComponents uriComponents = searchDatasource("0", "100");
+        RequestFilter requestFilter = new RequestFilter();
+        requestFilter.setOfficialname(name);
+
+        try {
+            String rs = restTemplate.postForObject(uriComponents.toUri(), requestFilter, String.class);
+            List<Repository> repos = Converter.jsonToRepositoryList(new JSONObject(rs));
+            for (Repository r : repos)
+                updateRepositoryInfo(r);
+            return repos;
+        } catch (Exception e) {
+            LOGGER.debug("Exception on getRepositoriesByName", e);
+            emailUtils.reportException(e);
+            throw e;
+        }
+
+    }
+
+    @Override
+    public List<RepositoryInterface> getRepositoryInterface(String id) throws JSONException {
+
+        UriComponents uriComponents = UriComponentsBuilder
+                .fromHttpUrl(baseAddress + "/ds/api/")
+                .path("/{id}")
+                .build().expand(id).encode();
+
+        try {
+            String rs = restTemplate.getForObject(uriComponents.toUri(), String.class);
+            return Converter.jsonToRepositoryInterfaceList(new JSONObject(rs));
+        } catch (Exception e) {
+            LOGGER.debug("Exception on getRepositoryInterface", e);
+            emailUtils.reportException(e);
+            throw e;
+        }
+
+    }
+
+    @Override
+    public Repository addRepository(String datatype,
+                                    Repository repository) throws Exception {
+
+        LOGGER.debug("storing " + datatype + " repository with id: " + repository.getId());
+
+        repository.setCountryCode(countriesMap.get(repository.getCountryName()));
+        repository.setActivationId(UUID.randomUUID().toString());
+        repository.setCollectedFrom("infrastruct_::openaire");
+
+        if (datatype.equals("journal")) {
+            repository.setId("openaire____::issn" + repository.getIssn());
+            repository.setNamespacePrefix("issn" + repository.getIssn());
+            this.storeRepository(repository, SecurityContextHolder.getContext().getAuthentication());
+        } else if (datatype.equals("aggregator")) {
+            repository.setId("openaire____::" + DigestUtils.md5Hex(repository.getOfficialName()));
+            repository.setNamespacePrefix(DigestUtils.md5Hex(repository.getOfficialName()).substring(0, 12));
+            this.storeRepository(repository, SecurityContextHolder.getContext().getAuthentication());
+        } else {
+            this.latentUpdate(repository, SecurityContextHolder.getContext().getAuthentication());
+        }
+
+        // TODO: move the following code elsewhere (creation and assignment of role to user) ??
+        // Create new role
+        String newRoleName = roleMappingService.getRoleIdByRepoId(repository.getId());
+        Role newRole = new Role(newRoleName, repository.getOfficialName());
+        Integer couId = null;
+        try {
+            couId = registryCalls.createRole(newRole);
+        } catch (HttpClientErrorException e) {
+            couId = registryCalls.getCouId(newRoleName);
+            if (couId == null) {
+                LOGGER.error(String.format("Could not create role '%s'", newRoleName), e);
+            }
+        } catch (Exception e) {
+            LOGGER.error(String.format("Could not create role '%s'", newRoleName), e);
+            throw e;
+        }
+
+        // Assign new role to the user that created it
+        Integer coPersonId = registryCalls.getCoPersonIdByIdentifier();
+        if (couId != null) {
+            Integer role = registryCalls.getRoleId(coPersonId, couId);
+            try {
+                registryCalls.assignMemberRole(coPersonId, couId, role);
+
+                // Add role to current user authorities
+                authoritiesUpdater.addRole(roleMappingService.convertRepoIdToAuthority(repository.getId()));
+            } catch (Exception e) {
+                LOGGER.debug("Exception on assign role to user during add repository", e);
+                throw e;
+            }
+
+        }
+
+
+        return repository;
+    }
+
+    /* update method acting as add -> send email with registration topic/body*/
+    private Repository latentUpdate(Repository repository, Authentication authentication) throws Exception {
+        UriComponents uriComponents = UriComponentsBuilder
+                .fromHttpUrl(baseAddress + "/ds/update/")
+                .build()
+                .encode();
+
+        try {
+            String json_repository = Converter.repositoryObjectToJson(repository);
+            LOGGER.debug("JSON to add(update) -> " + json_repository);
+
+            HttpEntity<String> httpEntity = new HttpEntity<String>(json_repository, httpHeaders);
+            ResponseEntity responseEntity = restTemplate.exchange(uriComponents.toUri(), HttpMethod.POST, httpEntity, ResponseEntity.class);
+
+            if (responseEntity.getStatusCode().equals(HttpStatus.OK)) {
+                emailUtils.sendUserRegistrationEmail(repository, authentication);
+                emailUtils.sendAdminRegistrationEmail(repository, authentication);
+            } else
+                LOGGER.debug(responseEntity.getBody().toString());
+
+            return repository;
+        } catch (Exception e) {
+            LOGGER.debug("Exception on updateRepository", e);
+            emailUtils.reportException(e);
+            throw e;
+        }
+
+
+    }
+
+    @Override
+    public Repository updateRepository(Repository repository, Authentication authentication) throws Exception {
+        UriComponents uriComponents = UriComponentsBuilder
+                .fromHttpUrl(baseAddress + "/ds/update/")
+                .build()
+                .encode();
+
+        try {
+            String json_repository = Converter.repositoryObjectToJson(repository);
+
+            LOGGER.debug("JSON to update -> " + json_repository);
+
+            HttpEntity<String> httpEntity = new HttpEntity<String>(json_repository, httpHeaders);
+            ResponseEntity responseEntity = restTemplate.exchange(uriComponents.toUri(), HttpMethod.POST, httpEntity
+                    , ResponseEntity.class);
+
+            if (responseEntity.getStatusCode().equals(HttpStatus.OK)) {
+                emailUtils.sendUserUpdateRepositoryInfoEmail(repository, authentication);
+                emailUtils.sendAdminUpdateRepositoryInfoEmail(repository, authentication);
+            } else
+                LOGGER.debug(responseEntity.getBody().toString());
+
+            return repository;
+        } catch (Exception e) {
+            LOGGER.debug("Exception on updateRepository", e);
+            emailUtils.reportException(e);
+            throw e;
+        }
+    }
+
+    private void storeRepository(Repository repository, Authentication authentication) throws Exception {
+
+        Date utilDate = new Date();
+        Timestamp date = new Timestamp(utilDate.getTime());
+        repository.setDateOfCollection(date);
+        repository.setAggregator("OPENAIRE");
+        repository.setCountryCode(countriesMap.get(repository.getCountryName()));
+
+        UriComponents uriComponents = UriComponentsBuilder
+                .fromHttpUrl(baseAddress + "/ds/add/")
+                .build()
+                .encode();
+        String json_repository = Converter.repositoryObjectToJson(repository);
+        HttpEntity<String> httpEntity = new HttpEntity<String>(json_repository, httpHeaders);
+        ResponseEntity responseEntity = restTemplate.exchange(uriComponents.toUri(), HttpMethod.POST, httpEntity, ResponseEntity.class);
+
+        if (responseEntity.getStatusCode().equals(HttpStatus.OK)) {
+            emailUtils.sendUserRegistrationEmail(repository, authentication);
+            emailUtils.sendAdminRegistrationEmail(repository, authentication);
+        } else {
+            LOGGER.debug(responseEntity.getBody().toString());
+        }
+    }
+
+    @Override
+    public void deleteRepositoryInterface(String id,
+                                          String registeredBy) {
+        UriComponents uriComponents = UriComponentsBuilder
+                .fromHttpUrl(baseAddress + "/ds/api/")
+                .path("/{id}")
+                .build().expand(id).encode();
+        LOGGER.debug(uriComponents.toUri());
+        restTemplate.delete(uriComponents.toUri());
+    }
+
+    @Override
+    public RepositoryInterface addRepositoryInterface(String datatype,
+                                                      String repoId,
+                                                      String registeredBy,
+                                                      String comment, RepositoryInterface repositoryInterface) throws Exception {
+        try {
+            Repository e = this.getRepositoryById(repoId);
+            repositoryInterface = createRepositoryInterface(e, repositoryInterface, datatype);
+            String json_interface = Converter.repositoryInterfaceObjectToJson(e, repositoryInterface);
+
+            UriComponents uriComponents = UriComponentsBuilder
+                    .fromHttpUrl(baseAddress + "/ds/api/add/")
+                    .build()
+                    .encode();
+
+            HttpEntity<String> httpEntity = new HttpEntity<>(json_interface, httpHeaders);
+
+            restTemplate.postForObject(uriComponents.toUri(), httpEntity, String.class);
+
+            emailUtils.sendAdminRegisterInterfaceEmail(e, comment, repositoryInterface, SecurityContextHolder.getContext().getAuthentication());
+            emailUtils.sendUserRegisterInterfaceEmail(e, comment, repositoryInterface, SecurityContextHolder.getContext().getAuthentication());
+
+            submitInterfaceValidation(e, registeredBy, repositoryInterface, false);
+
+            return repositoryInterface;
+
+        } catch (Exception e) {
+            LOGGER.error("Exception on addRepositoryInterface", e);
+            emailUtils.reportException(e);
+            throw e;
+        }
+    }
+
+    @Override
+    public RepositoryInterface updateRepositoryInterface(String repoId,
+                                                         String registeredBy,
+                                                         String comment, RepositoryInterface repositoryInterface) throws Exception {
+
+        this.updateBaseUrl(repoId, repositoryInterface.getId(), repositoryInterface.getBaseUrl());
+        this.updateCompliance(repoId, repositoryInterface.getId(), repositoryInterface.getCompliance());
+        this.updateValidationSet(repoId, repositoryInterface.getId(), repositoryInterface.getAccessSet());
+
+        Repository repository = this.getRepositoryById(repoId);
+        try {
+            emailUtils.sendAdminUpdateInterfaceEmail(repository, comment, repositoryInterface, SecurityContextHolder.getContext().getAuthentication());
+            emailUtils.sendUserUpdateInterfaceEmail(repository, comment, repositoryInterface, SecurityContextHolder.getContext().getAuthentication());
+        } catch (Exception e) {
+            LOGGER.warn("Could not send emails", e);
+        }
+
+        submitInterfaceValidation(getRepositoryById(repoId), registeredBy, repositoryInterface, true);
+
+        return repositoryInterface;
+    }
+
+    private void submitInterfaceValidation(Repository repo, String userEmail, RepositoryInterface iFace, boolean updateExisting) throws ValidatorServiceException {
+        JobForValidation job = new JobForValidation();
+
+        job.setActivationId(UUID.randomUUID().toString());
+        job.setAdminEmails(Collections.singletonList(this.adminEmail));
+        job.setBaseUrl(iFace.getBaseUrl());
+        job.setDatasourceId(repo.getId());
+        job.setDesiredCompatibilityLevel(iFace.getDesiredCompatibilityLevel());
+        job.setInterfaceId(iFace.getId());
+        job.setOfficialName(repo.getOfficialName());
+        job.setRepoType(repo.getDatasourceType());
+        job.setUserEmail(userEmail);
+        job.setValidationSet((iFace.getAccessSet().isEmpty() ? "none" : iFace.getAccessSet()));
+        job.setRecords(-1);
+        job.setRegistration(!updateExisting);
+        job.setUpdateExisting(updateExisting);
+
+        this.validatorService.submitJobForValidation(job);
+    }
+
+    private RepositoryInterface createRepositoryInterface(Repository repo, RepositoryInterface iFace, String datatype) {
+
+        iFace.setContentDescription("metadata");
+        iFace.setCompliance("UNKNOWN");
+
+        if (datatype.equals("re3data"))
+            iFace.setAccessFormat("oai_datacite");
+        else
+            iFace.setAccessFormat("oai_dc");
+
+
+        if (repo.getDatasourceClass() != null && !repo.getDatasourceClass().isEmpty())
+            iFace.setTypology(repo.getDatasourceClass());
+        else if (datatype.equalsIgnoreCase("journal"))
+            iFace.setTypology("pubsrepository::journal");
+        else if (datatype.equalsIgnoreCase("aggregator"))
+            iFace.setTypology("aggregator::pubsrepository::unknown");
+        else if (datatype.equalsIgnoreCase("opendoar"))
+            iFace.setTypology("pubsrepository::unknown");
+        else if (datatype.equalsIgnoreCase("re3data"))
+            iFace.setTypology("datarepository::unknown");
+
+        iFace.setRemovable(true);
+        iFace.setAccessProtocol("oai");
+        iFace.setMetadataIdentifierPath("//*[local-name()='header']/*[local-name()='identifier']");
+        iFace.setId("api_________::" + repo.getId() + "::" + UUID.randomUUID().toString().substring(0, 8));
+        if (iFace.getAccessSet() == null || iFace.getAccessSet().isEmpty()) {
+            LOGGER.debug("set is empty: " + iFace.getAccessSet());
+            iFace.removeAccessSet();
+            iFace.setAccessSet("none");
+        }
+        return iFace;
+    }
+
+    @Override
+    public List<String> getDnetCountries() {
+        LOGGER.debug("Getting dnet-countries!");
+        return Converter.readFile("countries.txt");
+    }
+
+    @Override
+    public List<String> getTypologies() {
+        return Converter.readFile("typologies.txt");
+    }
+
+    @Override
+    public List<Timezone> getTimezones() {
+        List<String> timezones = Converter.readFile("timezones.txt");
+        return Converter.toTimezones(timezones);
+    }
+
+    @Override
+    public List<String> getUrlsOfUserRepos(String userEmail,
+                                           String page,
+                                           String size) {
+        UriComponents uriComponents = UriComponentsBuilder
+                .fromHttpUrl(baseAddress + "/api/baseurl/")
+                .path("/{page}/{size}")
+                .build().expand(page, size).encode();
+
+        try {
+            RequestFilter requestFilter = new RequestFilter();
+            requestFilter.setRegisteredby(userEmail);
+            return Arrays.asList(restTemplate.postForObject(uriComponents.toUri(), requestFilter, String[].class));
+        } catch (Exception e) {
+            LOGGER.debug("Exception on addRepositoryInterface", e);
+            emailUtils.reportException(e);
+            throw e;
+        }
+    }
+
+    @Override
+    public List<String> getDatasourceVocabularies(String mode) {
+
+        List<String> resultSet = new ArrayList<>();
+        for (Map.Entry<String, String> entry : this.getVocabulary("dnet:datasource_typologies").getAsMap().entrySet()) {
+            if (mode.equalsIgnoreCase("aggregator")) {
+                if (entry.getKey().contains("aggregator"))
+                    resultSet.add(entry.getValue());
+            } else if (mode.equalsIgnoreCase("journal")) {
+                if (entry.getKey().contains("journal"))
+                    resultSet.add(entry.getValue());
+            } else if (mode.equalsIgnoreCase("opendoar")) {
+                if (entry.getKey().contains("pubsrepository"))
+                    resultSet.add(entry.getValue());
+            } else if (mode.equalsIgnoreCase("re3data")) {
+                if (entry.getKey().contains("datarepository"))
+                    resultSet.add(entry.getValue());
+            }
+        }
+
+
+        return resultSet;
+    }
+
+    private Vocabulary getVocabulary(String vocName) {
+
+        if (!vocabularyMap.containsKey(vocName)) {
+            vocabularyMap.put(vocName, vocabularyLoader.getVocabulary(vocName, Locale.ENGLISH, Locale.ROOT));
+        }
+        return vocabularyMap.get(vocName);
+    }
+
+
+    @Override
+    public Map<String, String> getCompatibilityClasses(String mode) {
+
+        LOGGER.debug("Getting compatibility classes for mode: " + mode);
+        Map<String, String> retMap = new HashMap<String, String>();
+
+        Map<String, String> compatibilityClasses = this.getVocabulary("dnet:compatibilityLevel").getAsMap();
+        boolean foundData = false;
+        for (Map.Entry<String, String> entry : compatibilityClasses.entrySet()) {
+            if (mode.equalsIgnoreCase(Constants.REPOSITORY_MODE_ALL))
+                return compatibilityClasses;
+            else if (mode.equalsIgnoreCase(Constants.REPOSITORY_MODE_RE3DATA)) {
+                if (entry.getKey().matches("^openaire[1-9].0_data$")) {
+                    retMap.put(entry.getKey(), entry.getValue());
+                    foundData = true;
+                }
+            } else {
+                if (entry.getKey().matches("^openaire[1-9].0$") || entry.getKey().equals("driver"))
+                    retMap.put(entry.getKey(), entry.getValue());
+            }
+        }
+
+        //TODO TO BE REMOVED WHEN VOCABULARIES ARE UPDATED
+        if (mode.equalsIgnoreCase(Constants.REPOSITORY_MODE_RE3DATA) && !foundData)
+            retMap.put("openaire2.0_data", "OpenAIRE Data (funded, referenced datasets)");
+
+        return retMap;
+    }
+
+    @Override
+    public Map<String, String> getDatasourceClasses(String mode) {
+
+        LOGGER.debug("Getting datasource classes for mode: " + mode);
+
+        Map<String, String> retMap = new HashMap<String, String>();
+
+        for (Map.Entry<String, String> entry : this.getVocabulary("dnet:datasource_typologies").getAsMap().entrySet()) {
+            if (mode.equalsIgnoreCase("aggregator")) {
+                if (entry.getKey().contains("aggregator"))
+                    retMap.put(entry.getKey(), entry.getValue());
+            } else if (mode.equalsIgnoreCase("journal")) {
+                if (entry.getKey().contains("journal"))
+                    retMap.put(entry.getKey(), entry.getValue());
+            } else if (mode.equalsIgnoreCase("opendoar")) {
+                if (entry.getKey().contains("pubsrepository"))
+                    retMap.put(entry.getKey(), entry.getValue());
+            } else if (mode.equalsIgnoreCase("re3data")) {
+                if (entry.getKey().contains("datarepository"))
+                    retMap.put(entry.getKey(), entry.getValue());
+            }
+        }
+        return filterResults(retMap, mode);
+
+    }
+
+    private Map<String, String> filterResults(Map<String, String> map, String mode) {
+
+        HashMap<String, String> filteredMap = new HashMap<>();
+        for (String key : map.keySet())
+            if (dataSourceClass.get(mode).contains(key))
+                filteredMap.put(key, map.get(key));
+
+        return filteredMap;
+    }
+
+    @Override
+    public String getCountryName(String countryCode) {
+        return inverseCountriesMap.get(countryCode);
+    }
+
+    @Override
+    public MetricsInfo getMetricsInfoForRepository(String repoId) throws RepositoryServiceException {
+        try {
+
+            MetricsInfo metricsInfo = new MetricsInfo();
+            metricsInfo.setDiagramsBaseURL(this.usageStatisticsDiagramsBaseURL);
+            metricsInfo.setMetricsNumbers(getMetricsNumbers(getOpenAIREId(repoId)));
+            return metricsInfo;
+
+        } catch (Exception e) {
+            LOGGER.error("Error while getting metrics info for repository: ", e);
+            emailUtils.reportException(e);
+            throw new RepositoryServiceException("General error", RepositoryServiceException.ErrorCode.GENERAL_ERROR);
+        }
+    }
+
+    @Override
+    public Map<String, String> getListLatestUpdate(String mode) throws JSONException {
+        if (mode.equals("opendoar"))
+            return Collections.singletonMap("lastCollectionDate", getRepositoryInterface("openaire____::" + mode).get(0).getLastCollectionDate());
+        else
+            /*
+             * first api of re3data has null value on collection date
+             * */
+            return Collections.singletonMap("lastCollectionDate", getRepositoryInterface("openaire____::" + mode).get(1).getLastCollectionDate());
+    }
+
+    private void updateValidationSet(String repositoryId, String repositoryInterfaceId, String validationSet) throws Exception {
+        UriComponents uriComponents = UriComponentsBuilder
+                .fromHttpUrl(baseAddress + "/ds/api/oaiset")
+                .queryParam("dsId", repositoryId)
+                .queryParam("apiId", repositoryInterfaceId)
+                .queryParam("oaiSet", validationSet)
+                .build().encode();
+        restTemplate.exchange(uriComponents.toUri(), HttpMethod.POST, null, ResponseEntity.class);
+
+    }
+
+
+    private void updateBaseUrl(String repositoryId, String repositoryInterfaceId, String baseUrl) {
+        UriComponents uriComponents = UriComponentsBuilder
+                .fromHttpUrl(baseAddress + "/ds/api/baseurl")
+                .queryParam("dsId", repositoryId)
+                .queryParam("apiId", repositoryInterfaceId)
+                .queryParam("baseUrl", baseUrl)
+                .build().encode();
+        restTemplate.postForObject(uriComponents.toUri(), null, String.class);
+    }
+
+    private void updateCompliance(String repositoryId, String repositoryInterfaceId, String compliance) {
+        UriComponents uriComponents = UriComponentsBuilder
+                .fromHttpUrl(baseAddress + "/ds/api/compliance")
+                .queryParam("dsId", repositoryId)
+                .queryParam("apiId", repositoryInterfaceId)
+                .queryParam("compliance", compliance)
+                .build().encode();
+        restTemplate.postForObject(uriComponents.toUri(), null, String.class);
+    }
+
+    private MetricsNumbers getMetricsNumbers(String openAIREID) throws BrokerException {
+
+        //build the uri params
+        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(this.usageStatisticsNumbersBaseURL + openAIREID + "/clicks");
+
+        //create new template engine
+        RestTemplate template = new RestTemplate();
+        template.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
+        ResponseEntity<MetricsNumbers> resp;
+        try {
+            //communicate with endpoint
+            resp = template.exchange(
+                    builder.build().encode().toUri(),
+                    HttpMethod.GET,
+                    null,
+                    new ParameterizedTypeReference<MetricsNumbers>() {
+                    });
+        } catch (RestClientException e) {
+            LOGGER.debug("Exception on getMetricsNumbers", e);
+            emailUtils.reportException(e);
+            throw e;
+        }
+
+        return resp.getBody();
+    }
+
+    private String getOpenAIREId(String repoId) {
+
+        if (repoId != null && repoId.contains("::")) {
+            return repoId.split("::")[0] + "::" + DigestUtils.md5Hex(repoId.split("::")[1]);
+        }
+
+        return null;
+    }
+
+    private UriComponents searchDatasource(String page, String size) {
+
+        return UriComponentsBuilder
+                .fromHttpUrl(baseAddress + "/ds/search/")
+                .path("/{page}/{size}/")
+                .queryParam("requestSortBy", "officialname")
+                .queryParam("order", "ASCENDING")
+                .build().expand(page, size).encode();
+    }
+
+    private UriComponents searchSnipperDatasource(String page, String size) {
+
+        return UriComponentsBuilder
+                .fromHttpUrl(baseAddress + "/ds/searchsnippet/")
+                .path("/{page}/{size}/")
+                .queryParam("requestSortBy", "officialname")
+                .queryParam("order", "ASCENDING")
+                .build().expand(page, size).encode();
+    }
+
+    private UriComponents searchRegisteredDatasource(String requestSortBy, String order, String page, String size) {
+
+        return UriComponentsBuilder
+                .fromHttpUrl(baseAddress + "/ds/searchregistered/")
+                .path("/{page}/{size}/")
+                .queryParam("requestSortBy", requestSortBy)
+                .queryParam("order", order)
+                .build().expand(page, size).encode();
+    }
+
+    private String getRepositoryType(String typology) {
+        return invertedDataSourceClass.get(typology);
+    }
+
+    private List<String> getRoleIdsFromUserRoles(String userEmail) {
+        Integer coPersonId = registryCalls.getCoPersonIdByEmail(userEmail);
+        JsonArray roles;
+        ArrayList<String> roleIds = new ArrayList<>();
+        ArrayList<Integer> couIds = new ArrayList<>();
+        if (coPersonId != null) {
+            roles = registryCalls.getRolesWithStatus(coPersonId, AaiRegistryService.RoleStatus.ACTIVE);
+            for (JsonElement role : roles) {
+                JsonObject object = role.getAsJsonObject();
+                if (object.get("CouId") == null) {
+                    continue;
+                }
+                couIds.add(object.get("CouId").getAsInt());
+            }
+
+            roleIds.addAll(registryCalls.getCouNames(couIds).values());
+
+        }
+        return roleIds;
+    }
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/RepositoryService.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/RepositoryService.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/RepositoryService.java	(revision 61527)
@@ -0,0 +1,95 @@
+package eu.dnetlib.repo.manager.service;
+
+import eu.dnetlib.domain.data.Repository;
+import eu.dnetlib.domain.data.RepositoryInterface;
+import eu.dnetlib.repo.manager.domain.*;
+import eu.dnetlib.repo.manager.exception.ResourceNotFoundException;
+import org.json.JSONException;
+import org.springframework.security.core.Authentication;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+public interface RepositoryService {
+
+
+    // TODO: move this elsewhere
+    Country[] getCountries();
+
+    List<Repository> getRepositories(List<String> ids) throws JSONException;
+
+    List<Repository> getRepositories(List<String> ids, int page, int size) throws JSONException;
+
+    List<RepositorySnippet> getRepositoriesSnippets(List<String> ids) throws Exception;
+
+    List<RepositorySnippet> getRepositoriesSnippets(List<String> ids, int page, int size) throws Exception;
+
+    List<RepositorySnippet> getRepositoriesByCountry(String country, String mode, Boolean managed) throws JSONException, IOException;
+
+    // TODO: remove?
+    List<Repository> getRepositoriesOfUser(String page, String size) throws JSONException, IOException;
+
+    // TODO: remove?
+    List<Repository> getRepositoriesOfUser(String userEmail,
+                                           String page,
+                                           String size) throws JSONException, IOException;
+
+    List<RepositorySnippet> getRepositoriesSnippetsOfUser(String page, String size) throws Exception;
+
+    List<RepositorySnippet> getRepositoriesSnippetsOfUser(String userEmail, String page, String size) throws Exception;
+
+    RepositorySnippet getRepositorySnippetById(String id) throws JSONException, ResourceNotFoundException;
+
+    Repository getRepositoryById(String id) throws JSONException, ResourceNotFoundException;
+
+    List<AggregationDetails> getRepositoryAggregations(String id, int from, int size) throws JSONException;
+
+    Map<String, List<AggregationDetails>> getRepositoryAggregationsByYear(String id) throws JSONException;
+
+    List<Repository> getRepositoriesByName(String name,
+                                           String page,
+                                           String size) throws JSONException;
+
+    List<RepositorySnippet> searchRegisteredRepositories(String country, String typology, String englishName,
+                                                         String officialName, String requestSortBy, String order,
+                                                         int page, int pageSize) throws Exception;
+
+    List<RepositoryInterface> getRepositoryInterface(String id) throws JSONException;
+
+    Repository addRepository(String datatype, Repository repository) throws Exception;
+
+    void deleteRepositoryInterface(String id, String registeredBy);
+
+    RepositoryInterface addRepositoryInterface(String datatype,
+                                               String repoId,
+                                               String registeredBy,
+                                               String comment, RepositoryInterface repositoryInterface) throws Exception;
+
+    List<String> getDnetCountries();
+
+    List<String> getTypologies();
+
+    List<Timezone> getTimezones();
+
+    Repository updateRepository(Repository repository, Authentication authentication) throws Exception;
+
+    List<String> getUrlsOfUserRepos(String user_email,
+                                    String page,
+                                    String size);
+
+    List<String> getDatasourceVocabularies(String mode);
+
+    Map<String, String> getCompatibilityClasses(String mode);
+
+    Map<String, String> getDatasourceClasses(String mode);
+
+    String getCountryName(String countryCode);
+
+    MetricsInfo getMetricsInfoForRepository(String repoId) throws RepositoryServiceException;
+
+    Map<String, String> getListLatestUpdate(String mode) throws JSONException;
+
+    RepositoryInterface updateRepositoryInterface(String repoId, String registeredBy, String comment, RepositoryInterface repositoryInterface) throws Exception;
+
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/customHystrixCommands/SoftwareHystrixCommand.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/customHystrixCommands/SoftwareHystrixCommand.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/customHystrixCommands/SoftwareHystrixCommand.java	(revision 61527)
@@ -0,0 +1,44 @@
+package eu.dnetlib.repo.manager.service.customHystrixCommands;
+
+import com.netflix.hystrix.HystrixCommand;
+import com.netflix.hystrix.HystrixCommandGroupKey;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.client.RestTemplate;
+import org.springframework.web.util.UriComponents;
+import org.springframework.web.util.UriComponentsBuilder;
+
+import java.util.Map;
+
+public class SoftwareHystrixCommand extends HystrixCommand<String> {
+
+    String baseAddress;
+    RestTemplate restTemplate;
+
+    public SoftwareHystrixCommand(String baseAddress, RestTemplate restTemplate) {
+        super(HystrixCommandGroupKey.Factory.asKey("StatisticsGroup"));
+        this.baseAddress = baseAddress;
+        this.restTemplate = restTemplate;
+    }
+
+    @Override
+    protected String run() {
+        String url = baseAddress + "/software/count";
+
+        UriComponents uriComponents = UriComponentsBuilder
+                .fromHttpUrl(url)
+                .queryParam("page", 0)
+                .queryParam("size", 0)
+                .queryParam("format", "json")
+                .build().encode();
+
+        ResponseEntity rs = restTemplate.exchange(uriComponents.toUri(), HttpMethod.GET, null, Map.class);
+        Map metadata = (Map) (rs.getBody());
+        return String.valueOf(metadata.get("total"));
+    }
+
+    @Override
+    protected String getFallback() {
+        return null;
+    }
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/UserServiceImpl.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/UserServiceImpl.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/UserServiceImpl.java	(revision 61527)
@@ -0,0 +1,42 @@
+package eu.dnetlib.repo.manager.service;
+
+import org.mitre.openid.connect.model.OIDCAuthenticationToken;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.stereotype.Service;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+@Service("userService")
+public class UserServiceImpl implements UserService {
+
+    private static final org.apache.log4j.Logger LOGGER = org.apache.log4j.Logger
+            .getLogger(UserServiceImpl.class);
+
+    @Value("${oidc.issuer}")
+    private String oidc_issuer;
+
+    @Override
+    public ResponseEntity<Object> login() {
+        OIDCAuthenticationToken authentication = (OIDCAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
+        LOGGER.debug("User authentication : " + authentication);
+        Map<String,Object> body = new HashMap<>();
+        body.put("sub",authentication.getSub());
+        if(authentication.getUserInfo().getName() == null || authentication.getUserInfo().getName().equals(""))
+            body.put("name",authentication.getUserInfo().getGivenName() + " " + authentication.getUserInfo().getFamilyName());
+        else
+            body.put("name",authentication.getUserInfo().getName());
+
+        body.put("email",authentication.getUserInfo().getEmail());
+        List<String> roles = authentication.getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList());
+        body.put("role",roles);
+
+        return new ResponseEntity<>(body, HttpStatus.OK);
+    }
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/Vocabulary.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/Vocabulary.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/Vocabulary.java	(revision 61527)
@@ -0,0 +1,36 @@
+package eu.dnetlib.repo.manager.domain;
+
+
+
+/**
+ * Created by stefania on 3/8/16.
+ */
+public class Vocabulary   {
+
+    private String id;
+    private String name;
+
+    public Vocabulary() {
+    }
+
+    public Vocabulary(String id, String name) {
+        this.id = id;
+        this.name = name;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/RepositorySummaryInfo.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/RepositorySummaryInfo.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/RepositorySummaryInfo.java	(revision 61527)
@@ -0,0 +1,84 @@
+package eu.dnetlib.repo.manager.domain;
+
+
+
+import java.util.Date;
+
+public class RepositorySummaryInfo{
+
+    String id;
+    String repositoryName;
+    String logoURL;
+    int recordsCollected;
+    Date lastIndexedVersion;
+    long enrichmentEvents;
+    String totalViews;
+    String totalDownloads;
+
+    public RepositorySummaryInfo() {
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getRepositoryName() {
+        return repositoryName;
+    }
+
+    public void setRepositoryName(String repositoryName) {
+        this.repositoryName = repositoryName;
+    }
+
+    public String getLogoURL() {
+        return logoURL;
+    }
+
+    public void setLogoURL(String logoURL) {
+        this.logoURL = logoURL;
+    }
+
+    public int getRecordsCollected() {
+        return recordsCollected;
+    }
+
+    public void setRecordsCollected(int recordsCollected) {
+        this.recordsCollected = recordsCollected;
+    }
+
+    public Date getLastIndexedVersion() {
+        return lastIndexedVersion;
+    }
+
+    public void setLastIndexedVersion(Date lastIndexedVersion) {
+        this.lastIndexedVersion = lastIndexedVersion;
+    }
+
+    public long getEnrichmentEvents() {
+        return enrichmentEvents;
+    }
+
+    public void setEnrichmentEvents(long enrichmentEvents) {
+        this.enrichmentEvents = enrichmentEvents;
+    }
+
+    public String getTotalViews() {
+        return totalViews;
+    }
+
+    public void setTotalViews(String totalViews) {
+        this.totalViews = totalViews;
+    }
+
+    public String getTotalDownloads() {
+        return totalDownloads;
+    }
+
+    public void setTotalDownloads(String totalDownloads) {
+        this.totalDownloads = totalDownloads;
+    }
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/Timezone.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/Timezone.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/Timezone.java	(revision 61527)
@@ -0,0 +1,16 @@
+package eu.dnetlib.repo.manager.domain;
+
+
+public class Timezone{
+	private String name;
+	private double offset;
+
+	public Timezone(){
+	}
+
+	public Timezone(String name, double offset) {
+		super();
+		this.name = name;
+		this.offset = offset;
+	}
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/config/FrontEndLinkURIAuthenticationSuccessHandler.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/config/FrontEndLinkURIAuthenticationSuccessHandler.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/config/FrontEndLinkURIAuthenticationSuccessHandler.java	(revision 61527)
@@ -0,0 +1,66 @@
+package eu.dnetlib.repo.manager.config;
+
+import com.google.gson.JsonParser;
+import org.apache.log4j.Logger;
+import org.mitre.openid.connect.model.OIDCAuthenticationToken;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
+import org.springframework.session.FindByIndexNameSessionRepository;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.Base64;
+import java.util.Date;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class FrontEndLinkURIAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
+
+    private String frontEndURI;
+
+    private static final Logger LOGGER = Logger
+            .getLogger(FrontEndLinkURIAuthenticationSuccessHandler.class);
+
+    public void init() {
+        LOGGER.debug("Front end uri : " + frontEndURI);
+    }
+
+
+    @Value("${aai.mode}")
+    private String aai_mode;
+
+    @Override
+    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
+        OIDCAuthenticationToken authOIDC = (OIDCAuthenticationToken) authentication;
+        request.getSession().setAttribute(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, authOIDC.getUserInfo().getEmail());
+
+        Cookie accessToken = new Cookie("AccessToken", authOIDC.getAccessTokenValue());
+        String regex = "^([A-Za-z0-9-_=]+)\\.([A-Za-z0-9-_=]+)\\.?([A-Za-z0-9-_.+=]*)$";
+        Matcher matcher = Pattern.compile(regex).matcher(authOIDC.getAccessTokenValue());
+        if (matcher.find()) {
+            long exp = new JsonParser().parse(new String(Base64.getDecoder().decode(matcher.group(2)))).getAsJsonObject().get("exp").getAsLong();
+            accessToken.setMaxAge((int) (exp - (new Date().getTime() / 1000)));
+        } else {
+            accessToken.setMaxAge(3600);
+        }
+        if (aai_mode.equalsIgnoreCase("production") || aai_mode.equalsIgnoreCase("beta"))
+            accessToken.setDomain(".openaire.eu");
+        accessToken.setPath("/");
+
+        response.addCookie(accessToken);
+        response.sendRedirect(frontEndURI);
+    }
+
+    public String getFrontEndURI() {
+        return frontEndURI;
+    }
+
+    public void setFrontEndURI(String frontEndURI) {
+        this.frontEndURI = frontEndURI;
+    }
+}
+
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/ValidationState.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/ValidationState.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/ValidationState.java	(revision 61527)
@@ -0,0 +1,16 @@
+package eu.dnetlib.repo.manager.domain;
+
+
+import eu.dnetlib.domain.functionality.validator.JobForValidation;
+
+/**
+ * Created by stefania on 2/10/16.
+ */
+public class ValidationState extends WizardState   {
+
+    private JobForValidation jobForValidation = new JobForValidation();
+
+    public JobForValidation getJobForValidation() {
+        return jobForValidation;
+    }
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/config/RedisConfiguration.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/config/RedisConfiguration.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/config/RedisConfiguration.java	(revision 61527)
@@ -0,0 +1,76 @@
+package eu.dnetlib.repo.manager.config;
+
+import org.apache.log4j.Logger;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.*;
+import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
+import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
+import org.springframework.session.web.http.CookieSerializer;
+import org.springframework.session.web.http.DefaultCookieSerializer;
+import org.springframework.web.client.RestTemplate;
+
+import javax.annotation.PostConstruct;
+
+@Configuration
+@EnableRedisHttpSession
+@PropertySource(value = {"classpath:application.properties"} )
+@ComponentScan(basePackages = {
+        "org.eurocris.openaire.cris.validator.service",
+        "eu.dnetlib.repo.manager.*"})
+public class RedisConfiguration {
+
+    private static Logger LOGGER = Logger.getLogger(RedisConfiguration.class);
+
+    @Value("${redis.host}")
+    private String host;
+
+    @Value("${redis.port:6379}")
+    private String port;
+
+    @Value("${redis.password}")
+    private String password;
+
+    @Value("${aai.mode}")
+    private String aai_mode;
+
+    @PostConstruct
+    private void init(){
+        LOGGER.info(String.format("Redis : %s Port : %s Password : %s",host,port,password));
+    }
+
+    @Bean
+    public JedisConnectionFactory connectionFactory() {
+        LOGGER.info(String.format("Redis : %s Port : %s Password : %s",host,port,password));
+        JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory();
+        jedisConnectionFactory.setHostName(host);
+        jedisConnectionFactory.setPort(Integer.parseInt(port));
+        jedisConnectionFactory.setUsePool(true);
+        if(password != null) jedisConnectionFactory.setPassword(password);
+        return jedisConnectionFactory;
+    }
+
+    @Bean
+    public CookieSerializer cookieSerializer() {
+        DefaultCookieSerializer serializer = new DefaultCookieSerializer();
+        serializer.setCookieName("openAIRESession");
+        serializer.setCookiePath("/");
+        if(aai_mode.equalsIgnoreCase("production") || aai_mode.equalsIgnoreCase("beta"))
+            serializer.setDomainName(".openaire.eu");
+//        serializer.setDomainName(".athenarc.gr");
+        LOGGER.info("Serializer : " + serializer);
+        return serializer;
+    }
+
+    @Bean
+    public RestTemplate restTemplate() {
+        RestTemplate restTemplate = new RestTemplate();
+        restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
+        HttpHeaders httpHeaders = new HttpHeaders();
+        httpHeaders.set("Content-Type", "application/json");
+        return restTemplate;
+    }
+
+
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/BrokerSummary.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/BrokerSummary.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/BrokerSummary.java	(revision 61527)
@@ -0,0 +1,36 @@
+package eu.dnetlib.repo.manager.domain;
+
+import eu.dnetlib.repo.manager.domain.broker.BrowseEntry;
+import eu.dnetlib.repo.manager.domain.broker.SimpleSubscriptionDesc;
+
+import java.util.List;
+import java.util.Map;
+
+public class BrokerSummary {
+    private Map<String, List<SimpleSubscriptionDesc>> userSubs;
+
+    private List<BrowseEntry> topicsForDatasource;
+
+    public BrokerSummary(){}
+
+    public BrokerSummary(Map<String, List<SimpleSubscriptionDesc>> userSubs, List<BrowseEntry> topicsForDatasource) {
+        this.userSubs = userSubs;
+        this.topicsForDatasource = topicsForDatasource;
+    }
+
+    public Map<String, List<SimpleSubscriptionDesc>> getUserSubs() {
+        return userSubs;
+    }
+
+    public void setUserSubs(Map<String, List<SimpleSubscriptionDesc>> userSubs) {
+        this.userSubs = userSubs;
+    }
+
+    public List<BrowseEntry> getTopicsForDatasource() {
+        return topicsForDatasource;
+    }
+
+    public void setTopicsForDatasource(List<BrowseEntry> topicsForDatasource) {
+        this.topicsForDatasource = topicsForDatasource;
+    }
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/config/RepoManagerContextLoaderListener.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/config/RepoManagerContextLoaderListener.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/config/RepoManagerContextLoaderListener.java	(revision 61527)
@@ -0,0 +1,109 @@
+package eu.dnetlib.repo.manager.config;
+
+import org.apache.commons.lang.ArrayUtils;
+import org.apache.log4j.Logger;
+import org.springframework.beans.BeansException;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+import org.springframework.web.context.ContextLoaderListener;
+import org.springframework.web.context.WebApplicationContext;
+import org.springframework.web.context.support.XmlWebApplicationContext;
+
+import javax.servlet.ServletContext;
+import java.util.Properties;
+
+public class RepoManagerContextLoaderListener extends ContextLoaderListener {
+	private static Logger logger = Logger.getLogger(RepoManagerContextLoaderListener.class);
+
+
+	public RepoManagerContextLoaderListener() {
+		super();
+	}
+
+	public RepoManagerContextLoaderListener(WebApplicationContext context) {
+		super(context);
+	}
+
+	@Override
+	protected WebApplicationContext createWebApplicationContext(
+			ServletContext servletContext)
+			throws BeansException {
+		logger.debug("Creating web application context");
+		Properties props = this.loadProperties();
+		String repoMode = props.getProperty("services.validator.mode.repo");
+		String userMode = props.getProperty("services.validator.mode.user");
+		Boolean standaloneMode = Boolean.parseBoolean(props.getProperty("services.validator.mode.standalone"));
+
+		logger.info("User mode: " + userMode);
+		logger.info("Repo mode: " + repoMode);
+		logger.info("Standalone mode: " + standaloneMode);
+//		logger.info("Dnet workflow enabled: " + repoMode);
+		XmlWebApplicationContext ctx = new XmlWebApplicationContext();
+
+		ctx.setServletContext(servletContext);
+
+		String userApiContext = null;
+		if (userMode.equalsIgnoreCase("local"))
+			userApiContext = "eu/dnetlib/validator/web/api/impls/users/springContext-validator-user-local.xml";
+		else if (userMode.equalsIgnoreCase("ldap"))
+			userApiContext = "eu/dnetlib/users/springContext-users-ldap.xml";
+
+		String[] springContextCore = new  String[] {
+				"classpath:META-INF/cxf/cxf.xml",
+				"classpath:META-INF/cxf/cxf-extension-soap.xml",
+				"classpath:META-INF/cxf/cxf-extension-jaxws.xml",
+				"classpath:META-INF/cxf/cxf-servlet.xml",
+				"classpath*:/cxf.xml",
+				"classpath*:/eu/dnetlib/repos/ehcacher/springContext-repos-ehcacher.xml",
+				"classpath*:/eu/dnetlib/clients/ws/springContext-locatorFactory.xml",
+				"classpath*:/eu/dnetlib/soap/cxf/applicationContext-eprbuilders.xml",
+//				"classpath*:/eu/dnetlib/validator/web/actions/springContext-validator-struts.xml",
+//				"classpath*:/eu/dnetlib/validator/web/actions/springContext-validator-emailer.xml",
+//				"classpath*:/eu/dnetlib/validator/web/config/springContext-validator.xml",
+				"classpath*:/eu/dnetlib/repo/manager/server/config/springContext-repo-manager-config.xml",
+//				"classpath*:/eu/dnetlib/validator/commons/dao/springContext-*.xml",
+				"classpath*:/eu/dnetlib/repos/springContext-repos-" + repoMode + ".xml",
+				"classpath*:/" + userApiContext
+		};
+
+
+		String[] springContextForStandalone = new String[] {
+		};
+
+		String[] springContextForIS = new String[] {
+				"classpath*:/gr/uoa/di/driver/util/springContext-locators.xml",
+				"classpath*:/gr/uoa/di/driver/app/springContext-lookupFactory.xml",
+				"classpath*:/gr/uoa/di/driver/app/springContext-lookupClients.xml",
+				"classpath*:/eu/dnetlib/enabling/hcm/springContext-hcmService.xml",
+				"classpath*:/gr/uoa/di/driver/app/springContext-commons.xml",
+				"classpath*:/gr/uoa/di/driver/app/springContext-registrator.xml"
+		};
+
+		if (standaloneMode) {
+			logger.debug("Loading contexts for standalone mode");
+			ctx.setConfigLocations((String[])ArrayUtils.addAll(springContextCore,springContextForStandalone));
+		} else {
+			logger.debug("Loading contexts for dnet");
+			ctx.setConfigLocations((String[])ArrayUtils.addAll(springContextCore,springContextForIS));
+		}
+
+		ctx.refresh();
+
+		logger.debug("done");
+
+		return ctx;
+	}
+
+	private Properties loadProperties() {
+		ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(new String[] {
+				"classpath*:/eu/dnetlib/repo/manager/server/config/springContext-repo-manager-config.xml"
+		});
+
+		CascadingPropertyLoader pLoader = (CascadingPropertyLoader) ctx.getBean("propertyLoader");
+		Properties props = pLoader.getProperties();
+
+		ctx.destroy();
+		ctx.close();
+		return props;
+	}
+
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/MetricsNumbers.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/MetricsNumbers.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/MetricsNumbers.java	(revision 61527)
@@ -0,0 +1,100 @@
+package eu.dnetlib.repo.manager.domain;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.util.List;
+
+/**
+ * Created by stefania on 11/7/17.
+ */
+public class MetricsNumbers{
+
+    private List<String> downloads;
+    private List<String> views;
+
+    @JsonProperty("total_downloads")
+    private String totalDownloads;
+
+    @JsonProperty("total_views")
+    private String totalViews;
+
+    @JsonProperty("total_openaire_downloads")
+    private String totalOpenAIREDownloads;
+
+    @JsonProperty("total_openaire_views")
+    private String totalOpenAIREViews;
+
+    @JsonProperty("pageviews")
+    private String pageViews;
+
+    public MetricsNumbers() {
+    }
+
+    public MetricsNumbers(List<String> downloads, List<String> views, String totalDownloads, String totalViews,
+                          String totalOpenAIREDownloads, String totalOpenAIREViews, String pageViews) {
+        this.downloads = downloads;
+        this.views = views;
+        this.totalDownloads = totalDownloads;
+        this.totalViews = totalViews;
+        this.totalOpenAIREDownloads = totalOpenAIREDownloads;
+        this.totalOpenAIREViews = totalOpenAIREViews;
+        this.pageViews = pageViews;
+    }
+
+    public List<String> getDownloads() {
+        return downloads;
+    }
+
+    public void setDownloads(List<String> downloads) {
+        this.downloads = downloads;
+    }
+
+    public List<String> getViews() {
+        return views;
+    }
+
+    public void setViews(List<String> views) {
+        this.views = views;
+    }
+
+    public String getTotalDownloads() {
+        return totalDownloads;
+    }
+
+    public void setTotalDownloads(String totalDownloads) {
+        this.totalDownloads = totalDownloads;
+    }
+
+    public String getTotalViews() {
+        return totalViews;
+    }
+
+    public void setTotalViews(String totalViews) {
+        this.totalViews = totalViews;
+    }
+
+    public String getTotalOpenAIREDownloads() {
+        return totalOpenAIREDownloads;
+    }
+
+    public void setTotalOpenAIREDownloads(String totalOpenAIREDownloads) {
+        this.totalOpenAIREDownloads = totalOpenAIREDownloads;
+    }
+
+    public String getTotalOpenAIREViews() {
+        return totalOpenAIREViews;
+    }
+
+    public void setTotalOpenAIREViews(String totalOpenAIREViews) {
+        this.totalOpenAIREViews = totalOpenAIREViews;
+    }
+
+    public String getPageViews() {
+        return pageViews;
+    }
+
+    public void setPageViews(String pageViews) {
+        this.pageViews = pageViews;
+    }
+}
+
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/aai/registry/RegistryCalls.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/aai/registry/RegistryCalls.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/aai/registry/RegistryCalls.java	(revision 61527)
@@ -0,0 +1,439 @@
+package eu.dnetlib.repo.manager.service.aai.registry;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import eu.dnetlib.repo.manager.domain.dto.Role;
+import eu.dnetlib.repo.manager.domain.dto.User;
+import eu.dnetlib.repo.manager.service.aai.registry.utils.RegistryUtils;
+import eu.dnetlib.repo.manager.utils.HttpUtils;
+import org.apache.log4j.Logger;
+import org.mitre.openid.connect.model.OIDCAuthenticationToken;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.stereotype.Service;
+
+import java.net.URLEncoder;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Service
+public class RegistryCalls implements AaiRegistryService {
+
+    private static final Logger logger = Logger.getLogger(RegistryCalls.class);
+
+    private final String coid;
+    public final HttpUtils httpUtils;
+    public final RegistryUtils jsonUtils;
+
+    @Autowired
+    RegistryCalls(@Value("${aai.registry.coid:2}") String coid,
+                  HttpUtils httpUtils, RegistryUtils registryUtils) {
+        this.coid = coid;
+        this.httpUtils = httpUtils;
+        this.jsonUtils = registryUtils;
+    }
+
+    private String mapType(String type, boolean communityMap) {
+        if (type.equals("organization")) {
+            type = "institution";
+        } else if (type.equals("ri") && communityMap) {
+            type = "community";
+        }
+        return type;
+    }
+
+    @Override
+    public Integer getCoPersonIdByEmail() {
+        try {
+            OIDCAuthenticationToken authentication = (OIDCAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
+            String email = authentication.getUserInfo().getEmail();
+            Map<String, String> params = new HashMap<>();
+            params.put("coid", coid);
+            params.put("mail", email);
+            JsonElement response = httpUtils.get("co_people.json", params);
+            return (response != null) ? response.getAsJsonObject().get("CoPeople").getAsJsonArray().get(0).getAsJsonObject().get("Id").getAsInt() : null;
+        } catch (Exception e) {
+            logger.error("Get User info: An error occurred ", e);
+            return null;
+        }
+    }
+
+    @Override
+    public Integer getCoPersonIdByEmail(String email) {
+        Map<String, String> params = new HashMap<>();
+        params.put("coid", coid);
+        params.put("mail", email);
+        JsonElement response = httpUtils.get("co_people.json", params);
+        if (response != null) {
+            JsonArray coPeople = response.getAsJsonObject().get("CoPeople").getAsJsonArray();
+            if (coPeople.size() > 0) {
+                return coPeople.get(0).getAsJsonObject().get("Id").getAsInt();
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public List<Integer> getCoPersonIdsByEmail(String email) {
+        List<Integer> coPersonIds = new ArrayList<>();
+        Map<String, String> params = new HashMap<>();
+        params.put("coid", coid);
+        params.put("mail", email);
+        JsonElement response = httpUtils.get("co_people.json", params);
+        if (response != null) {
+            JsonArray coPeople = response.getAsJsonObject().get("CoPeople").getAsJsonArray();
+            for (int i = 0; i < coPeople.size(); i++) {
+                coPersonIds.add(coPeople.get(i).getAsJsonObject().get("Id").getAsInt());
+            }
+        }
+        return coPersonIds;
+    }
+
+    @Override
+    public Integer getCoPersonIdByIdentifier() {
+        try {
+            OIDCAuthenticationToken authentication = (OIDCAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
+            String sub = authentication.getUserInfo().getSub();
+            Map<String, String> params = new HashMap<>();
+            params.put("coid", coid);
+            params.put("search.identifier", sub);
+            JsonElement response = httpUtils.get("co_people.json", params);
+            return (response != null) ? response.getAsJsonObject().get("CoPeople").getAsJsonArray().get(0).getAsJsonObject().get("Id").getAsInt() : null;
+        } catch (Exception e) {
+            logger.error("Get User info: An error occurred ", e);
+            return null;
+        }
+    }
+
+    public Integer getCoPersonIdByIdentifier(String sub) {
+        Map<String, String> params = new HashMap<>();
+        params.put("coid", coid);
+        params.put("search.identifier", sub);
+        JsonElement response = httpUtils.get("co_people.json", params);
+        return (response != null) ? response.getAsJsonObject().get("CoPeople").getAsJsonArray().get(0).getAsJsonObject().get("Id").getAsInt() : null;
+    }
+
+    @Override
+    public JsonArray getCous(String name) {
+        Map<String, String> params = new HashMap<>();
+        params.put("coid", coid);
+        if (name != null) {
+            params.put("name", URLEncoder.encode(name).toLowerCase());
+        }
+        JsonElement response = httpUtils.get("cous.json", params);
+        return (response != null) ? response.getAsJsonObject().get("Cous").getAsJsonArray() : new JsonArray();
+    }
+
+    @Override
+    public JsonArray getCous() {
+        return getCous(null);
+    }
+
+    @Override
+    public Integer getCouId(String name) {
+        JsonArray cous = getCous(name);
+        for (JsonElement cou : cous) {
+            if (cou.getAsJsonObject().get("Name").getAsString().equalsIgnoreCase(name)) {
+                return cou.getAsJsonObject().get("Id").getAsInt();
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public Integer getCouId(String type, String id, boolean communityMap) {
+        return getCouId(mapType(type, communityMap) + "." + id);
+    }
+
+    @Override
+    public Integer getCouId(String type, String id) {
+        return getCouId(type, id, true);
+    }
+
+    @Override
+    public JsonArray getRoles(Integer coPersonId) {
+        Map<String, String> params = new HashMap<>();
+        params.put("copersonid", coPersonId.toString());
+        JsonElement response = httpUtils.get("co_person_roles.json", params);
+        return (response != null) ? response.getAsJsonObject().get("CoPersonRoles").getAsJsonArray() : new JsonArray();
+    }
+
+    @Override
+    public JsonArray getRolesWithStatus(Integer coPersonId, RoleStatus status) {
+        JsonArray roles = getRoles(coPersonId);
+        if (status == null) {
+            return roles;
+        }
+        JsonArray activeRoles = new JsonArray();
+        for (JsonElement role : roles) {
+            if (role.getAsJsonObject().get("Status").getAsString().equalsIgnoreCase(status.toString())) {
+                activeRoles.add(role);
+            }
+        }
+        return activeRoles;
+    }
+
+    @Override
+    public Integer getRoleId(Integer coPersonId, Integer couId) {
+        JsonArray roles = getRoles(coPersonId);
+        for (JsonElement role : roles) {
+            JsonObject object = role.getAsJsonObject();
+            if (object.get("CouId").getAsInt() == couId && !object.get("Status").getAsString().equals("Deleted")) {
+                return object.get("Id").getAsInt();
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public JsonArray getUserGroups(Integer coPersonId) {
+        Map<String, String> params = new HashMap<>();
+        params.put("copersonid", coPersonId.toString());
+        JsonElement response = httpUtils.get("co_groups.json", params);
+        return (response != null) ? response.getAsJsonObject().get("CoGroups").getAsJsonArray() : new JsonArray();
+    }
+
+    @Override
+    public JsonObject getUserAdminGroup(Integer coPersonId, Integer couId) {
+        Map<String, String> params = new HashMap<>();
+        params.put("copersonid", coPersonId.toString());
+        JsonElement response = httpUtils.get("co_groups.json", params);
+        JsonArray roles = (response != null) ? response.getAsJsonObject().get("CoGroups").getAsJsonArray() : new JsonArray();
+        for (JsonElement role : roles) {
+            JsonObject object = role.getAsJsonObject();
+            if (object.get("CouId") != null && object.get("CouId").getAsInt() == couId) {
+                if (object.get("Name").getAsString().contains("admins")) {
+                    return object;
+                }
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public JsonArray getCouGroups(Integer couId) {
+        Map<String, String> params = new HashMap<>();
+        params.put("coid", coid);
+        params.put("couid", couId.toString());
+        JsonElement response = httpUtils.get("co_groups.json", params);
+        return (response != null) ? response.getAsJsonObject().get("CoGroups").getAsJsonArray() : new JsonArray();
+    }
+
+    @Override
+    public JsonObject getCouAdminGroup(Integer couId) {
+        JsonArray groups = getCouGroups(couId);
+        for (JsonElement group : groups) {
+            if (group.getAsJsonObject().get("Name").getAsString().contains("admins")) {
+                return group.getAsJsonObject();
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public JsonArray getGroupMembers(Integer coGroupId) {
+        Map<String, String> params = new HashMap<>();
+        params.put("cogroupid", coGroupId.toString());
+        JsonElement response = httpUtils.get("co_group_members.json", params);
+        return (response != null) ? response.getAsJsonObject().get("CoGroupMembers").getAsJsonArray() : new JsonArray();
+    }
+
+
+    @Override
+    public JsonArray getUserEmailByCouId(Integer couId, boolean admin) {
+        Map<String, String> params = new HashMap<>();
+        if (couId == null) {
+            throw new IllegalArgumentException("Provided 'couId' is null");
+        }
+        params.put("couid", couId.toString());
+        if (admin) {
+            params.put("admin", "true");
+        }
+        JsonElement response = httpUtils.get("email_addresses.json", params);
+        JsonArray infos = (response != null) ? response.getAsJsonObject().get("EmailAddresses").getAsJsonArray() : new JsonArray();
+        JsonArray emails = new JsonArray();
+        infos.forEach(info -> {
+            JsonObject user = new JsonObject();
+            boolean add = true;
+            String email = info.getAsJsonObject().get("Mail").getAsString();
+            for (JsonElement element : emails) {
+                if (element.getAsJsonObject().get("email").getAsString().equals(email)) {
+                    add = false;
+                }
+            }
+            if (add) {
+                user.addProperty("email", email);
+                user.addProperty("memberSince", info.getAsJsonObject().get("Created").getAsString());
+                emails.add(user);
+            }
+        });
+        return emails;
+    }
+
+    @Override
+    public JsonArray getUsersByCouId(Integer couId) {
+        Map<String, String> params = new HashMap<>();
+        params.put("couid", couId.toString());
+        JsonElement response = httpUtils.get("co_person_roles.json", params);
+        JsonArray infos = (response != null) ? response.getAsJsonObject().get("CoPersonRoles").getAsJsonArray() : new JsonArray();
+//        JsonArray users = new JsonArray();
+//        infos.forEach(info -> {
+//            JsonObject user = new JsonObject();
+//            user.addProperty("email", info.getAsJsonObject().get("Mail").getAsString());
+//            user.addProperty("memberSince", info.getAsJsonObject().get("Created").getAsString());
+//            emails.add(user);
+//        });
+        return infos;
+    }
+
+    @Override
+    public List<User> getUsers(Integer couId) {
+        List<User> users = new ArrayList<>();
+        JsonArray infos = getUserEmailByCouId(couId, false);
+
+        infos.forEach(info -> {
+            User user = new User();
+            user.setEmail(info.getAsJsonObject().get("email").getAsString());
+
+            users.add(user);
+        });
+        return users;
+    }
+
+    @Override
+    public JsonArray getUserNamesByCouId(Integer couId, boolean admin) {
+        Map<String, String> params = new HashMap<>();
+        params.put("couid", couId.toString());
+        if (admin) {
+            params.put("admin", "true");
+        }
+        JsonElement response = httpUtils.get("names.json", params);
+        JsonArray infos = (response != null) ? response.getAsJsonObject().get("Names").getAsJsonArray() : new JsonArray();
+        JsonArray names = new JsonArray();
+        infos.forEach(info -> {
+            JsonObject user = new JsonObject();
+            user.addProperty("name", info.getAsJsonObject().get("Given").getAsString() + " " + info.getAsJsonObject().get("Family").getAsString());
+            user.addProperty("memberSince", info.getAsJsonObject().get("Created").getAsString());
+            names.add(user);
+        });
+        return names;
+    }
+
+    @Override
+    public JsonArray getUserIdByCouId(Integer couId, boolean admin) {
+        Map<String, String> params = new HashMap<>();
+        params.put("couid", couId.toString());
+        if (admin) {
+            params.put("admin", "true");
+        }
+        JsonElement response = httpUtils.get("identifiers.json", params);
+        JsonArray infos = (response != null) ? response.getAsJsonObject().get("Identifiers").getAsJsonArray() : new JsonArray();
+        JsonArray emails = new JsonArray();
+        infos.forEach(info -> {
+            JsonObject user = new JsonObject();
+            user.addProperty("id", info.getAsJsonObject().get("Identifier").getAsString());
+            user.addProperty("memberSince", info.getAsJsonObject().get("Created").getAsString());
+            emails.add(user);
+        });
+        return emails;
+    }
+
+    @Override
+    public void assignMemberRole(Integer coPersonId, Integer couId, Integer id) {
+        if (id != null) {
+            httpUtils.put("co_person_roles/" + id.toString() + ".json", jsonUtils.coPersonRoles(coPersonId, couId, "Active"));
+        } else {
+            httpUtils.post("co_person_roles.json", jsonUtils.coPersonRoles(coPersonId, couId, "Active"));
+        }
+    }
+
+    @Override
+    public void removeMemberRole(Integer coPersonId, Integer couId, Integer id) {
+        if (id != null) {
+            httpUtils.put("co_person_roles/" + id.toString() + ".json", jsonUtils.coPersonRoles(coPersonId, couId, "Deleted"));
+        }
+    }
+
+    @Override
+    public Integer createRole(Role role) {
+        JsonElement element = httpUtils.post("cous.json", jsonUtils.createNewCou(role));
+        return element.getAsJsonObject().get("Id").getAsInt();
+    }
+
+    @Override
+    public String getUserEmail(Integer coPersonId) {
+        Map<String, String> params = new HashMap<>();
+        params.put("copersonid", coPersonId.toString());
+        JsonElement response = httpUtils.get("email_addresses.json", params);
+        JsonObject info = (response != null) ? response.getAsJsonObject().get("EmailAddresses").getAsJsonArray().get(0).getAsJsonObject() : null;
+        return (info != null) ? info.getAsJsonObject().get("Mail").getAsString() : null;
+    }
+
+    @Override
+    public String getUserNames(Integer coPersonId) {
+        Map<String, String> params = new HashMap<>();
+        params.put("copersonid", coPersonId.toString());
+        JsonElement response = httpUtils.get("names.json", params);
+        JsonObject info = (response != null) ? response.getAsJsonObject().get("Names").getAsJsonArray().get(0).getAsJsonObject() : null;
+        return (info != null) ? info.getAsJsonObject().get("Given").getAsString() + " " + info.getAsJsonObject().get("Family").getAsString() : null;
+    }
+
+    @Override
+    public String getUserId(Integer coPersonId) {
+        Map<String, String> params = new HashMap<>();
+        params.put("copersonid", coPersonId.toString());
+        JsonElement response = httpUtils.get("identifiers.json", params);
+        JsonObject info = (response != null) ? response.getAsJsonObject().get("Identifiers").getAsJsonArray().get(0).getAsJsonObject() : null;
+        return (info != null) ? info.getAsJsonObject().get("Identifier").getAsString() : null;
+    }
+
+    @Override
+    public void assignAdminRole(Integer coPersonId, Integer couId) {
+        JsonObject group = getCouAdminGroup(couId);
+        if (group != null) {
+            httpUtils.post("co_group_members.json", jsonUtils.coGroupMembers(group.get("Id").getAsInt(), coPersonId, true));
+        }
+    }
+
+    @Override
+    public void removeAdminRole(Integer coPersonId, Integer couId) {
+        JsonObject adminGroup = this.getCouAdminGroup(couId);
+        JsonArray admins = this.getGroupMembers(adminGroup.get("Id").getAsInt());
+        Integer id = null;
+        for (JsonElement admin : admins) {
+            if (admin.getAsJsonObject().get("Person").getAsJsonObject().get("Id").getAsInt() == coPersonId) {
+                id = admin.getAsJsonObject().get("Id").getAsInt();
+            }
+        }
+        if (id != null) {
+            httpUtils.delete("co_group_members/" + id.toString() + ".json");
+        }
+    }
+
+    @Override
+    public Map<Integer, String> getCouNames(List<Integer> couIds) {
+        Map<Integer, String> idNameMap = new HashMap<>();
+        for (Integer id : couIds) {
+            idNameMap.put(id, null);
+        }
+
+        JsonArray cous = getCous();
+        int count = 0;
+        int total = couIds.size();
+        for (JsonElement cou : cous) {
+            if (count < total) {
+                if (idNameMap.containsKey(cou.getAsJsonObject().get("Id").getAsInt())) {
+                    idNameMap.put(cou.getAsJsonObject().get("Id").getAsInt(), cou.getAsJsonObject().get("Name").getAsString());
+                    count++;
+                }
+            } else {
+                break;
+            }
+        }
+        return idNameMap;
+    }
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/utils/JsonUtils.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/utils/JsonUtils.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/utils/JsonUtils.java	(revision 61527)
@@ -0,0 +1,40 @@
+package eu.dnetlib.repo.manager.utils;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+
+public class JsonUtils {
+
+    private JsonUtils() {
+    }
+
+    public JsonObject createResponse(JsonElement response) {
+        JsonObject json = new JsonObject();
+        json.add("response", response);
+        return json;
+    }
+
+    public static JsonObject createResponse(String response) {
+        JsonObject json = new JsonObject();
+        json.addProperty("response", response);
+        return json;
+    }
+
+    public JsonObject createResponse(Number response) {
+        JsonObject json = new JsonObject();
+        json.addProperty("response", response);
+        return json;
+    }
+
+    public static JsonObject createResponse(Boolean response) {
+        JsonObject json = new JsonObject();
+        json.addProperty("response", response);
+        return json;
+    }
+
+    public static JsonObject createResponse(Character response) {
+        JsonObject json = new JsonObject();
+        json.addProperty("response", response);
+        return json;
+    }
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/dto/Role.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/dto/Role.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/dto/Role.java	(revision 61527)
@@ -0,0 +1,32 @@
+package eu.dnetlib.repo.manager.domain.dto;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement
+public class Role {
+    String name;
+    String description;
+
+    public Role() {}
+
+    public Role(String name, String description) {
+        this.name = name;
+        this.description = description;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/aai/registry/AaiRegistryService.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/aai/registry/AaiRegistryService.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/aai/registry/AaiRegistryService.java	(revision 61527)
@@ -0,0 +1,285 @@
+package eu.dnetlib.repo.manager.service.aai.registry;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+import eu.dnetlib.repo.manager.domain.dto.Role;
+import eu.dnetlib.repo.manager.domain.dto.User;
+
+import java.util.List;
+import java.util.Map;
+
+public interface AaiRegistryService {
+
+    /**
+     * 1.1 Get CoPersonId by authenticated user's Email
+     *
+     * @return
+     */
+    Integer getCoPersonIdByEmail();
+
+    /**
+     * 1.2 Get CoPersonId by Email
+     *
+     * @param email
+     * @return
+     */
+    Integer getCoPersonIdByEmail(String email);
+
+    /**
+     * 1. Get CoPersonId List by Email
+     *
+     * @param email
+     * @return
+     */
+    List<Integer> getCoPersonIdsByEmail(String email);
+
+    /**
+     * 2. Get CoPersonId by AAI identifier
+     *
+     * @return
+     */
+    Integer getCoPersonIdByIdentifier();
+
+    /**
+     * 3.1 Get OpenAIRE cous with a specific name(or substring)
+     *
+     * @param name
+     * @return
+     */
+    JsonArray getCous(String name);
+
+    /**
+     * 3.2 Get all OpenAIRE cous
+     *
+     * @return
+     */
+    JsonArray getCous();
+
+    /**
+     * 4.1 Get a couId by name
+     *
+     * @param name
+     * @return
+     */
+    Integer getCouId(String name);
+
+    /**
+     * 4.2 Get a couId by type.id with/without mapping type
+     *
+     * @param type
+     * @param id
+     * @return
+     */
+    Integer getCouId(String type, String id, boolean communityMap);
+
+    /**
+     * 4.3 Get a couId by type.id with mapping type
+     *
+     * @param type
+     * @param id
+     * @return
+     */
+    Integer getCouId(String type, String id);
+
+    /**
+     * 5. Get User non admin roles
+     *
+     * @param coPersonId
+     * @return
+     */
+    JsonArray getRoles(Integer coPersonId);
+
+    /**
+     * 5.2 Get User non admin active roles
+     *
+     * @param coPersonId
+     * @return
+     */
+    JsonArray getRolesWithStatus(Integer coPersonId, RoleStatus status);
+
+    /**
+     * 6. Get Role id of User base on couId.
+     *
+     * @param coPersonId
+     * @param couId
+     * @return
+     */
+    Integer getRoleId(Integer coPersonId, Integer couId);
+
+    /**
+     * 7. Get User Groups
+     *
+     * @param coPersonId
+     * @return
+     */
+    JsonArray getUserGroups(Integer coPersonId);
+
+    /**
+     * 8. Get User Admin Group of a Cou
+     *
+     * @param coPersonId
+     * @param couId
+     * @return
+     */
+    JsonObject getUserAdminGroup(Integer coPersonId, Integer couId);
+
+    /**
+     * 9. Get Groups of a Cou
+     *
+     * @param couId
+     * @return
+     */
+    JsonArray getCouGroups(Integer couId);
+
+    /**
+     * 10. Get Admin Group of a Cou
+     *
+     * @param couId
+     * @return
+     */
+    JsonObject getCouAdminGroup(Integer couId);
+
+    /**
+     * 11. Get users of a group
+     *
+     * @param coGroupId
+     * @return
+     */
+    JsonArray getGroupMembers(Integer coGroupId);
+
+
+    /**
+     * 12. Get Users' email of a Cou
+     *
+     * @param couId
+     * @param admin
+     * @return
+     */
+    JsonArray getUserEmailByCouId(Integer couId, boolean admin);
+
+    /**
+     * 12.2 Get All Users that have a specific role // TODO: Keep or delete
+     *
+     * @param couId
+     * @return
+     */
+    JsonArray getUsersByCouId(Integer couId);
+
+    /**
+     * 13. Get Users' names of a Cou
+     *
+     * @param couId
+     * @param admin
+     * @return
+     */
+    JsonArray getUserNamesByCouId(Integer couId, boolean admin);
+
+    /**
+     * 14. Get Users' identifiers of a Cou
+     *
+     * @param couId
+     * @param admin
+     * @return
+     */
+    JsonArray getUserIdByCouId(Integer couId, boolean admin);
+
+    /**
+     * 15. Assign a member role to a User
+     *
+     * @param coPersonId
+     * @param couId
+     * @param id
+     */
+    void assignMemberRole(Integer coPersonId, Integer couId, Integer id);
+
+    /**
+     * 16. Remove a member role from a User
+     *
+     * @param coPersonId
+     * @param couId
+     * @param id
+     */
+    void removeMemberRole(Integer coPersonId, Integer couId, Integer id);
+
+    /**
+     * 17. Create a new role
+     *
+     * @param role
+     * @return
+     */
+    Integer createRole(Role role);
+
+    /**
+     * 18. Get User's email
+     *
+     * @param coPersonId
+     * @return
+     */
+    String getUserEmail(Integer coPersonId);
+
+    /**
+     * 19. Get User's names
+     *
+     * @param coPersonId
+     * @return
+     */
+    String getUserNames(Integer coPersonId);
+
+    /**
+     * 20. Get User's identifier
+     *
+     * @param coPersonId
+     * @return
+     */
+    String getUserId(Integer coPersonId);
+
+    /**
+     * 21. Assign an admin role to a User
+     *
+     * @param coPersonId
+     * @param couId
+     */
+    void assignAdminRole(Integer coPersonId, Integer couId);
+
+    /**
+     * 22. Remove an admin role from a User
+     *
+     * @param coPersonId
+     * @param couId
+     */
+    void removeAdminRole(Integer coPersonId, Integer couId);
+
+    /**
+     * 23. Get a cou Names from couIds.
+     *
+     * @param couIds
+     * @return
+     */
+    Map<Integer, String> getCouNames(List<Integer> couIds);
+
+    // TODO: add description
+    List<User> getUsers(Integer couId);
+
+    enum RoleStatus {
+        ACTIVE("Active"),
+        APPROVED("Approved"),
+        CONFIRMED("Confirmed"),
+        DECLINED("Declined"),
+        DELETED("Deleted"),
+        DENIED("Denied"),
+        DUPLICATE("Duplicate"),
+        EXPIRED("Expired"),
+        GRACE_PERIOD("GracePeriod"),
+        INVITED("Invited"),
+        PENDING("Pending"),
+        PENDING_APPROVAL("PendingApproval"),
+        PENDING_CONFIRMATION("PendingConfirmation"),
+        SUSPENDED("Suspended");
+
+        public final String status;
+
+        RoleStatus(String status) {
+            this.status = status;
+        }
+    }
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/aai/registry/utils/RegistryUtils.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/aai/registry/utils/RegistryUtils.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/aai/registry/utils/RegistryUtils.java	(revision 61527)
@@ -0,0 +1,76 @@
+package eu.dnetlib.repo.manager.service.aai.registry.utils;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+import eu.dnetlib.repo.manager.domain.dto.Role;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+@Component
+public class RegistryUtils {
+
+    @Value("1.0")
+    private String version;
+
+    @Value("2")
+    private String coid;
+
+    public JsonObject coPersonRoles(Integer coPersonId, Integer couId, String status) {
+        JsonObject role = new JsonObject();
+        JsonArray coPersonRoles = new JsonArray();
+        JsonObject coPersonRole = new JsonObject();
+        JsonObject person = new JsonObject();
+        person.addProperty("Type", "CO");
+        person.addProperty("Id", coPersonId.toString());
+        coPersonRole.addProperty("Version", version);
+        coPersonRole.add("Person", person);
+        coPersonRole.addProperty("CouId", couId.toString());
+        coPersonRole.addProperty("Affiliation", "member");
+        coPersonRole.addProperty("Title", "");
+        coPersonRole.addProperty("O", "Openaire");
+        coPersonRole.addProperty("Status", status);
+        coPersonRole.addProperty("ValidFrom", "");
+        coPersonRole.addProperty("ValidThrough", "");
+        coPersonRoles.add(coPersonRole);
+        role.addProperty("RequestType", "CoPersonRoles");
+        role.addProperty("Version", version);
+        role.add("CoPersonRoles", coPersonRoles);
+        return role;
+    }
+
+    public JsonObject createNewCou(Role role) {
+        JsonObject cou = new JsonObject();
+        JsonArray cous = new JsonArray();
+        JsonObject newCou = new JsonObject();
+        newCou.addProperty("Version", version);
+        newCou.addProperty("CoId", coid);
+        newCou.addProperty("Name", role.getName());
+        newCou.addProperty("Description", role.getDescription());
+        cous.add(newCou);
+        cou.addProperty("RequestType", "Cous");
+        cou.addProperty("Version", version);
+        cou.add("Cous", cous);
+        return cou;
+    }
+
+    public JsonObject coGroupMembers(Integer coGroupId, Integer coPersonId, boolean member) {
+        JsonObject coGroup = new JsonObject();
+        JsonArray coGroupMembers = new JsonArray();
+        JsonObject coGroupMember = new JsonObject();
+        JsonObject person = new JsonObject();
+        person.addProperty("Type", "CO");
+        person.addProperty("Id", coPersonId.toString());
+        coGroupMember.addProperty("Version", version);
+        coGroupMember.add("Person", person);
+        coGroupMember.addProperty("CoGroupId", coGroupId.toString());
+        coGroupMember.addProperty("Member", member);
+        coGroupMember.addProperty("Owner", false);
+        coGroupMember.addProperty("ValidFrom", "");
+        coGroupMember.addProperty("ValidThrough", "");
+        coGroupMembers.add(coGroupMember);
+        coGroup.addProperty("RequestType", "CoGroupMembers");
+        coGroup.addProperty("Version", version);
+        coGroup.add("CoGroupMembers", coGroupMembers);
+        return coGroup;
+    }
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/Aggregations.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/Aggregations.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/Aggregations.java	(revision 61527)
@@ -0,0 +1,38 @@
+package eu.dnetlib.repo.manager.domain;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Aggregations{
+
+    private List<AggregationDetails> aggregationHistory = new ArrayList<>();
+    private AggregationDetails lastCollection;
+    private AggregationDetails lastTransformation;
+
+    public Aggregations() {
+    }
+
+    public List<AggregationDetails> getAggregationHistory() {
+        return aggregationHistory;
+    }
+
+    public void setAggregationHistory(List<AggregationDetails> aggregationHistory) {
+        this.aggregationHistory = aggregationHistory;
+    }
+
+    public AggregationDetails getLastCollection() {
+        return lastCollection;
+    }
+
+    public void setLastCollection(AggregationDetails lastCollection) {
+        this.lastCollection = lastCollection;
+    }
+
+    public AggregationDetails getLastTransformation() {
+        return lastTransformation;
+    }
+
+    public void setLastTransformation(AggregationDetails lastTransformation) {
+        this.lastTransformation = lastTransformation;
+    }
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/broker/ConditionOperator.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/broker/ConditionOperator.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/broker/ConditionOperator.java	(revision 61527)
@@ -0,0 +1,10 @@
+package eu.dnetlib.repo.manager.domain.broker;
+
+
+
+/**
+ * Created by stefanos on 17/3/2017.
+ */
+public enum ConditionOperator   {
+    EXACT, MATCH_ANY, MATCH_ALL, RANGE
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/UsageSummary.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/UsageSummary.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/UsageSummary.java	(revision 61527)
@@ -0,0 +1,33 @@
+package eu.dnetlib.repo.manager.domain;
+
+import eu.dnetlib.domain.data.PiwikInfo;
+
+public class UsageSummary {
+    private MetricsInfo metricsInfo;
+
+    private PiwikInfo piwikInfo;
+
+    public UsageSummary() {
+    }
+
+    public UsageSummary(MetricsInfo metricsInfo, PiwikInfo piwikInfo) {
+        this.metricsInfo = metricsInfo;
+        this.piwikInfo = piwikInfo;
+    }
+
+    public MetricsInfo getMetricsInfo() {
+        return metricsInfo;
+    }
+
+    public void setMetricsInfo(MetricsInfo metricsInfo) {
+        this.metricsInfo = metricsInfo;
+    }
+
+    public PiwikInfo getPiwikInfo() {
+        return piwikInfo;
+    }
+
+    public void setPiwikInfo(PiwikInfo piwikInfo) {
+        this.piwikInfo = piwikInfo;
+    }
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/UserAccessException.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/UserAccessException.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/UserAccessException.java	(revision 61527)
@@ -0,0 +1,51 @@
+package eu.dnetlib.repo.manager.domain;
+
+
+
+/**
+ * Created by nikonas on 7/12/15.
+ */
+public class UserAccessException extends Exception   {
+
+    public enum ErrorCode   {
+        USER_ALREADY_EXISTS,
+        SQL_ERROR,
+        INVALID_USERNAME,
+        INVALID_PASSWORD,
+        NOT_ACTIVATED,
+        ACTIVATION_ERROR,
+        LDAP_ERROR,
+        USERNAME_ALREADY_EXISTS, MAIL_ALREADY_EXISTS, GENERAL_ERROR, ALREADY_ACTIVATED, INVALID_EMAIL_FORMAT, WRONG_SECURITY_CODE, INCORRECT_CAPTCHA
+    }
+
+    private ErrorCode errorCode = null;
+
+    public UserAccessException() {
+    }
+
+    public UserAccessException(ErrorCode errorCode) {
+        this.errorCode = errorCode;
+    }
+
+    public UserAccessException(String message, Throwable cause, ErrorCode errorCode) {
+        super(message, cause);
+
+        this.errorCode = errorCode;
+    }
+
+    public UserAccessException(String message, ErrorCode errorCode) {
+        super(message);
+
+        this.errorCode = errorCode;
+    }
+
+    public UserAccessException(Throwable cause, ErrorCode errorCode) {
+        super(cause);
+
+        this.errorCode = errorCode;
+    }
+
+    public ErrorCode getErrorCode() {
+        return errorCode;
+    }
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/SushiliteServiceImpl.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/SushiliteServiceImpl.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/SushiliteServiceImpl.java	(revision 61527)
@@ -0,0 +1,114 @@
+package eu.dnetlib.repo.manager.service;
+
+import eu.dnetlib.usagestats.sushilite.domain.ReportItem;
+import eu.dnetlib.usagestats.sushilite.domain.ReportResponseWrapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.core.ParameterizedTypeReference;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.ResponseEntity;
+import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.RestClientException;
+import org.springframework.web.client.RestTemplate;
+import org.springframework.web.util.UriComponentsBuilder;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Service("sushiliteService")
+public class SushiliteServiceImpl implements SushiliteService {
+
+
+    @Value("${services.repomanager.usagestats.sushiliteEndpoint}")
+    private String usagestatsSushiliteEndpoint;
+
+    @Autowired
+    private EmailUtils emailUtils;
+
+    private static final org.apache.log4j.Logger LOGGER = org.apache.log4j.Logger.getLogger(SushiliteServiceImpl.class);
+
+
+    @Override
+    @PreAuthorize("hasAuthority('REGISTERED_USER')")
+    public ReportResponseWrapper getReportResults(String page,
+                                                  String pageSize,
+                                                  String Report,
+                                                  String Release,
+                                                  String RequestorID,
+                                                  String BeginDate,
+                                                  String EndDate,
+                                                  String RepositoryIdentifier,
+                                                  String ItemIdentifier,
+                                                  String ItemDataType,
+                                                  String Granularity,
+                                                  String Pretty) {
+
+            //build the uri params
+            UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(this.usagestatsSushiliteEndpoint + "GetReport/")
+                                                                .queryParam("Report", Report)
+                                                                .queryParam("Release", Release)
+                                                                .queryParam("RequestorID", RequestorID)
+                                                                .queryParam("BeginDate", BeginDate)
+                                                                .queryParam("EndDate", EndDate)
+                                                                .queryParam("RepositoryIdentifier", RepositoryIdentifier)
+                                                                .queryParam("ItemIdentifier", ItemIdentifier)
+                                                                .queryParam("ItemDataType", ItemDataType)
+                                                                .queryParam("Granularity", Granularity)
+                                                                .queryParam("Pretty", Pretty);
+
+            //create new template engine
+            RestTemplate template = new RestTemplate();
+            template.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
+
+            ResponseEntity<ReportResponseWrapper> resp;
+            try {
+                //communicate with endpoint
+                resp = template.exchange(
+                        builder.build().encode().toUri(),
+                        HttpMethod.GET,
+                        null,
+                        new ParameterizedTypeReference<ReportResponseWrapper>() {
+                        });
+            } catch (RestClientException e) {
+                LOGGER.debug("Exception on getReportResults" , e);
+                emailUtils.reportException(e);
+                throw e;
+            }
+
+            // check remote api's response
+            System.out.println("sushi responded status " + resp.getStatusCode());
+
+            // get the items corresponding to the requested page
+            List<ReportItem> requestedItemList = new ArrayList<>();
+            if (resp.getBody().getReportResponse().getReportWrapper().getReport().getCustomer().getReportItems() != null) {
+                try {
+                    int totalItems = resp.getBody().getReportResponse().getReportWrapper().getReport().getCustomer().getReportItems().size();
+                    int size = Integer.parseInt(pageSize);
+                    int offset = Integer.parseInt(page)*size;
+
+                    if (offset < totalItems ) {
+                        int upperIndex = offset+size;
+                        if (upperIndex > totalItems) {
+                            upperIndex = totalItems;
+                        }
+                        requestedItemList = resp.getBody().getReportResponse().getReportWrapper().getReport().getCustomer().getReportItems().subList(offset,upperIndex);
+                    }
+
+                } catch (NumberFormatException e) {
+                    LOGGER.debug("Exception on getReportResults - trying to cast strings to integers", e);
+                    //emailUtils.reportException(e);
+                    throw e;
+                }
+
+            }
+
+            ReportResponseWrapper newReportResponse = resp.getBody();
+            newReportResponse.getReportResponse().getReportWrapper().getReport().getCustomer().setReportItems(requestedItemList);
+
+
+            return newReportResponse;
+    }
+
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/DatasourceRegistrationState.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/DatasourceRegistrationState.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/DatasourceRegistrationState.java	(revision 61527)
@@ -0,0 +1,47 @@
+package eu.dnetlib.repo.manager.domain;
+
+import eu.dnetlib.domain.data.Repository;
+
+/**
+ * Created by stefania on 12/17/15.
+ */
+public class DatasourceRegistrationState extends WizardState {
+
+    private String mode;
+    private String selectedRepositoryId;
+
+    private Repository repository;
+
+    public DatasourceRegistrationState() {
+    }
+
+    public DatasourceRegistrationState(String mode, String selectedRepositoryId, Repository repository) {
+        this.mode = mode;
+        this.selectedRepositoryId = selectedRepositoryId;
+        this.repository = repository;
+    }
+
+    public String getMode() {
+        return mode;
+    }
+
+    public void setMode(String mode) {
+        this.mode = mode;
+    }
+
+    public String getSelectedRepositoryId() {
+        return selectedRepositoryId;
+    }
+
+    public void setSelectedRepositoryId(String selectedRepositoryId) {
+        this.selectedRepositoryId = selectedRepositoryId;
+    }
+
+    public Repository getRepository() {
+        return repository;
+    }
+
+    public void setRepository(Repository repository) {
+        this.repository = repository;
+    }
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/DatasourceVocabularies.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/DatasourceVocabularies.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/DatasourceVocabularies.java	(revision 61527)
@@ -0,0 +1,60 @@
+package eu.dnetlib.repo.manager.domain;
+
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Created by nikonas on 21/12/15.
+ */
+public class DatasourceVocabularies{
+
+    private Map<String, String> countries;
+    private List<Timezone> timezones;
+    private Map<String, String> datasourceClasses;
+    private List<String> typologies;
+    private Map<String, String> compatibilityLevels;
+
+    public DatasourceVocabularies() {
+    }
+
+    public Map<String, String> getCountries() {
+        return countries;
+    }
+
+    public void setCountries(Map<String, String> countries) {
+        this.countries = countries;
+    }
+
+    public List<Timezone> getTimezones() {
+        return timezones;
+    }
+
+    public void setTimezones(List<Timezone> timezones) {
+        this.timezones = timezones;
+    }
+
+    public Map<String, String> getDatasourceClasses() {
+        return datasourceClasses;
+    }
+
+    public void setDatasourceClasses(Map<String, String> datasourceClasses) {
+        this.datasourceClasses = datasourceClasses;
+    }
+
+    public List<String> getTypologies() {
+        return typologies;
+    }
+
+    public void setTypologies(List<String> typologies) {
+        this.typologies = typologies;
+    }
+
+    public Map<String, String> getCompatibilityLevels() {
+        return compatibilityLevels;
+    }
+
+    public void setCompatibilityLevels(Map<String, String> compatibilityLevels) {
+        this.compatibilityLevels = compatibilityLevels;
+    }
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/BrokerServiceImpl.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/BrokerServiceImpl.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/BrokerServiceImpl.java	(revision 61527)
@@ -0,0 +1,381 @@
+package eu.dnetlib.repo.manager.service;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import eu.dnetlib.repo.manager.domain.BrokerException;
+import eu.dnetlib.repo.manager.domain.RepositorySnippet;
+import eu.dnetlib.repo.manager.domain.Term;
+import eu.dnetlib.repo.manager.domain.Tuple;
+import eu.dnetlib.repo.manager.domain.broker.*;
+import org.apache.commons.lang.NotImplementedException;
+import org.json.JSONException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.core.ParameterizedTypeReference;
+import org.springframework.http.*;
+import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
+import org.springframework.stereotype.Service;
+import org.springframework.util.LinkedMultiValueMap;
+import org.springframework.util.MultiValueMap;
+import org.springframework.web.client.RestClientException;
+import org.springframework.web.client.RestTemplate;
+import org.springframework.web.util.UriComponents;
+import org.springframework.web.util.UriComponentsBuilder;
+
+import javax.annotation.PostConstruct;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.*;
+
+@Service("brokerService")
+public class BrokerServiceImpl implements BrokerService {
+
+    @Autowired
+    private RepositoryServiceImpl repoAPI;
+    @Value("${services.broker.url}:${services.broker.port}/${services.broker.api}${services.broker.openaire}")
+    private String openairePath;
+    @Value("${services.broker.url}:${services.broker.port}/${services.broker.api}")
+    private String apiPath;
+    @Value("${topic_types.url}")
+    private String topicsURL;
+
+    private static final org.apache.log4j.Logger LOGGER = org.apache.log4j.Logger
+            .getLogger(BrokerServiceImpl.class);
+
+    @Autowired
+    RestTemplate restTemplate;
+
+    private HttpHeaders httpHeaders;
+
+    private HashMap<String, Term> topics = new HashMap<String, Term>();
+
+    @Autowired
+    private EmailUtils emailUtils;
+
+    @PostConstruct
+    private void initDnetTopicsMap() {
+
+        httpHeaders = new HttpHeaders();
+        httpHeaders.set("Content-Type", "application/json");
+
+        LOGGER.debug("Init dnet topics!");
+        try (InputStream is = new URL(topicsURL).openStream()) {
+            ObjectMapper mapper = new ObjectMapper();
+            JsonNode root = mapper.readTree(is);
+            for (JsonNode term : root.path("terms"))
+                topics.put(term.path("code").textValue(), parseTerm(term));
+        } catch (IOException e) {
+            LOGGER.debug("Exception on initDnetTopicsMap", e);
+            emailUtils.reportException(e);
+        }
+    }
+
+    private Term parseTerm(JsonNode term) {
+        return new Term(term.path("englishName").textValue(), term.path("nativeName").textValue(),
+                term.path("encoding").textValue(), term.path("code").textValue());
+    }
+
+
+    @Override
+    public DatasourcesBroker getDatasourcesOfUser(String user, String includeShared, String includeByOthers) throws JSONException {
+        long start = System.currentTimeMillis();
+        DatasourcesBroker ret = new DatasourcesBroker();
+        try {
+            ret.setDatasourcesOfUser(getDatasourcesOfUserType(repoAPI.getRepositoriesSnippetsOfUser(user, "0", "100")));
+            //TODO fix bug when values are true
+//            if (Boolean.parseBoolean(includeShared)) {
+//                List<String> sharedDatasourceIds = new ArrayList<String>();
+//                ret.setSharedDatasources(getDatasourcesOfUserType(getRepositoriesByIds(sharedDatasourceIds)));
+//            }
+
+//            if (Boolean.parseBoolean(includeByOthers)) {
+//                ret.setDatasourcesOfOthers(getDatasourcesOfUserType(getRepositoriesOfUser(user)));
+//            }
+        } catch (Exception e) {
+            LOGGER.debug("Exception on getDatasourcesOfUser", e);
+            emailUtils.reportException(e);
+        }
+        long end = System.currentTimeMillis();
+        System.out.println("Getting datasources of user in " + (end - start) + "ms");
+        return ret;
+    }
+
+    @Override
+    public List<BrowseEntry> getTopicsForDatasource(String datasourceName) throws BrokerException {
+        final String service = "/topicsForDatasource";
+
+        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(openairePath + service)
+                .queryParam("ds", datasourceName);
+
+        ResponseEntity<List<BrowseEntry>> resp;
+        try {
+            resp = restTemplate.exchange(
+                    builder.build().encode().toUri(),
+                    HttpMethod.GET,
+                    null,
+                    new ParameterizedTypeReference<List<BrowseEntry>>() {
+                    });
+        } catch (RestClientException e) {
+            LOGGER.debug("Exception on getTopicsForDatasource", e);
+            emailUtils.reportException(e);
+            throw new BrokerException(e);
+        }
+
+        return resp.getBody();
+    }
+
+    @Override
+    public EventsPage advancedShowEvents(String page,
+                                         String size,
+                                         AdvQueryObject advQueryObject) throws BrokerException, JSONException, IOException {
+
+        final String service = "/events/{page}/{pageSize}";
+
+        Map<String, Long> uriParams = new HashMap<>();
+        uriParams.put("page", Long.parseLong(page));
+        uriParams.put("pageSize", Long.parseLong(size));
+
+        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(openairePath + service);
+
+        MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
+        advQueryObject.setPage(Long.parseLong(page));
+        HttpEntity<AdvQueryObject> entity = new HttpEntity<>(advQueryObject, httpHeaders);
+        ResponseEntity<EventsPage> resp;
+        try {
+            resp = restTemplate.exchange(
+                    builder.buildAndExpand(uriParams).encode().toUri(),
+                    HttpMethod.POST,
+                    entity,
+                    new ParameterizedTypeReference<EventsPage>() {
+                    }
+            );
+        } catch (RestClientException e) {
+            LOGGER.debug("Exception on advancedShowEvents", e);
+            emailUtils.reportException(e);
+            throw new BrokerException(e);
+        }
+        return resp.getBody();
+
+
+    }
+
+
+    private List<Tuple<BrowseEntry, String>> getDatasourcesOfUserType(List<RepositorySnippet> repositories) throws BrokerException {
+        long start = System.currentTimeMillis();
+        List<Tuple<BrowseEntry, String>> entries = new ArrayList<>();
+        for (RepositorySnippet repo : repositories) {
+            BrowseEntry temp = new BrowseEntry();
+            temp.setValue(repo.getOfficialname());
+            temp.setSize(new Long(0));
+            for (BrowseEntry e : getTopicsForDatasource(repo.getOfficialname())) {
+                temp.setSize(temp.getSize() + e.getSize());
+            }
+            Tuple<BrowseEntry, String> tup = new Tuple<>(temp, repo.getLogoUrl());
+            entries.add(tup);
+        }
+
+        // sort the collection by the second field of the tuple which is size
+        Collections.sort(entries, new Comparator<Tuple<BrowseEntry, String>>() {
+            @Override
+            public int compare(Tuple<BrowseEntry, String> e1, Tuple<BrowseEntry, String> e2) {
+                return (int) (e2.getFirst().getSize().longValue() - e1.getFirst().getSize().longValue());
+            }
+        });
+        long stop = System.currentTimeMillis();
+        System.out.println("getDatasourcesOfUserType returned in " + (stop - start) + "ms ");
+
+        return entries;
+    }
+
+    @Override
+    public EventsPage showEvents(String datasourceName,
+                                 String topic,
+                                 String page,
+                                 String size) throws BrokerException, JSONException {
+
+        final String service = "/events";
+
+        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(openairePath + service)
+                .queryParam("ds", datasourceName)
+                .queryParam("topic", topic)
+                .path("/{page}/{size}/");
+
+        ResponseEntity<EventsPage> resp;
+        try {
+            resp = restTemplate.exchange(
+                    builder.build().expand(page, size).encode().toUri(),
+                    HttpMethod.GET,
+                    null,
+                    new ParameterizedTypeReference<EventsPage>() {
+                    });
+        } catch (RestClientException e) {
+            LOGGER.debug("Exception on showEvents", e);
+            emailUtils.reportException(e);
+            throw new BrokerException(e);
+        }
+        return resp.getBody();
+    }
+
+    @Override
+    public Map<String, List<SimpleSubscriptionDesc>> getSimpleSubscriptionsOfUser(String userEmail)
+            throws BrokerException {
+
+        final String service = "/subscriptions";
+
+        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(openairePath + service)
+                .queryParam("email", userEmail);
+
+        LOGGER.debug(builder.build().encode().toUri());
+        ResponseEntity<Map<String, List<SimpleSubscriptionDesc>>> resp;
+        try {
+            resp = restTemplate.exchange(
+                    builder.build().encode().toUri(),
+                    HttpMethod.GET,
+                    null,
+                    new ParameterizedTypeReference<Map<String, List<SimpleSubscriptionDesc>>>() {
+                    });
+        } catch (RestClientException e) {
+            LOGGER.debug("Exception on getSimpleSubscriptionsOfUser", e);
+            emailUtils.reportException(e);
+            throw new BrokerException(e);
+        }
+        return resp.getBody();
+    }
+
+    @Override
+    public Map<String, List<SimpleSubscriptionDesc>> getSimpleSubscriptionsOfUserByRepoId(String userEmail, String repoId) throws BrokerException {
+        Map<String, List<SimpleSubscriptionDesc>> subscriptionsOfUser = getSimpleSubscriptionsOfUser(userEmail);
+        throw new NotImplementedException();
+//        return null;
+    }
+
+    @Override
+    public Subscription subscribe(OpenaireSubscription obj) throws BrokerException {
+        final String service = "/subscribe";
+
+        //build the uri params
+        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(openairePath + service);
+
+        HttpEntity<OpenaireSubscription> entity = new HttpEntity<>(obj, httpHeaders);
+
+        //create new template engine
+        RestTemplate template = new RestTemplate();
+        template.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
+        ResponseEntity<Subscription> resp;
+        try {
+            //communicate with endpoint
+            resp = restTemplate.exchange(
+                    builder.build().encode().toUri(),
+                    HttpMethod.POST,
+                    entity,
+                    new ParameterizedTypeReference<Subscription>() {
+                    });
+        } catch (RestClientException e) {
+            LOGGER.debug("Exception on OpenaireSubscription", e);
+            emailUtils.reportException(e);
+            throw new BrokerException(e);
+        }
+
+        return resp.getBody();
+    }
+
+    @Override
+    public ResponseEntity<Object> unsubscribe(String subscriptionId) throws BrokerException {
+        final String service = "/subscriptions/" + subscriptionId;
+
+        //build the uri params
+        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(apiPath + service);
+
+        try {
+            //communicate with endpoint
+            restTemplate.exchange(
+                    builder.build().encode().toUri(),
+                    HttpMethod.DELETE,
+                    null,
+                    new ParameterizedTypeReference<Void>() {
+                    });
+        } catch (RestClientException e) {
+            LOGGER.debug("Exception on unsubscribe", e);
+            emailUtils.reportException(e);
+            throw new BrokerException(e);
+        }
+        return new ResponseEntity<>("OK", HttpStatus.OK);
+    }
+
+    @Override
+    public Subscription getSubscription(String subscriptionId) throws BrokerException {
+        final String service = "/subscriptions/" + subscriptionId;
+
+        //build the uri params
+        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(apiPath + service);
+
+        ResponseEntity<Subscription> resp;
+        try {
+            //communicate with endpoint
+            resp = restTemplate.exchange(
+                    builder.build().encode().toUri(),
+                    HttpMethod.GET,
+                    null,
+                    new ParameterizedTypeReference<Subscription>() {
+                    });
+        } catch (RestClientException e) {
+            LOGGER.debug("Exception on getSubscription", e);
+            emailUtils.reportException(e);
+            throw new BrokerException(e);
+        }
+        return resp.getBody();
+    }
+
+    @Override
+    public Map<String, Term> getDnetTopics() throws BrokerException {
+        return topics;
+    }
+
+    @Override
+    public EventsPage getNotificationsBySubscriptionId(String subscriptionId,
+                                                       String page,
+                                                       String size) throws BrokerException {
+
+        UriComponents uriComponents = UriComponentsBuilder
+                .fromHttpUrl(openairePath + "/notifications/")
+                .path("/{id}/{page}/{size}/")
+                .build().expand(subscriptionId, page, size).encode();
+
+        ResponseEntity<EventsPage> resp;
+        try {
+            resp = restTemplate.exchange(
+                    uriComponents.toUri(),
+                    HttpMethod.GET,
+                    null,
+                    new ParameterizedTypeReference<EventsPage>() {
+                    });
+        } catch (RestClientException e) {
+            LOGGER.debug("Exception on getNotificationsBySubscriptionId", e);
+            emailUtils.reportException(e);
+            throw new BrokerException(e);
+        }
+        return resp.getBody();
+    }
+
+    //@Override
+    public Map<String, List<Subscription>> getSubscriptionsOfUser(String userEmail)
+            throws BrokerException {
+
+        Map<String, List<SimpleSubscriptionDesc>> simpleSubs = getSimpleSubscriptionsOfUser(userEmail);
+        Map<String, List<Subscription>> subs = new HashMap<>();
+        List<Subscription> subscriptions = null;
+
+        for (String s : simpleSubs.keySet()) {
+            List<SimpleSubscriptionDesc> simpleSubscriptionDescs = simpleSubs.get(s);
+            for (SimpleSubscriptionDesc simpleSubscriptionDesc : simpleSubscriptionDescs) {
+                subscriptions = new ArrayList<>();
+                subscriptions.add(getSubscription(simpleSubscriptionDesc.getId()));
+            }
+            subs.put(s, subscriptions);
+        }
+        return subs;
+    }
+
+
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/ValidationServiceException.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/ValidationServiceException.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/ValidationServiceException.java	(revision 61527)
@@ -0,0 +1,44 @@
+package eu.dnetlib.repo.manager.domain;
+
+/**
+ * Created by nikonas on 7/12/15.
+ */
+public class ValidationServiceException extends Exception{
+
+    public enum ErrorCode{
+        NO_ADMIN_EMAILS,
+        NOT_VALID_BASEURL,
+        GENERAL_ERROR, NOT_VALID_SET
+    }
+
+    private ErrorCode errorCode = null;
+
+    public ValidationServiceException() {
+    }
+
+    public ValidationServiceException(ErrorCode errorCode) {
+        this.errorCode = errorCode;
+    }
+
+    public ValidationServiceException(String message, Throwable cause, ErrorCode errorCode) {
+        super(message, cause);
+
+        this.errorCode = errorCode;
+    }
+
+    public ValidationServiceException(String message, ErrorCode errorCode) {
+        super(message);
+
+        this.errorCode = errorCode;
+    }
+
+    public ValidationServiceException(Throwable cause, ErrorCode errorCode) {
+        super(cause);
+
+        this.errorCode = errorCode;
+    }
+
+    public ErrorCode getErrorCode() {
+        return errorCode;
+    }
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/OrderByField.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/OrderByField.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/OrderByField.java	(revision 61527)
@@ -0,0 +1,26 @@
+package eu.dnetlib.repo.manager.domain;
+
+public enum OrderByField {
+
+    REPOSITORY_NAME("repositoryname"),
+    REPOSITORY_ID("repositoryid"),
+    SITE_ID("siteid"),
+    CREATION_DATE("creationdate"),
+    VALIDATION_DATE("validationdate"),
+    REQUESTOR_NAME("requestorname"),
+    REQUESTOR_EMAIL("requestoremail"),
+    VALIDATED("validated"),
+    COUNTRY("country");
+
+
+    private final String text;
+
+    OrderByField(String text) {
+        this.text = text;
+    }
+
+    @Override
+    public String toString() {
+        return text;
+    }
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/security/AaiRoleMappingService.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/security/AaiRoleMappingService.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/security/AaiRoleMappingService.java	(revision 61527)
@@ -0,0 +1,120 @@
+package eu.dnetlib.repo.manager.service.security;
+
+import org.apache.log4j.Logger;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.stereotype.Service;
+
+import java.net.URLEncoder;
+import java.util.Collection;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+@Service("roleMappingService")
+public class AaiRoleMappingService implements RoleMappingService {
+
+    private static final Logger logger = Logger.getLogger(AaiRoleMappingService.class);
+
+    @Value("${aai.registry.production:true}")
+    private boolean production;
+
+
+    private String createRepoRoleName(String prefix, String repoId) {
+        return prefix + "." + repoId.replace(":", "$");
+    }
+
+    @Override
+    public String getRepoNameWithoutType(String fullName, String prefix) {
+        if (fullName != null && prefix != null && fullName.startsWith(prefix)) {
+            return fullName.substring(prefix.length());
+        }
+        return null;
+    }
+
+    @Override
+    public String getRepoIdByRoleId(String roleId) {
+        if (!roleActive(roleId)) {
+            return null;
+        }
+        return roleId.replaceFirst(".*datasource\\.", "").replace("$", ":");
+    }
+
+    @Override
+    public Collection<String> getRepoIdsByRoleIds(Collection<String> roleIds) {
+        return roleIds
+                .stream()
+                //.filter(this::roleActive) //  implicitly executed in the next statement
+                .map(this::getRepoIdByRoleId)
+                .filter(Objects::nonNull)
+                .collect(Collectors.toList());
+    }
+
+    @Override
+    public String getRoleIdByRepoId(String repoId) {
+        String roleId = "";
+        String prefix = (production ? "" : "beta.") + "datasource";
+        if (repoId != null) {
+            roleId = createRepoRoleName(prefix, repoId);
+            return roleId;
+        } else {
+            return null;
+        }
+
+    }
+
+    @Override
+    public Collection<String> getRoleIdsByRepoIds(Collection<String> repoIds) {
+        return repoIds
+                .stream()
+                .map(this::getRoleIdByRepoId)
+                .filter(Objects::nonNull)
+                .collect(Collectors.toList());
+    }
+
+    @Override
+    public String convertAuthorityIdToRepoId(String authorityId) {
+        String repo = "";
+        if (authorityId != null && roleActive(authorityId)) {
+            repo = authorityId
+                    .replaceFirst(".*datasource\\.", "")
+                    .replace("$", ":")
+                    .toLowerCase();
+        }
+        return repo;
+    }
+
+    @Override
+    public String convertAuthorityToRepoId(GrantedAuthority authority) {
+        return convertAuthorityIdToRepoId(authority.toString());
+    }
+
+    @Override
+    public String convertRepoIdToAuthorityId(String repoId) {
+        StringBuilder roleBuilder = new StringBuilder();
+        String role = "";
+        if (repoId != null) {
+            roleBuilder.append(production ? "" : "beta.");
+            roleBuilder.append("datasource.");
+            roleBuilder.append(repoId.replace(":", "$"));
+            role = roleBuilder.toString().replace(".", "_").toUpperCase();
+        }
+        return role;
+    }
+
+    @Override
+    public String convertRepoIdToEncodedAuthorityId(String repoId) {
+        return URLEncoder.encode(convertRepoIdToAuthorityId(repoId));
+    }
+
+    @Override
+    public SimpleGrantedAuthority convertRepoIdToAuthority(String repoId) {
+        String role = convertRepoIdToEncodedAuthorityId(repoId);
+        return new SimpleGrantedAuthority(role);
+    }
+
+    private boolean roleActive(String roleId) {
+        return (production && !roleId.toLowerCase().startsWith("beta."))
+                || (!production && roleId.toLowerCase().startsWith("beta."));
+    }
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/broker/OpenaireSubscription.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/broker/OpenaireSubscription.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/broker/OpenaireSubscription.java	(revision 61527)
@@ -0,0 +1,60 @@
+package eu.dnetlib.repo.manager.domain.broker;
+
+
+/**
+ * Created by stefanos on 10-Mar-17.
+ */
+
+public class OpenaireSubscription {
+
+    private String subscriber;
+    private NotificationFrequency frequency;
+    private NotificationMode mode;
+    private AdvQueryObject query;
+
+    public OpenaireSubscription() {
+    }
+
+    public OpenaireSubscription(final String subscriber, final NotificationFrequency frequency, final
+    NotificationMode mode,
+                                final AdvQueryObject query) {
+        this.subscriber = subscriber;
+        this.frequency = frequency;
+        this.mode = mode;
+        this.query = query;
+    }
+
+    public String getSubscriber() {
+        return this.subscriber;
+    }
+
+    public void setSubscriber(final String subscriber) {
+        this.subscriber = subscriber;
+    }
+
+    public NotificationFrequency getFrequency() {
+        return this.frequency;
+    }
+
+    public void setFrequency(final NotificationFrequency frequency) {
+        this.frequency = frequency;
+    }
+
+    public NotificationMode getMode() {
+        return this.mode;
+    }
+
+    public void setMode(final NotificationMode mode) {
+        this.mode = mode;
+    }
+
+    public AdvQueryObject getQuery() {
+        return this.query;
+    }
+
+    public void setQuery(final AdvQueryObject query) {
+        this.query = query;
+    }
+
+
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/exception/ServerError.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/exception/ServerError.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/exception/ServerError.java	(revision 61527)
@@ -0,0 +1,21 @@
+package eu.dnetlib.repo.manager.exception;
+
+public class ServerError {
+
+    public final String url;
+    public final String error;
+
+    public ServerError(String url, Exception ex) {
+        this.url = url;
+        this.error = ex.getMessage();
+    }
+
+    public String getUrl() {
+        return this.url;
+    }
+
+    public String getError() {
+        return this.error;
+    }
+
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/RequestFilter.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/RequestFilter.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/RequestFilter.java	(revision 61527)
@@ -0,0 +1,78 @@
+package eu.dnetlib.repo.manager.domain;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class RequestFilter{
+
+    private String registeredby = null;
+    private String typology = null;
+    private String country = null;
+    private String id = null;
+    private String officialname = null;
+    private String englishname = null;
+    private String collectedfrom = null;
+
+
+
+
+    public RequestFilter() {
+
+    }
+
+    public String getTypology() {
+        return typology;
+    }
+
+    public void setTypology(String typology) {
+        this.typology = typology;
+    }
+
+    public String getRegisteredby() {
+        return registeredby;
+    }
+
+    public void setRegisteredby(String registeredby) {
+        this.registeredby = registeredby;
+    }
+
+    public String getCountry() {
+        return country;
+    }
+
+    public void setCountry(String country) {
+        this.country = country;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getOfficialname() {
+        return officialname;
+    }
+
+    public void setOfficialname(String officialname) {
+        this.officialname = officialname;
+    }
+
+    public String getCollectedfrom() {
+        return collectedfrom;
+    }
+
+    public void setCollectedfrom(String collectedfrom) {
+        this.collectedfrom = collectedfrom;
+    }
+
+    public String getEnglishname() {
+        return englishname;
+    }
+
+    public void setEnglishname(String englishname) {
+        this.englishname = englishname;
+    }
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/security/AuthorizationService.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/security/AuthorizationService.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/security/AuthorizationService.java	(revision 61527)
@@ -0,0 +1,69 @@
+package eu.dnetlib.repo.manager.service.security;
+
+import eu.dnetlib.repo.manager.domain.dto.User;
+import eu.dnetlib.repo.manager.exception.ResourceNotFoundException;
+
+import java.util.Collection;
+import java.util.List;
+
+public interface AuthorizationService {
+
+    /**
+     * @param type
+     * @param id
+     * @return
+     */
+    String member(String type, String id); //TODO: use or delete
+
+    /**
+     * @param id Resource Id to check.
+     * @return Checks if a user is a member of a resource.
+     */
+    boolean isMemberOf(String id);
+
+
+    /**
+     * Returns a list of admins of the resource.
+     *
+     * @param repoId
+     * @return
+     */
+    List<User> getAdminsOfRepo(String repoId);
+
+    /**
+     * Add a user as admin to a resource.
+     *
+     * @param id    Resource id
+     * @param email User email
+     * @return
+     * @throws ResourceNotFoundException
+     */
+    boolean addAdmin(String id, String email) throws ResourceNotFoundException;
+
+    /**
+     * Remove user from resource admins.
+     *
+     * @param id    Resource id
+     * @param email User email
+     * @return
+     * @throws ResourceNotFoundException
+     */
+    boolean removeAdmin(String id, String email) throws ResourceNotFoundException;
+
+
+    /**
+     * Returns the roles of the authenticated user.
+     * 
+     * @return
+     */
+    Collection<String> getUserRoles();
+
+    /**
+     * Returns the roles of the user with the given email.
+     *
+     * @param email
+     * @return
+     */
+    Collection<String> getUserRoles(String email);
+
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/security/AuthorizationServiceImpl.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/security/AuthorizationServiceImpl.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/security/AuthorizationServiceImpl.java	(revision 61527)
@@ -0,0 +1,149 @@
+package eu.dnetlib.repo.manager.service.security;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import eu.dnetlib.repo.manager.domain.dto.User;
+import eu.dnetlib.repo.manager.exception.ResourceNotFoundException;
+import eu.dnetlib.repo.manager.service.aai.registry.AaiRegistryService;
+import org.mitre.openid.connect.model.OIDCAuthenticationToken;
+import org.mitre.openid.connect.model.UserInfo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+@Service("authorizationService")
+public class AuthorizationServiceImpl implements AuthorizationService {
+
+    public static final String SUPER_ADMINISTRATOR = "SUPER_ADMINISTRATOR";
+    public static final String CONTENT_PROVIDER_DASHBOARD_ADMINISTRATOR = "CONTENT_PROVIDER_DASHBOARD_ADMINISTRATOR";
+    public static final String REGISTERED_USER = "REGISTERED_USER";
+
+    private final RoleMappingService roleMappingService;
+    private final AaiRegistryService aaiRegistryService;
+    private final AuthoritiesUpdater authoritiesUpdater;
+
+    @Autowired
+    AuthorizationServiceImpl(RoleMappingService roleMappingService, AaiRegistryService aaiRegistryService,
+                             AuthoritiesUpdater authoritiesUpdater) {
+        this.roleMappingService = roleMappingService;
+        this.aaiRegistryService = aaiRegistryService;
+        this.authoritiesUpdater = authoritiesUpdater;
+    }
+
+    private String mapType(String type) {
+        if (type.equals("datasource")) {
+            type = "datasource";
+        }
+        return type;
+    }
+
+    /**
+     * Type = DATASOURCE
+     */
+    @Override
+    public String member(String type, String id) {
+        return mapType(type).toUpperCase() + "_" + id.toUpperCase();
+    }
+
+    @Override
+    public boolean isMemberOf(String repoId) {
+        String repoRole = roleMappingService.convertRepoIdToEncodedAuthorityId(repoId);
+        return SecurityContextHolder.getContext().getAuthentication().getAuthorities()
+                .parallelStream().anyMatch(authority -> authority.toString().equals(repoRole));
+    }
+
+    @Override
+    public List<User> getAdminsOfRepo(String repoId) {
+        List<String> userList = new ArrayList<>();
+
+        // find couId by role name
+        String role = roleMappingService.getRoleIdByRepoId(repoId);
+        Integer couId = aaiRegistryService.getCouId(role);
+        if (couId != null) {
+            JsonArray users = aaiRegistryService.getUsersByCouId(couId);
+            for (JsonElement jsonElement : users) {
+                userList.add(jsonElement.toString());
+            }
+        }
+        return aaiRegistryService.getUsers(couId);
+    }
+
+
+    @Override
+    public boolean addAdmin(String id, String email) throws ResourceNotFoundException {
+        Integer coPersonId = aaiRegistryService.getCoPersonIdByEmail(email);
+        if (coPersonId != null) {
+            String role = roleMappingService.getRoleIdByRepoId(id);
+            Integer couId = aaiRegistryService.getCouId(role);
+            if (couId != null) {
+                Integer roleId = aaiRegistryService.getRoleId(coPersonId, couId);
+                aaiRegistryService.assignMemberRole(coPersonId, couId, roleId);
+
+                // Add role to user current authorities
+                authoritiesUpdater.addRole(email, roleMappingService.convertRepoIdToAuthority(id));
+
+                return true;
+            } else {
+                throw new ResourceNotFoundException("Cannot find CouId for role: " + role);
+            }
+        } else {
+            throw new ResourceNotFoundException("Cannot find coPersonId for user with email: " + email);
+        }
+    }
+
+    @Override
+    public boolean removeAdmin(String id, String email) throws ResourceNotFoundException {
+        Integer coPersonId = aaiRegistryService.getCoPersonIdByEmail(email);
+        if (coPersonId != null) {
+            String role = roleMappingService.getRoleIdByRepoId(id);
+            Integer couId = aaiRegistryService.getCouId(role);
+            Integer roleId = null;
+            if (couId != null) {
+                roleId = aaiRegistryService.getRoleId(coPersonId, couId);
+            }
+            if (couId != null && roleId != null) {
+                aaiRegistryService.removeMemberRole(coPersonId, couId, roleId);
+
+                // Remove role from user current authorities
+                authoritiesUpdater.removeRole(email, roleMappingService.convertRepoIdToAuthority(id));
+
+                return true;
+            } else {
+                throw new ResourceNotFoundException("Cannot find CouId for role: " + role);
+            }
+        } else {
+            throw new ResourceNotFoundException("Cannot find coPersonId for user with email: " + email);
+        }
+    }
+
+    @Override
+    public Collection<String> getUserRoles() {
+        List<String> roles;
+        JsonArray entitlements;
+        UserInfo userInfo = ((OIDCAuthenticationToken) SecurityContextHolder.getContext().getAuthentication()).getUserInfo();
+        if (userInfo.getSource().getAsJsonArray("edu_person_entitlements") != null) {
+            entitlements = userInfo.getSource().getAsJsonArray("edu_person_entitlements");
+        } else if (userInfo.getSource().getAsJsonArray("eduperson_entitlement") != null) {
+            entitlements = userInfo.getSource().getAsJsonArray("eduperson_entitlement");
+        } else {
+            entitlements = new JsonArray();
+        }
+        roles = AuthoritiesMapper.entitlementRoles(entitlements);
+        return roles;
+    }
+
+    @Override
+    public Collection<String> getUserRoles(String email) {
+        int coPersonId = aaiRegistryService.getCoPersonIdByEmail(email);
+        List<Integer> list = new ArrayList<>();
+        for (JsonElement element : aaiRegistryService.getRolesWithStatus(coPersonId, AaiRegistryService.RoleStatus.ACTIVE)) {
+            list.add(element.getAsJsonObject().get("CouId").getAsInt());
+        }
+        return aaiRegistryService.getCouNames(list).values();
+    }
+
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/resources/application.properties
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/resources/application.properties	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/resources/application.properties	(revision 61527)
@@ -0,0 +1,167 @@
+#container.hostname = dl114.madgik.di.uoa.gr
+#container.hostname = mpagasas.di.uoa.gr
+#container.hostname = adonis.athenarc.gr
+container.hostname = estella.athenarc.gr
+
+provider.endpoint=http://estella.athenarc.gr:8480/uoa-repository-manager-service
+
+
+#container.hostname = validator.mincyt.research-infrastructures.eu
+container.port = 8080
+#container.context = <yourContext>
+
+# BASIC SETTINGS
+services.validator.mode.user = ldap
+services.validator.mail.override = false
+services.validator.mode.repo = dms
+services.validator.baseUrl = http://${container.hostname}:${container.port}/${container.context}
+services.validator.dnetWorkflow = true
+services.validator.deploy.environment = openaire-beta
+#services.validator.deploy.environment = mincyt
+services.validator.registration.files.download = true
+services.validator.autoRestoreOnStartup = false
+services.validator.mode.standalone = false
+services.validator.mail.override = false
+services.validator.adminEmail = antleb@di.uoa.gr
+services.validator.admins.master = antleb@di.uoa.gr
+services.validator.admins.secondary = ant.lebesis@gmail.com
+services.validator.adminBaseUrl = ../validator-admin
+services.validator.webBaseUrl = http://${container.hostname}:${container.port}/validator
+services.validator.registrationsReport.email = ant.lebesis@gmail.com
+services.repo-manager.repository.testing.mode = false
+
+# EMAIL SETTINGS
+services.validator.mail.host = smtp.gmail.com
+services.validator.mail.port = 465
+services.validator.mail.username = test.openaire@gmail.com
+services.validator.mail.password = ^($*@$)*!$
+services.validator.mail.authenticate = true
+services.validator.mail.mode = ssl
+ervices.validator.mail.fromAddress = no-reply@mpagasas.openaire.eu
+services.validator.mail.override = false
+services.validator.mail.overrideEmail = nikonas@di.uoa.gr
+services.validator.mail.specialRecipients = antleb@di.uoa.gr
+
+
+# VALIDATOR DB
+services.validator.db.driverClassName = org.postgresql.Driver
+#services.validator.db.url = jdbc:postgresql://194.177.192.119:5432/validator
+services.validator.db.url = jdbc:postgresql://88.197.53.70:5432/validator
+services.validator.db.username = dnet
+services.validator.db.password = dnetPwd
+
+# IS
+#ISLookUpService.url = http://node1.t.openaire.research-infrastructures.eu:8280/is/services/isLookUp
+#ISRegistryService.url = http://node1.t.openaire.research-infrastructures.eu:8280/is/services/isRegistry
+#ISSNService.url = http://node1.t.openaire.research-infrastructures.eu:8280/is/services/isSN
+
+#ISLookUpService.url = http://skalny.icm.edu.pl:8280/is/services/isLookUp
+#ISRegistryService.url = http://skalny.icm.edu.pl:8280/is/services/isRegistry
+#ISSNService.url = skalny.icm.edu.pl:8280/is/services/isSN
+
+#ISLookUpService.url = http://node0.t.openaire.research-infrastructures.eu:8080/is/services/isLookUp
+#ISRegistryService.url = http://node0.t.openaire.research-infrastructures.eu:8080/is/services/isRegistry
+#ISSNService.url = http://node0.t.openaire.research-infrastructures.eu:8080/is/services/isSN
+
+#ISLookUpService.url = http://node6.t.openaire.research-infrastructures.eu:8980/dnet/services/isLookUp
+#ISRegistryService.url = http://node6.t.openaire.research-infrastructures.eu:8980/dnet/services/isRegistry
+#ISSNService.url = http://node6.t.openaire.research-infrastructures.eu:8980/dnet/services/isSN
+
+#ISLookUpService.url = http://node6.t.openaire.research-infrastructures.eu:8280/is/services/isLookUp
+#ISRegistryService.url = http://node6.t.openaire.research-infrastructures.eu:8280/is/services/isRegistry
+#ISSNService.url = http://node6.t.openaire.research-infrastructures.eu:8280/is/services/isSN
+
+#ISLookUpService.url = http://aggregator.mincyt.research-infrastructures.eu:8080/is/services/isLookUp
+#ISRegistryService.url = http://aggregator.mincyt.research-infrastructures.eu:8080/is/services/isRegistry
+#ISSNService.url = http://aggregator.mincyt.research-infrastructures.eu:8080/is/services/isSN
+
+#ISLookUpService.url = http://node0.d.hudl.research-infrastructures.eu:8080/is/services/isLookUp
+#ISRegistryService.url = http://node0.d.hudl.research-infrastructures.eu:8080/is/services/isRegistry
+#ISSNService.url = http://node0.d.hudl.research-infrastructures.eu:8080/is/is/services/isSN
+
+ISLookUpService.url = https://dev-openaire.d4science.org:443/is/services/isLookUp
+ISRegistryService.url = https://dev-openaire.d4science.org:443/is/services/isRegistry
+ISSNService.url = https://dev-openaire.d4science.org:443/is/services/isSN
+ValidatorService.url=http://estella.athenarc.gr:8080/validator-service/services/validatorWebService
+
+# LDAP
+#services.validator.ldap.address = 88.197.53.113
+#services.validator.ldap.address = 194.197.192.119
+#services.validator.ldap.port = 389
+#services.validator.ldap.username = cn=admin,dc=openaire,dc=eu
+#services.validator.ldap.password = serenata
+#services.validator.ldap.usersDN = ou=users,dc=openaire,dc=eu
+
+services.users.ldap.address = 194.177.192.119
+services.users.ldap.port = 389
+services.users.ldap.username = cn=admin,dc=openaire,dc=eu
+services.users.ldap.password = serenata
+services.users.ldap.usersDN = ou=users,dc=openaire,dc=eu
+
+services.validator.ldap.address = 194.177.192.119
+services.validator.ldap.port = 389
+services.validator.ldap.username = cn=admin,dc=openaire,dc=eu
+services.validator.ldap.password = serenata
+services.validator.ldap.usersDN = ou=users,dc=openaire,dc=eu
+
+#AAI-REDIS
+redis.host = estella.athenarc.gr
+redis.port = 6379
+redis.password = redis123
+
+oidc.dev.home = http://localhost:8480/uoa-repository-manager-service/openid_connect_login
+webapp.dev.front = http://localhost:4200/dashboard
+
+repomanager.db.driverClassName=org.postgresql.Driver
+repomanager.db.url=jdbc:postgresql://194.177.192.119:5432/repomanager
+repomanager.db.username=dnet
+repomanager.db.password=dnetPwd
+infrastructure.name=integration
+
+transport.soap.baseAddress=http://${container.hostname}:${container.port}/${container.context}
+transport.soap.force.local.address=false
+services.validator.mail.host=smtp.gmail.com
+services.validator.mail.port=465
+services.validator.mail.fromAddress=no-reply@openaire.eu
+services.validator.mail.replyToAddress=no-reply@openaire.eu
+services.validator.mail.username=test.openaire@gmail.com
+services.validator.mail.password=^($*@$)*!$
+services.validator.mail.authenticate=true
+services.validator.mail.override=false
+services.validator.mail.logonly=false
+services.validator.mail.mode=ssl
+services.validator.mail.debug=false
+services.validator.mail.overrideEmail=antleb@di.uoa.gr
+services.validator.mail.specialRecipients=antleb@di.uoa.gr
+services.validator.repoRegistration.override=antleb@di.uoa.gr
+
+oidc.issuer=https://aai.openaire.eu/oidc/
+oidc.id=767422b9-5461-4807-a80a-f9a2072d3a7d
+oidc.secret=AMQtGlbTXNjwjhF0st28LmM6V0XypMdaVS7tJmGuYFlmH36iIv4t7tVqYuLYrNPkhnZ_GPUJvhymBhFupdgb6aU
+search.api.baseAddress=https://beta.services.openaire.eu/search/v2/api
+search.api.usagestats=https://services.openaire.eu/usagestats
+search.api.usageEvents=http://beta.lbs.openaire.eu:8080/ajax/summary
+api.baseAddress=http://beta.services.openaire.eu/openaire
+services.repo-manager.baseUrl=http://${container.hostname}:${container.port}/${container.context}
+services.repo-manager.adminEmail=antleb@di.uoa.gr
+services.repo-manager.repository.testing.mode=false
+services.repo-manager.deploy.environment=development
+services.repomanager.usageStatisticsDiagramsBaseURL=https://beta.openaire.eu/stats3/
+services.repomanager.usageStatisticsNumbersBaseURL=https://beta.services.openaire.eu/usagestats/datasources/
+services.repomanager.usagestats.adminEmail=antleb@di.uoa.gr
+services.repomanager.usagestats.sushiliteEndpoint=http://beta.services.openaire.eu/usagestats/sushilite/
+services.repomanager.analyticsURL=https://analytics.openaire.eu/addsite.php?
+
+aai.mode=develop
+#uoa-repository-manager-service
+#oidc.dev.home=http://88.197.53.69:8080/uoa-repository-manager-service/openid_connect_login
+#webapp.dev.front=http://88.197.53.69/landing
+services.repo-manager.adminEmail=antleb@di.uoa.gr
+services.repomanager.usagestats.adminEmail=antleb@di.uoa.gr
+services.provide.adminEmail=antleb@di.uoa.gr
+validator.results.url=https://beta.provide.openaire.eu/compatibility/browseHistory/
+topic_types.url=https://beta.services.openaire.eu/provision/mvc/vocabularies/dnet:topic_types.json
+services.broker.url=http://broker1-dev-dnet.d4science.org
+services.broker.port=8080
+services.broker.api=api/
+services.broker.openaire=openaireBroker
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/security/AuthoritiesMapper.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/security/AuthoritiesMapper.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/security/AuthoritiesMapper.java	(revision 61527)
@@ -0,0 +1,73 @@
+package eu.dnetlib.repo.manager.service.security;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import org.apache.log4j.Logger;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+
+import java.net.URLDecoder;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class AuthoritiesMapper {
+
+    private static final Logger logger = Logger.getLogger(AuthoritiesMapper.class);
+    private static final String ENTITLEMENT_REGEX = "urn:geant:openaire[.]eu:group:([^:]*):?(.*)?:role=member#aai[.]openaire[.]eu";
+
+    private AuthoritiesMapper() {
+    }
+
+    public static Collection<GrantedAuthority> map(JsonArray entitlements) {
+        HashSet<GrantedAuthority> authorities = new HashSet<>();
+        entityRoles(entitlements, authorities);
+        return authorities;
+    }
+
+    public static List<String> entitlementRoles(JsonArray entitlements) {
+        List<String> roles = new ArrayList<>();
+        if (entitlements != null) {
+            for (JsonElement obj : entitlements) {
+                Matcher matcher = Pattern.compile(ENTITLEMENT_REGEX).matcher(obj.getAsString());
+                if (matcher.find()) {
+                    StringBuilder sb = new StringBuilder();
+                    if (matcher.group(1) != null && matcher.group(1).length() > 0) {
+                        sb.append(matcher.group(1));
+                    }
+                    if (matcher.group(2).length() > 0) {
+                        sb.append(":");
+                        sb.append(matcher.group(2));
+                    }
+                    String role = sb.toString().replace("+", " ");
+                    roles.add(URLDecoder.decode(role));
+                }
+            }
+        }
+        return roles;
+    }
+
+    private static void entityRoles(JsonArray entitlements, Set<GrantedAuthority> authorities) {
+        if (entitlements != null) {
+            for (JsonElement obj : entitlements) {
+                Matcher matcher = Pattern.compile(ENTITLEMENT_REGEX).matcher(obj.getAsString());
+                if (matcher.find()) {
+                    StringBuilder sb = new StringBuilder();
+                    if (matcher.group(1) != null && matcher.group(1).length() > 0) {
+                        sb.append(matcher.group(1).replace("+-+", "_").replaceAll("[+.]", "_").toUpperCase());
+                    }
+                    if (matcher.group(2).length() > 0) {
+                        sb.append("_");
+                        if (matcher.group(2).equals("admins")) {
+                            sb.append("MANAGER");
+                        } else {
+                            sb.append(matcher.group(2).toUpperCase());
+                        }
+                    }
+                    authorities.add(new SimpleGrantedAuthority(sb.toString()));
+                }
+            }
+        }
+    }
+
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/resources/eu/dnetlib/repo/manager/service/typologies.txt
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/resources/eu/dnetlib/repo/manager/service/typologies.txt	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/resources/eu/dnetlib/repo/manager/service/typologies.txt	(revision 61527)
@@ -0,0 +1,42 @@
+CONTENTdm
+Digibib
+Digital Commons
+DigiTool
+DIVA
+Diva-Portal
+dLibra
+Doks
+Drupal
+DSpace
+Earmas
+EPrints
+ETD
+ETD-db
+Fedora
+Fez
+Greenstone
+HAL
+invenio
+MyCoRe
+Open Repository
+OPUS
+Pica-Verbundkatalog
+Proprietary Software
+PUMA
+PURE
+SciELO
+SFIX
+VITAL
+VTOAI
+WEKO
+XooNIps
+------------------------
+OJS
+HyperJournal
+ePubTk
+GAPworks
+DPubS
+E-Journal
+------------------------
+[Other]
+
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/ValidatorServiceImpl.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/ValidatorServiceImpl.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/ValidatorServiceImpl.java	(revision 61527)
@@ -0,0 +1,297 @@
+package eu.dnetlib.repo.manager.service;
+
+import eu.dnetlib.api.functionality.ValidatorServiceException;
+import eu.dnetlib.domain.data.RepositoryInterface;
+import eu.dnetlib.domain.functionality.validator.*;
+import eu.dnetlib.repo.manager.domain.Constants;
+import eu.dnetlib.repo.manager.domain.InterfaceInformation;
+import eu.dnetlib.repo.manager.domain.ValidationServiceException;
+import eu.dnetlib.repo.manager.utils.CrisValidatorUtils;
+import eu.dnetlib.repo.manager.utils.OaiTools;
+import gr.uoa.di.driver.util.ServiceLocator;
+import org.apache.log4j.Logger;
+import org.eurocris.openaire.cris.validator.model.Job;
+import org.eurocris.openaire.cris.validator.service.JobExecutor;
+import org.eurocris.openaire.cris.validator.service.MapJobDao;
+import org.json.JSONException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.Resource;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Collectors;
+
+
+@Service("validatorService")
+public class ValidatorServiceImpl implements ValidatorService {
+
+    @Autowired
+    private MonitorServiceImpl monitorApi;
+
+    @Autowired
+    private RepositoryService repositoryService;
+
+    @Resource(name = "validatorServiceLocator")
+    private ServiceLocator<eu.dnetlib.api.functionality.ValidatorService> validatorServiceLocator;
+
+    private eu.dnetlib.api.functionality.ValidatorService getValidationService() {
+        return this.validatorServiceLocator.getService();
+    }
+
+    public ServiceLocator<eu.dnetlib.api.functionality.ValidatorService> getValidatorServiceLocator() {
+        return validatorServiceLocator;
+    }
+
+    public void setValidatorServiceLocator(ServiceLocator<eu.dnetlib.api.functionality.ValidatorService> validatorServiceLocator) {
+        this.validatorServiceLocator = validatorServiceLocator;
+    }
+
+    private Map<String, List<RuleSet>> rulesetMap = new ConcurrentHashMap<String, List<RuleSet>>();
+
+    private static final Logger LOGGER = Logger
+            .getLogger(ValidatorServiceImpl.class);
+
+    @Autowired
+    private EmailUtils emailUtils;
+
+    @Autowired
+    private JobExecutor crisValidatorExecutor;
+
+    @Autowired
+    private MapJobDao crisJobs;
+
+    @PostConstruct
+    private void loadRules(){
+        LOGGER.debug("PostConstruct method! Load rules!");
+        try {
+            for (RuleSet ruleSet : getValidationService().getRuleSets()) {
+                if (ruleSet.getVisibility() != null && ruleSet.getVisibility().contains("development")) {
+                    String key = "";
+                    if (ruleSet.getGuidelinesAcronym().matches("^openaire[1-9].0_data$"))
+                        key = Constants.VALIDATION_MODE_DATA;
+                    else if (ruleSet.getGuidelinesAcronym().matches("^openaire[1-9].0$") || ruleSet.getGuidelinesAcronym().equals("driver"))
+                        key = Constants.VALIDATION_MODE_LITERATURE;
+                    else if (ruleSet.getGuidelinesAcronym().matches("^openaire[1-9].0_cris$"))
+                        key = Constants.VALIDATION_MODE_CRIS;
+                    else if (ruleSet.getGuidelinesAcronym().matches(".*fair$"))
+                        key = Constants.VALIDATION_MODE_FAIR;
+
+                    if (rulesetMap.containsKey(key))
+                        rulesetMap.get(key).add(ruleSet);
+                    else {
+                        List<RuleSet> ruleSets = new ArrayList<RuleSet>();
+                        ruleSets.add(ruleSet);
+                        rulesetMap.put(key, ruleSets);
+                    }
+                }
+            }
+
+            /////////////////////////////////////////////////////////////////////////////////////////
+            // FIXME: this is a hack for CRIS Jan Dvorak Validator, should be implemented properly //
+            /////////////////////////////////////////////////////////////////////////////////////////
+            int ruleId = -1000;
+            Rule rule = new Rule();
+            rule.setType("cris");
+            rule.setName("CRIS Rules");
+            rule.setId(ruleId);
+            rule.setMandatory(true);
+            RuleSet crisRuleSet = new RuleSet();
+            crisRuleSet.setContentRulesIds(Collections.singleton(ruleId));
+            crisRuleSet.setContentRules(Collections.singletonList(rule));
+            crisRuleSet.setUsageRulesIds(Collections.singleton(ruleId));
+            crisRuleSet.setUsageRules(Collections.singletonList(rule));
+            crisRuleSet.setId(-1);
+            crisRuleSet.setDescription("Validates using the CRIS Validator implementation");
+            crisRuleSet.setName("CRIS Validation");
+
+            String crisKey = Constants.VALIDATION_MODE_CRIS;
+            if (rulesetMap.containsKey(crisKey))
+                rulesetMap.get(crisKey).add(crisRuleSet);
+            else {
+                List<RuleSet> ruleSets = new ArrayList<RuleSet>();
+                ruleSets.add(crisRuleSet);
+                rulesetMap.put(crisKey, ruleSets);
+            }
+            /////////////////////////////////////////////////////////////////////////////////////////
+            /////////////////////////////////////////////////////////////////////////////////////////
+        } catch (ValidatorServiceException e) {
+            LOGGER.error(e);
+        }
+
+    }
+
+    @Override
+    @PreAuthorize("hasAuthority('REGISTERED_USER') and #jobForValidation.userEmail == authentication.userInfo.email")
+    public JobForValidation submitJobForValidation(JobForValidation jobForValidation) throws ValidatorServiceException {
+        LOGGER.debug("Submit job for validation with id : " + jobForValidation.getDatasourceId());
+        try {
+            emailUtils.sendSubmitJobForValidationEmail(SecurityContextHolder.getContext().getAuthentication(),jobForValidation);
+            /////////////////////////////////////////////////////////////////////////////////////////
+            // FIXME: this is a hack for CRIS Jan Dvorak Validator, should be implemented properly //
+            /////////////////////////////////////////////////////////////////////////////////////////
+            if (jobForValidation.getSelectedContentRules()!=null && jobForValidation.getSelectedContentRules().size() == 1 &&
+                    jobForValidation.getSelectedContentRules().contains(-1000)) {
+                crisValidatorExecutor.submit(jobForValidation.getBaseUrl(), jobForValidation.getUserEmail());
+            } else {
+                this.getValidationService().submitValidationJob(jobForValidation);
+            }
+            /////////////////////////////////////////////////////////////////////////////////////////
+            /////////////////////////////////////////////////////////////////////////////////////////
+//            this.getValidationService().submitValidationJob(jobForValidation);
+        } catch (ValidatorServiceException e) {
+            LOGGER.debug("Exception on submitJobForValidation" , e);
+            emailUtils.reportException(e);
+            throw e;
+        } catch (Exception e) {
+            LOGGER.error(e);
+        }
+        return jobForValidation;
+    }
+
+    @Override
+    @PreAuthorize("hasAuthority('REGISTERED_USER') and #email == authentication.userInfo.email")
+    public ResponseEntity<Object> reSubmitJobForValidation(String email,
+                                                           String jobId) throws JSONException, ValidatorServiceException {
+        LOGGER.debug("Resubmit validation job with id : " + jobId);
+        StoredJob job = monitorApi.getJobSummary(jobId, "all");
+        Set<Integer> contentRules = new HashSet<Integer>();
+        Set<Integer> usageRules = new HashSet<Integer>();
+
+        RuleSet ruleSet = null;
+        for (List<RuleSet> ruleSets : this.rulesetMap.values()) {
+            for (RuleSet rSet : ruleSets) {
+                if (rSet.getName().equalsIgnoreCase("CRIS Validation")) {
+                    crisValidatorExecutor.submit(job.getBaseUrl(), job.getUserEmail());
+                    return new ResponseEntity<>("OK",HttpStatus.OK);
+                } else if(rSet.getGuidelinesAcronym().equals(job.getDesiredCompatibilityLevel())){
+                    ruleSet = rSet;
+                    break;
+                }
+            }
+        }
+        if (ruleSet != null){
+            for (int ruleId : job.getRules()) {
+                if (ruleSet.getContentRulesIds().contains(ruleId))
+                    contentRules.add(ruleId);
+                else if (ruleSet.getUsageRulesIds().contains(ruleId))
+                    usageRules.add(ruleId);
+            }
+        }
+        if (!contentRules.isEmpty())
+            job.setSelectedContentRules(contentRules);
+        if (!usageRules.isEmpty())
+            job.setSelectedUsageRules(usageRules);
+        this.submitJobForValidation(job);
+        return new ResponseEntity<>("OK",HttpStatus.OK);
+    }
+
+    @Override
+    public List<RuleSet> getRuleSets(String mode) {
+        LOGGER.info("Getting rulesets for mode: " + mode);
+        return rulesetMap.get(mode);
+    }
+
+    @Override
+    public List<String> getSetsOfRepository(String url) {
+        LOGGER.debug("Getting sets of repository with url : " + url);
+        try {
+            return OaiTools.getSetsOfRepo(url);
+        } catch (Exception e) {
+            LOGGER.debug("Exception on getSetsOfRepository" , e);
+            emailUtils.reportException(e);
+        }
+        return null;
+    }
+
+    @Override
+    public boolean identifyRepo(String url) {
+        LOGGER.debug("Identify repository with url : " + url);
+        try {
+            return OaiTools.identifyRepository(url);
+        } catch (Exception e) {
+            LOGGER.error("Error while identifying repository with url: " + url, e);
+            emailUtils.reportException(e);
+            return false;
+        }
+    }
+
+    @Override
+    public RuleSet getRuleSet(String acronym) {
+        LOGGER.debug("Getting ruleset with acronym : " + acronym);
+        RuleSet ruleSet = null;
+        try {
+            for (List<RuleSet> ruleSets : this.rulesetMap.values()) {
+                for (RuleSet rSet : ruleSets)
+                    if (rSet.getGuidelinesAcronym().equals(acronym)) {
+                        ruleSet = rSet;
+                        break;
+                    }
+            }
+            return ruleSet;
+        } catch (Exception e) {
+            LOGGER.error("Error getting ruleset", e);
+            emailUtils.reportException(e);
+            return null;
+        }
+    }
+
+    @Override
+    @PreAuthorize("hasAuthority('REGISTERED_USER')")
+    public List<StoredJob> getStoredJobsNew(String user,
+                                            String jobType,
+                                            String offset,
+                                            String limit,
+                                            String dateFrom,
+                                            String dateTo,
+                                            String validationStatus ) throws ValidatorServiceException {
+//        return getValidationService().getStoredJobsNew(user, jobType, Integer.parseInt(offset), Integer.parseInt(limit), dateFrom, dateTo, validationStatus);
+        List<StoredJob> jobs = getValidationService().getStoredJobsNew(user, jobType, Integer.parseInt(offset), Integer.parseInt(limit), dateFrom, dateTo, validationStatus);
+        /////////////////////////////////////////////////////////////////////////////////////////
+        // FIXME: this is a hack for CRIS Jan Dvorak Validator, should be implemented properly //
+        /////////////////////////////////////////////////////////////////////////////////////////
+        if (jobs == null) {
+            jobs = new ArrayList<>();
+        }
+        List<Job> cj = crisJobs.getJobs(user);
+        for (Job job : cj) {
+            jobs.add(CrisValidatorUtils.convertJobToStoredJob(job));
+        }
+        /////////////////////////////////////////////////////////////////////////////////////////
+        /////////////////////////////////////////////////////////////////////////////////////////
+        return jobs;
+    }
+
+    @Override
+    public int getStoredJobsTotalNumberNew(String user, String jobType, String validationStatus) throws  ValidatorServiceException {
+        return getValidationService().getStoredJobsTotalNumberNew(user, jobType, validationStatus);
+    }
+
+    @Override
+    public InterfaceInformation getInterfaceInformation(String baseUrl) throws ValidationServiceException {
+        try {
+            LOGGER.debug("Getting interface information with url: " + baseUrl);
+            InterfaceInformation interfaceInformation = new InterfaceInformation();
+            interfaceInformation.setIdentified(this.identifyRepo(baseUrl));
+            if (interfaceInformation.isIdentified())
+                interfaceInformation.setSets(this.getSetsOfRepository(baseUrl));
+
+            return interfaceInformation;
+        } catch (Exception e) {
+            LOGGER.error("Error getting interface information with url: " + baseUrl, e);
+            emailUtils.reportException(e);
+            throw new ValidationServiceException("login.generalError", ValidationServiceException.ErrorCode.GENERAL_ERROR);
+        }
+    }
+
+    @Override
+    public List<StoredJob> getJobsSummary(String repoId, int limit) throws JSONException, ValidatorServiceException {
+        return getValidationService().getJobSummary(repositoryService.getRepositoryInterface(repoId).stream().map(RepositoryInterface::getBaseUrl).collect(Collectors.toList()),limit);
+    }
+
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/resources/eu/dnetlib/repo/manager/service/timezones.txt
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/resources/eu/dnetlib/repo/manager/service/timezones.txt	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/resources/eu/dnetlib/repo/manager/service/timezones.txt	(revision 61527)
@@ -0,0 +1,11 @@
+-2.0	[GMT - 2] Fernando de Noronha Time,	South Georg...
+-1.0	[GMT - 1] Azores Standard Time, Cape Verde Time...
+0.0	[GMT] Western European Time, Greenwich Mean Time
+1.0	[GMT + 1] Central European Time, West African Time
+2.0	[GMT + 2] Eastern European Time, Central Africa...
+3.0	[GMT + 3] Moscow Standard Time, Eastern African...
+3.5	[GMT + 3:30] Iran Standard Time
+4.0	[GMT + 4] Gulf Standard Time, Samara Standard Time
+4.5	[GMT + 4:30] Afghanistan Time
+5.0	[GMT + 5] Pakistan Standard Time, Yekaterinburg...
+8.0	[GMT + 8] Beijing, Hong Kong, Irkutsk, Kuala Lumpur, Manila, Perth
\ No newline at end of file
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/webapp/WEB-INF/log4j.properties
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/webapp/WEB-INF/log4j.properties	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/webapp/WEB-INF/log4j.properties	(revision 61527)
@@ -0,0 +1,13 @@
+log4j.rootLogger = INFO
+
+log4j.logger.eu.dnetlib = INFO, R
+log4j.logger.eu.dnetlib.repo.manager = INFO, R
+log4j.logger.eu.dnetlib.clients.data.datasourcemanager.ws.Converter = FATAL
+log4j.logger.org.springframework = INFO, R
+
+log4j.appender.R=org.apache.log4j.RollingFileAppender
+log4j.appender.R.File=/var/log/dnet/repository-manager.log
+log4j.appender.R.MaxFileSize=10MB
+log4j.appender.R.MaxBackupIndex=10
+log4j.appender.R.layout=org.apache.log4j.PatternLayout
+log4j.appender.R.layout.ConversionPattern= %d %p %t [%c] - %m%n
\ No newline at end of file
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/webapp/WEB-INF/web.xml
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/webapp/WEB-INF/web.xml	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/webapp/WEB-INF/web.xml	(revision 61527)
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app>
+
+    <listener>
+        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
+    </listener>
+
+    <context-param>
+        <param-name>contextConfigLocation</param-name>
+        <param-value>
+            /WEB-INF/applicationContext.xml
+        </param-value>
+    </context-param>
+    <context-param>
+        <param-name>log4jRefreshInterval</param-name>
+        <param-value>1000</param-value>
+    </context-param>
+    <context-param>
+        <param-name>log4jExposeWebAppRoot</param-name>
+        <param-value>false</param-value>
+    </context-param>
+
+    <servlet>
+        <servlet-name>spring</servlet-name>
+        <servlet-class>
+            org.springframework.web.servlet.DispatcherServlet
+        </servlet-class>
+        <init-param>
+            <param-name>throwExceptionIfNoHandlerFound</param-name>
+            <param-value>true</param-value>
+        </init-param>
+        <load-on-startup>1</load-on-startup>
+    </servlet>
+
+    <filter>
+        <filter-name>springSecurityFilterChain</filter-name>
+        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
+        <init-param>
+            <param-name>contextAttribute</param-name>
+            <param-value>org.springframework.web.servlet.FrameworkServlet.CONTEXT.spring</param-value>
+        </init-param>
+    </filter>
+
+    <filter>
+        <filter-name>CorsFilter</filter-name>
+        <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
+        <init-param>
+            <param-name>cors.allowed.origins</param-name>
+            <param-value>*</param-value>
+        </init-param>
+        <init-param>
+            <param-name>cors.allowed.headers</param-name>
+            <param-value>Content-Type,X-Requested-With,accept,authorization,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value>
+        </init-param>
+        <init-param>
+            <param-name>cors.allowed.methods</param-name>
+            <param-value>GET, POST, PUT, DELETE, OPTIONS, HEAD</param-value>
+        </init-param>
+    </filter>
+
+    <filter-mapping>
+        <filter-name>CorsFilter</filter-name>
+        <url-pattern>/*</url-pattern>
+    </filter-mapping>
+
+    <filter>
+        <filter-name>springSessionRepositoryFilter</filter-name>
+        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
+    </filter>
+    <filter-mapping>
+        <filter-name>springSessionRepositoryFilter</filter-name>
+        <url-pattern>/*</url-pattern>
+        <dispatcher>REQUEST</dispatcher>
+        <dispatcher>ERROR</dispatcher>
+    </filter-mapping>
+
+    <filter-mapping>
+        <filter-name>springSecurityFilterChain</filter-name>
+        <url-pattern>/*</url-pattern>
+    </filter-mapping>
+
+    <servlet-mapping>
+        <servlet-name>spring</servlet-name>
+        <url-pattern>/</url-pattern>
+    </servlet-mapping>
+</web-app>
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/broker/ConditionParams.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/broker/ConditionParams.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/broker/ConditionParams.java	(revision 61527)
@@ -0,0 +1,34 @@
+package eu.dnetlib.repo.manager.domain.broker;
+
+/**
+ * Created by stefanos on 17/3/2017.
+ */
+public class ConditionParams {
+
+    private String value;
+    private String otherValue;
+
+    public ConditionParams() {
+    }
+
+    public ConditionParams(final String value, final String otherValue) {
+        this.value = value;
+        this.otherValue = otherValue;
+    }
+
+    public String getValue() {
+        return this.value;
+    }
+
+    public void setValue(final String value) {
+        this.value = value;
+    }
+
+    public String getOtherValue() {
+        return this.otherValue;
+    }
+
+    public void setOtherValue(final String otherValue) {
+        this.otherValue = otherValue;
+    }
+}
\ No newline at end of file
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/DashboardServiceImpl.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/DashboardServiceImpl.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/DashboardServiceImpl.java	(revision 61527)
@@ -0,0 +1,88 @@
+package eu.dnetlib.repo.manager.service;
+
+import eu.dnetlib.repo.manager.domain.*;
+import eu.dnetlib.repo.manager.domain.broker.BrowseEntry;
+import org.apache.log4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Service("dashboardService")
+public class DashboardServiceImpl implements DashboardService {
+
+    private static final Logger logger = Logger.getLogger(DashboardServiceImpl.class);
+
+    @Autowired
+    private EmailUtils emailUtils;
+
+    @Autowired
+    private RepositoryService repositoryService;
+
+    @Autowired
+    private BrokerService brokerService;
+
+    @Override
+    public List<RepositorySummaryInfo> getRepositoriesSummaryInfo(String userEmail,
+                                                                  String page,
+                                                                  String size) {
+
+        List<RepositorySummaryInfo> repositorySummaryInfoList = new ArrayList<>();
+
+        try {
+
+            List<RepositorySnippet> repositoriesOfUser = repositoryService.getRepositoriesSnippetsOfUser(userEmail, page, size);
+            for (RepositorySnippet repository : repositoriesOfUser) {
+                RepositorySummaryInfo repositorySummaryInfo = new RepositorySummaryInfo();
+                repositorySummaryInfo.setId(repository.getId());
+                repositorySummaryInfo.setRepositoryName(repository.getOfficialname());
+                repositorySummaryInfo.setLogoURL(repository.getLogoUrl());
+
+                //TODO getRepositoryAggregations returns only the 20 more recent items. Is it positive that we will find an indexed version there?
+                long start = System.currentTimeMillis();
+                List<AggregationDetails> aggregationDetailsList = repositoryService.getRepositoryAggregations(repository.getId(), 0, 20);
+                for (AggregationDetails aggregationDetails : aggregationDetailsList) {
+                    if (aggregationDetails.getIndexedVersion()) {
+                        repositorySummaryInfo.setRecordsCollected(aggregationDetails.getNumberOfRecords());
+                        repositorySummaryInfo.setLastIndexedVersion(aggregationDetails.getDate());
+                        break;
+                    }
+                }
+                long end = System.currentTimeMillis();
+
+                System.out.println("Got repo aggregations in " + (end - start) + "ms");
+
+                try {
+
+                    MetricsInfo metricsInfo = repositoryService.getMetricsInfoForRepository(repository.getId());
+                    repositorySummaryInfo.setTotalDownloads(metricsInfo.getMetricsNumbers().getTotalDownloads());
+                    repositorySummaryInfo.setTotalViews(metricsInfo.getMetricsNumbers().getTotalViews());
+
+                } catch (RepositoryServiceException e) {
+                    logger.error("Exception getting metrics info for repository: " + repository.getId(), e);
+                }
+
+                try {
+
+                    List<BrowseEntry> events = brokerService.getTopicsForDatasource(repository.getOfficialname());
+                    Long totalEvents = 0L;
+                    for (BrowseEntry browseEntry : events)
+                        totalEvents += browseEntry.getSize();
+                    repositorySummaryInfo.setEnrichmentEvents(totalEvents);
+
+
+                } catch (BrokerException e) {
+                    logger.error("Exception getting broker events for repository: " + repository.getId(), e);
+                }
+
+                repositorySummaryInfoList.add(repositorySummaryInfo);
+            }
+
+        } catch (Exception e) {
+            logger.error("Something baad happened!", e);
+        }
+
+        return repositorySummaryInfoList;
+    }
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/broker/SimpleSubscriptionDesc.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/broker/SimpleSubscriptionDesc.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/broker/SimpleSubscriptionDesc.java	(revision 61527)
@@ -0,0 +1,76 @@
+package eu.dnetlib.repo.manager.domain.broker;
+
+
+
+import java.util.Date;
+
+/**
+ * Created by stefanos on 10-Mar-17.
+ */
+public class SimpleSubscriptionDesc   {
+
+    private String id;
+    private String datasource;
+    private String topic;
+    private long count;
+    private Date creationDate;
+    private Date lastNotificationDate;
+
+    public SimpleSubscriptionDesc() {
+    }
+
+    public SimpleSubscriptionDesc(final String id, final String datasource, final String topic, final long count) {
+        this.id = id;
+        this.datasource = datasource;
+        this.topic = topic;
+        this.count = count;
+    }
+
+    public String getId() {
+        return this.id;
+    }
+
+    public void setId(final String id) {
+        this.id = id;
+    }
+
+    public String getDatasource() {
+        return this.datasource;
+    }
+
+    public void setDatasource(final String datasource) {
+        this.datasource = datasource;
+    }
+
+    public String getTopic() {
+        return this.topic;
+    }
+
+    public void setTopic(final String topic) {
+        this.topic = topic;
+    }
+
+    public long getCount() {
+        return this.count;
+    }
+
+    public void setCount(final long count) {
+        this.count = count;
+    }
+
+    public Date getCreationDate() {
+        return creationDate;
+    }
+
+    public void setCreationDate(Date creationDate) {
+        this.creationDate = creationDate;
+    }
+
+    public Date getLastNotificationDate() {
+        return lastNotificationDate;
+    }
+
+    public void setLastNotificationDate(Date lastNotificationDate) {
+        this.lastNotificationDate = lastNotificationDate;
+    }
+}
\ No newline at end of file
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/test/java/unitest/PiwikTest.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/test/java/unitest/PiwikTest.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/test/java/unitest/PiwikTest.java	(revision 61527)
@@ -0,0 +1,72 @@
+/*
+package unitest;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import eu.dnetlib.repo.manager.config.RepoManagerContextLoaderListener;
+import org.apache.commons.lang.StringEscapeUtils;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URL;
+import java.net.URLEncoder;
+import java.util.Map;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(classes = RepoManagerContextLoaderListener.class)
+public class PiwikTest {
+
+    String analyticsURL = "https://analytics.openaire.eu/addsite.php?";
+
+    @Test
+    public void enableMetricsRepo1(){
+
+        String officialName = "BỘ SƯU TẬP SỐ";
+        String repoWebsite = "http://www.vnulib.edu.vn:8000/dspace/";
+
+        enableMetrics(officialName, repoWebsite, analyticsURL);
+
+    }
+
+    @Test
+    public void enableMetricsRepo2(){
+
+        String officialName = "ILC4CLARIN repository of language resources and tools";
+        String repoWebsite = "https://dspace-clarin-it.ilc.cnr.it/repository/xmlui";
+
+        enableMetrics(officialName, repoWebsite, analyticsURL);
+    }
+
+    @Test
+    public void enableMetricsRepo3(){
+
+        String officialName = "ANSTO Publications Online";
+        String repoWebsite = "http://apo.ansto.gov.au/dspace/";
+
+        enableMetrics(officialName, repoWebsite, analyticsURL);
+    }
+
+    private void enableMetrics(String officialName, String repoWebsite, String analyticsURL) {
+        String url;
+        try {
+            url = analyticsURL + "siteName=" + URLEncoder.encode(officialName, "UTF-8") + "&url="
+                    + URLEncoder.encode(repoWebsite, "UTF-8");
+            url = StringEscapeUtils.escapeJava(url);
+
+            Map map = null;
+            String siteId = null;
+
+            URL u = new URL(url);
+            map = new ObjectMapper().readValue(u, Map.class);
+            if(map.get("value")!=null) {
+                siteId = map.get("value").toString();
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}*/
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/test/java/unitest/ValidatorTest.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/test/java/unitest/ValidatorTest.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/test/java/unitest/ValidatorTest.java	(revision 61527)
@@ -0,0 +1,31 @@
+//package unitest;
+//
+//import eu.dnetlib.repo.manager.config.RepoManagerContextLoaderListener;
+//import eu.dnetlib.repo.manager.utils.OaiTools;
+//import org.junit.Test;
+//import org.junit.runner.RunWith;
+//import org.springframework.test.context.ContextConfiguration;
+//import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+//
+//@RunWith(SpringJUnit4ClassRunner.class)
+//@ContextConfiguration(classes = RepoManagerContextLoaderListener.class)
+////@WebAppConfiguration
+//public class ValidatorTest {
+//
+//
+//    @Test
+//    public void identiFy(){
+//
+//        String url = "https://repozitorij.srce.unizg.hr/oai";
+//
+//
+//        System.out.println("Identify repository with url : " + url);
+//        try {
+//            System.out.println(OaiTools.identifyRepository(url));
+//        } catch (Exception e) {
+//            System.out.println(e);
+//        }
+//    }
+//
+//
+//}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/MonitorServiceImpl.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/MonitorServiceImpl.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/MonitorServiceImpl.java	(revision 61527)
@@ -0,0 +1,195 @@
+package eu.dnetlib.repo.manager.service;
+
+import eu.dnetlib.api.functionality.ValidatorService;
+import eu.dnetlib.api.functionality.ValidatorServiceException;
+import eu.dnetlib.domain.functionality.validator.StoredJob;
+import eu.dnetlib.repo.manager.domain.Constants;
+import eu.dnetlib.repo.manager.domain.JobsOfUser;
+import eu.dnetlib.repo.manager.utils.CrisValidatorUtils;
+import gr.uoa.di.driver.util.ServiceLocator;
+import org.apache.log4j.Logger;
+import org.eurocris.openaire.cris.validator.model.Job;
+import org.eurocris.openaire.cris.validator.service.MapJobDao;
+import org.json.JSONException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+@Service("monitorService")
+public class MonitorServiceImpl implements MonitorService {
+
+    @Autowired
+    private MapJobDao crisJobs;
+
+    @Resource(name = "validatorServiceLocator")
+    private ServiceLocator<ValidatorService> validatorServiceLocator;
+
+    private ValidatorService getValidationService() {
+        return this.validatorServiceLocator.getService();
+    }
+
+    public ServiceLocator<ValidatorService> getValidatorServiceLocator() {
+        return validatorServiceLocator;
+    }
+
+    public void setValidatorServiceLocator(ServiceLocator<ValidatorService> validatorServiceLocator) {
+        this.validatorServiceLocator = validatorServiceLocator;
+    }
+
+
+    private static final Logger LOGGER = Logger
+            .getLogger(MonitorServiceImpl.class);
+
+    @Override
+    public JobsOfUser getJobsOfUser(String user,
+                                    String jobType,
+                                    String offset,
+                                    String limit,
+                                    String dateFrom,
+                                    String dateTo,
+                                    String validationStatus,
+                                    String includeJobsTotal) throws JSONException, ValidatorServiceException {
+
+        LOGGER.debug("Getting jobs of user : " + user);
+        LOGGER.debug(user + "/" + jobType + "/" + offset + "/" + dateFrom + "/" + dateTo + "/" + validationStatus + "/" + includeJobsTotal);
+
+        /////////////////////////////////////////////////////////////////////////////////////////
+        // FIXME: this is a hack for CRIS Jan Dvorak Validator, should be implemented properly //
+        /////////////////////////////////////////////////////////////////////////////////////////
+        int crisOffset = 0;
+        int limitWithCris = 0;
+        if (offset.equals("0")) {
+            limitWithCris = crisJobs.getJobs(user, validationStatus).size();
+        } else {
+            crisOffset = crisJobs.getJobs(user, validationStatus).size();
+        }
+
+        offset = String.valueOf(Math.max(Integer.parseInt(offset) - crisOffset, 0));
+        limit = String.valueOf(Math.max(Integer.parseInt(limit) - limitWithCris, 0));
+        /////////////////////////////////////////////////////////////////////////////////////////
+        /////////////////////////////////////////////////////////////////////////////////////////
+
+        JobsOfUser retJobs = new JobsOfUser();
+        retJobs.setJobs(getValidationService().getStoredJobsNew(user, jobType, Integer.parseInt(offset),
+                Integer.parseInt(limit), dateFrom, dateTo, validationStatus));
+
+        if (Boolean.parseBoolean(includeJobsTotal)) {
+            retJobs.setTotalJobs(this.getJobsTotalNumberOfUser(user, jobType, null));
+            retJobs.setTotalJobsSuccessful(this.getJobsTotalNumberOfUser(user, jobType, Constants.VALIDATION_JOB_STATUS_SUCCESSFUL));
+            retJobs.setTotalJobsFailed(this.getJobsTotalNumberOfUser(user, jobType, Constants.VALIDATION_JOB_STATUS_FAILED));
+            retJobs.setTotalJobsOngoing(this.getJobsTotalNumberOfUser(user, jobType, Constants.VALIDATION_JOB_STATUS_ONGOING));
+        }
+
+        //TODO fix status with new validator version
+        if (retJobs.getJobs() != null) {
+            for (StoredJob job : retJobs.getJobs()) {
+                if (job.getContentJobStatus().equals("ongoing") || job.getUsageJobStatus().equals("ongoing")) {
+                    job.setValidationStatus("ongoing");
+                } else if ((job.getValidationType().equals("CU") && job.getContentJobStatus().equals("finished") && job.getUsageJobStatus().equals("finished") && job.getContentJobScore() > 50 && job.getUsageJobScore() > 50)
+                        || (job.getValidationType().equals("C") && job.getContentJobStatus().equals("finished") && job.getUsageJobStatus().equals("none") && job.getContentJobScore() > 50)
+                        || (job.getValidationType().equals("U") && job.getContentJobStatus().equals("none") && job.getUsageJobStatus().equals("finished") && job.getUsageJobScore() > 50)) {
+                    job.setValidationStatus("successful");
+                } else if ((job.getValidationType().equals("CU") && job.getContentJobStatus().equals("finished") && job.getUsageJobStatus().equals("finished") && (job.getContentJobScore() <= 50 || job.getUsageJobScore() <= 50))
+                        || (job.getValidationType().equals("C") && job.getContentJobStatus().equals("finished") && job.getUsageJobStatus().equals("none") && job.getContentJobScore() <= 50)
+                        || (job.getValidationType().equals("U") && job.getContentJobStatus().equals("none") && job.getUsageJobStatus().equals("finished") && job.getUsageJobScore() <= 50)) {
+                    job.setValidationStatus("failed");
+                }
+
+            }
+        }
+
+
+        /////////////////////////////////////////////////////////////////////////////////////////
+        // FIXME: this is a hack for CRIS Jan Dvorak Validator, should be implemented properly //
+        /////////////////////////////////////////////////////////////////////////////////////////
+        if (crisOffset == 0) {
+            List<StoredJob> jobs = new ArrayList<>();
+
+            List<Job> cj = crisJobs.getJobs(user, validationStatus);
+            for (Job job : cj) {
+                StoredJob sj = CrisValidatorUtils.convertJobToStoredJob(job);
+                jobs.add(sj);
+
+//                // filter out entries based on 'validationStatus'
+//                if ("all".equals(validationStatus)) {
+//                    jobs.add(sj);
+//                } else {
+//                    if (sj.getValidationStatus().equals(validationStatus)) {
+//                        jobs.add(sj);
+//                    }
+//                }
+            }
+
+            // add to CRIS Jan jobs all other jobs
+            if (retJobs.getJobs() != null) {
+                jobs.addAll(retJobs.getJobs());
+            }
+            // set all jobs back to retJobs
+            retJobs.setJobs(jobs);
+        }
+
+        // fix number of jobs
+        if (Boolean.parseBoolean(includeJobsTotal)) {
+            retJobs.setTotalJobs(retJobs.getTotalJobs() + crisJobs.getJobs(user).size());
+            retJobs.setTotalJobsSuccessful(retJobs.getTotalJobsSuccessful() + crisJobs.getJobs(user, Job.Status.SUCCESSFUL.getKey()).size());
+            retJobs.setTotalJobsFailed(retJobs.getTotalJobsFailed() + crisJobs.getJobs(user, Job.Status.FAILED.getKey()).size());
+            retJobs.setTotalJobsOngoing(retJobs.getTotalJobsOngoing() + crisJobs.getJobs(user, Job.Status.ONGOING.getKey()).size());
+        }
+        /////////////////////////////////////////////////////////////////////////////////////////
+        /////////////////////////////////////////////////////////////////////////////////////////
+
+        return retJobs;
+
+    }
+
+    private int getJobsTotalNumberOfUser(String user, String jobType, String validationStatus) throws ValidatorServiceException {
+        return getValidationService().getStoredJobsTotalNumberNew(user, jobType, validationStatus);
+    }
+
+    @Override
+    public int getJobsOfUserPerValidationStatus(String user,
+                                                String jobType,
+                                                String validationStatus) throws JSONException {
+        LOGGER.debug("Getting job with validation status : " + validationStatus);
+
+        if (jobType.equalsIgnoreCase("cris")) {
+            return crisJobs.getJobs(user, validationStatus).size();
+        }
+
+        try {
+            return getValidationService().getStoredJobsTotalNumberNew(user, jobType, validationStatus);
+        } catch (ValidatorServiceException e) {
+            LOGGER.error(e);
+        }
+        return 0;
+    }
+
+    @Override
+    public StoredJob getJobSummary(String jobId,
+                                   String groupBy) throws JSONException {
+        LOGGER.debug("Getting job summary with id : " + jobId);
+        StoredJob job = null;
+        try {
+            job = getValidationService().getStoredJob(Integer.parseInt(jobId), groupBy);
+        } catch (ValidatorServiceException e) {
+            LOGGER.error(e);
+        }
+        /////////////////////////////////////////////////////////////////////////////////////////
+        // FIXME: this is a hack for CRIS Jan Dvorak Validator, should be implemented properly //
+        /////////////////////////////////////////////////////////////////////////////////////////
+        if (job == null) {
+            // not a good way to do it but Job id field is string
+            List<Job> cJobs = crisJobs.getAll().stream().filter(j -> j.getId().hashCode() == Integer.parseInt(jobId)).collect(Collectors.toList());
+            if (!cJobs.isEmpty()) {
+                job = CrisValidatorUtils.convertJobToStoredJob(cJobs.get(0));
+            }
+        }
+        /////////////////////////////////////////////////////////////////////////////////////////
+        /////////////////////////////////////////////////////////////////////////////////////////
+        return job;
+    }
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/Dockerfile
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/Dockerfile	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/Dockerfile	(revision 61527)
@@ -0,0 +1,11 @@
+FROM tomcat:7.0.90-jre8
+MAINTAINER "pkanakakis@di.uoa.gr"
+RUN ["rm", "-fr", "/usr/local/tomcat/webapps/ROOT"]
+COPY ./target/uoa-repository-manager-service.war /usr/local/tomcat/webapps/uoa-repository-manager-service.war
+#COPY src/main/resources/dnet-override-new.properties /usr/local/tomcat/lib/dnet-override.properties
+COPY src/main/resources/application.properties /usr/local/tomcat/lib/dnet-override.properties
+#COPY src/main/resources/application.properties /usr/local/tomcat/lib/application.properties
+#COPY src/main/resources/email-texts.properties /usr/local/tomcat/lib/email-texts.properties
+VOLUME /var/log/uoa-repository-manager-service:/var/log/uoa-repository-manager-service/
+CMD ["catalina.sh", "run"]
+
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/pom.xml
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/pom.xml	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/pom.xml	(revision 61527)
@@ -0,0 +1,381 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <parent>
+        <groupId>eu.dnetlib</groupId>
+        <artifactId>dnet45-parent</artifactId>
+        <version>1.0.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>uoa-repository-manager-service</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <packaging>war</packaging>
+
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-webmvc</artifactId>
+            <version>${spring.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.hibernate</groupId>
+            <artifactId>hibernate-validator-annotation-processor</artifactId>
+            <version>4.1.0.Final</version>
+        </dependency>
+        <dependency>
+            <groupId>log4j</groupId>
+            <artifactId>log4j</artifactId>
+            <version>${log4j.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>eu.dnetlib</groupId>
+            <artifactId>dnet-runtime</artifactId>
+            <version>[1.0.0-SNAPSHOT, 2.0.0)</version>
+            <exclusions>
+                <exclusion>  <!-- declare the exclusion here -->
+                    <groupId>org.apache.geronimo.specs</groupId>
+                    <artifactId>geronimo-javamail_1.4_spec</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>eu.dnetlib</groupId>
+            <artifactId>uoa-utils</artifactId>
+            <version>[2.0.0-SNAPSHOT, 3.0.0)</version>
+        </dependency>
+        <dependency>
+            <groupId>eu.dnetlib</groupId>
+            <artifactId>uoa-domain</artifactId>
+            <version>[2.0.0-SNAPSHOT, 3.0.0)</version>
+            <exclusions>
+                <exclusion>  <!-- declare the exclusion here -->
+                    <groupId>cglib</groupId>
+                    <artifactId>cglib</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>eu.dnetlib</groupId>
+            <artifactId>dnet-openaire-usage-stats-sushilite</artifactId>
+            <version>1.0.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>eu.dnetlib.dhp</groupId>
+            <artifactId>dnet-openaire-broker-common</artifactId>
+            <version>3.1.1-SNAPSHOT</version>
+	    <exclusions>
+		    <exclusion>
+			    <groupId>javax.validation</groupId>
+			    <artifactId>validation-api</artifactId>
+		    </exclusion>
+	    </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>cglib</groupId>
+            <artifactId>cglib-nodep</artifactId>
+            <version>2.2</version>
+        </dependency>
+
+        <dependency>
+            <groupId>eu.dnetlib</groupId>
+            <artifactId>uoa-commons</artifactId>
+            <version>[2.0.0-SNAPSHOT, 3.0.0)</version>
+        </dependency>
+        <dependency>
+            <groupId>eu.dnetlib</groupId>
+            <artifactId>uoa-clients</artifactId>
+            <version>[2.0.0-SNAPSHOT, 3.0.0)</version>
+        </dependency>
+        <dependency>
+            <groupId>eu.dnetlib</groupId>
+            <artifactId>uoa-hcm</artifactId>
+            <version>[2.0.0-SNAPSHOT, 3.0.0)</version>
+        </dependency>
+
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+            <version>2.4</version>
+        </dependency>
+
+        <dependency>
+            <groupId>se.kb</groupId>
+            <artifactId>oai4j</artifactId>
+            <version>[0.6b1,)</version>
+        </dependency>
+        <dependency>
+            <groupId>xalan</groupId>
+            <artifactId>xalan</artifactId>
+            <version>2.7.2</version>
+        </dependency>
+
+        <dependency>
+            <groupId>xerces</groupId>
+            <artifactId>xercesImpl</artifactId>
+            <version>2.11.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-core</artifactId>
+            <version>2.5.1</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+            <version>2.5.1</version>
+            <scope>compile</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-context</artifactId>
+            <version>${spring.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-jdbc</artifactId>
+            <version>${spring.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.sun.jersey</groupId>
+            <artifactId>jersey-client</artifactId>
+            <version>1.19.3</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.aksw.gson</groupId>
+            <artifactId>gson-utils-core</artifactId>
+            <version>1.0.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.json</groupId>
+            <artifactId>json</artifactId>
+            <version>20080701</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.sun.mail</groupId>
+            <artifactId>javax.mail</artifactId>
+            <version>1.6.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>io.springfox</groupId>
+            <artifactId>springfox-swagger2</artifactId>
+            <version>2.7.0</version>
+        </dependency>
+        <dependency>
+            <groupId>io.springfox</groupId>
+            <artifactId>springfox-swagger-ui</artifactId>
+            <version>2.7.0</version>
+        </dependency>
+
+        <!-- https://mvnrepository.com/artifact/postgresql/postgresql -->
+        <dependency>
+            <groupId>postgresql</groupId>
+            <artifactId>postgresql</artifactId>
+            <version>9.1-901.jdbc3</version>
+        </dependency>
+
+        <!-- https://mvnrepository.com/artifact/org.apache.tomcat/tomcat-catalina -->
+        <dependency>
+            <groupId>org.apache.tomcat</groupId>
+            <artifactId>tomcat-catalina</artifactId>
+            <version>9.0.22</version>
+        </dependency>
+
+        <dependency>
+            <groupId>commons-fileupload</groupId>
+            <artifactId>commons-fileupload</artifactId>
+            <version>1.4</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.mitre</groupId>
+            <artifactId>openid-connect-client</artifactId>
+            <version>1.3.0</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.slf4j</groupId>
+                    <artifactId>jcl-over-slf4j</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.session</groupId>
+            <artifactId>spring-session-data-redis</artifactId>
+            <version>1.3.1.RELEASE</version>
+            <type>pom</type>
+        </dependency>
+        <!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
+        <dependency>
+            <groupId>redis.clients</groupId>
+            <artifactId>jedis</artifactId>
+            <version>2.9.0</version>
+        </dependency>
+        <dependency>
+            <groupId>com.google.code.gson</groupId>
+            <artifactId>gson</artifactId>
+            <version>2.6.2</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.thetransactioncompany</groupId>
+            <artifactId>cors-filter</artifactId>
+            <version>2.5</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.netflix.hystrix</groupId>
+            <artifactId>hystrix-core</artifactId>
+            <version>1.5.18</version>
+        </dependency>
+        <dependency>
+            <groupId>com.netflix.rxjava</groupId>
+            <artifactId>rxjava-core</artifactId>
+            <version>0.20.7</version>
+        </dependency>
+
+        <!-- https://mvnrepository.com/artifact/javax.xml.ws/jaxws-api -->
+        <dependency>
+            <groupId>javax.xml.ws</groupId>
+            <artifactId>jaxws-api</artifactId>
+            <version>2.3.0</version>
+        </dependency>
+        <!-- https://mvnrepository.com/artifact/javax.jws/javax.jws-api -->
+        <dependency>
+            <groupId>javax.jws</groupId>
+            <artifactId>javax.jws-api</artifactId>
+            <version>1.1</version>
+        </dependency>
+        <dependency>
+            <groupId>javax.xml.bind</groupId>
+            <artifactId>jaxb-api</artifactId>
+            <version>2.3.0</version>
+        </dependency>
+        <dependency>
+            <groupId>com.sun.xml.bind</groupId>
+            <artifactId>jaxb-impl</artifactId>
+            <version>2.3.0</version>
+        </dependency>
+        <!-- https://mvnrepository.com/artifact/com.sun.xml.bind/jaxb-core -->
+        <dependency>
+            <groupId>com.sun.xml.bind</groupId>
+            <artifactId>jaxb-core</artifactId>
+            <version>2.3.0</version>
+        </dependency>
+        <dependency>
+            <groupId>javax.activation</groupId>
+            <artifactId>activation</artifactId>
+            <version>1.1-rev-1</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.eurocris</groupId>
+            <artifactId>openaire-cris-validator</artifactId>
+            <version>1.0.1-SNAPSHOT</version>
+<!--            <exclusions>-->
+<!--                <exclusion>-->
+<!--                    <groupId>org.apache.logging.log4j</groupId>-->
+<!--                    <artifactId>log4j-1.2-api</artifactId>-->
+<!--                </exclusion>-->
+<!--            </exclusions>-->
+        </dependency>
+
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+            <version>2.26.0</version>
+            <scope>test</scope>
+        </dependency>
+
+        <!-- Enable micrometer >> -->
+        <dependency> <!-- TODO: remove this with ActuatorConfig class -->
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-actuator</artifactId>
+            <version>1.3.5.RELEASE</version>
+        </dependency>
+<!--        <dependency>-->
+<!--            <groupId>org.springframework.boot</groupId>-->
+<!--            <artifactId>spring-boot-actuator-autoconfigure</artifactId>-->
+<!--            <version>2.1.18.RELEASE</version>-->
+<!--        </dependency>-->
+        <dependency>
+            <groupId>io.micrometer</groupId>
+            <artifactId>micrometer-core</artifactId>
+            <version>1.7.2</version>
+        </dependency>
+        <dependency>
+            <groupId>io.micrometer</groupId>
+            <artifactId>micrometer-registry-prometheus</artifactId>
+            <version>1.7.2</version>
+            <scope>compile</scope>
+        </dependency>
+        <!-- << Enable micrometer -->
+
+    </dependencies>
+
+    <build>
+        <outputDirectory>${project.build.directory}/${project.build.finalName}/WEB-INF/classes</outputDirectory>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.7.0</version>
+                <configuration>
+                    <source>1.8</source>
+                    <target>1.8</target>
+                    <encoding>UTF-8</encoding>
+                </configuration>
+            </plugin>
+
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-war-plugin</artifactId>
+                <version>2.6</version>
+                <configuration>
+                    <failOnMissingWebXml>false</failOnMissingWebXml>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>cz.habarta.typescript-generator</groupId>
+                <artifactId>typescript-generator-maven-plugin</artifactId>
+                <version>2.16.538</version>
+                <executions>
+                    <execution>
+                        <id>java to typeScript</id>
+                        <goals>
+                            <goal>generate</goal>
+                        </goals>
+                        <configuration>
+                            <jsonLibrary>jackson2</jsonLibrary>
+                            <outputFileType>implementationFile</outputFileType>
+                            <mapClasses>asClasses</mapClasses>
+                            <classPatterns>
+                                <pattern>eu.dnetlib.domain.functionality.validator.*</pattern>
+                            </classPatterns>
+                            <outputFile>target/operation.ts</outputFile>
+                            <outputKind>module</outputKind>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+        <finalName>uoa-repository-manager-service</finalName>
+        <resources>
+            <resource>
+                <directory>src/main/resources</directory>
+                <filtering>true</filtering>
+            </resource>
+        </resources>
+    </build>
+
+
+</project>
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/InterfaceInformation.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/InterfaceInformation.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/InterfaceInformation.java	(revision 61527)
@@ -0,0 +1,41 @@
+package eu.dnetlib.repo.manager.domain;
+
+
+import java.util.List;
+
+/**
+ * Created by nikonas on 7/1/16.
+ */
+public class InterfaceInformation{
+
+    private boolean identified;
+    private List<String> sets;
+    private List<String> adminEmails;
+
+    public InterfaceInformation() {
+    }
+
+    public boolean isIdentified() {
+        return identified;
+    }
+
+    public void setIdentified(boolean identified) {
+        this.identified = identified;
+    }
+
+    public List<String> getSets() {
+        return sets;
+    }
+
+    public void setSets(List<String> sets) {
+        this.sets = sets;
+    }
+
+    public List<String> getAdminEmails() {
+        return adminEmails;
+    }
+
+    public void setAdminEmails(List<String> adminEmails) {
+        this.adminEmails = adminEmails;
+    }
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/BrokerService.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/BrokerService.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/BrokerService.java	(revision 61527)
@@ -0,0 +1,44 @@
+package eu.dnetlib.repo.manager.service;
+
+import eu.dnetlib.repo.manager.domain.BrokerException;
+import eu.dnetlib.repo.manager.domain.Term;
+import eu.dnetlib.repo.manager.domain.broker.*;
+import org.json.JSONException;
+import org.springframework.http.ResponseEntity;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+
+public interface BrokerService {
+
+    DatasourcesBroker getDatasourcesOfUser(String user, String includeShared, String includeByOthers) throws BrokerException, JSONException;
+
+    List<BrowseEntry> getTopicsForDatasource(String datasourceName) throws BrokerException;
+
+    EventsPage advancedShowEvents(String page,
+                                  String size,
+                                  AdvQueryObject advQueryObject) throws BrokerException, JSONException ,IOException;
+
+    EventsPage showEvents(String datasourceName,
+                          String topic,
+                          String page,
+                          String size) throws BrokerException, JSONException;
+
+    Map<String, List<SimpleSubscriptionDesc>> getSimpleSubscriptionsOfUser(String userEmail) throws BrokerException;
+
+    Map<String, List<SimpleSubscriptionDesc>> getSimpleSubscriptionsOfUserByRepoId(String userEmail, String repoId) throws BrokerException;
+
+    Subscription subscribe(OpenaireSubscription obj) throws BrokerException;
+
+    ResponseEntity<Object> unsubscribe(String subscriptionId) throws BrokerException;
+
+    Subscription getSubscription(String subscriptionId) throws BrokerException;
+
+    Map<String, Term> getDnetTopics() throws BrokerException;
+
+    EventsPage getNotificationsBySubscriptionId(String subscriptionId, String page, String size) throws BrokerException;
+
+    Map<String, List<Subscription>> getSubscriptionsOfUser(String userEmail) throws BrokerException;
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/JobsOfUser.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/JobsOfUser.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/JobsOfUser.java	(revision 61527)
@@ -0,0 +1,59 @@
+package eu.dnetlib.repo.manager.domain;
+
+
+import eu.dnetlib.domain.functionality.validator.StoredJob;
+
+import java.util.List;
+
+/**
+ * Created by nikonas on 29/3/16.
+ */
+public class JobsOfUser   {
+
+    private int totalJobs;
+    private int totalJobsSuccessful;
+    private int totalJobsFailed;
+    private int totalJobsOngoing;
+
+    private List<StoredJob> jobs;
+
+    public int getTotalJobs() {
+        return totalJobs;
+    }
+
+    public void setTotalJobs(int totalJobs) {
+        this.totalJobs = totalJobs;
+    }
+
+    public int getTotalJobsSuccessful() {
+        return totalJobsSuccessful;
+    }
+
+    public void setTotalJobsSuccessful(int totalJobsSuccessful) {
+        this.totalJobsSuccessful = totalJobsSuccessful;
+    }
+
+    public int getTotalJobsFailed() {
+        return totalJobsFailed;
+    }
+
+    public void setTotalJobsFailed(int totalJobsFailed) {
+        this.totalJobsFailed = totalJobsFailed;
+    }
+
+    public int getTotalJobsOngoing() {
+        return totalJobsOngoing;
+    }
+
+    public void setTotalJobsOngoing(int totalJobsOngoing) {
+        this.totalJobsOngoing = totalJobsOngoing;
+    }
+
+    public List<StoredJob> getJobs() {
+        return jobs;
+    }
+
+    public void setJobs(List<StoredJob> jobs) {
+        this.jobs = jobs;
+    }
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/UserService.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/UserService.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/UserService.java	(revision 61527)
@@ -0,0 +1,9 @@
+package eu.dnetlib.repo.manager.service;
+
+import org.springframework.http.ResponseEntity;
+
+
+public interface UserService {
+
+    ResponseEntity<Object> login();
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/Triple.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/Triple.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/Triple.java	(revision 61527)
@@ -0,0 +1,27 @@
+package eu.dnetlib.repo.manager.domain;
+
+
+
+/**
+ * Created by stefania on 3/8/16.
+ */
+public class Triple<K, V, L> extends Tuple<K, V>   {
+
+    private L third;
+
+    public Triple() {
+    }
+
+    public Triple(K first, V second, L third) {
+        super(first, second);
+        this.third = third;
+    }
+
+    public L getThird() {
+        return third;
+    }
+
+    public void setThird(L third) {
+        this.third = third;
+    }
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/customHystrixCommands/UsageStatsTotalHystrixCommand.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/customHystrixCommands/UsageStatsTotalHystrixCommand.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/customHystrixCommands/UsageStatsTotalHystrixCommand.java	(revision 61527)
@@ -0,0 +1,43 @@
+package eu.dnetlib.repo.manager.service.customHystrixCommands;
+
+import com.netflix.hystrix.HystrixCommand;
+import com.netflix.hystrix.HystrixCommandGroupKey;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.client.RestTemplate;
+import org.springframework.web.util.UriComponents;
+import org.springframework.web.util.UriComponentsBuilder;
+
+import java.util.Map;
+
+public class UsageStatsTotalHystrixCommand extends HystrixCommand<Integer> {
+
+    RestTemplate restTemplate ;
+    String usagestatsEvents;
+
+    public UsageStatsTotalHystrixCommand(String usagestatsEvents,RestTemplate restTemplate) {
+        super(HystrixCommandGroupKey.Factory.asKey("StatisticsGroup"));
+        this.usagestatsEvents = usagestatsEvents;
+        this.restTemplate = restTemplate;
+    }
+
+    @Override
+    protected Integer run() {
+        UriComponents uriComponents = UriComponentsBuilder
+                .fromHttpUrl(usagestatsEvents)
+                .build().encode();
+
+        ResponseEntity rs = restTemplate.exchange(uriComponents.toUri(), HttpMethod.GET,null,Map.class);
+        Map metadata = (Map) ((Map)rs.getBody()).get("totals");
+//        String rs = restTemplate.getForObject(uriComponents.toUri(), String.class);
+//        JSONObject resultSet = new JSONObject(rs);
+//        JSONObject totals = resultSet.getJSONObject("totals");
+        return (Integer) metadata.get("events");
+    }
+
+    @Override
+    protected Integer getFallback() {
+        return null;
+    }
+
+}
\ No newline at end of file
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/Term.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/Term.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/Term.java	(revision 61527)
@@ -0,0 +1,53 @@
+package eu.dnetlib.repo.manager.domain;
+
+
+
+/**
+ * Created by panagiotis on 15/1/2018.
+ */
+public class Term   {
+
+    private String englishName;
+    private String nativeName;
+    private String encoding;
+    private String code;
+
+    public Term(String englishName, String nativeName, String encoding, String code) {
+        this.englishName = englishName;
+        this.nativeName = nativeName;
+        this.encoding = encoding;
+        this.code = code;
+    }
+
+    public String getEnglishName() {
+        return englishName;
+    }
+
+    public void setEnglishName(String englishName) {
+        this.englishName = englishName;
+    }
+
+    public String getNativeName() {
+        return nativeName;
+    }
+
+    public void setNativeName(String nativeName) {
+        this.nativeName = nativeName;
+    }
+
+    public String getEncoding() {
+        return encoding;
+    }
+
+    public void setEncoding(String encoding) {
+        this.encoding = encoding;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/customHystrixCommands/PublicationHystrixCommand.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/customHystrixCommands/PublicationHystrixCommand.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/customHystrixCommands/PublicationHystrixCommand.java	(revision 61527)
@@ -0,0 +1,45 @@
+package eu.dnetlib.repo.manager.service.customHystrixCommands;
+
+import com.netflix.hystrix.HystrixCommand;
+import com.netflix.hystrix.HystrixCommandGroupKey;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.client.RestTemplate;
+import org.springframework.web.util.UriComponents;
+import org.springframework.web.util.UriComponentsBuilder;
+
+import java.util.Map;
+
+public class PublicationHystrixCommand extends HystrixCommand<String> {
+
+    RestTemplate restTemplate;
+    private String baseAddress;
+
+    public PublicationHystrixCommand(String baseAddress, RestTemplate restTemplate) {
+        super(HystrixCommandGroupKey.Factory.asKey("StatisticsGroup"));
+        this.baseAddress = baseAddress;
+        this.restTemplate = restTemplate;
+    }
+
+    @Override
+    protected String run() throws Exception {
+        String url = baseAddress + "/publications/count";
+
+        UriComponents uriComponents = UriComponentsBuilder
+                .fromHttpUrl(url)
+                .queryParam("page", 0)
+                .queryParam("size", 0)
+                .queryParam("format", "json")
+                .build().encode();
+
+        ResponseEntity rs = restTemplate.exchange(uriComponents.toUri(), HttpMethod.GET, null, Map.class);
+        Map metadata = (Map) (rs.getBody());
+        return String.valueOf(metadata.get("total"));
+    }
+
+    @Override
+    protected String getFallback() {
+        return null;
+    }
+
+}
\ No newline at end of file
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/MetricsInfo.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/MetricsInfo.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/MetricsInfo.java	(revision 61527)
@@ -0,0 +1,36 @@
+package eu.dnetlib.repo.manager.domain;
+
+
+
+/**
+ * Created by stefania on 11/6/17.
+ */
+public class MetricsInfo   {
+
+    private MetricsNumbers metricsNumbers;
+    private String diagramsBaseURL;
+
+    public MetricsInfo() {
+    }
+
+    public MetricsInfo(MetricsNumbers metricsNumbers, String diagramsBaseURL) {
+        this.metricsNumbers = metricsNumbers;
+        this.diagramsBaseURL = diagramsBaseURL;
+    }
+
+    public MetricsNumbers getMetricsNumbers() {
+        return metricsNumbers;
+    }
+
+    public void setMetricsNumbers(MetricsNumbers metricsNumbers) {
+        this.metricsNumbers = metricsNumbers;
+    }
+
+    public String getDiagramsBaseURL() {
+        return diagramsBaseURL;
+    }
+
+    public void setDiagramsBaseURL(String diagramsBaseURL) {
+        this.diagramsBaseURL = diagramsBaseURL;
+    }
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/customHystrixCommands/DataRepositoriesHystrixCommand.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/customHystrixCommands/DataRepositoriesHystrixCommand.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/service/customHystrixCommands/DataRepositoriesHystrixCommand.java	(revision 61527)
@@ -0,0 +1,47 @@
+package eu.dnetlib.repo.manager.service.customHystrixCommands;
+
+import com.netflix.hystrix.HystrixCommand;
+import com.netflix.hystrix.HystrixCommandGroupKey;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.client.RestTemplate;
+import org.springframework.web.util.UriComponents;
+import org.springframework.web.util.UriComponentsBuilder;
+
+import java.util.Map;
+
+public class DataRepositoriesHystrixCommand extends HystrixCommand<String> {
+
+    RestTemplate restTemplate ;
+    private String baseAddress;
+
+    public DataRepositoriesHystrixCommand(String baseAddress,RestTemplate restTemplate) {
+        super(HystrixCommandGroupKey.Factory.asKey("StatisticsGroup"));
+        this.baseAddress = baseAddress;
+        this.restTemplate = restTemplate;
+    }
+
+    @Override
+    protected String run() {
+        String url = baseAddress+"/resources" +
+                "?query= " +
+                " oaftype exact datasource and " +
+                " datasourcetypename exact Data Repository ";
+
+        UriComponents uriComponents = UriComponentsBuilder
+                .fromHttpUrl(url)
+                .queryParam("page",0)
+                .queryParam("size",0)
+                .queryParam("format","json")
+                .build().encode();
+
+        ResponseEntity rs = restTemplate.exchange(uriComponents.toUri(), HttpMethod.GET,null,Map.class);
+        Map metadata = (Map) ((Map)rs.getBody()).get("meta");
+        return String.valueOf(metadata.get("total"));
+    }
+
+    @Override
+    protected String getFallback() {
+        return null;
+    }
+}
\ No newline at end of file
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/DatasourcesCollection.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/DatasourcesCollection.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/DatasourcesCollection.java	(revision 61527)
@@ -0,0 +1,46 @@
+package eu.dnetlib.repo.manager.domain;
+
+import eu.dnetlib.domain.data.Repository;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by nikonas on 14/1/16.
+ */
+public class DatasourcesCollection{
+
+    private List<Repository> datasourcesOfUser;
+    private List<Repository> sharedDatasources;
+    private List<Repository> datasourcesOfOthers;
+
+    public DatasourcesCollection() {
+        this.datasourcesOfOthers = new ArrayList<Repository>();
+        this.datasourcesOfUser = new ArrayList<Repository>();
+        this.datasourcesOfOthers = new ArrayList<Repository>();
+    }
+
+    public List<Repository> getDatasourcesOfUser() {
+        return datasourcesOfUser;
+    }
+
+    public void setDatasourcesOfUser(List<Repository> datasourcesOfUser) {
+        this.datasourcesOfUser = datasourcesOfUser;
+    }
+
+    public List<Repository> getDatasourcesOfOthers() {
+        return datasourcesOfOthers;
+    }
+
+    public void setDatasourcesOfOthers(List<Repository> datasourcesOfOthers) {
+        this.datasourcesOfOthers = datasourcesOfOthers;
+    }
+
+    public List<Repository> getSharedDatasources() {
+        return sharedDatasources;
+    }
+
+    public void setSharedDatasources(List<Repository> sharedDatasources) {
+        this.sharedDatasources = sharedDatasources;
+    }
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/config/AaiSecurityConfiguration.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/config/AaiSecurityConfiguration.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/config/AaiSecurityConfiguration.java	(revision 61527)
@@ -0,0 +1,180 @@
+package eu.dnetlib.repo.manager.config;
+
+import org.mitre.oauth2.model.ClientDetailsEntity.AuthMethod;
+import org.mitre.oauth2.model.RegisteredClient;
+import org.mitre.openid.connect.client.OIDCAuthenticationFilter;
+import org.mitre.openid.connect.client.OIDCAuthenticationProvider;
+import org.mitre.openid.connect.client.service.impl.*;
+import org.mitre.openid.connect.config.ServerConfiguration;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.builders.WebSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
+import org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter;
+
+import java.util.*;
+
+@Configuration
+@EnableWebSecurity
+public class AaiSecurityConfiguration extends WebSecurityConfigurerAdapter {
+
+    @Value("${webapp.dev.front}")
+    private String logoutSuccessUrl;
+
+    @Value("${oidc.issuer}")
+    private String oidcIssuer;
+
+    @Value("${oidc.id}")
+    private String oidcId;
+
+    @Value("${oidc.secret}")
+    private String oidcSecret;
+
+    @Value("${oidc.dev.home}")
+    private String oidcDevHome;
+
+    @Value("${webapp.dev.front}")
+    private String webAppFrontEnd;
+
+    @Bean
+    @Override
+    public AuthenticationManager authenticationManagerBean() throws Exception {
+        return authenticationManager();
+    }
+
+    @Override
+    protected void configure(AuthenticationManagerBuilder auth) {
+        auth.authenticationProvider(openIdConnectAuthenticationProvider());
+    }
+
+    @Override
+    public void configure(WebSecurity web) {
+        web.ignoring().antMatchers("/stats/**");
+    }
+
+    @Override
+    protected void configure(HttpSecurity http) throws Exception {
+        http
+                .csrf().disable()
+                .authorizeRequests()
+                    .regexMatchers("/actuator/.*").permitAll()
+                    .regexMatchers("/metrics").permitAll()
+                    .anyRequest().authenticated()
+                .and()
+//                .anonymous().disable()
+                .httpBasic()
+                .authenticationEntryPoint(authenticationEntryPoint())
+                .and()
+                .logout().logoutUrl("/openid_logout")
+                .invalidateHttpSession(true)
+                .deleteCookies("openAIRESession")
+                .logoutSuccessUrl(logoutSuccessUrl)
+                .and()
+                .addFilterBefore(openIdConnectAuthenticationFilter(), AbstractPreAuthenticatedProcessingFilter.class)
+        ;
+    }
+
+    @Bean
+    public OIDCAuthenticationProvider openIdConnectAuthenticationProvider() {
+        OIDCAuthenticationProvider oidcProvider = new OIDCAuthenticationProvider();
+        oidcProvider.setAuthoritiesMapper(authoritiesMapper());
+        return oidcProvider;
+    }
+
+    @Bean
+    public OpenAIREAuthoritiesMapper authoritiesMapper() {
+        OpenAIREAuthoritiesMapper authoritiesMapper = new OpenAIREAuthoritiesMapper();
+        return authoritiesMapper;
+    }
+
+    @Bean
+    public StaticServerConfigurationService staticServerConfigurationService() {
+        StaticServerConfigurationService staticServerConfigurationService = new StaticServerConfigurationService();
+        Map<String, ServerConfiguration> servers = new HashMap<>();
+        servers.put(oidcIssuer, serverConfiguration());
+        staticServerConfigurationService.setServers(servers);
+        return staticServerConfigurationService;
+    }
+
+    @Bean
+    public StaticClientConfigurationService staticClientConfigurationService() {
+        StaticClientConfigurationService staticClientConfigurationService = new StaticClientConfigurationService();
+        Map<String, RegisteredClient> clients = new HashMap<>();
+        clients.put(oidcIssuer, registeredClient());
+        staticClientConfigurationService.setClients(clients);
+        return staticClientConfigurationService;
+    }
+
+    @Bean
+    public RegisteredClient registeredClient() {
+        RegisteredClient registeredClient = new RegisteredClient();
+        registeredClient.setClientId(oidcId);
+        registeredClient.setClientSecret(oidcSecret);
+        registeredClient.setScope(new HashSet<>(Arrays.asList("openid", "eduperson_entitlement", "profile", "email")));
+        registeredClient.setTokenEndpointAuthMethod(AuthMethod.SECRET_BASIC);
+        registeredClient.setRedirectUris(new HashSet<>(Collections.singletonList(oidcDevHome)));
+        return registeredClient;
+    }
+
+    @Bean
+    public StaticAuthRequestOptionsService staticAuthRequestOptionsService() {
+        return new StaticAuthRequestOptionsService();
+    }
+
+    @Bean
+    public PlainAuthRequestUrlBuilder plainAuthRequestUrlBuilder() {
+        return new PlainAuthRequestUrlBuilder();
+    }
+
+    @Bean
+    public ServerConfiguration serverConfiguration() {
+        ServerConfiguration serverConfiguration = new ServerConfiguration();
+        serverConfiguration.setIssuer(oidcIssuer);
+        serverConfiguration.setAuthorizationEndpointUri(oidcIssuer + "authorize");
+        serverConfiguration.setTokenEndpointUri(oidcIssuer + "token");
+        serverConfiguration.setUserInfoUri(oidcIssuer + "userinfo");
+        serverConfiguration.setJwksUri(oidcIssuer + "jwk");
+        serverConfiguration.setRevocationEndpointUri(oidcIssuer + "revoke");
+        return serverConfiguration;
+    }
+
+    @Bean
+    public LoginUrlAuthenticationEntryPoint authenticationEntryPoint() {
+        return new LoginUrlAuthenticationEntryPoint("/openid_connect_login");
+    }
+
+
+    @Bean
+    public OIDCAuthenticationFilter openIdConnectAuthenticationFilter() throws Exception {
+        OIDCAuthenticationFilter oidc = new OIDCAuthenticationFilter();
+        oidc.setAuthenticationManager(authenticationManagerBean());
+        oidc.setIssuerService(staticSingleIssuerService());
+        oidc.setServerConfigurationService(staticServerConfigurationService());
+        oidc.setClientConfigurationService(staticClientConfigurationService());
+        oidc.setAuthRequestOptionsService(staticAuthRequestOptionsService());
+        oidc.setAuthRequestUrlBuilder(plainAuthRequestUrlBuilder());
+        oidc.setAuthenticationSuccessHandler(frontEndRedirect());
+        return oidc;
+    }
+
+    @Bean
+    public StaticSingleIssuerService staticSingleIssuerService() {
+        StaticSingleIssuerService staticSingleIssuerService = new StaticSingleIssuerService();
+        staticSingleIssuerService.setIssuer(oidcIssuer);
+        return staticSingleIssuerService;
+    }
+
+    @Bean(initMethod = "init")
+    public FrontEndLinkURIAuthenticationSuccessHandler frontEndRedirect() {
+        FrontEndLinkURIAuthenticationSuccessHandler frontEnd = new FrontEndLinkURIAuthenticationSuccessHandler();
+        frontEnd.setFrontEndURI(webAppFrontEnd);
+        return frontEnd;
+    }
+
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/Paging.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/Paging.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/Paging.java	(revision 61527)
@@ -0,0 +1,77 @@
+package eu.dnetlib.repo.manager.domain;
+
+
+import javax.validation.constraints.NotNull;
+import java.util.ArrayList;
+import java.util.List;
+
+public class Paging<T> {
+
+    private int total;
+
+    private int from;
+
+    private int to;
+
+    private List<T> results;
+
+    public Paging(int total, int from, int to, List<T> results) {
+        this.total = total;
+        this.from = from;
+        this.to = to;
+        this.results = results;
+    }
+
+    public Paging(@NotNull Paging<T> page) {
+        this.total = page.getTotal();
+        this.from = page.getFrom();
+        this.to = page.getTo();
+        this.results = page.getResults();
+    }
+
+    public <K> Paging(@NotNull Paging<K> page, List<T> results) {
+        this.total = page.getTotal();
+        this.from = page.getFrom();
+        this.to = page.getTo();
+        this.results = results;
+    }
+
+    public Paging() {
+        this.total = 0;
+        this.from = 0;
+        this.to = 0;
+        this.results = new ArrayList<>();
+    }
+
+    public int getTotal() {
+        return total;
+    }
+
+    public void setTotal(int total) {
+        this.total = total;
+    }
+
+    public int getFrom() {
+        return from;
+    }
+
+    public void setFrom(int from) {
+        this.from = from;
+    }
+
+    public int getTo() {
+        return to;
+    }
+
+    public void setTo(int to) {
+        this.to = to;
+    }
+
+    public List<T> getResults() {
+        return results;
+    }
+
+    public void setResults(List<T> results) {
+        this.results = results;
+    }
+}
\ No newline at end of file
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/config/SwaggerConfig.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/config/SwaggerConfig.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/config/SwaggerConfig.java	(revision 61527)
@@ -0,0 +1,59 @@
+package eu.dnetlib.repo.manager.config;
+
+import eu.dnetlib.repo.manager.controllers.*;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.EnableWebMvc;
+import springfox.documentation.builders.PathSelectors;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.service.ApiInfo;
+import springfox.documentation.service.Contact;
+import springfox.documentation.service.VendorExtension;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+import java.util.ArrayList;
+
+
+/**
+ * Created by panagiotis on 16/11/2017.
+ */
+@Configuration
+@EnableSwagger2
+@EnableWebMvc
+@ComponentScan(basePackageClasses = {
+        RepositoryController.class,
+        MonitorController.class,
+        ValidatorController.class,
+        PiWikController.class,
+        BrokerController.class,
+        StatsController.class,
+        UserController.class,
+        SushiliteController.class
+},basePackages = "eu.dnetlib.repo.manager.*")
+public class SwaggerConfig  {
+
+    @Bean
+    public Docket productApi() {
+        return new Docket(DocumentationType.SWAGGER_2)
+                .select()
+                .apis(RequestHandlerSelectors.any())
+                .paths(PathSelectors.any())
+                .build()
+                .pathMapping("/")
+                .apiInfo(getApiInfo());
+    }
+
+    private ApiInfo getApiInfo() {
+        return new ApiInfo("Repository Manager Dashboard API Documentation",
+                "Repository Manager Dashboard API Documentation",
+                "1.0",
+                "urn:tos",
+                new Contact("", "", ""),
+                "Apache 2.0", "http://www.apache.org/licenses/LICENSE-2.0",
+                new ArrayList<VendorExtension>());
+    }
+
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/exception/EndPointException.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/exception/EndPointException.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/exception/EndPointException.java	(revision 61527)
@@ -0,0 +1,16 @@
+package eu.dnetlib.repo.manager.exception;
+
+import java.io.IOException;
+
+//@ResponseStatus(HttpStatus.GATEWAY_TIMEOUT)
+public class EndPointException extends IOException {
+
+    public EndPointException() {
+            super("Endpoint not responding!");
+        }
+
+    public EndPointException(String url) {
+            super("Endpoint with url: " + url + " not responding!");
+        }
+
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/config/CascadingPropertyLoader.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/config/CascadingPropertyLoader.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/config/CascadingPropertyLoader.java	(revision 61527)
@@ -0,0 +1,56 @@
+package eu.dnetlib.repo.manager.config;
+
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
+
+import java.util.Properties;
+
+/**
+ * CascadingPropertyLoader loads a number of property files and mergers them together, so that the last properties
+ * override the previous. It also supports property expansion like:
+ * 
+ * <code>
+ *   something = 1
+ *   somethingelse = 2
+ *   test = ${something}/${somethingelse}
+ *  </code>
+ * 
+ * <p>
+ * And if you override something to XX, then test will become XX/2
+ * </p>
+ * 
+ * 
+ * @author marko
+ * 
+ */
+public class CascadingPropertyLoader extends PropertyPlaceholderConfigurer implements InitializingBean {
+
+	private Properties properties;
+
+	public void afterPropertiesSet() throws Exception {
+		this.properties = mergeProperties();
+
+		// Convert the merged properties, if necessary.
+		convertProperties(this.properties);
+		
+		logger.debug("Properties: " + properties);
+	}
+
+	@Override
+	protected void processProperties(final ConfigurableListableBeanFactory beanFactoryToProcess, final Properties props) throws BeansException {
+		super.processProperties(beanFactoryToProcess, props);
+	}
+
+	public Properties getProperties() {
+		return properties;
+	}
+
+	public void setProperties(final Properties properties) {
+		super.setProperties(properties);
+		
+		this.properties = properties;
+	}
+}
+
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/resources/eu/dnetlib/repo/manager/service/countries.txt
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/resources/eu/dnetlib/repo/manager/service/countries.txt	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/resources/eu/dnetlib/repo/manager/service/countries.txt	(revision 61527)
@@ -0,0 +1,195 @@
+Afghanistan
+Albania
+Algeria
+Andorra
+Angola
+Antigua & Deps
+Argentina
+Armenia
+Australia
+Austria
+Azerbaijan
+Bahamas
+Bahrain
+Bangladesh
+Barbados
+Belarus
+Belgium
+Belize
+Benin
+Bhutan
+Bolivia
+Bosnia Herzegovina
+Botswana
+Brazil
+Brunei
+Bulgaria
+Burkina
+Burundi
+Cambodia
+Cameroon
+Canada
+Cape Verde
+Central African Rep
+Chad
+Chile
+China
+Colombia
+Comoros
+Congo
+Congo {Democratic Rep}
+Costa Rica
+Croatia
+Cuba
+Cyprus
+Czech Republic
+Denmark
+Djibouti
+Dominica
+Dominican Republic
+East Timor
+Ecuador
+Egypt
+El Salvador
+Equatorial Guinea
+Eritrea
+Estonia
+Ethiopia
+Fiji
+Finland
+France
+Gabon
+Gambia
+Georgia
+Germany
+Ghana
+Greece
+Grenada
+Guatemala
+Guinea
+Guinea-Bissau
+Guyana
+Haiti
+Honduras
+Hungary
+Iceland
+India
+Indonesia
+Iran
+Iraq
+Ireland {Republic}
+Israel
+Italy
+Ivory Coast
+Jamaica
+Japan
+Jordan
+Kazakhstan
+Kenya
+Kiribati
+Korea North
+Korea South
+Kosovo
+Kuwait
+Kyrgyzstan
+Laos
+Latvia
+Lebanon
+Lesotho
+Liberia
+Libya
+Liechtenstein
+Lithuania
+Luxembourg
+Macedonia
+Madagascar
+Malawi
+Malaysia
+Maldives
+Mali
+Malta
+Marshall Islands
+Mauritania
+Mauritius
+Mexico
+Micronesia
+Moldova
+Monaco
+Mongolia
+Montenegro
+Morocco
+Mozambique
+Myanmar, {Burma}
+Namibia
+Nauru
+Nepal
+Netherlands
+New Zealand
+Nicaragua
+Niger
+Nigeria
+Norway
+Oman
+Pakistan
+Palau
+Panama
+Papua New Guinea
+Paraguay
+Peru
+Philippines
+Poland
+Portugal
+Qatar
+Romania
+Russian Federation
+Rwanda
+St Kitts & Nevis
+St Lucia
+Saint Vincent & the Grenadines
+Samoa
+San Marino
+Sao Tome & Principe
+Saudi Arabia
+Senegal
+Serbia
+Seychelles
+Sierra Leone
+Singapore
+Slovakia
+Slovenia
+Solomon Islands
+Somalia
+South Africa
+Spain
+Sri Lanka
+Sudan
+Suriname
+Swaziland
+Sweden
+Switzerland
+Syria
+Taiwan
+Tajikistan
+Tanzania
+Thailand
+Togo
+Tonga
+Trinidad & Tobago
+Tunisia
+Turkey
+Turkmenistan
+Tuvalu
+Uganda
+Ukraine
+United Arab Emirates
+United Kingdom
+United States
+Uruguay
+Uzbekistan
+Vanuatu
+Vatican City
+Venezuela
+Vietnam
+Yemen
+Zambia
+Zimbabwe
\ No newline at end of file
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/webapp/WEB-INF/applicationContext.xml
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/webapp/WEB-INF/applicationContext.xml	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/webapp/WEB-INF/applicationContext.xml	(revision 61527)
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:tx="http://www.springframework.org/schema/tx"
+       xmlns:mvc="http://www.springframework.org/schema/mvc"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans
+
+       http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
+	http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
+    http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">
+
+    <import resource="classpath*:/application-context.xml"/>
+
+    <import resource="classpath*:/eu/dnetlib/soap/cxf/applicationContext-eprbuilders.xml"/>
+    <import resource="classpath*:/eu/dnetlib/clients/ws/springContext-locatorFactory.xml"/>
+    <import resource="classpath*:/gr/uoa/di/driver/util/springContext-locators.xml"/>
+    <import resource="classpath*:/gr/uoa/di/driver/app/springContext-lookupFactory.xml"/>
+    <import resource="classpath*:/gr/uoa/di/driver/app/springContext-lookupClients.xml"/>
+    <import resource="classpath*:/eu/dnetlib/enabling/hcm/springContext-hcmService.xml"/>
+    <import resource="classpath*:/gr/uoa/di/driver/app/springContext-commons.xml"/>
+
+    <!--<import resource="classpath*:/gr/uoa/di/driver/app/springContext-registrator.xml"/>-->
+
+
+
+
+    <bean id="maillib" class="eu.dnetlib.utils.MailLibrary" init-method="init">
+        <property name="mailhost" value="${services.validator.mail.host}"/>
+        <property name="smtpPort" value="${services.validator.mail.port}"/>
+        <property name="authenticate" value="${services.validator.mail.authenticate}"/>
+        <property name="username" value="${services.validator.mail.username}"/>
+        <property name="password" value="${services.validator.mail.password}"/>
+        <property name="from" value="${services.validator.mail.fromAddress}"/>
+        <property name="replyTo" value="${services.validator.mail.replyToAddress}"/>
+        <property name="mode" value="${services.validator.mail.mode}"/>
+        <property name="debug" value="${services.validator.mail.debug}"/>
+    </bean>
+
+    <bean class="eu.dnetlib.repo.manager.config.CascadingPropertyLoader"
+          id="propertyLoader">
+        <property name="order" value="2"/>
+        <property name="properties">
+            <bean class="eu.dnetlib.conf.WebappContextProperyFactory">
+                <property name="propertyFetcher">
+                    <bean class="eu.dnetlib.conf.PropertyFetcher"/>
+                </property>
+            </bean>
+        </property>
+        <property name="ignoreUnresolvablePlaceholders" value="true"/>
+        <property name="locations">
+            <list>
+                <value>classpath*:/gr/**/springContext-*.properties</value>
+                <value>classpath*:/eu/**/springContext-*.properties</value>
+
+                <value>classpath*:/application.properties</value>
+                <value>classpath*:/email-texts.properties</value>
+
+                <value>classpath*:dnet-site-wizard.properties</value>
+                <value>classpath*:dnet-site-override.properties</value>
+                <value>classpath*:dnet-wizard.properties</value>
+                <value>classpath*:dnet-override.properties</value>
+                <value>classpath*:dnet-validator-wizard.properties</value>
+                <value>classpath*:dnet-validator-override.properties</value>
+                <value>classpath*:dnet-site-force-override.properties</value>
+                <value>classpath*:dnet-force-override.properties</value>
+            </list>
+        </property>
+    </bean>
+
+    <mvc:resources mapping="swagger-ui.html" location="classpath:/META-INF/resources/"/>
+    <mvc:resources mapping="/webjars/**" location="classpath:/META-INF/resources/webjars/"/>
+    <bean class="eu.dnetlib.repo.manager.config.SwaggerConfig"/>
+
+</beans>
\ No newline at end of file
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/utils/Converter.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/utils/Converter.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/utils/Converter.java	(revision 61527)
@@ -0,0 +1,406 @@
+package eu.dnetlib.repo.manager.utils;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import eu.dnetlib.domain.data.Repository;
+import eu.dnetlib.domain.data.RepositoryInterface;
+import eu.dnetlib.repo.manager.domain.AggregationDetails;
+import eu.dnetlib.repo.manager.domain.RepositorySnippet;
+import eu.dnetlib.repo.manager.domain.Timezone;
+import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.log4j.Logger;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.springframework.stereotype.Component;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+@Component
+public class Converter {
+
+    private static final Logger LOGGER = Logger.getLogger(Converter.class);
+
+    public static Repository jsonToRepositoryObject(JSONObject repositoryObject) throws JSONException {
+
+        Repository repository = new Repository();
+
+        JSONObject datasource = repositoryObject.getJSONObject("datasource");
+
+        //if( datasource.equals(null))
+        //    return null;
+
+        repository.setId(datasource.get("id").toString());
+        repository.setOfficialName(datasource.get("officialname").toString());
+
+        repository.setEnglishName(datasource.get("englishname").toString());
+        if (repository.getEnglishName().equals("null"))
+            repository.setEnglishName("");
+
+        repository.setWebsiteUrl(datasource.get("websiteurl").toString());
+        if (repository.getWebsiteUrl().equals("null"))
+            repository.setWebsiteUrl("");
+
+        repository.setLogoUrl(datasource.get("logourl").toString());
+        if (repository.getLogoUrl().equals("null"))
+            repository.setLogoUrl("");
+
+        repository.setContactEmail(datasource.get("contactemail").toString());
+        if (repository.getContactEmail().equals("null"))
+            repository.setContactEmail("");
+
+
+        repository.setLatitude(toDouble(datasource.get("latitude").toString()));
+        repository.setLongitude(toDouble(datasource.get("longitude").toString()));
+        Double timezone = toDouble(datasource.get("timezone").toString());
+        repository.setTimezone(timezone != null ? timezone : 0.0);
+        repository.setNamespacePrefix(datasource.get("namespaceprefix").toString());
+        repository.setOdLanguages(datasource.get("languages").toString());
+        repository.setDateOfValidation(convertStringToDate(datasource.get("dateofvalidation").toString()));
+
+        /*  typology -> platform
+         *  datasource class -> typology */
+        repository.setTypology(datasource.get("platform").toString());
+        if (repository.getTypology().equals("null"))
+            repository.setTypology("");
+        repository.setDatasourceClass(datasource.get("typology").toString());
+
+        repository.setDateOfCollection(convertStringToDate(datasource.get("dateofcollection").toString()));
+        repository.setActivationId(datasource.get("activationId").toString());
+
+        repository.setDescription(datasource.get("description").toString());
+        if (repository.getDescription().equals("null"))
+            repository.setDescription("");
+
+        repository.setIssn(datasource.get("issn").toString());
+        repository.setLissn(datasource.get("lissn").toString());
+        if (repository.getLissn().equals("null"))
+            repository.setLissn("");
+        repository.setEissn(datasource.get("eissn").toString());
+        if (repository.getEissn().equals("null"))
+            repository.setEissn("");
+        repository.setRegisteredBy(datasource.get("registeredby").toString());
+
+        /* managed field */
+        repository.setRegistered(Boolean.parseBoolean(datasource.get("managed").toString()));
+
+        //subjects
+
+        repository.setAggregator(datasource.get("aggregator").toString());
+        repository.setCollectedFrom(datasource.get("collectedfrom").toString());
+
+        //TODO change organization to list
+        JSONArray organizations = ((JSONArray) datasource.get("organizations"));
+        if (organizations.length() != 0) {
+            repository.setOrganization(((JSONArray) datasource.get("organizations")).getJSONObject(0).get("legalname").toString());
+            String countryCode = ((JSONArray) datasource.get("organizations")).getJSONObject(0).get("country").toString();
+            repository.setCountryCode(countryCode);
+        }
+
+        /* identities field  */
+
+        return repository;
+    }
+
+    public static Date convertStringToDate(String date) {
+
+        if (Objects.equals(date, "null"))
+            return null;
+
+        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
+        try {
+            return formatter.parse(date);
+        } catch (ParseException e) {
+            LOGGER.error(e);
+        }
+        return null;
+    }
+
+    public static String convertDateToString(Date date) {
+
+        if (Objects.equals(date, null))
+            return null;
+
+        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
+        return formatter.format(date);
+    }
+
+    public static Double toDouble(String number) {
+        if (Objects.equals(number, "null"))
+            return 0.0;
+        else
+            return Double.valueOf(number);
+    }
+
+    public static List<RepositorySnippet> jsonToRepositorySnippetList(JSONObject json) throws JSONException {
+
+        List<RepositorySnippet> resultSet = new ArrayList<>();
+        JSONArray rs = json.getJSONArray("datasourceInfo");
+        for (int i = 0; i < rs.length(); i++)
+            resultSet.add(jsonToRepositorySnippetObject(rs.getJSONObject(i)));
+        return resultSet;
+    }
+
+    public static RepositorySnippet jsonToRepositorySnippetObject(JSONObject repositorySnippetObject) throws JSONException {
+
+
+        RepositorySnippet repositorySnippet = new RepositorySnippet();
+
+//        JSONObject datasource = repositorySnippetObject.getJSONObject("datasource");
+
+
+        repositorySnippet.setId(repositorySnippetObject.get("id").toString());
+        repositorySnippet.setOfficialname(repositorySnippetObject.get("officialname").toString());
+
+        repositorySnippet.setEnglishname(repositorySnippetObject.get("englishname").toString());
+        if (repositorySnippet.getEnglishname().equals("null"))
+            repositorySnippet.setEnglishname("");
+
+        repositorySnippet.setWebsiteurl(repositorySnippetObject.get("websiteurl").toString());
+        if (repositorySnippet.getWebsiteurl().equals("null"))
+            repositorySnippet.setWebsiteurl("");
+
+        repositorySnippet.setRegisteredby(repositorySnippetObject.get("registeredby").toString());
+        if (repositorySnippet.getRegisteredby().equals("null"))
+            repositorySnippet.setRegisteredby("");
+        return repositorySnippet;
+
+    }
+
+    public static List<Repository> jsonToRepositoryList(JSONObject json) throws JSONException {
+
+        List<Repository> resultSet = new ArrayList<>();
+        JSONArray rs = json.getJSONArray("datasourceInfo");
+        for (int i = 0; i < rs.length(); i++)
+            resultSet.add(jsonToRepositoryObject(rs.getJSONObject(i)));
+        return resultSet;
+    }
+
+    public static List<RepositoryInterface> jsonToRepositoryInterfaceList(JSONObject json) throws JSONException {
+
+        List<RepositoryInterface> resultSet = new ArrayList<>();
+        JSONArray rs = json.getJSONArray("api");
+        for (int i = 0; i < rs.length(); i++)
+            resultSet.add(jsonToRepositoryInterfaceObject(rs.getJSONObject(i)));
+        return resultSet;
+    }
+
+    public static RepositoryInterface jsonToRepositoryInterfaceObject(JSONObject repositoryInterfaceObject) throws JSONException {
+
+        RepositoryInterface repositoryInterface = new RepositoryInterface();
+
+        repositoryInterface.setId(repositoryInterfaceObject.get("id").toString());
+        repositoryInterface.setAccessProtocol(repositoryInterfaceObject.get("protocol").toString());
+        repositoryInterface.setContentDescription(repositoryInterfaceObject.get("contentdescription").toString());
+        repositoryInterface.setTypology(repositoryInterfaceObject.get("typology").toString());
+        repositoryInterface.setCompliance(repositoryInterfaceObject.get("compatibility").toString());
+        repositoryInterface.setLastCollectionDate(repositoryInterfaceObject.get("lastCollectionDate").toString());
+
+        repositoryInterface.setBaseUrl(repositoryInterfaceObject.get("baseurl").toString());
+        repositoryInterface.setRemovable(Boolean.parseBoolean(repositoryInterfaceObject.get("removable").toString()));
+
+
+        // repositoryInterface.setMetadataIdentifierPath(repositoryInterfaceObject.get("metadataIdentifierPath").toString());
+        repositoryInterface.setDesiredCompatibilityLevel(repositoryInterfaceObject.get("compatibility").toString());
+        //repositoryInterface.setActive(Boolean.parseBoolean(repositoryInterfaceObject.get("active").toString()));
+
+
+        Map<String, String> accessParams = new HashMap<>();
+        Map<String, String> extraFields = new HashMap<>();
+
+        ObjectMapper mapper = new ObjectMapper();
+        JSONArray apiparams = repositoryInterfaceObject.getJSONArray("apiParams");
+
+        for (int i = 0; i < apiparams.length(); i++)
+            accessParams.put(apiparams.getJSONObject(i).getString("param"), apiparams.getJSONObject(i).getString("value"));
+
+        repositoryInterface.setAccessParams(accessParams);
+
+        return repositoryInterface;
+    }
+
+    public static String repositoryObjectToJson(Repository repository) throws JSONException, JsonProcessingException {
+
+        HashMap<String, Object> repositoryMap = new HashMap<>();
+        ObjectMapper mapper = new ObjectMapper();
+
+        repositoryMap.put("id", repository.getId());
+        repositoryMap.put("openaireId", getOpenaireId(repository.getId()));
+        repositoryMap.put("officialname", repository.getOfficialName());
+        repositoryMap.put("englishname", repository.getEnglishName());
+        repositoryMap.put("websiteurl", repository.getWebsiteUrl());
+        repositoryMap.put("logourl", repository.getLogoUrl());
+        repositoryMap.put("contactemail", repository.getContactEmail());
+        repositoryMap.put("longitude", repository.getLongitude().toString());
+        repositoryMap.put("latitude", repository.getLatitude().toString());
+        repositoryMap.put("timezone", repository.getTimezone());
+
+        repositoryMap.put("namespaceprefix", repository.getNamespacePrefix() != null ? repository.getNamespacePrefix() : "");
+        repositoryMap.put("languages", repository.getOdLanguages() != null ? repository.getOdLanguages() : "");
+
+        repositoryMap.put("dateofcollection", repository.getDateOfCollection() != null ? convertDateToString(repository.getDateOfCollection()) : "");
+
+        /*
+         * typology -> platform
+         * datasource class -> typology
+         * */
+        repositoryMap.put("typology", repository.getDatasourceClass());
+        repositoryMap.put("platform", repository.getTypology());
+
+        repositoryMap.put("dateofvalidation", repository.getDateOfCollection() != null ? convertDateToString(repository.getDateOfCollection()) : "");
+        repositoryMap.put("activationId", repository.getActivationId() != null ? repository.getActivationId() : "");
+
+        repositoryMap.put("description", repository.getDescription());
+
+        repositoryMap.put("eissn", repository.getEissn() != null ? repository.getEissn() : "");
+        repositoryMap.put("issn", repository.getIssn() != null ? repository.getIssn() : "");
+        repositoryMap.put("lissn", repository.getLissn() != null ? repository.getLissn() : "");
+
+        repositoryMap.put("registeredby", repository.getRegisteredBy());
+
+        repositoryMap.put("aggregator", repository.getAggregator() != null ? repository.getAggregator() : "");
+        repositoryMap.put("collectedfrom", repository.getCollectedFrom() != null ? repository.getCollectedFrom() : "");
+
+        repositoryMap.put("managed", repository.isRegistered());
+
+        Map<String, String> organization = new HashMap<>();
+        organization.put("legalname", repository.getOrganization());
+        organization.put("country", repository.getCountryCode());
+        organization.put("legalshortname", "");
+        organization.put("websiteurl", "");
+        organization.put("logourl", "");
+
+        List organizations = new ArrayList();
+        organizations.add(organization);
+        repositoryMap.put("organizations", organizations);
+
+        //TODO check identitites
+        //Map<String,String> identity = new HashMap<>();
+
+        if (repository.getPiwikInfo() != null) {
+            Map<String, Object> identity = new HashMap<>();
+            HashSet<Map<String, Object>> identities = new HashSet<>();
+
+            identity.put("issuertype", "piwik");
+            identity.put("pid", "piwik:" + repository.getPiwikInfo().getSiteId());
+
+            identities.add(identity);
+
+            repositoryMap.put("identities", identities);
+        }
+
+        repositoryMap.put("subjects", "");
+
+        return mapper.writeValueAsString(repositoryMap);
+    }
+
+    public static String repositoryInterfaceObjectToJson(Repository repository, RepositoryInterface repositoryInterface) throws JSONException {
+
+        JSONObject jsonObject = new JSONObject();
+
+        jsonObject.put("id", repositoryInterface.getId());
+        jsonObject.put("protocol", repositoryInterface.getAccessProtocol());
+        jsonObject.put("datasource", repository.getId());
+        jsonObject.put("contentdescription", repositoryInterface.getContentDescription());
+        jsonObject.put("typology", repositoryInterface.getTypology());
+        jsonObject.put("compatibility", repositoryInterface.getDesiredCompatibilityLevel());
+        jsonObject.put("compatibilityOverride", repositoryInterface.getDesiredCompatibilityLevel());
+
+        jsonObject.put("lastCollectionTotal", "");
+
+        jsonObject.put("lastCollectionDate", repositoryInterface.getLastCollectionDate());
+        jsonObject.put("lastAggregationTotal", "");
+        jsonObject.put("lastAggregationDate", "");
+        jsonObject.put("lastDownloadTotal", "");
+        jsonObject.put("lastDownloadDate", "");
+
+        jsonObject.put("baseurl", repositoryInterface.getBaseUrl());
+        jsonObject.put("removable", repositoryInterface.isRemovable());
+
+
+        JSONArray apiparams = new JSONArray();
+        for (String param : repositoryInterface.getAccessParams().keySet()) {
+            JSONObject jo = new JSONObject();
+            jo.put("param", param);
+            jo.put("value", repositoryInterface.getAccessParams().get(param));
+            apiparams.put(jo);
+        }
+        jsonObject.put("apiParams", apiparams);
+
+
+//        jsonObject.put("metadataIdentifierPath",repositoryInterface.getMetadataIdentifierPath());
+
+
+        return jsonObject.toString();
+    }
+
+    public static ArrayList<String> readFile(String filename) {
+        String line;
+        ArrayList<String> list = new ArrayList<String>();
+        try {
+            //InputStream in = Converter.class.getResourceAsStream("resources/eu/dnetlib/repo/manager/service/utils/"+filename);
+            InputStream in = Converter.class.getClass().getResourceAsStream("/eu/**/" + filename);
+            BufferedReader br = new BufferedReader(new InputStreamReader(in));
+            while ((line = br.readLine()) != null) {
+                list.add(line.trim());
+            }
+            br.close();
+        } catch (IOException e) {
+            LOGGER.debug("Error opening file!");
+            LOGGER.error(e);
+        }
+        return list;
+    }
+
+    public static List<AggregationDetails> getAggregationHistoryFromJson(JSONObject datasourceInfo) throws JSONException {
+        JSONArray rs;
+        List<AggregationDetails> aggregationDetailsList = new ArrayList<>();
+
+        if (datasourceInfo.get("aggregationHistory") != null && !datasourceInfo.get("aggregationHistory").toString().equals("null")) {
+            rs = new JSONArray(datasourceInfo.get("aggregationHistory").toString());
+
+            for (int i = 0; i < rs.length(); i++)
+                aggregationDetailsList.add(jsonToAggregationDetails(rs.getJSONObject(i)));
+        }
+
+        return aggregationDetailsList;
+    }
+
+    private static AggregationDetails jsonToAggregationDetails(JSONObject aggregationObject) throws JSONException {
+
+        AggregationDetails aggregationDetails = new AggregationDetails();
+
+        aggregationDetails.setAggregationStage(aggregationObject.get("aggregationStage").toString());
+        if (aggregationObject.has("collectionMode"))
+            aggregationDetails.setCollectionMode(aggregationObject.get("collectionMode").toString());
+        if (aggregationObject.has("indexedVersion"))
+            aggregationDetails.setIndexedVersion(Boolean.parseBoolean(aggregationObject.get("indexedVersion").toString()));
+        aggregationDetails.setDate(convertStringToDate(aggregationObject.get("date").toString()));
+        aggregationDetails.setNumberOfRecords(Integer.parseInt(aggregationObject.get("numberOfRecords").toString()));
+        return aggregationDetails;
+    }
+
+
+    public static List<Timezone> toTimezones(List<String> timezones) {
+
+        List<Timezone> tmz = new ArrayList<>();
+        for (String t : timezones) {
+            String[] s = t.split("\t");
+            tmz.add(new Timezone(s[1], Double.parseDouble(s[0])));
+        }
+        return tmz;
+    }
+
+    private static String getOpenaireId(String repositoryId) {
+        if (repositoryId != null && repositoryId.contains("::"))
+            return repositoryId.split("::")[0] + "::" + DigestUtils.md5Hex(repositoryId.split("::")[1]);
+        return null;
+    }
+
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/test/java/metrics/PrometheusTest.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/test/java/metrics/PrometheusTest.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/test/java/metrics/PrometheusTest.java	(revision 61527)
@@ -0,0 +1,54 @@
+package metrics;
+
+import eu.dnetlib.repo.manager.controllers.PrometheusController;
+import eu.dnetlib.repo.manager.service.PiWikService;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.when;
+
+@Component
+public class PrometheusTest {
+
+    private static final int TOTAL = 10;
+    private static final int VALIDATED = 8;
+
+    @Autowired
+    @Mock
+    PiWikService piWikService;
+
+    @Autowired
+    @InjectMocks
+    private PrometheusController prometheusController;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+
+        when(piWikService.getTotal()).thenReturn(TOTAL);
+        when(piWikService.getValidated(true)).thenReturn(VALIDATED);
+        when(piWikService.getValidated(false)).thenReturn(TOTAL - VALIDATED);
+    }
+
+    @Test
+    public void testMetrics() {
+        String report = prometheusController.getMetrics();
+        assertTrue(report.startsWith("#"));
+        System.out.println(report);
+    }
+
+    @Test
+    public void testPiwikMetrics() {
+        assertTrue(piWikService.getValidated(false).equals(TOTAL - VALIDATED));
+        String report = prometheusController.getPiwikMetrics();
+        assertTrue(report.contains("total_total " + TOTAL));
+        assertTrue(report.contains("validated_total " + VALIDATED));
+        System.out.println(report);
+    }
+}
\ No newline at end of file
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/dto/User.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/dto/User.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/dto/User.java	(revision 61527)
@@ -0,0 +1,61 @@
+package eu.dnetlib.repo.manager.domain.dto;
+
+import org.mitre.openid.connect.model.UserInfo;
+
+public class User {
+
+    private String sub;
+    private String firstName;
+    private String lastName;
+    private String email;
+
+    public User() {}
+
+    public User(String sub, String firstName, String lastName, String email) {
+        this.sub = sub;
+        this.firstName = firstName;
+        this.lastName = lastName;
+        this.email = email;
+    }
+
+    public static User from(UserInfo userInfo) {
+        User user = new User();
+        user.setSub(user.getSub());
+        user.setFirstName(userInfo.getGivenName());
+        user.setLastName(userInfo.getFamilyName());
+        user.setEmail(userInfo.getEmail());
+        return user;
+    }
+
+    public String getSub() {
+        return sub;
+    }
+
+    public void setSub(String sub) {
+        this.sub = sub;
+    }
+
+    public String getFirstName() {
+        return firstName;
+    }
+
+    public void setFirstName(String firstName) {
+        this.firstName = firstName;
+    }
+
+    public String getLastName() {
+        return lastName;
+    }
+
+    public void setLastName(String lastName) {
+        this.lastName = lastName;
+    }
+
+    public String getEmail() {
+        return email;
+    }
+
+    public void setEmail(String email) {
+        this.email = email;
+    }
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/broker/EventsPage.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/broker/EventsPage.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/broker/EventsPage.java	(revision 61527)
@@ -0,0 +1,79 @@
+package eu.dnetlib.repo.manager.domain.broker;
+
+import eu.dnetlib.broker.objects.OaBrokerEventPayload;
+
+import java.util.List;
+
+/**
+ * Created by stefanos on 26/10/2016.
+ */
+public class EventsPage{
+
+    private String datasource;
+    private String topic;
+    private long currPage;
+    private long totalPages;
+    private long total;
+    private List<OaBrokerEventPayload> values;
+
+    public EventsPage() {
+
+    }
+    public EventsPage(final String datasource, final String topic, final long currPage, final long totalPages, final long total,
+                      final List<OaBrokerEventPayload> values) {
+        this.datasource = datasource;
+        this.topic = topic;
+        this.currPage = currPage;
+        this.totalPages = totalPages;
+        this.total = total;
+        this.values = values;
+    }
+
+    public String getDatasource() {
+        return datasource;
+    }
+
+    public void setDatasource(String datasource) {
+        this.datasource = datasource;
+    }
+
+    public String getTopic() {
+        return topic;
+    }
+
+    public void setTopic(String topic) {
+        this.topic = topic;
+    }
+
+    public long getCurrPage() {
+        return currPage;
+    }
+
+    public void setCurrPage(long currPage) {
+        this.currPage = currPage;
+    }
+
+    public long getTotalPages() {
+        return totalPages;
+    }
+
+    public void setTotalPages(long totalPages) {
+        this.totalPages = totalPages;
+    }
+
+    public long getTotal() {
+        return total;
+    }
+
+    public void setTotal(long total) {
+        this.total = total;
+    }
+
+    public List<OaBrokerEventPayload> getValues() {
+        return values;
+    }
+
+    public void setValues(List<OaBrokerEventPayload> values) {
+        this.values = values;
+    }
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/test/resources/applicationContext.xml
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/test/resources/applicationContext.xml	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/test/resources/applicationContext.xml	(revision 61527)
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:tx="http://www.springframework.org/schema/tx"
+       xmlns:mvc="http://www.springframework.org/schema/mvc"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans
+
+       http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
+	http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
+    http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">
+
+    <import resource="classpath*:/application-context.xml"/>
+
+    <import resource="classpath*:/eu/dnetlib/soap/cxf/applicationContext-eprbuilders.xml"/>
+    <import resource="classpath*:/eu/dnetlib/clients/ws/springContext-locatorFactory.xml"/>
+    <import resource="classpath*:/gr/uoa/di/driver/util/springContext-locators.xml"/>
+    <import resource="classpath*:/gr/uoa/di/driver/app/springContext-lookupFactory.xml"/>
+    <import resource="classpath*:/gr/uoa/di/driver/app/springContext-lookupClients.xml"/>
+    <import resource="classpath*:/eu/dnetlib/enabling/hcm/springContext-hcmService.xml"/>
+    <import resource="classpath*:/gr/uoa/di/driver/app/springContext-commons.xml"/>
+
+    <!--<import resource="classpath*:/gr/uoa/di/driver/app/springContext-registrator.xml"/>-->
+
+
+
+
+    <bean id="maillib" class="eu.dnetlib.utils.MailLibrary" init-method="init">
+        <property name="mailhost" value="${services.validator.mail.host}"/>
+        <property name="smtpPort" value="${services.validator.mail.port}"/>
+        <property name="authenticate" value="${services.validator.mail.authenticate}"/>
+        <property name="username" value="${services.validator.mail.username}"/>
+        <property name="password" value="${services.validator.mail.password}"/>
+        <property name="from" value="${services.validator.mail.fromAddress}"/>
+        <property name="replyTo" value="${services.validator.mail.replyToAddress}"/>
+        <property name="mode" value="${services.validator.mail.mode}"/>
+        <property name="debug" value="${services.validator.mail.debug}"/>
+    </bean>
+
+    <bean class="eu.dnetlib.repo.manager.config.CascadingPropertyLoader"
+          id="propertyLoader">
+        <property name="order" value="2"/>
+        <property name="properties">
+            <bean class="eu.dnetlib.conf.WebappContextProperyFactory">
+                <property name="propertyFetcher">
+                    <bean class="eu.dnetlib.conf.PropertyFetcher"/>
+                </property>
+            </bean>
+        </property>
+        <property name="ignoreUnresolvablePlaceholders" value="true"/>
+        <property name="locations">
+            <list>
+                <value>classpath*:/gr/**/springContext-*.properties</value>
+                <value>classpath*:/eu/**/springContext-*.properties</value>
+
+                <value>classpath*:/application.properties</value>
+                <value>classpath*:/email-texts.properties</value>
+
+<!--                <value>classpath*:dnet-site-wizard.properties</value>-->
+<!--                <value>classpath*:dnet-site-override.properties</value>-->
+<!--                <value>classpath*:dnet-wizard.properties</value>-->
+<!--                <value>classpath*:dnet-override-new.properties</value>-->
+<!--                <value>classpath*:dnet-validator-wizard.properties</value>-->
+<!--                <value>classpath*:dnet-validator-override.properties</value>-->
+<!--                <value>classpath*:dnet-site-force-override.properties</value>-->
+<!--                <value>classpath*:dnet-force-override.properties</value>-->
+            </list>
+        </property>
+    </bean>
+
+</beans>
\ No newline at end of file
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/broker/Subscription.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/broker/Subscription.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/broker/Subscription.java	(revision 61527)
@@ -0,0 +1,107 @@
+package eu.dnetlib.repo.manager.domain.broker;
+
+/**
+ * Created by stefanos on 10-Mar-17.
+ */
+
+
+import java.util.Date;
+import java.util.List;
+
+
+public class Subscription{
+
+    private String subscriptionId;
+
+    private String subscriber;
+
+    private String topic;
+
+    private NotificationFrequency frequency;
+
+    private NotificationMode mode;
+
+    private Date lastNotificationDate;
+
+    private Date creationDate;
+
+    private String conditions;
+
+    private List<MapConditions> conditionsAsList;
+
+    public Subscription() {
+    }
+
+    public String getSubscriptionId() {
+        return subscriptionId;
+    }
+
+    public void setSubscriptionId(String subscriptionId) {
+        this.subscriptionId = subscriptionId;
+    }
+
+    public String getSubscriber() {
+        return subscriber;
+    }
+
+    public void setSubscriber(String subscriber) {
+        this.subscriber = subscriber;
+    }
+
+    public String getTopic() {
+        return topic;
+    }
+
+    public void setTopic(String topic) {
+        this.topic = topic;
+    }
+
+    public NotificationFrequency getFrequency() {
+        return frequency;
+    }
+
+    public void setFrequency(NotificationFrequency frequency) {
+        this.frequency = frequency;
+    }
+
+    public NotificationMode getMode() {
+        return mode;
+    }
+
+    public void setMode(NotificationMode mode) {
+        this.mode = mode;
+    }
+
+    public Date getLastNotificationDate() {
+        return lastNotificationDate;
+    }
+
+    public void setLastNotificationDate(Date lastNotificationDate) {
+        this.lastNotificationDate = lastNotificationDate;
+    }
+
+    public String getConditions() {
+        return conditions;
+    }
+
+    public void setConditions(String conditions) {
+        this.conditions = conditions;
+    }
+
+    public List<MapConditions> getConditionsAsList() {
+        return conditionsAsList;
+    }
+
+    public void setConditionsAsList(List<MapConditions> conditionsAsList) {
+        this.conditionsAsList = conditionsAsList;
+    }
+
+    public Date getCreationDate() {
+        return creationDate;
+    }
+
+    public void setCreationDate(Date creationDate) {
+        this.creationDate = creationDate;
+    }
+
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/broker/NotificationFrequency.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/broker/NotificationFrequency.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/broker/NotificationFrequency.java	(revision 61527)
@@ -0,0 +1,10 @@
+package eu.dnetlib.repo.manager.domain.broker;
+
+
+
+/**
+ * Created by stefanos on 10-Mar-17.
+ */
+public enum NotificationFrequency   {
+    never, realtime, daily, weekly, monthly
+}
\ No newline at end of file
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/broker/Range.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/broker/Range.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/broker/Range.java	(revision 61527)
@@ -0,0 +1,36 @@
+package eu.dnetlib.repo.manager.domain.broker;
+
+/**
+ * Created by stefanos on 26/10/2016.
+ */
+public class Range{
+
+    private String min;
+    private String max;
+
+    public Range() {
+    }
+
+    public Range(final String min, final String max) {
+        super();
+        this.min = min;
+        this.max = max;
+    }
+
+    public String getMin() {
+        return this.min;
+    }
+
+    public void setMin(final String min) {
+        this.min = min;
+    }
+
+    public String getMax() {
+        return this.max;
+    }
+
+    public void setMax(final String max) {
+        this.max = max;
+    }
+
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/Organization.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/Organization.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/Organization.java	(revision 61527)
@@ -0,0 +1,51 @@
+package eu.dnetlib.repo.manager.domain;
+
+
+
+public class Organization{
+    private String country;
+    private String legalname;
+    private String websiteurl;
+    private String legalshortname;
+    private String logourl;
+
+    public String getCountry() {
+        return country;
+    }
+
+    public void setCountry(String country) {
+        this.country = country;
+    }
+
+    public String getLegalname() {
+        return legalname;
+    }
+
+    public void setLegalname(String legalname) {
+        this.legalname = legalname;
+    }
+
+    public String getWebsiteurl() {
+        return websiteurl;
+    }
+
+    public void setWebsiteurl(String websiteurl) {
+        this.websiteurl = websiteurl;
+    }
+
+    public String getLegalshortname() {
+        return legalshortname;
+    }
+
+    public void setLegalshortname(String legalshortname) {
+        this.legalshortname = legalshortname;
+    }
+
+    public String getLogourl() {
+        return logourl;
+    }
+
+    public void setLogourl(String logourl) {
+        this.logourl = logourl;
+    }
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/RepositoryServiceException.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/RepositoryServiceException.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/RepositoryServiceException.java	(revision 61527)
@@ -0,0 +1,51 @@
+package eu.dnetlib.repo.manager.domain;
+
+/**
+ * Created by nikonas on 7/12/15.
+ */
+public class RepositoryServiceException extends Exception {
+
+    public enum ErrorCode{
+        REPOSITORY_ALREADY_EXISTS,
+        SQL_ERROR,
+        NOT_ACTIVATED,
+        ACTIVATION_ERROR,
+        LDAP_ERROR,
+        MAIL_ALREADY_EXISTS,
+        GENERAL_ERROR,
+        ALREADY_ACTIVATED,
+        INVALID_EMAIL_FORMAT,
+        NO_REPOS_FOR_THIS_COUNTRY, REPOSITORY_NOT_EXISTS, INCORRECT_CAPTCHA
+    }
+
+    private ErrorCode errorCode = null;
+
+    public RepositoryServiceException() {
+    }
+
+    public RepositoryServiceException(ErrorCode errorCode) {
+        this.errorCode = errorCode;
+    }
+
+    public RepositoryServiceException(String message, Throwable cause, ErrorCode errorCode) {
+        super(message, cause);
+
+        this.errorCode = errorCode;
+    }
+
+    public RepositoryServiceException(String message, ErrorCode errorCode) {
+        super(message);
+
+        this.errorCode = errorCode;
+    }
+
+    public RepositoryServiceException(Throwable cause, ErrorCode errorCode) {
+        super(cause);
+
+        this.errorCode = errorCode;
+    }
+
+    public ErrorCode getErrorCode() {
+        return errorCode;
+    }
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/AggregationDetails.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/AggregationDetails.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/AggregationDetails.java	(revision 61527)
@@ -0,0 +1,63 @@
+package eu.dnetlib.repo.manager.domain;
+
+import java.util.Calendar;
+import java.util.Date;
+
+public class AggregationDetails{
+
+
+    private String aggregationStage;
+    private Date date;
+    private int numberOfRecords;
+    private String collectionMode;
+    private Boolean indexedVersion;
+
+    public AggregationDetails() {
+    }
+
+    public String getAggregationStage() {
+        return aggregationStage;
+    }
+
+    public String getCollectionMode() {
+        return collectionMode;
+    }
+
+    public void setCollectionMode(String collectionMode) {
+        this.collectionMode = collectionMode;
+    }
+
+    public void setAggregationStage(String aggregationStage) {
+        this.aggregationStage = aggregationStage;
+    }
+
+    public Date getDate() {
+        return date;
+    }
+
+    public void setDate(Date date) {
+        this.date = date;
+    }
+
+    public int getNumberOfRecords() {
+        return numberOfRecords;
+    }
+
+    public void setNumberOfRecords(int numberOfRecords) {
+        this.numberOfRecords = numberOfRecords;
+    }
+
+    public String getYear() {
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(getDate());
+        return String.valueOf(calendar.get(Calendar.YEAR));
+    }
+
+    public Boolean getIndexedVersion() {
+        return indexedVersion;
+    }
+
+    public void setIndexedVersion(Boolean indexedVersion) {
+        this.indexedVersion = indexedVersion;
+    }
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/Country.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/Country.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/Country.java	(revision 61527)
@@ -0,0 +1,24 @@
+package eu.dnetlib.repo.manager.domain;
+
+public class Country {
+
+    private String name;
+    private String code;
+
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/CollectionMonitorSummary.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/CollectionMonitorSummary.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/CollectionMonitorSummary.java	(revision 61527)
@@ -0,0 +1,32 @@
+package eu.dnetlib.repo.manager.domain;
+
+import java.util.List;
+
+public class CollectionMonitorSummary {
+    private List<AggregationDetails> aggregationDetails;
+
+    private AggregationDetails lastIndexedVersion;
+
+    public CollectionMonitorSummary(){}
+
+    public CollectionMonitorSummary(List<AggregationDetails> aggregationDetails, AggregationDetails lastIndexedVersion) {
+        this.aggregationDetails = aggregationDetails;
+        this.lastIndexedVersion = lastIndexedVersion;
+    }
+
+    public List<AggregationDetails> getAggregationDetails() {
+        return aggregationDetails;
+    }
+
+    public void setAggregationDetails(List<AggregationDetails> aggregationDetails) {
+        this.aggregationDetails = aggregationDetails;
+    }
+
+    public AggregationDetails getLastIndexedVersion() {
+        return lastIndexedVersion;
+    }
+
+    public void setLastIndexedVersion(AggregationDetails lastIndexedVersion) {
+        this.lastIndexedVersion = lastIndexedVersion;
+    }
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/Tuple.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/Tuple.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/Tuple.java	(revision 61527)
@@ -0,0 +1,36 @@
+package eu.dnetlib.repo.manager.domain;
+
+
+
+/**
+ * Created by stefania on 12/18/15.
+ */
+public class Tuple<K, V>   {
+
+    private K first;
+    private V second;
+
+    public Tuple() {
+    }
+
+    public Tuple(K first, V second) {
+        this.first = first;
+        this.second = second;
+    }
+
+    public K getFirst() {
+        return first;
+    }
+
+    public void setFirst(K first) {
+        this.first = first;
+    }
+
+    public V getSecond() {
+        return second;
+    }
+
+    public void setSecond(V second) {
+        this.second = second;
+    }
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/OrderByType.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/OrderByType.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/domain/OrderByType.java	(revision 61527)
@@ -0,0 +1,18 @@
+package eu.dnetlib.repo.manager.domain;
+
+public enum OrderByType {
+
+    ASC("ASC"),
+    DSC("DESC");
+
+    private final String text;
+
+    OrderByType(String text) {
+        this.text = text;
+    }
+
+    @Override
+    public String toString() {
+        return text;
+    }
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/exception/ResourceNotFoundException.java
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/exception/ResourceNotFoundException.java	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/java/eu/dnetlib/repo/manager/exception/ResourceNotFoundException.java	(revision 61527)
@@ -0,0 +1,19 @@
+package eu.dnetlib.repo.manager.exception;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.ResponseStatus;
+
+@ResponseStatus(HttpStatus.NOT_FOUND)
+public class ResourceNotFoundException extends Exception {
+    public ResourceNotFoundException() {
+        super("Resource Not Found");
+    }
+
+    public ResourceNotFoundException(String message) {
+        super(message);
+    }
+
+    public ResourceNotFoundException(String id, String resourceType) {
+        super(resourceType + " with id " + id + " was not found");
+    }
+}
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/resources/application-context.xml
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/resources/application-context.xml	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/resources/application-context.xml	(revision 61527)
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans
+               http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
+
+
+    <context:annotation-config/>
+    <context:component-scan base-package="eu.dnetlib.repo.manager.service.*"/>
+
+    <bean class="eu.dnetlib.repo.manager.config.CascadingPropertyLoader"
+          id="propertyLoader">
+        <property name="order" value="2"/>
+        <property name="properties">
+            <bean class="eu.dnetlib.conf.WebappContextProperyFactory">
+                <property name="propertyFetcher">
+                    <bean class="eu.dnetlib.conf.PropertyFetcher"/>
+                </property>
+            </bean>
+        </property>
+        <property name="ignoreUnresolvablePlaceholders" value="true"/>
+        <property name="locations">
+            <list>
+                <value>classpath*:/gr/**/springContext-*.properties</value>
+                <value>classpath*:/eu/**/springContext-*.properties</value>
+
+                <value>classpath*:/application.properties</value>
+                <value>classpath*:email-texts.properties</value>
+
+                <!--                <value>classpath*:dnet-site-wizard.properties</value>-->
+                <!--                <value>classpath*:dnet-site-override.properties</value>-->
+                <!--                <value>classpath*:dnet-wizard.properties</value>-->
+                <!--                <value>classpath*:dnet-override.properties</value>-->
+                <!--                <value>classpath*:dnet-validator-wizard.properties</value>-->
+                <!--                <value>classpath*:dnet-validator-override.properties</value>-->
+                <!--                <value>classpath*:dnet-site-force-override.properties</value>-->
+                <!--                <value>classpath*:dnet-force-override.properties</value>-->
+            </list>
+        </property>
+    </bean>
+</beans>
\ No newline at end of file
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/resources/email-texts.properties
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/resources/email-texts.properties	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/resources/email-texts.properties	(revision 61527)
@@ -0,0 +1,7 @@
+user.registration.mail.subject = OpenAIRE Account Activation
+user.registration.mail.message = Please follow this link to activate your account
+
+user.forgotPassword.mail.Subject = OpenAIRE Reset Password Request
+user.forgotPassword.mail.Body1 = To complete your password reset please follow this link
+user.forgotPassword.mail.Body2 = Security Code
+
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/webapp/WEB-INF/spring-servlet.xml
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/webapp/WEB-INF/spring-servlet.xml	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/main/webapp/WEB-INF/spring-servlet.xml	(revision 61527)
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:mvc="http://www.springframework.org/schema/mvc"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:context="http://www.springframework.org/schema/context"
+       xmlns:security="http://www.springframework.org/schema/security"
+       xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
+		http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd
+		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
+		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd"
+      >
+
+    <security:global-method-security pre-post-annotations="enabled" proxy-target-class="true"
+                                     authentication-manager-ref="authenticationManager">
+    </security:global-method-security>
+
+    <bean id="webexpressionHandler"
+          class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler"/>
+
+    <context:annotation-config/>
+    <mvc:annotation-driven />
+
+</beans>
\ No newline at end of file
Index: modules/uoa-repository-manager-service/tags/release-2.0.0/src/test/resources/application-context.xml
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0/src/test/resources/application-context.xml	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0/src/test/resources/application-context.xml	(revision 61527)
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans
+               http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
+
+
+    <context:annotation-config/>
+    <context:component-scan base-package="eu.dnetlib.repo.manager.service.*"/>
+
+    <bean class="eu.dnetlib.repo.manager.config.CascadingPropertyLoader"
+          id="propertyLoader">
+        <property name="order" value="2"/>
+        <property name="properties">
+            <bean class="eu.dnetlib.conf.WebappContextProperyFactory">
+                <property name="propertyFetcher">
+                    <bean class="eu.dnetlib.conf.PropertyFetcher"/>
+                </property>
+            </bean>
+        </property>
+        <property name="ignoreUnresolvablePlaceholders" value="true"/>
+        <property name="locations">
+            <list>
+                <value>classpath*:/gr/**/springContext-*.properties</value>
+                <value>classpath*:/eu/**/springContext-*.properties</value>
+
+                <value>classpath*:/application.properties</value>
+                <value>classpath*:email-texts.properties</value>
+
+                <!--                <value>classpath*:dnet-site-wizard.properties</value>-->
+                <!--                <value>classpath*:dnet-site-override.properties</value>-->
+                <!--                <value>classpath*:dnet-wizard.properties</value>-->
+                <!--                <value>classpath*:dnet-override.properties</value>-->
+                <!--                <value>classpath*:dnet-validator-wizard.properties</value>-->
+                <!--                <value>classpath*:dnet-validator-override.properties</value>-->
+                <!--                <value>classpath*:dnet-site-force-override.properties</value>-->
+                <!--                <value>classpath*:dnet-force-override.properties</value>-->
+            </list>
+        </property>
+    </bean>
+</beans>
\ No newline at end of file
Index: modules/uoa-repository-manager-service/tags/release-2.0.0
===================================================================
--- modules/uoa-repository-manager-service/tags/release-2.0.0	(nonexistent)
+++ modules/uoa-repository-manager-service/tags/release-2.0.0	(revision 61527)

Property changes on: modules/uoa-repository-manager-service/tags/release-2.0.0
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,3 ##
+.idea
+target
+*.iml
