Merged dev-api branch to trunk. merge -r54925:HEAD https://svn.driver.research-infrastructures.eu/driver/dnet45/modules/uoa-repository-manager-service/branches/dev-api
This commit is contained in:
parent
368538ddd4
commit
ed247a82f3
|
@ -2,7 +2,8 @@ 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/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/
|
||||
|
|
35
pom.xml
35
pom.xml
|
@ -246,6 +246,41 @@
|
|||
<version>1.1.5.RELEASE</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>
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
package eu.dnetlib.repo.manager.controllers;
|
||||
|
||||
import eu.dnetlib.repo.manager.domain.RepositorySummaryInfo;
|
||||
import eu.dnetlib.repo.manager.service.DashboardService;
|
||||
import io.swagger.annotations.Api;
|
||||
import org.json.JSONException;
|
||||
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.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping(value = "/dashboard")
|
||||
@Api(description = "Dashboard API", tags = {"dashboard"})
|
||||
public class DashboardController {
|
||||
|
||||
@Autowired
|
||||
DashboardService dashboardService;
|
||||
|
||||
@RequestMapping(value = "/getRepositoriesSummary/{userEmail}/{page}/{size}" , method = RequestMethod.GET,
|
||||
produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@ResponseBody
|
||||
@PreAuthorize("hasRole('ROLE_USER')")
|
||||
public List<RepositorySummaryInfo> getRepositoriesSummaryInfo(@PathVariable("userEmail") String userEmail,
|
||||
@PathVariable("page") String page,
|
||||
@PathVariable("size") String size) throws JSONException {
|
||||
return dashboardService.getRepositoriesSummaryInfo(userEmail, page, size);
|
||||
}
|
||||
}
|
|
@ -28,7 +28,7 @@ public class PiWikController {
|
|||
}
|
||||
|
||||
@RequestMapping(value = "/savePiwikInfo" , method = RequestMethod.POST,produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_PORTAL_ADMIN') or (hasRole('ROLE_USER') " +
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_PROVIDE_ADMIN') or (hasRole('ROLE_USER') " +
|
||||
"and #piwikInfo.requestorEmail == authentication.userInfo.email)")
|
||||
public PiwikInfo savePiwikInfo(@RequestBody PiwikInfo piwikInfo) {
|
||||
return piWikService.savePiwikInfo(piwikInfo);
|
||||
|
@ -41,7 +41,7 @@ public class PiWikController {
|
|||
|
||||
@RequestMapping(value = "/approvePiwikSite/{repositoryId}" , method = RequestMethod.GET)
|
||||
@ResponseBody
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_PORTAL_ADMIN')")
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_PROVIDE_ADMIN')")
|
||||
public ResponseEntity<Object> approvePiwikSite(@PathVariable("repositoryId") String repositoryId) {
|
||||
return piWikService.approvePiwikSite(repositoryId);
|
||||
}
|
||||
|
@ -55,14 +55,14 @@ public class PiWikController {
|
|||
@RequestMapping(value = "/markPiwikSiteAsValidated/{repositoryId}" , method = RequestMethod.POST,
|
||||
consumes = MediaType.APPLICATION_JSON_VALUE)
|
||||
@ResponseBody
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_PORTAL_ADMIN')")
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_PROVIDE_ADMIN')")
|
||||
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("hasRole('ROLE_ADMIN') or hasRole('ROLE_PORTAL_ADMIN') or (hasRole('ROLE_USER') and #piwikInfo.requestorEmail == authentication.userInfo.email)")
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_PROVIDE_ADMIN') or (hasRole('ROLE_USER') and #piwikInfo.requestorEmail == authentication.userInfo.email)")
|
||||
public PiwikInfo enableMetricsForRepository(@RequestParam("officialName") String officialName,
|
||||
@RequestParam("repoWebsite") String repoWebsite,
|
||||
@RequestBody PiwikInfo piwikInfo) throws RepositoryServiceException {
|
||||
|
|
|
@ -14,6 +14,7 @@ import org.springframework.security.access.prepost.PreAuthorize;
|
|||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.ws.rs.Path;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -51,6 +52,22 @@ public class RepositoryController {
|
|||
return repositoryService.getRepositoriesOfUser(userEmail, page, size);
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/searchRegisteredRepositories/{page}/{size}",method = RequestMethod.GET,
|
||||
produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@ResponseBody
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_PROVIDE_ADMIN')")
|
||||
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
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
package eu.dnetlib.repo.manager.domain;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class Organization implements Serializable {
|
||||
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;
|
||||
}
|
||||
}
|
|
@ -8,8 +8,10 @@ public class RepositorySnippet implements IsSerializable {
|
|||
private String officialname;
|
||||
private String englishname;
|
||||
private String websiteurl;
|
||||
private String typology;
|
||||
private String registeredby;
|
||||
|
||||
private Organization[] organizations;
|
||||
private String registrationdate;
|
||||
|
||||
public RepositorySnippet() {}
|
||||
|
||||
|
@ -52,4 +54,28 @@ public class RepositorySnippet implements IsSerializable {
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
package eu.dnetlib.repo.manager.domain;
|
||||
|
||||
import com.google.gwt.user.client.rpc.IsSerializable;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
public class RepositorySummaryInfo implements IsSerializable {
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
|
@ -10,9 +10,12 @@ public class RequestFilter{
|
|||
private String country = null;
|
||||
private String id = null;
|
||||
private String officialname = null;
|
||||
private String englishname = null;
|
||||
private String collectedfrom = null;
|
||||
|
||||
|
||||
|
||||
|
||||
public RequestFilter() {
|
||||
|
||||
}
|
||||
|
@ -64,4 +67,12 @@ public class RequestFilter{
|
|||
public void setCollectedfrom(String collectedfrom) {
|
||||
this.collectedfrom = collectedfrom;
|
||||
}
|
||||
|
||||
public String getEnglishname() {
|
||||
return englishname;
|
||||
}
|
||||
|
||||
public void setEnglishname(String englishname) {
|
||||
this.englishname = englishname;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
package eu.dnetlib.repo.manager.service;
|
||||
|
||||
import eu.dnetlib.domain.data.Repository;
|
||||
import eu.dnetlib.repo.manager.domain.RepositorySummaryInfo;
|
||||
import eu.dnetlib.repo.manager.shared.AggregationDetails;
|
||||
import eu.dnetlib.repo.manager.shared.BrokerException;
|
||||
import eu.dnetlib.repo.manager.shared.MetricsInfo;
|
||||
import eu.dnetlib.repo.manager.shared.RepositoryServiceException;
|
||||
import eu.dnetlib.repo.manager.shared.broker.BrowseEntry;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.json.JSONException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
|
||||
import javax.xml.ws.ServiceMode;
|
||||
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(@PathVariable("userEmail") String userEmail,
|
||||
@PathVariable("page") String page,
|
||||
@PathVariable("size") String size) throws JSONException {
|
||||
|
||||
List<RepositorySummaryInfo> repositorySummaryInfoList = new ArrayList<>();
|
||||
|
||||
try {
|
||||
|
||||
List<Repository> repositoriesOfUser = repositoryService.getRepositoriesOfUser(userEmail, page, size);
|
||||
for(Repository 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?
|
||||
List<AggregationDetails> aggregationDetailsList = repositoryService.getRepositoryAggregations(repository.getId());
|
||||
for(AggregationDetails aggregationDetails: aggregationDetailsList) {
|
||||
if(aggregationDetails.getIndexedVersion()) {
|
||||
repositorySummaryInfo.setRecordsCollected(aggregationDetails.getNumberOfRecords());
|
||||
repositorySummaryInfo.setLastIndexedVersion(aggregationDetails.getDate());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return repositorySummaryInfoList;
|
||||
}
|
||||
}
|
|
@ -18,8 +18,12 @@ public interface EmailUtils {
|
|||
|
||||
void sendUserMetricsEnabled(PiwikInfo piwikInfo) throws Exception;
|
||||
|
||||
void sendAdminRegistrationEmail(Repository repository, Authentication authentication) throws Exception;
|
||||
|
||||
void sendUserRegistrationEmail(Repository repository, Authentication authentication) throws Exception;
|
||||
|
||||
void sendAdminUpdateRepositoryEmail(Repository repository, Authentication authentication) throws Exception;
|
||||
|
||||
void sendUserUpdateRepositoryEmail(Repository repository, Authentication authentication) throws Exception;
|
||||
|
||||
void sendSubmitJobForValidationEmail(Authentication authentication, JobForValidation jobForValidation) throws Exception;
|
||||
|
|
|
@ -44,6 +44,9 @@ public class EmailUtilsImpl implements EmailUtils {
|
|||
@Value("${services.repomanager.usagestats.adminEmail}")
|
||||
private String usageStatsAdminEmail;
|
||||
|
||||
@Value("${services.provide.adminEmail}")
|
||||
private String provideAdminEmail;
|
||||
|
||||
|
||||
@PostConstruct
|
||||
public void init(){
|
||||
|
@ -190,6 +193,32 @@ public class EmailUtilsImpl implements EmailUtils {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendAdminRegistrationEmail(Repository repository, Authentication authentication) throws Exception {
|
||||
try {
|
||||
String subject = "OpenAIRE content provider registration request started for " +
|
||||
repository.getDatasourceType() + "[" + repository.getEnglishName() + "]";
|
||||
|
||||
String message = "Dear administrator" + ",\n" +
|
||||
"\n" +
|
||||
"We received a request to register the " + repository.getDatasourceType() + "[" + repository.getEnglishName() + "]" +
|
||||
" to the OpenAIRE compliant list of content providers. " +
|
||||
"A validation process 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(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 {
|
||||
|
@ -199,12 +228,12 @@ public class EmailUtilsImpl implements EmailUtils {
|
|||
String message = "Dear " + ((OIDCAuthenticationToken) authentication).getUserInfo().getName() + ",\n" +
|
||||
"\n" +
|
||||
"We received a request to register the " + repository.getDatasourceType() + "[" + repository.getEnglishName() + "]" +
|
||||
" to the OpenAIRE compliant list of content providers.\n " +
|
||||
" to the OpenAIRE compliant list of content providers. " +
|
||||
"A validation process against the OpenAIRE guidelines compatibility " +
|
||||
"has been started. You will be informed in another message once the process is finished." +
|
||||
"\n" +
|
||||
"Please do not reply to this message.\n" +
|
||||
"This message has been generated automatically.\n" +
|
||||
"\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";
|
||||
|
@ -217,6 +246,29 @@ public class EmailUtilsImpl implements EmailUtils {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendAdminUpdateRepositoryEmail(Repository repository, Authentication authentication) throws Exception {
|
||||
try {
|
||||
String subject = "OpenAIRE content provider update request started for " +
|
||||
repository.getDatasourceType() + "[" + repository.getEnglishName() + "]";
|
||||
|
||||
String message = "Dear administrator" + ",\n" +
|
||||
"\n" +
|
||||
"We received a request to update the " + repository.getDatasourceType() + "[" + repository.getEnglishName() + "]." +
|
||||
"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" +
|
||||
"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 sendUserUpdateRepositoryEmail(Repository repository, Authentication authentication) throws Exception {
|
||||
try {
|
||||
|
@ -225,10 +277,10 @@ public class EmailUtilsImpl implements EmailUtils {
|
|||
|
||||
String message = "Dear " + ((OIDCAuthenticationToken) authentication).getUserInfo().getName() + ",\n" +
|
||||
"\n" +
|
||||
"We received a request to update the " + repository.getDatasourceType() + "[" + repository.getEnglishName() + "].\n" +
|
||||
"A new iteration process of the validation against the OpenAIRE guidelines compatibility has been started.\n" +
|
||||
"Please do not reply to this message.\n" +
|
||||
"This message has been generated automatically.\n" +
|
||||
"We received a request to update the " + repository.getDatasourceType() + "[" + repository.getEnglishName() + "]." +
|
||||
"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";
|
||||
|
|
|
@ -72,7 +72,7 @@ public class PiWikServiceImpl implements PiWikService {
|
|||
}
|
||||
|
||||
@Override
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_PORTAL_ADMIN') or (hasRole('ROLE_USER') and #piwikInfo.requestorEmail == authentication.userInfo.email)")
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_PROVIDE_ADMIN') or (hasRole('ROLE_USER') and #piwikInfo.requestorEmail == authentication.userInfo.email)")
|
||||
public PiwikInfo savePiwikInfo(@RequestBody PiwikInfo piwikInfo) {
|
||||
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
|
||||
jdbcTemplate.update(INSERT_PIWIK_INFO, new Object[]{piwikInfo.getRepositoryId(), piwikInfo.getSiteId(), piwikInfo.getRequestorName(),
|
||||
|
@ -93,7 +93,7 @@ public class PiWikServiceImpl implements PiWikService {
|
|||
}
|
||||
|
||||
@Override
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_PORTAL_ADMIN')")
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_PROVIDE_ADMIN')")
|
||||
public ResponseEntity<Object> approvePiwikSite(@PathVariable("repositoryId") String repositoryId) {
|
||||
new JdbcTemplate(dataSource).update(APPROVE_PIWIK_SITE, new Object[] {repositoryId}, new int[] {Types.VARCHAR});
|
||||
return new ResponseEntity<>("OK",HttpStatus.OK);
|
||||
|
@ -107,7 +107,7 @@ public class PiWikServiceImpl implements PiWikService {
|
|||
}
|
||||
|
||||
@Override
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_PORTAL_ADMIN')")
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_PROVIDE_ADMIN')")
|
||||
public ResponseEntity<Object> markPiwikSiteAsValidated(@PathVariable("repositoryId") String repositoryId) throws RepositoryServiceException {
|
||||
try {
|
||||
approvePiwikSite(repositoryId);
|
||||
|
@ -128,7 +128,7 @@ public class PiWikServiceImpl implements PiWikService {
|
|||
}
|
||||
|
||||
@Override
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_PORTAL_ADMIN') or (hasRole('ROLE_USER') and #piwikInfo.requestorEmail == authentication.userInfo.email)")
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_PROVIDE_ADMIN') or (hasRole('ROLE_USER') and #piwikInfo.requestorEmail == authentication.userInfo.email)")
|
||||
public PiwikInfo enableMetricsForRepository(@RequestParam("officialName") String officialName,
|
||||
@RequestParam("repoWebsite") String repoWebsite,
|
||||
@RequestBody PiwikInfo piwikInfo) throws RepositoryServiceException {
|
||||
|
|
|
@ -32,6 +32,10 @@ public interface RepositoryService {
|
|||
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;
|
||||
|
|
|
@ -3,15 +3,18 @@ package eu.dnetlib.repo.manager.service;
|
|||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
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.RepositorySnippet;
|
||||
import eu.dnetlib.repo.manager.domain.RequestFilter;
|
||||
import eu.dnetlib.repo.manager.exception.ResourceNotFoundException;
|
||||
import eu.dnetlib.repo.manager.shared.*;
|
||||
import eu.dnetlib.repo.manager.utils.Converter;
|
||||
import gr.uoa.di.driver.enabling.vocabulary.VocabularyLoader;
|
||||
import gr.uoa.di.driver.xml.repository.INTERFACE;
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.json.JSONArray;
|
||||
|
@ -46,6 +49,9 @@ public class RepositoryServiceImpl implements RepositoryService {
|
|||
@Value("${api.baseAddress}")
|
||||
private String baseAddress;
|
||||
|
||||
@Value("${services.repo-manager.adminEmail}")
|
||||
private String adminEmail;
|
||||
|
||||
@Autowired
|
||||
RestTemplate restTemplate;
|
||||
|
||||
|
@ -70,6 +76,9 @@ public class RepositoryServiceImpl implements RepositoryService {
|
|||
@Autowired
|
||||
private EmailUtils emailUtils;
|
||||
|
||||
@Autowired
|
||||
ValidatorService validatorService;
|
||||
|
||||
|
||||
private Map<String, Vocabulary> vocabularyMap = new ConcurrentHashMap<String, Vocabulary>();
|
||||
|
||||
|
@ -185,8 +194,35 @@ public class RepositoryServiceImpl implements RepositoryService {
|
|||
// 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 {
|
||||
|
@ -411,11 +447,17 @@ public class RepositoryServiceImpl implements RepositoryService {
|
|||
String json_repository = Converter.repositoryObjectToJson(repository);
|
||||
LOGGER.debug("JSON to add(update) -> " + json_repository);
|
||||
|
||||
//
|
||||
// // TODO delete these 3 lines
|
||||
// HttpHeaders temp = new HttpHeaders();
|
||||
// temp.setContentType(MediaType.APPLICATION_JSON_UTF8);
|
||||
|
||||
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());
|
||||
|
||||
|
@ -442,11 +484,13 @@ public class RepositoryServiceImpl implements RepositoryService {
|
|||
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);
|
||||
ResponseEntity responseEntity = restTemplate.exchange(uriComponents.toUri(),HttpMethod.POST, httpEntity
|
||||
, ResponseEntity.class);
|
||||
|
||||
if (responseEntity.getStatusCode().equals(HttpStatus.OK))
|
||||
if (responseEntity.getStatusCode().equals(HttpStatus.OK)) {
|
||||
emailUtils.sendUserUpdateRepositoryEmail(repository, authentication);
|
||||
else
|
||||
emailUtils.sendAdminUpdateRepositoryEmail(repository, authentication);
|
||||
} else
|
||||
LOGGER.debug(responseEntity.getBody().toString());
|
||||
|
||||
return repository;
|
||||
|
@ -498,9 +542,10 @@ public class RepositoryServiceImpl implements RepositoryService {
|
|||
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))
|
||||
if(responseEntity.getStatusCode().equals(HttpStatus.OK)) {
|
||||
emailUtils.sendUserRegistrationEmail(repository, authentication);
|
||||
else {
|
||||
emailUtils.sendAdminRegistrationEmail(repository, authentication);
|
||||
} else {
|
||||
LOGGER.debug(responseEntity.getBody().toString());
|
||||
}
|
||||
}
|
||||
|
@ -542,6 +587,38 @@ public class RepositoryServiceImpl implements RepositoryService {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public RepositoryInterface updateRepositoryInterface(@RequestParam("repoId") String repoId,
|
||||
@RequestParam("registeredBy") String registeredBy,
|
||||
@RequestBody 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());
|
||||
return repositoryInterface;
|
||||
}
|
||||
|
||||
private void submitInterfaceValidation(Repository repo, String repoType, String userEmail, RepositoryInterface iFace) 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.setInterfaceIdOld(null);
|
||||
job.setOfficialName(repo.getOfficialName());
|
||||
job.setRepoType(repoType);
|
||||
job.setUserEmail(userEmail);
|
||||
job.setValidationSet(iFace.getAccessSet());
|
||||
job.setRecords(-1);
|
||||
job.setRegistration(true);
|
||||
job.setUpdateExisting(false);
|
||||
|
||||
this.validatorService.submitJobForValidation(job);
|
||||
}
|
||||
|
||||
private RepositoryInterface createRepositoryInterface(Repository repo, RepositoryInterface iFace, String datatype) {
|
||||
|
||||
iFace.setContentDescription("metadata");
|
||||
|
@ -742,17 +819,6 @@ public class RepositoryServiceImpl implements RepositoryService {
|
|||
return Collections.singletonMap("lastCollectionDate", getRepositoryInterface("openaire____::"+mode).get(1).getLastCollectionDate());
|
||||
}
|
||||
|
||||
@Override
|
||||
public RepositoryInterface updateRepositoryInterface(@RequestParam("repoId") String repoId,
|
||||
@RequestParam("registeredBy") String registeredBy,
|
||||
@RequestBody 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());
|
||||
return repositoryInterface;
|
||||
}
|
||||
|
||||
private void updateValidationSet(String repositoryId, String repositoryInterfaceId, String validationSet) throws Exception {
|
||||
UriComponents uriComponents = UriComponentsBuilder
|
||||
.fromHttpUrl(baseAddress + "/ds/api/oaiset")
|
||||
|
@ -840,6 +906,16 @@ public class RepositoryServiceImpl implements RepositoryService {
|
|||
.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);
|
||||
}
|
||||
|
|
|
@ -368,11 +368,16 @@ public class Converter {
|
|||
}
|
||||
|
||||
public static List<AggregationDetails> getAggregationHistoryFromJson(JSONObject datasourceInfo) throws JSONException {
|
||||
|
||||
JSONArray rs = new JSONArray(datasourceInfo.get("aggregationHistory").toString());
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,9 +10,11 @@ ISLookUpService.url = ${IS.url}/isLookUp
|
|||
ISRegistryService.url = ${IS.url}/isRegistry
|
||||
ISSNService.url = ${IS.url}/services/isSN
|
||||
|
||||
#ValidatorService.url=http://adonis.athenarc.gr:8080/validator-service/services/validatorWebService
|
||||
ValidatorService.url=http://localhost:8080/validator-service/services/validatorWebService
|
||||
#ValidatorService.url=http://beta.services.openaire.eu/validator-service/services/validatorWebService
|
||||
ValidatorService.url=http://88.197.53.69:8080/validator-service/
|
||||
#ValidatorService.url=http://88.197.53.69:8080/validator-service/
|
||||
|
||||
services.provide.adminEmail=antleb@di.uoa.gr
|
||||
|
||||
## Broker Service
|
||||
services.broker.url = http://broker1-dev-dnet.d4science.org
|
||||
|
@ -29,7 +31,7 @@ services.repo-manager.baseUrl = http://${container.hostname}:${container.port}/$
|
|||
transport.soap.baseAddress = http://${container.hostname}:${container.port}/${container.context}
|
||||
transport.soap.force.local.address = false
|
||||
|
||||
services.repo-manager.adminEmail = pkanakakis@di.uoa.gr
|
||||
services.repo-manager.adminEmail = antleb@di.uoa.gr
|
||||
services.repo-manager.repository.testing.mode = false
|
||||
services.repo-manager.deploy.environment = development
|
||||
services.validator.mail.host = smtp.gmail.com
|
||||
|
@ -43,10 +45,10 @@ services.validator.mail.override = false
|
|||
services.validator.mail.logonly = false
|
||||
services.validator.mail.mode = ssl
|
||||
services.validator.mail.debug = false
|
||||
services.validator.mail.overrideEmail = pkanakakis@di.uoa.gr
|
||||
services.validator.mail.specialRecipients = pkanakakis@di.uoa.gr
|
||||
services.validator.mail.overrideEmail = antleb@di.uoa.gr
|
||||
services.validator.mail.specialRecipients = antleb@di.uoa.gr
|
||||
|
||||
services.validator.repoRegistration.override = pkanakakis@di.uoa.gr
|
||||
services.validator.repoRegistration.override = antleb@di.uoa.gr
|
||||
|
||||
repomanager.db.driverClassName = org.postgresql.Driver
|
||||
repomanager.db.url = jdbc:postgresql://194.177.192.119:5432/repomanager
|
||||
|
@ -61,19 +63,29 @@ oidc.issuer = https://aai.openaire.eu/oidc/
|
|||
oidc.id = 767422b9-5461-4807-a80a-f9a2072d3a7d
|
||||
oidc.secret = AMQtGlbTXNjwjhF0st28LmM6V0XypMdaVS7tJmGuYFlmH36iIv4t7tVqYuLYrNPkhnZ_GPUJvhymBhFupdgb6aU
|
||||
|
||||
oidc.dev.home = http://aleka.athenarc.gr:8480/uoa-repository-manager-service/openid_connect_login
|
||||
webapp.dev.front = http://aleka.athenarc.gr:4200/landing
|
||||
oidc.dev.home = http://localhost:8480/uoa-repository-manager-service/openid_connect_login
|
||||
webapp.dev.front = http://localhost:4200/landing
|
||||
|
||||
##REDIS-AAI
|
||||
|
||||
redis.host = aleka.athenarc.gr
|
||||
redis.host=vereniki.athenarc.gr
|
||||
redis.port=6379
|
||||
redis.password =
|
||||
redis.password=redis01041992s
|
||||
aai.mode=develop
|
||||
|
||||
#redis.host = aleka.athenarc.gr
|
||||
#redis.port = 6379
|
||||
#redis.password =
|
||||
#aai.mode = develop
|
||||
|
||||
#redis.host=localhost
|
||||
#redis.port=6379
|
||||
#redis.password=
|
||||
#aai.mode=develop
|
||||
|
||||
services.repomanager.usageStatisticsDiagramsBaseURL = https://beta.openaire.eu/stats3/
|
||||
services.repomanager.usageStatisticsNumbersBaseURL = https://beta.services.openaire.eu/usagestats/datasources/
|
||||
services.repomanager.usagestats.adminEmail = pkanakakis@di.uoa.gr
|
||||
services.repomanager.usagestats.adminEmail = antleb@di.uoa.gr
|
||||
|
||||
##SUSHI
|
||||
services.repomanager.usagestats.sushiliteEndpoint = http://beta.services.openaire.eu/usagestats/sushilite/
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
|
||||
<util:map id="userRoles">
|
||||
<entry key="urn:geant:openaire.eu:group:Super+Administrator#aai.openaire.eu" value="ROLE_ADMIN"/>
|
||||
<entry key="urn:geant:openaire.eu:group:Portal+Administrator#aai.openaire.eu" value="ROLE_PORTAL_ADMIN"/>
|
||||
<entry key="urn:geant:openaire.eu:group:Content+Provider+Dashboard+Administrator#aai.openaire.eu" value="ROLE_PROVIDE_ADMIN"/>
|
||||
</util:map>
|
||||
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ log4j.rootLogger = WARN, R
|
|||
|
||||
log4j.logger.eu.dnetlib = DEBUG
|
||||
log4j.logger.eu.dnetlib.clients.data.datasourcemanager.ws.Converter = FATAL
|
||||
log4j.logger.org.springframework = DEBUG, S
|
||||
log4j.logger.org.springframework = INFO, S
|
||||
log4j.additivity.org.springframework = false
|
||||
|
||||
log4j.logger.com.opensymphony.xwork2.ognl.OgnlValueStack = FATAL
|
||||
|
|
Loading…
Reference in New Issue