Merge remote-tracking branch 'origin/master' into new-is-app

This commit is contained in:
Michele Artini 2022-11-16 10:37:47 +01:00
commit 304baf9bf3
159 changed files with 3633 additions and 2022 deletions

View File

@ -3,7 +3,7 @@
<parent>
<groupId>eu.dnetlib.dhp</groupId>
<artifactId>apps</artifactId>
<version>3.2.9-SNAPSHOT</version>
<version>3.3.3-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -1,42 +1,52 @@
package eu.dnetlib.bioschemas.api;
import eu.dnetlib.common.app.AbstractDnetApp;
import io.swagger.v3.oas.models.tags.Tag;
import org.springdoc.core.GroupedOpenApi;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.scheduling.annotation.EnableScheduling;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import eu.dnetlib.common.app.AbstractDnetApp;
import java.util.Arrays;
import java.util.List;
@SpringBootApplication
@EnableSwagger2
@EnableCaching
@EnableScheduling
@ComponentScan(basePackages = "eu.dnetlib")
public class MainApplication extends AbstractDnetApp {
public static final String BIOSCHEMAS_APIS = "D-Net Bioschemas Service APIs";
public static void main(final String[] args) {
SpringApplication.run(MainApplication.class, args);
}
@Bean
public GroupedOpenApi publicApi() {
return GroupedOpenApi.builder()
.group(BIOSCHEMAS_APIS)
.pathsToMatch("/api/**")
.build();
}
@Override
protected void configSwagger(final Docket docket) {
docket.select()
.apis(RequestHandlerSelectors.any())
.paths(p -> p.contains("/api/"))
.build()
.apiInfo(new ApiInfoBuilder()
.title("D-Net Bioschemas Service APIs")
.description("APIs documentation")
.version("1.1")
.contact(ApiInfo.DEFAULT_CONTACT)
.license("Apache 2.0")
.licenseUrl("http://www.apache.org/licenses/LICENSE-2.0")
.build());
protected String swaggerTitle() {
return BIOSCHEMAS_APIS;
}
@Override
protected List<Tag> swaggerTags() {
return Arrays.asList(new Tag().name(BIOSCHEMAS_APIS).description(BIOSCHEMAS_APIS));
}
@Override
protected String swaggerDesc() {
return BIOSCHEMAS_APIS;
}
}

View File

@ -44,19 +44,12 @@ public class ServiceScrapeDriver {
private static final Log logger = LogFactory.getLog(ServiceScrapeDriver.class);
public ServiceScrapeDriver(String sitemapUrl, String sitemapURLKey, String maxScrapedPages, String outputFilename) {
public ServiceScrapeDriver(String sitemapUrl, String sitemapURLKey, String maxScrapedPages, String outputFilename, String outputFolder) {
this.sitemapUrl = sitemapUrl;
this.sitemapURLKey = sitemapURLKey;
this.maxScrapedPages = maxScrapedPages;
this.outputFilename = outputFilename;
}
/**
* Runs the scrape process
*
*/
public void start() throws IOException {
runScrape();
this.outputFolder = outputFolder;
}
/**
@ -66,7 +59,7 @@ public class ServiceScrapeDriver {
* as been left in situ in case it is useful in the future.
*
*/
private void runScrape() throws IOException {
public void runScrape() throws IOException {
processProperties();
String url = sitemapUrl.toLowerCase();
Elements urls = UrlParser.getSitemapList(getSitemapUrl(), getSitemapURLKey());
@ -189,8 +182,6 @@ public class ServiceScrapeDriver {
waitTime = Integer.parseInt(prop.getProperty("waitTime").trim());
logger.info(" waitTime: " + waitTime);
outputFolder = prop.getProperty("outputFolder").trim();
logger.info(" outputFolder: " + outputFolder);
numberOfPagesToCrawlInALoop = Integer.parseInt(prop.getProperty("numberOfPagesToCrawlInALoop").trim());
logger.info(" numberOfPagesToCrawl: " + numberOfPagesToCrawlInALoop);
totalNumberOfPagesToCrawlInASession = Integer.parseInt(prop.getProperty("totalNumberOfPagesToCrawlInASession").trim());

View File

@ -1,9 +1,14 @@
package eu.dnetlib.bioschemas.api.controller;
import eu.dnetlib.bioschemas.api.MainApplication;
import eu.dnetlib.bioschemas.api.scraper.ScrapingExecution;
import eu.dnetlib.bioschemas.api.scraper.ScrapingExecutor;
import eu.dnetlib.bioschemas.api.utils.BioschemasException;
import eu.dnetlib.common.controller.AbstractDnetController;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.LineIterator;
import org.apache.commons.logging.Log;
@ -27,6 +32,7 @@ import java.nio.charset.StandardCharsets;
@RestController
@RequestMapping("/api")
@Tag(name = MainApplication.BIOSCHEMAS_APIS)
public class BioschemasAPIController extends AbstractDnetController {
@Value("${outputFolder}")
@ -41,19 +47,24 @@ public class BioschemasAPIController extends AbstractDnetController {
private static final Log log = LogFactory.getLog(BioschemasAPIController.class);
@Operation(summary = "start the scraping operation", description = "<H1>Working input values are in the following table</H1><BR><TABLE><TR><TH>datasourceKey</TH><TH>sitemapUrl</TH></TR><TR><TD>ped</TD><TD>https://proteinensemble.org/sitemap2.xml.gz</TD></TR><TR><TD>disprot</TD><TD>https://disprot.org/sitemap2.xml.gz</TD></TR><TR><TD>mobidb</TD><TD>https://mobidb.org/sitemap2.xml.gz</TD></TR></TABLE>")
@GetMapping("/startScraping")
public ScrapingExecution startScraping(@RequestParam final String datasourceKey, @RequestParam final String sitemapUrl, final HttpServletRequest req) {
public ScrapingExecution startScraping(@Parameter(name = "datasourceKey") @RequestParam final String datasourceKey,
@Parameter(name = "sitemapUrl") @RequestParam final String sitemapUrl,
final HttpServletRequest req) {
logger.info("<STARTSCRAPING> datasourceKey: "+datasourceKey+" sitemapUrl:"+sitemapUrl);
return scrapingExecutor.startScraping(datasourceKey, sitemapUrl, getOutputDataPattern(), req.getRemoteAddr());
return scrapingExecutor.startScraping(datasourceKey, sitemapUrl, getOutputDataPattern(), req.getRemoteAddr(), getOutputFolder());
}
@Operation(summary = "check the status of last scraping operation")
@GetMapping("/startScraping/status")
public final ScrapingExecution statusScraping() {
return scrapingExecutor.getLastScrapingExecution();
}
@Operation(summary = "retrieve the nquads downloaded for one specific provider")
@RequestMapping(value = "/getNQuads", method = RequestMethod.GET)
public String getNQuads(@RequestParam final String datasourceKey, HttpServletResponse response) throws BioschemasException, IOException {
public String getNQuads(@Parameter(name = "datasourceKey") @RequestParam final String datasourceKey, HttpServletResponse response) throws BioschemasException, IOException {
logger.info("<GETNQUADS> datasourceKey: "+datasourceKey);
@ -76,4 +87,12 @@ public class BioschemasAPIController extends AbstractDnetController {
public String getOutputDataPattern() {
return outputDataPattern;
}
public void setOutputFolder(String outputFolder) {
this.outputFolder = outputFolder;
}
public void setOutputDataPattern(String outputDataPattern) {
this.outputDataPattern = outputDataPattern;
}
}

View File

@ -11,7 +11,7 @@ public class HomeController extends AbstractDnetController {
"/doc", "/swagger"
})
public String apiDoc() {
return "redirect:swagger-ui/";
return "redirect:swagger-ui/index.html";
}
}

View File

@ -14,7 +14,7 @@ public class ScrapingExecutor {
return lastScrapingExecution;
}
public ScrapingExecution startScraping(final String datasourceKey, final String sitemapUrl, final String outputDataPattern, final String remoteAddr) {
public ScrapingExecution startScraping(final String datasourceKey, final String sitemapUrl, final String outputDataPattern, final String remoteAddr, final String outputFolder) {
synchronized (lastScrapingExecution) {
if (lastScrapingExecution.getStatus() != ScrapingStatus.RUNNING) {
lastScrapingExecution.startNew("Scraping for " + datasourceKey + " " + sitemapUrl + " - request from " + remoteAddr);
@ -22,8 +22,8 @@ public class ScrapingExecutor {
try {
String sitemapUrlKey = "loc";
String outputFilename = datasourceKey.concat(outputDataPattern);
ServiceScrapeDriver service = new ServiceScrapeDriver(sitemapUrl, sitemapUrlKey, null, outputFilename);
service.start();
ServiceScrapeDriver service = new ServiceScrapeDriver(sitemapUrl, sitemapUrlKey, null, outputFilename, outputFolder);
service.runScrape();
lastScrapingExecution.complete();
} catch (final Throwable e) {
lastScrapingExecution.fail(e);

View File

@ -1,9 +1,12 @@
server.servlet.context-path=/bioschemas
server.servlet.context-path=/bioschemas-api
server.port=8281
server.public_url = http://localhost:8281/bioschemas-api
server.public_desc = API Base URL
spring.profiles.active=garr
logging.file.name = /var/log/bioschemas/log/bioschemas-api.log
logging.file.name = /var/log/bioschemas-api/bioschemas.log
maven.pom.path = /META-INF/maven/eu.dnetlib.dhp/bioschemas-api/effective-pom.xml
@ -17,9 +20,8 @@ management.endpoints.web.path-mapping.prometheus = metrics
management.endpoints.web.path-mapping.health = health
waitTime=5
outputFolder=/data
outputFolder=/data/bioschemas-harvest
outputDataPattern=_base64_gzipped_nquads.txt
numberOfPagesToCrawlInALoop=8
totalNumberOfPagesToCrawlInASession=32
chromiumDriverLocation = /usr/local/bin/chromedriver
scrapeVersion=1

View File

@ -4,7 +4,7 @@
<parent>
<groupId>eu.dnetlib.dhp</groupId>
<artifactId>apps</artifactId>
<version>3.2.9-SNAPSHOT</version>
<version>3.3.3-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
@ -18,14 +18,6 @@
<dependencies>
<!-- Mail -->
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.7</version>
</dependency>
<!-- Openaire -->
<dependency>
<groupId>eu.dnetlib.dhp</groupId>

View File

@ -1,14 +1,15 @@
package eu.dnetlib.broker;
import java.util.ArrayList;
import java.util.List;
import org.springdoc.core.GroupedOpenApi;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import eu.dnetlib.common.app.AbstractDnetApp;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Tag;
import springfox.documentation.spring.web.plugins.Docket;
import io.swagger.v3.oas.models.tags.Tag;
@SpringBootApplication
public class LiteratureBrokerServiceApplication extends AbstractDnetApp {
@ -24,22 +25,28 @@ public class LiteratureBrokerServiceApplication extends AbstractDnetApp {
SpringApplication.run(LiteratureBrokerServiceApplication.class, args);
}
@Override
protected void configSwagger(final Docket docket) {
docket.select()
.apis(RequestHandlerSelectors.any())
.paths(p -> p.startsWith("/api/"))
.build()
.tags(new Tag(TAG_EVENTS, "Events management"), new Tag(TAG_SUBSCRIPTIONS, "Subscriptions management"), new Tag(TAG_NOTIFICATIONS,
"Notifications management"), new Tag(TAG_TOPIC_TYPES, "Topic types management"), new Tag(TAG_OPENAIRE, "OpenAIRE use case"))
.apiInfo(new ApiInfoBuilder()
.title("Literature Broker Service")
.description("APIs documentation")
.version("1.1")
.contact(ApiInfo.DEFAULT_CONTACT)
.license("Apache 2.0")
.licenseUrl("http://www.apache.org/licenses/LICENSE-2.0")
.build());
@Bean
public GroupedOpenApi publicApi() {
return GroupedOpenApi.builder()
.group("Broker APIs")
.pathsToMatch("/api/**")
.build();
}
@Override
protected String swaggerTitle() {
return "OpenAIRE Broker API";
}
@Override
protected List<Tag> swaggerTags() {
final List<Tag> tags = new ArrayList<>();
tags.add(new Tag().name(TAG_EVENTS).description("Events management"));
tags.add(new Tag().name(TAG_SUBSCRIPTIONS).description("Subscriptions management"));
tags.add(new Tag().name(TAG_NOTIFICATIONS).description("Notifications management"));
tags.add(new Tag().name(TAG_TOPIC_TYPES).description("Topic types management"));
tags.add(new Tag().name(TAG_OPENAIRE).description("OpenAIRE use case"));
return tags;
}
}

View File

@ -16,10 +16,8 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
import eu.dnetlib.broker.common.elasticsearch.Event;
import eu.dnetlib.broker.common.elasticsearch.Notification;
import eu.dnetlib.broker.common.properties.ElasticSearchProperties;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
@EnableCaching
@EnableScheduling
@EnableTransactionManagement

View File

@ -8,6 +8,6 @@ public class ApiDocController {
@GetMapping({ "/apidoc", "/api-doc", "/doc", "/swagger" })
public String apiDoc() {
return "redirect:swagger-ui/";
return "redirect:swagger-ui/index.html";
}
}

View File

@ -31,12 +31,12 @@ import eu.dnetlib.broker.common.elasticsearch.EventStatsManager.BrowseEntry;
import eu.dnetlib.broker.common.subscriptions.Subscription;
import eu.dnetlib.broker.common.subscriptions.SubscriptionRepository;
import eu.dnetlib.common.controller.AbstractDnetController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
@RestController
@RequestMapping("/api/events")
@Api(tags = LiteratureBrokerServiceApplication.TAG_EVENTS)
@Tag(name = LiteratureBrokerServiceApplication.TAG_EVENTS)
public class EventsController extends AbstractDnetController {
private static final Log log = LogFactory.getLog(AbstractDnetController.class);
@ -50,25 +50,25 @@ public class EventsController extends AbstractDnetController {
@Autowired
private EventStatsManager eventStatsManager;
@ApiOperation("Return an event by ID")
@Operation(summary = "Return an event by ID")
@GetMapping("/{id}")
public Event getEvent(@PathVariable final String id) {
return eventRepository.findById(id).get();
}
@ApiOperation("Delete an event by ID")
@Operation(summary = "Delete an event by ID")
@DeleteMapping("/{id}")
public void deleteEvent(@PathVariable final String id) {
eventRepository.deleteById(id);
}
@ApiOperation("Save an event by ID")
@Operation(summary = "Save an event by ID")
@PostMapping("/{id}")
public Event saveEvent(@RequestBody final Event event) {
return eventRepository.save(event);
}
@ApiOperation("Return a page of events")
@Operation(summary = "Return a page of events")
@GetMapping("/list/{page}/{pageSize}")
public List<Event> events(
@PathVariable final int page,
@ -76,7 +76,7 @@ public class EventsController extends AbstractDnetController {
return Lists.newArrayList(eventRepository.findAll(PageRequest.of(page, pageSize)));
}
@ApiOperation("Return a page of events by topic")
@Operation(summary = "Return a page of events by topic")
@GetMapping("/byTopic/{page}/{pageSize}")
public List<Event> eventsByTopic(
@PathVariable final int page,
@ -85,7 +85,7 @@ public class EventsController extends AbstractDnetController {
return Lists.newArrayList(eventRepository.findByTopic(topic, PageRequest.of(page, pageSize)));
}
@ApiOperation("Delete all the events")
@Operation(summary = "Delete all the events")
@DeleteMapping("/all")
public Map<String, Object> clearEvents() {
eventRepository.deleteAll();
@ -94,13 +94,13 @@ public class EventsController extends AbstractDnetController {
return res;
}
@ApiOperation("Delete the expired events")
@Operation(summary = "Delete the expired events")
@DeleteMapping("/expired")
public Map<String, Object> deleteExpiredEvents() {
return deleteEventsByExpiryDate(0, new Date().getTime());
}
@ApiOperation("Delete the events with the creationDate in a range")
@Operation(summary = "Delete the events with the creationDate in a range")
@DeleteMapping("/byCreationDate/{from}/{to}")
public Map<String, Long> deleteEventsByCreationDate(@PathVariable final long from, @PathVariable final long to) {
final Map<String, Long> res = new HashMap<>();
@ -113,7 +113,7 @@ public class EventsController extends AbstractDnetController {
return res;
}
@ApiOperation("Delete the events with the expiryDate in a range")
@Operation(summary = "Delete the events with the expiryDate in a range")
@DeleteMapping("/byExpiryDate/{from}/{to}")
public Map<String, Object> deleteEventsByExpiryDate(@PathVariable final long from, @PathVariable final long to) {
new Thread(() -> {
@ -128,13 +128,13 @@ public class EventsController extends AbstractDnetController {
return res;
}
@ApiOperation("Return the topics of the indexed events (all)")
@Operation(summary = "Return the topics of the indexed events (all)")
@GetMapping("/topics/all")
public List<BrowseEntry> browseTopics() {
return eventStatsManager.browseTopics();
}
@ApiOperation("Return the topics of the indexed events (only with subscriptions)")
@Operation(summary = "Return the topics of the indexed events (only with subscriptions)")
@GetMapping("/topics/withSubscriptions")
public List<BrowseEntry> browseTopicsWithSubscriptions() {

View File

@ -14,16 +14,15 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import eu.dnetlib.broker.LiteratureBrokerServiceApplication;
import eu.dnetlib.broker.common.elasticsearch.Notification;
import eu.dnetlib.broker.common.elasticsearch.NotificationRepository;
import eu.dnetlib.common.controller.AbstractDnetController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
@RestController
@RequestMapping("/api/notifications")
@Api(tags = LiteratureBrokerServiceApplication.TAG_NOTIFICATIONS)
@Tag(name = "LiteratureBrokerServiceApplication.TAG_NOTIFICATIONS")
public class NotificationsController extends AbstractDnetController {
private static final Log log = LogFactory.getLog(NotificationsController.class);
@ -31,31 +30,31 @@ public class NotificationsController extends AbstractDnetController {
@Autowired
private NotificationRepository notificationRepository;
@ApiOperation("Return a notification by ID")
@Operation(summary = "Return a notification by ID")
@GetMapping("/{id}")
public Notification getNotification(@PathVariable final String id) {
return notificationRepository.findById(id).get();
}
@ApiOperation("Delete a notification by ID")
@Operation(summary = "Delete a notification by ID")
@DeleteMapping("/{id}")
public void deleteNotification(@PathVariable final String id) {
notificationRepository.deleteById(id);
}
@ApiOperation("Save a notification by ID")
@Operation(summary = "Save a notification by ID")
@PostMapping("/{id}")
public Notification saveNotification(@RequestBody final Notification notification) {
return notificationRepository.save(notification);
}
@ApiOperation("Delete all notifications")
@Operation(summary = "Delete all notifications")
@DeleteMapping("")
public void deleteAllNotifications() {
notificationRepository.deleteAll();
}
@ApiOperation("Delete the notifications with the date in a range")
@Operation(summary = "Delete the notifications with the date in a range")
@DeleteMapping("/byDate/{from}/{to}")
public Map<String, Object> deleteNotificationsByDate(@PathVariable final long from, @PathVariable final long to) {
new Thread(() -> {

View File

@ -16,13 +16,13 @@ import eu.dnetlib.broker.common.subscriptions.Subscription;
import eu.dnetlib.broker.common.subscriptions.SubscriptionRepository;
import eu.dnetlib.broker.matchers.SubscriptionEventMatcher;
import eu.dnetlib.common.controller.AbstractDnetController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
@Profile("!openaire")
@RestController
@RequestMapping("/api/matching")
@Api(tags = LiteratureBrokerServiceApplication.TAG_MATCHING)
@Tag(name = LiteratureBrokerServiceApplication.TAG_MATCHING)
public class StartMatchingController extends AbstractDnetController {
@Autowired
@ -31,7 +31,7 @@ public class StartMatchingController extends AbstractDnetController {
@Autowired(required = false)
private SubscriptionEventMatcher subscriptionEventMatcher;
@ApiOperation("Launch the thread that produces new notifications")
@Operation(summary = "Launch the thread that produces new notifications")
@GetMapping("/start")
public List<String> startMatching() {
if (subscriptionEventMatcher != null) {
@ -42,7 +42,7 @@ public class StartMatchingController extends AbstractDnetController {
}
}
@ApiOperation("Launch the thread that produces new notifications by subscriptuion id")
@Operation(summary = "Launch the thread that produces new notifications by subscriptuion id")
@GetMapping("/start/{subscriptionId}")
public List<String> startMatching(@PathVariable final String subscriptionId) {
final Optional<Subscription> s = subscriptionRepo.findById(subscriptionId);

View File

@ -29,12 +29,12 @@ import eu.dnetlib.broker.common.subscriptions.NotificationMode;
import eu.dnetlib.broker.common.subscriptions.Subscription;
import eu.dnetlib.broker.common.subscriptions.SubscriptionRepository;
import eu.dnetlib.common.controller.AbstractDnetController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
@RestController
@RequestMapping("/api/subscriptions")
@Api(tags = LiteratureBrokerServiceApplication.TAG_SUBSCRIPTIONS)
@Tag(name = LiteratureBrokerServiceApplication.TAG_SUBSCRIPTIONS)
public class SubscriptionsController extends AbstractDnetController {
@Autowired
@ -53,26 +53,26 @@ public class SubscriptionsController extends AbstractDnetController {
}
};
@ApiOperation("Return the list of subscriptions")
@Operation(summary = "Return the list of subscriptions")
@GetMapping("")
public Iterable<Subscription> listSubscriptions() {
return subscriptionRepo.findAll();
}
@ApiOperation("Return a subscription by ID")
@Operation(summary = "Return a subscription by ID")
@GetMapping("/{id}")
public Subscription getSubscription(@PathVariable final String id) {
return subscriptionRepo.findById(id).get();
}
@ApiOperation("Delete a subscription by ID and its notifications")
@Operation(summary = "Delete a subscription by ID and its notifications")
@DeleteMapping("/{id}")
public void deleteSubscription(@PathVariable final String id) {
subscriptionRepo.deleteById(id);
notificationRepo.deleteBySubscriptionId(id);
}
@ApiOperation("Perform a new subscription")
@Operation(summary = "Perform a new subscription")
@PostMapping("")
public Subscription registerSubscription(@RequestBody final InSubscription inSub) {
final Subscription sub = inSub.asSubscription();
@ -80,7 +80,7 @@ public class SubscriptionsController extends AbstractDnetController {
return sub;
}
@ApiOperation("Delete all subscriptions and notifications")
@Operation(summary = "Delete all subscriptions and notifications")
@DeleteMapping("")
public Map<String, Object> clearSubscriptions() {
final Map<String, Object> res = new HashMap<>();
@ -90,7 +90,7 @@ public class SubscriptionsController extends AbstractDnetController {
return res;
}
@ApiOperation("Reset the last notification date")
@Operation(summary = "Reset the last notification date")
@DeleteMapping("/{id}/date")
public void deleteNotificationDate(@PathVariable final String id) {
final Subscription s = subscriptionRepo.findById(id).get();
@ -98,7 +98,7 @@ public class SubscriptionsController extends AbstractDnetController {
subscriptionRepo.save(s);
}
@ApiOperation("Reset all the last notification dates")
@Operation(summary = "Reset all the last notification dates")
@GetMapping("/resetLastNotificationDates")
public void deleteAllNotificationDates() {
for (final Subscription s : subscriptionRepo.findAll()) {

View File

@ -22,12 +22,12 @@ import eu.dnetlib.broker.LiteratureBrokerServiceApplication;
import eu.dnetlib.broker.common.topics.TopicType;
import eu.dnetlib.broker.common.topics.TopicTypeRepository;
import eu.dnetlib.common.controller.AbstractDnetController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
@RestController
@RequestMapping("/api/topic-types")
@Api(tags = LiteratureBrokerServiceApplication.TAG_TOPIC_TYPES)
@Tag(name = LiteratureBrokerServiceApplication.TAG_TOPIC_TYPES)
public class TopicsController extends AbstractDnetController {
@Autowired
@ -36,13 +36,13 @@ public class TopicsController extends AbstractDnetController {
private final Predicate<String> verifyExpression =
Pattern.compile("^([a-zA-Z0-9._-]+|<[a-zA-Z0-9._-]+>)(\\/([a-zA-Z0-9._-]+|<[a-zA-Z0-9._-]+>))+$").asPredicate();
@ApiOperation("Return the list of topic types")
@Operation(summary = "Return the list of topic types")
@GetMapping("")
public Iterable<TopicType> listTopicTypes() {
return topicTypeRepo.findAll();
}
@ApiOperation("Register a new topic type")
@Operation(summary = "Register a new topic type")
@PostMapping("/add")
public TopicType registerTopicType(@RequestParam final String name,
@RequestParam final String expression,
@ -61,20 +61,20 @@ public class TopicsController extends AbstractDnetController {
return type;
}
@ApiOperation("Return a topic type by ID")
@Operation(summary = "Return a topic type by ID")
@GetMapping("/{id}")
public TopicType getTopicType(@PathVariable final String id) {
return topicTypeRepo.findById(id).get();
}
@ApiOperation("Delete a topic type by ID")
@Operation(summary = "Delete a topic type by ID")
@DeleteMapping("/{id}")
public List<String> deleteTopicType(@PathVariable final String id) {
topicTypeRepo.deleteById(id);
return Arrays.asList("Done.");
}
@ApiOperation("Delete all topic types")
@Operation(summary = "Delete all topic types")
@DeleteMapping("")
public Map<String, Object> clearTopicTypes() {
final Map<String, Object> res = new HashMap<>();

View File

@ -56,13 +56,13 @@ import eu.dnetlib.broker.common.subscriptions.SubscriptionRepository;
import eu.dnetlib.broker.events.output.DispatcherManager;
import eu.dnetlib.broker.objects.OaBrokerEventPayload;
import eu.dnetlib.common.controller.AbstractDnetController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
@Profile("openaire")
@RestController
@RequestMapping("/api/openaireBroker")
@Api(tags = LiteratureBrokerServiceApplication.TAG_OPENAIRE)
@Tag(name = LiteratureBrokerServiceApplication.TAG_OPENAIRE)
public class OpenaireBrokerController extends AbstractDnetController {
@Autowired
@ -85,7 +85,7 @@ public class OpenaireBrokerController extends AbstractDnetController {
private static final Log log = LogFactory.getLog(OpenaireBrokerController.class);
@ApiOperation("Return the datasources having events")
@Operation(summary = "Return the datasources having events")
@GetMapping("/datasources")
public List<BrowseEntry> findDatasourcesWithEvents(@RequestParam(defaultValue = "false", required = false) final boolean useIndex) {
return useIndex ? findDatasourcesWithEventsUsingIndex() : findDatasourcesWithEventsUsingDb();
@ -123,7 +123,7 @@ public class OpenaireBrokerController extends AbstractDnetController {
}
}
@ApiOperation("Return the topics of the events of a datasource")
@Operation(summary = "Return the topics of the events of a datasource")
@GetMapping("/topicsForDatasource")
public List<BrowseEntry> findTopicsForDatasource(@RequestParam final String ds,
@RequestParam(defaultValue = "false", required = false) final boolean useIndex) {
@ -163,7 +163,7 @@ public class OpenaireBrokerController extends AbstractDnetController {
}
}
@ApiOperation("Return a page of events of a datasource (by topic)")
@Operation(summary = "Return a page of events of a datasource (by topic)")
@GetMapping("/events/{nPage}/{size}")
public EventsPage showEvents(@RequestParam final String ds, @RequestParam final String topic, @PathVariable final int nPage, @PathVariable final int size) {
@ -191,7 +191,7 @@ public class OpenaireBrokerController extends AbstractDnetController {
return new EventsPage(ds, topic, nPage, overrideGetTotalPage(page, size), page.getTotalHits(), list);
}
@ApiOperation("Return a page of events of a datasource (by query)")
@Operation(summary = "Return a page of events of a datasource (by query)")
@PostMapping("/events/{nPage}/{size}")
public EventsPage advancedShowEvents(@PathVariable final int nPage, @PathVariable final int size, @RequestBody final AdvQueryObject qObj) {
@ -227,7 +227,7 @@ public class OpenaireBrokerController extends AbstractDnetController {
return new EventsPage(qObj.getDatasource(), qObj.getTopic(), nPage, overrideGetTotalPage(page, size), page.getTotalHits(), list);
}
@ApiOperation("Perform a subscription")
@Operation(summary = "Perform a subscription")
@PostMapping("/subscribe")
public Subscription registerSubscription(@RequestBody final OpenaireSubscription oSub) {
final Subscription sub = oSub.asSubscription();
@ -237,7 +237,7 @@ public class OpenaireBrokerController extends AbstractDnetController {
return sub;
}
@ApiOperation("Return the subscriptions of an user (by email and datasource (optional))")
@Operation(summary = "Return the subscriptions of an user (by email and datasource (optional))")
@GetMapping("/subscriptions")
public Map<String, List<SimpleSubscriptionDesc>> subscriptions(@RequestParam final String email, @RequestParam(required = false) final String ds) {
final Iterable<Subscription> iter = subscriptionRepo.findBySubscriber(email);
@ -247,7 +247,7 @@ public class OpenaireBrokerController extends AbstractDnetController {
.collect(Collectors.groupingBy(SimpleSubscriptionDesc::getDatasource));
}
@ApiOperation("Return a page of notifications")
@Operation(summary = "Return a page of notifications")
@GetMapping("/notifications/{subscrId}/{nPage}/{size}")
public EventsPage notifications(@PathVariable final String subscrId, @PathVariable final int nPage, @PathVariable final int size) {
@ -279,14 +279,14 @@ public class OpenaireBrokerController extends AbstractDnetController {
}
@ApiOperation("Send notifications")
@Operation(summary = "Send notifications")
@GetMapping("/notifications/send/{date}")
private List<String> sendMailForNotifications(@PathVariable final long date) {
new Thread(() -> innerSendMailForNotifications(date)).start();
return Arrays.asList("Sending ...");
}
@ApiOperation("Update stats")
@Operation(summary = "Update stats")
@GetMapping("/stats/update")
private List<String> updateStats() {
new Thread(() -> {

View File

@ -1,5 +1,8 @@
spring.profiles.active = dev,openaire
server.public_url =
server.public_desc = API Base URL
#logging.level.root=DEBUG
maven.pom.path = /META-INF/maven/eu.dnetlib.dhp/dhp-broker-application/effective-pom.xml

View File

@ -27,7 +27,7 @@
<a class="nav-link dropdown-toggle" href="javascript:void(0)" data-toggle="dropdown">Tools <span class="caret"></span></a>
<div class="dropdown-menu dropdown-menu-right">
<a class="dropdown-item" href="{{t.url}}" target="_blank" ng-repeat="t in tools">{{t.name}}</a>
<a class="dropdown-item" href="/swagger-ui/" target="_blank">API documentation</a>
<a class="dropdown-item" href="/apidoc" target="_blank">API documentation</a>
</div>
</li>
</ul>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>eu.dnetlib.dhp</groupId>
<artifactId>apps</artifactId>
<version>3.2.9-SNAPSHOT</version>
<version>3.3.3-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -16,10 +16,8 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
import eu.dnetlib.broker.common.elasticsearch.Event;
import eu.dnetlib.broker.common.elasticsearch.Notification;
import eu.dnetlib.broker.common.properties.ElasticSearchProperties;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
@EnableCaching
@EnableScheduling
@EnableTransactionManagement

View File

@ -1,14 +1,15 @@
package eu.dnetlib.broker;
import java.util.Arrays;
import java.util.List;
import org.springdoc.core.GroupedOpenApi;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import eu.dnetlib.common.app.AbstractDnetApp;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Tag;
import springfox.documentation.spring.web.plugins.Docket;
import io.swagger.v3.oas.models.tags.Tag;
@SpringBootApplication
public class BrokerPublicApplication extends AbstractDnetApp {
@ -19,22 +20,22 @@ public class BrokerPublicApplication extends AbstractDnetApp {
SpringApplication.run(BrokerPublicApplication.class, args);
}
@Override
protected void configSwagger(final Docket docket) {
docket.select()
.apis(RequestHandlerSelectors.any())
.paths(p -> p.startsWith("/"))
.build()
.tags(new Tag(OA_PUBLIC_APIS, OA_PUBLIC_APIS))
.apiInfo(new ApiInfoBuilder()
.title("OpenAIRE Public Broker API")
.description("APIs documentation")
.version("1.1")
.contact(ApiInfo.DEFAULT_CONTACT)
.license("Apache 2.0")
.licenseUrl("http://www.apache.org/licenses/LICENSE-2.0")
.build());
@Bean
public GroupedOpenApi publicApi() {
return GroupedOpenApi.builder()
.group("Broker Public APIs")
.pathsToMatch("/**")
.build();
}
@Override
protected String swaggerTitle() {
return "OpenAIRE Public Broker API";
}
@Override
protected List<Tag> swaggerTags() {
return Arrays.asList(new Tag().name(OA_PUBLIC_APIS).description(OA_PUBLIC_APIS));
}
}

View File

@ -8,6 +8,6 @@ public class ApiDocController {
@GetMapping({ "/apidoc", "/api-doc", "/doc", "/swagger" })
public String apiDoc() {
return "redirect:swagger-ui/";
return "redirect:swagger-ui/index.html";
}
}

View File

@ -63,13 +63,13 @@ import eu.dnetlib.broker.common.subscriptions.Subscription;
import eu.dnetlib.broker.common.subscriptions.SubscriptionRepository;
import eu.dnetlib.broker.objects.OaBrokerEventPayload;
import eu.dnetlib.common.controller.AbstractDnetController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
@Profile("openaire")
@RestController
@RequestMapping("/")
@Api(tags = BrokerPublicApplication.OA_PUBLIC_APIS)
@Tag(name = BrokerPublicApplication.OA_PUBLIC_APIS)
public class OpenairePublicController extends AbstractDnetController {
@Autowired
@ -97,7 +97,7 @@ public class OpenairePublicController extends AbstractDnetController {
private static final Log log = LogFactory.getLog(OpenairePublicController.class);
@ApiOperation("Returns notifications by subscription using scrolls (first page)")
@Operation(summary = "Returns notifications by subscription using scrolls (first page)")
@GetMapping("/scroll/notifications/bySubscriptionId/{subscrId}")
public ScrollPage<ShortEventMessage> prepareScrollNotificationsBySubscrId(@PathVariable final String subscrId) {
@ -130,7 +130,7 @@ public class OpenairePublicController extends AbstractDnetController {
}
}
@ApiOperation("Returns notifications using scrolls (other pages)")
@Operation(summary = "Returns notifications using scrolls (other pages)")
@GetMapping("/scroll/notifications/{scrollId}")
public ScrollPage<ShortEventMessage> scrollNotifications(@PathVariable final String scrollId) {
@ -147,7 +147,7 @@ public class OpenairePublicController extends AbstractDnetController {
}
}
@ApiOperation("Returns notifications as file")
@Operation(summary = "Returns notifications as file")
@GetMapping(value = "/file/notifications/bySubscriptionId/{subscrId}", produces = "application/gzip")
public void notificationsAsFile(final HttpServletResponse res, @PathVariable final String subscrId) throws Exception {
@ -184,7 +184,7 @@ public class OpenairePublicController extends AbstractDnetController {
}
@ApiOperation("Returns events as file by opendoarId")
@Operation(summary = "Returns events as file by opendoarId")
@GetMapping(value = "/file/events/opendoar/{id}", produces = "application/gzip")
public void opendoarEventsAsFile(final HttpServletResponse res, @PathVariable final String id) {
@ -252,13 +252,13 @@ public class OpenairePublicController extends AbstractDnetController {
return first;
}
@ApiOperation("Returns the list of subscriptions by user email")
@Operation(summary = "Returns the list of subscriptions by user email")
@GetMapping(value = "/subscriptions")
private Iterable<Subscription> listSubscriptionsByUser(@RequestParam final String email) {
return subscriptionRepo.findBySubscriber(email);
}
@ApiOperation("Returns the status of the application")
@Operation(summary = "Returns the status of the application")
@GetMapping(value = "/status")
private Map<String, Long> status() {
final Map<String, Long> res = new LinkedHashMap<>();
@ -269,7 +269,7 @@ public class OpenairePublicController extends AbstractDnetController {
return res;
}
@ApiOperation("Store the feedback of an event (MOCK)")
@Operation(summary = "Store the feedback of an event (MOCK)")
@RequestMapping(value = "/feedback/events", method = {
RequestMethod.POST, RequestMethod.PATCH
})

View File

@ -1,5 +1,8 @@
spring.profiles.active = dev,openaire
server.public_url =
server.public_desc = API Base URL
#logging.level.root=DEBUG
maven.pom.path = /META-INF/maven/eu.dnetlib.dhp/dhp-broker-public-application/effective-pom.xml

View File

@ -2,6 +2,6 @@
<html>
<head>
<title>OpenAIRE Broker Public API</title>
<meta http-equiv="refresh" content="2; url = ./swagger" />
<meta http-equiv="refresh" content="2; url = ./apidoc" />
</head>
</html>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>eu.dnetlib.dhp</groupId>
<artifactId>apps</artifactId>
<version>3.2.9-SNAPSHOT</version>
<version>3.3.3-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -1,53 +1,36 @@
package eu.dnetlib.data.mdstore.manager;
import org.springframework.beans.factory.annotation.Value;
import org.springdoc.core.GroupedOpenApi;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.EnableScheduling;
import eu.dnetlib.common.app.AbstractDnetApp;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@SpringBootApplication
@EnableSwagger2
@EnableCaching
@EnableScheduling
@EntityScan("eu.dnetlib.dhp.schema.mdstore")
public class MainApplication extends AbstractDnetApp {
@Value("${dhp.swagger.api.host}")
private String swaggetHost;
@Value("${dhp.swagger.api.basePath}")
private String swaggerPath;
public static void main(final String[] args) {
SpringApplication.run(MainApplication.class, args);
}
@Bean
public GroupedOpenApi publicApi() {
return GroupedOpenApi.builder()
.group("MDStore APIs")
.pathsToMatch("/mdstores/**")
.build();
}
@Override
protected void configSwagger(final Docket docket) {
docket
.host(swaggetHost)
.pathMapping(swaggerPath)
.select()
.apis(RequestHandlerSelectors.any())
.paths(p -> p.contains("/mdstores"))
.build()
.apiInfo(new ApiInfoBuilder()
.title("MDStore Manager APIs")
.description("APIs documentation")
.version("1.1")
.contact(ApiInfo.DEFAULT_CONTACT)
.license("Apache 2.0")
.licenseUrl("http://www.apache.org/licenses/LICENSE-2.0")
.build());
protected String swaggerTitle() {
return "MDStore Manager APIs";
}
}

View File

@ -23,15 +23,13 @@ import eu.dnetlib.data.mdstore.manager.utils.DatabaseUtils;
import eu.dnetlib.data.mdstore.manager.utils.HdfsClient;
import eu.dnetlib.dhp.schema.mdstore.MDStoreVersion;
import eu.dnetlib.dhp.schema.mdstore.MDStoreWithInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
@RestController
@RequestMapping("/mdstores")
@Api(tags = {
"Metadata Stores"
})
@Tag(name = "Metadata Stores")
public class MDStoreController extends AbstractDnetController {
@Autowired
@ -42,67 +40,67 @@ public class MDStoreController extends AbstractDnetController {
private static final Logger log = LoggerFactory.getLogger(DatabaseUtils.class);
@ApiOperation("Return all the mdstores")
@Operation(summary = "Return all the mdstores")
@GetMapping("/")
public Iterable<MDStoreWithInfo> find() {
return databaseUtils.listMdStores();
}
@ApiOperation("Return all the mdstore identifiers")
@Operation(summary = "Return all the mdstore identifiers")
@GetMapping("/ids")
public List<String> findIdentifiers() {
return databaseUtils.listMdStoreIDs();
}
@ApiOperation("Return a mdstores by id")
@Operation(summary = "Return a mdstores by id")
@GetMapping("/mdstore/{mdId}")
public MDStoreWithInfo getMdStore(@ApiParam("the mdstore identifier") @PathVariable final String mdId) throws MDStoreManagerException {
public MDStoreWithInfo getMdStore(@Parameter(name = "the mdstore identifier") @PathVariable final String mdId) throws MDStoreManagerException {
return databaseUtils.findMdStore(mdId);
}
@ApiOperation("Increase the read count of the current mdstore")
@Operation(summary = "Increase the read count of the current mdstore")
@GetMapping("/mdstore/{mdId}/startReading")
public MDStoreVersion startReading(@ApiParam("the mdstore identifier") @PathVariable final String mdId) throws MDStoreManagerException {
public MDStoreVersion startReading(@Parameter(name = "the mdstore identifier") @PathVariable final String mdId) throws MDStoreManagerException {
return databaseUtils.startReading(mdId);
}
@ApiOperation("Create a new mdstore")
@Operation(summary = "Create a new mdstore")
@GetMapping("/new/{format}/{layout}/{interpretation}")
public MDStoreWithInfo createMDStore(
@ApiParam("mdstore format") @PathVariable final String format,
@ApiParam("mdstore layout") @PathVariable final String layout,
@ApiParam("mdstore interpretation") @PathVariable final String interpretation,
@ApiParam("datasource name") @RequestParam(required = true) final String dsName,
@ApiParam("datasource id") @RequestParam(required = true) final String dsId,
@ApiParam("api id") @RequestParam(required = true) final String apiId) throws MDStoreManagerException {
@Parameter(name = "mdstore format") @PathVariable final String format,
@Parameter(name = "mdstore layout") @PathVariable final String layout,
@Parameter(name = "mdstore interpretation") @PathVariable final String interpretation,
@Parameter(name = "datasource name") @RequestParam(required = true) final String dsName,
@Parameter(name = "datasource id") @RequestParam(required = true) final String dsId,
@Parameter(name = "api id") @RequestParam(required = true) final String apiId) throws MDStoreManagerException {
final String id = databaseUtils.createMDStore(format, layout, interpretation, dsName, dsId, apiId);
return databaseUtils.findMdStore(id);
}
@ApiOperation("Delete a mdstore by id")
@Operation(summary = "Delete a mdstore by id")
@DeleteMapping("/mdstore/{mdId}")
public StatusResponse delete(@ApiParam("the id of the mdstore that will be deleted") @PathVariable final String mdId) throws MDStoreManagerException {
public StatusResponse delete(@Parameter(name = "the id of the mdstore that will be deleted") @PathVariable final String mdId) throws MDStoreManagerException {
final String hdfsPath = databaseUtils.deleteMdStore(mdId);
hdfsClient.deletePath(hdfsPath);
return StatusResponse.DELETED;
}
@ApiOperation("Return all the versions of a mdstore")
@Operation(summary = "Return all the versions of a mdstore")
@GetMapping("/mdstore/{mdId}/versions")
public Iterable<MDStoreVersion> listVersions(@PathVariable final String mdId) throws MDStoreManagerException {
return databaseUtils.listVersions(mdId);
}
@ApiOperation("Create a new preliminary version of a mdstore")
@Operation(summary = "Create a new preliminary version of a mdstore")
@GetMapping("/mdstore/{mdId}/newVersion")
public MDStoreVersion prepareNewVersion(@ApiParam("the id of the mdstore for which will be created a new version") @PathVariable final String mdId) {
public MDStoreVersion prepareNewVersion(@Parameter(name = "the id of the mdstore for which will be created a new version") @PathVariable final String mdId) {
return databaseUtils.prepareMdStoreVersion(mdId);
}
@ApiOperation("Promote a preliminary version to current")
@Operation(summary = "Promote a preliminary version to current")
@GetMapping("/version/{versionId}/commit/{size}")
public MDStoreVersion commitVersion(@ApiParam("the id of the version that will be promoted to the current version") @PathVariable final String versionId,
@ApiParam("the size of the new current mdstore") @PathVariable final long size) throws MDStoreManagerException {
public MDStoreVersion commitVersion(@Parameter(name = "the id of the version that will be promoted to the current version") @PathVariable final String versionId,
@Parameter(name = "the size of the new current mdstore") @PathVariable final long size) throws MDStoreManagerException {
try {
return databaseUtils.commitMdStoreVersion(versionId, size);
} finally {
@ -110,46 +108,46 @@ public class MDStoreController extends AbstractDnetController {
}
}
@ApiOperation("Abort a preliminary version")
@Operation(summary = "Abort a preliminary version")
@GetMapping("/version/{versionId}/abort")
public StatusResponse commitVersion(@ApiParam("the id of the version to abort") @PathVariable final String versionId) throws MDStoreManagerException {
public StatusResponse commitVersion(@Parameter(name = "the id of the version to abort") @PathVariable final String versionId) throws MDStoreManagerException {
final String hdfsPath = databaseUtils.deleteMdStoreVersion(versionId, true);
hdfsClient.deletePath(hdfsPath);
return StatusResponse.ABORTED;
}
@ApiOperation("Return an existing mdstore version")
@Operation(summary = "Return an existing mdstore version")
@GetMapping("/version/{versionId}")
public MDStoreVersion getVersion(@ApiParam("the id of the version that has to be deleted") @PathVariable final String versionId)
public MDStoreVersion getVersion(@Parameter(name = "the id of the version that has to be deleted") @PathVariable final String versionId)
throws MDStoreManagerException {
return databaseUtils.findVersion(versionId);
}
@ApiOperation("Delete a mdstore version")
@Operation(summary = "Delete a mdstore version")
@DeleteMapping("/version/{versionId}")
public StatusResponse deleteVersion(@ApiParam("the id of the version that has to be deleted") @PathVariable final String versionId,
@ApiParam("if true, the controls on writing and readcount values will be skipped") @RequestParam(required = false, defaultValue = "false") final boolean force)
public StatusResponse deleteVersion(@Parameter(name = "the id of the version that has to be deleted") @PathVariable final String versionId,
@Parameter(name = "if true, the controls on writing and readcount values will be skipped") @RequestParam(required = false, defaultValue = "false") final boolean force)
throws MDStoreManagerException {
final String hdfsPath = databaseUtils.deleteMdStoreVersion(versionId, force);
hdfsClient.deletePath(hdfsPath);
return StatusResponse.DELETED;
}
@ApiOperation("Decrease the read count of a mdstore version")
@Operation(summary = "Decrease the read count of a mdstore version")
@GetMapping("/version/{versionId}/endReading")
public MDStoreVersion endReading(@ApiParam("the id of the version that has been completely read") @PathVariable final String versionId)
public MDStoreVersion endReading(@Parameter(name = "the id of the version that has been completely read") @PathVariable final String versionId)
throws MDStoreManagerException {
return databaseUtils.endReading(versionId);
}
@ApiOperation("Reset the read count of a mdstore version")
@Operation(summary = "Reset the read count of a mdstore version")
@GetMapping("/version/{versionId}/resetReading")
public MDStoreVersion resetReading(@ApiParam("the id of the version") @PathVariable final String versionId)
public MDStoreVersion resetReading(@Parameter(name = "the id of the version") @PathVariable final String versionId)
throws MDStoreManagerException {
return databaseUtils.resetReading(versionId);
}
@ApiOperation("Delete expired versions")
@Operation(summary = "Delete expired versions")
@DeleteMapping("/versions/expired")
public StatusResponse deleteExpiredVersions() {
new Thread(this::performDeleteOfExpiredVersions).start();
@ -169,10 +167,10 @@ public class MDStoreController extends AbstractDnetController {
log.info("Done.");
}
@ApiOperation("Fix the inconsistencies on HDFS")
@Operation(summary = "Fix the inconsistencies on HDFS")
@GetMapping("/hdfs/inconsistencies")
public Set<String> fixHdfsInconsistencies(
@ApiParam("force the deletion of hdfs paths") @RequestParam(required = false, defaultValue = "false") final boolean delete)
@Parameter(name = "force the deletion of hdfs paths") @RequestParam(required = false, defaultValue = "false") final boolean delete)
throws MDStoreManagerException {
final Set<String> hdfsDirs = hdfsClient.listHadoopDirs();
@ -189,7 +187,7 @@ public class MDStoreController extends AbstractDnetController {
return toDelete;
}
@ApiOperation("Show informations")
@Operation(summary = "Show informations")
@GetMapping("/info")
public Map<String, Object> info() {
final Map<String, Object> info = new LinkedHashMap<>();
@ -201,21 +199,21 @@ public class MDStoreController extends AbstractDnetController {
return info;
}
@ApiOperation("list the file inside the path of a mdstore version")
@Operation(summary = "list the file inside the path of a mdstore version")
@GetMapping("/version/{versionId}/parquet/files")
public Set<String> listVersionFiles(@PathVariable final String versionId) throws MDStoreManagerException {
final String path = databaseUtils.findVersion(versionId).getHdfsPath();
return hdfsClient.listContent(path + "/store", HdfsClient::isParquetFile);
}
@ApiOperation("read the parquet file of a mdstore version")
@Operation(summary = "read the parquet file of a mdstore version")
@GetMapping("/version/{versionId}/parquet/content/{limit}")
public List<Map<String, String>> listVersionParquet(@PathVariable final String versionId, @PathVariable final long limit) throws MDStoreManagerException {
final String path = databaseUtils.findVersion(versionId).getHdfsPath();
return hdfsClient.readParquetFiles(path + "/store", limit);
}
@ApiOperation("read the parquet file of a mdstore (current version)")
@Operation(summary = "read the parquet file of a mdstore (current version)")
@GetMapping("/mdstore/{mdId}/parquet/content/{limit}")
public List<Map<String, String>> listMdstoreParquet(@PathVariable final String mdId, @PathVariable final long limit) throws MDStoreManagerException {
final String versionId = databaseUtils.findMdStore(mdId).getCurrentVersion();

View File

@ -11,6 +11,6 @@ public class SwaggerController {
"/apidoc", "/api-doc", "/doc", "/swagger"
}, method = RequestMethod.GET)
public String apiDoc() {
return "redirect:swagger-ui/";
return "redirect:swagger-ui/index.html";
}
}

View File

@ -1,5 +1,8 @@
spring.main.banner-mode = console
server.public_url =
server.public_desc = API Base URL
logging.level.root = INFO
maven.pom.path = /META-INF/maven/eu.dnetlib.dhp/dhp-mdstore-manager/effective-pom.xml
@ -42,5 +45,5 @@ dhp.mdstore-manager.hadoop.zeppelin.name-prefix = mdstoreManager
dhp.mdstore-manager.inspector.records.max = 1000
dhp.swagger.api.host = localhost
dhp.swagger.api.basePath = /
# dhp.swagger.api.host = localhost
dhp.swagger.api.basePath = /**

View File

@ -20,7 +20,7 @@
<h1>Metadata Store Manager</h1>
<hr />
<a href="./swagger-ui/" target="_blank">API documentation</a>
<a href="./apidoc" target="_blank">API documentation</a>
<hr />
<a href="javascript:void(0)" data-toggle="modal" data-target="#newMdstoreModal">create a new mdstore</a>
<hr />

View File

@ -3,7 +3,7 @@
<parent>
<groupId>eu.dnetlib.dhp</groupId>
<artifactId>apps</artifactId>
<version>3.2.9-SNAPSHOT</version>
<version>3.3.3-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>

View File

@ -1,19 +1,15 @@
package eu.dnetlib;
import static springfox.documentation.builders.RequestHandlerSelectors.basePackage;
import java.time.LocalDate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springdoc.core.GroupedOpenApi;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.solr.SolrAutoConfiguration;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.EnableScheduling;
import eu.dnetlib.DnetOpenaireExporterProperties.Swagger;
import eu.dnetlib.common.app.AbstractDnetApp;
import eu.dnetlib.openaire.community.CommunityApiController;
import eu.dnetlib.openaire.context.ContextApiController;
@ -21,16 +17,9 @@ import eu.dnetlib.openaire.dsm.DsmApiController;
import eu.dnetlib.openaire.funders.FundersApiController;
import eu.dnetlib.openaire.info.InfoController;
import eu.dnetlib.openaire.project.ProjectsController;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@EnableCaching
@EnableScheduling
@EnableSwagger2
@SpringBootApplication
@EnableAutoConfiguration(exclude = {
SolrAutoConfiguration.class
@ -43,67 +32,56 @@ public class DNetOpenaireExporterApplication extends AbstractDnetApp {
SpringApplication.run(DNetOpenaireExporterApplication.class, args);
}
@Autowired
private DnetOpenaireExporterProperties config;
@Bean
public Docket dsm() {
return _docket("Datasource Manager", DsmApiController.class.getPackage().getName(), config.getSwaggerDsm(), V1);
}
@Bean
public Docket projects() {
return _docket("OpenAIRE Projects", ProjectsController.class.getPackage().getName(), config.getSwaggerProjects(), V1);
}
@Bean
public Docket funders() {
return _docket("OpenAIRE Funders", FundersApiController.class.getPackage().getName(), config.getSwaggerFunders(), V1);
}
@Bean
public Docket communities() {
return _docket("OpenAIRE Communities", CommunityApiController.class.getPackage().getName(), config.getSwaggerCommunities(), V1);
}
@Bean
public Docket contexts() {
return _docket("OpenAIRE Contexts", ContextApiController.class.getPackage().getName(), config.getSwaggerCommunities(), V1);
}
private Docket _docket(final String groupName, final String controllerPackage, final Swagger swag, final String version) {
final Docket d = new Docket(DocumentationType.SWAGGER_2);
configSwagger(d, groupName, controllerPackage, swag, version);
return d;
@Override
protected String swaggerTitle() {
return "D-Net Exporter APIs";
}
@Override
protected void configSwagger(final Docket docket) {
configSwagger(docket, "OpenAIRE Info", InfoController.class.getPackage().getName(), config.getSwaggerInfo(), V1);
protected String swaggerVersion() {
return V1;
}
private void configSwagger(final Docket docket, final String groupName, final String controllerPackage, final Swagger swag, final String version) {
docket
.groupName(groupName)
.select()
.apis(basePackage(controllerPackage))
.build()
.directModelSubstitute(LocalDate.class, java.sql.Date.class)
.apiInfo(apiInfo(swag, version));
@Bean
@ConditionalOnProperty(value = "openaire.exporter.enable.dsm", havingValue = "true")
public GroupedOpenApi dsm() {
return newGroupedOpenApi("Datasource Manager", DsmApiController.class.getPackage().getName());
}
private ApiInfo apiInfo(final Swagger swag, final String version) {
return new ApiInfoBuilder()
.title(swag.getApiTitle())
.description(swag.getApiDescription())
.license(swag.getApiLicense())
.licenseUrl(swag.getApiLicenseUrl())
.termsOfServiceUrl("")
.version(version)
.contact(new Contact(
swag.getApiContactName(),
swag.getApiContactUrl(),
swag.getApiContactEmail()))
@Bean
@ConditionalOnProperty(value = "openaire.exporter.enable.project", havingValue = "true")
public GroupedOpenApi projects() {
return newGroupedOpenApi("OpenAIRE Projects", ProjectsController.class.getPackage().getName());
}
@Bean
@ConditionalOnProperty(value = "openaire.exporter.enable.funders", havingValue = "true")
public GroupedOpenApi funders() {
return newGroupedOpenApi("OpenAIRE Funders", FundersApiController.class.getPackage().getName());
}
@Bean
@ConditionalOnProperty(value = "openaire.exporter.enable.community", havingValue = "true")
public GroupedOpenApi communities() {
return newGroupedOpenApi("OpenAIRE Communities", CommunityApiController.class.getPackage().getName());
}
@Bean
@ConditionalOnProperty(value = "openaire.exporter.enable.context", havingValue = "true")
public GroupedOpenApi contexts() {
return newGroupedOpenApi("OpenAIRE Contexts", ContextApiController.class.getPackage().getName());
}
@Bean
@ConditionalOnProperty(value = "openaire.exporter.enable.info", havingValue = "true")
public GroupedOpenApi info() {
return newGroupedOpenApi("OpenAIRE Info", InfoController.class.getPackage().getName());
}
private GroupedOpenApi newGroupedOpenApi(final String groupName, final String controllerPackage) {
return GroupedOpenApi.builder()
.group(groupName)
.packagesToScan(controllerPackage)
.build();
}

View File

@ -40,12 +40,6 @@ public class DnetOpenaireExporterProperties {
private Datasource datasource;
private Project project;
private Jdbc jdbc;
private Swagger swaggerDsm;
private Swagger swaggerProjects;
private Swagger swaggerFunders;
private Swagger swaggerCommunities;
private Swagger swaggerContexts;
private Swagger swaggerInfo;
private Vocabularies vocabularies;
@ -485,54 +479,6 @@ public class DnetOpenaireExporterProperties {
this.jdbc = jdbc;
}
public Swagger getSwaggerDsm() {
return swaggerDsm;
}
public void setSwaggerDsm(final Swagger swaggerDsm) {
this.swaggerDsm = swaggerDsm;
}
public Swagger getSwaggerProjects() {
return swaggerProjects;
}
public void setSwaggerProjects(final Swagger swaggerProjects) {
this.swaggerProjects = swaggerProjects;
}
public Swagger getSwaggerFunders() {
return swaggerFunders;
}
public void setSwaggerFunders(final Swagger swaggerFunders) {
this.swaggerFunders = swaggerFunders;
}
public Swagger getSwaggerCommunities() {
return swaggerCommunities;
}
public void setSwaggerCommunities(final Swagger swaggerCommunities) {
this.swaggerCommunities = swaggerCommunities;
}
public Swagger getSwaggerContexts() {
return swaggerContexts;
}
public void setSwaggerContexts(final Swagger swaggerContexts) {
this.swaggerContexts = swaggerContexts;
}
public Swagger getSwaggerInfo() {
return swaggerInfo;
}
public void setSwaggerInfo(final Swagger swaggerInfo) {
this.swaggerInfo = swaggerInfo;
}
public Vocabularies getVocabularies() {
return vocabularies;
}

View File

@ -7,10 +7,10 @@ import org.springframework.web.bind.annotation.RequestMapping;
public class SwaggerController {
@RequestMapping(value = {
"/", "/docs", "swagger-ui.html"
"/", "/docs", "swagger-ui.html", "swagger-ui/"
})
public String index() {
return "redirect:swagger-ui/";
return "redirect:swagger-ui/index.html";
}
}

View File

@ -3,12 +3,9 @@ package eu.dnetlib.openaire.common;
import java.util.List;
import java.util.stream.Collectors;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import eu.dnetlib.enabling.datasources.common.DsmException;
import eu.dnetlib.enabling.datasources.common.DsmForbiddenException;
import eu.dnetlib.enabling.datasources.common.DsmNotFoundException;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.commons.lang3.time.StopWatch;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.http.HttpStatus;
@ -17,6 +14,13 @@ import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import eu.dnetlib.enabling.datasources.common.DsmException;
import eu.dnetlib.enabling.datasources.common.DsmForbiddenException;
import eu.dnetlib.enabling.datasources.common.DsmNotFoundException;
import eu.dnetlib.openaire.dsm.domain.Response;
/**
* Created by claudio on 18/07/2017.
*/
@ -25,7 +29,9 @@ public abstract class AbstractExporterController {
private static final Log log = LogFactory.getLog(AbstractExporterController.class); // NOPMD by marko on 11/24/08 5:02 PM
@ResponseBody
@ExceptionHandler({DsmException.class})
@ExceptionHandler({
DsmException.class
})
@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
public ErrorMessage handleDSMException(final Exception e) {
return _handleError(e);
@ -39,7 +45,9 @@ public abstract class AbstractExporterController {
}
@ResponseBody
@ExceptionHandler({DsmNotFoundException.class})
@ExceptionHandler({
DsmNotFoundException.class
})
@ResponseStatus(value = HttpStatus.NOT_FOUND)
public ErrorMessage handleNotFoundException(final Exception e) {
return _handleError(e);
@ -50,23 +58,33 @@ public abstract class AbstractExporterController {
@ResponseStatus(HttpStatus.BAD_REQUEST)
public List<ErrorMessage> processValidationError(final MethodArgumentNotValidException e) {
return e.getBindingResult()
.getFieldErrors().stream()
.map(fe -> new ErrorMessage(
String.format("field '%s'", fe.getField()),
String.format("rejected value '%s'", fe.getRejectedValue()),
fe.getDefaultMessage()))
.collect(Collectors.toList());
.getFieldErrors()
.stream()
.map(fe -> new ErrorMessage(
String.format("field '%s'", fe.getField()),
String.format("rejected value '%s'", fe.getRejectedValue()),
fe.getDefaultMessage()))
.collect(Collectors.toList());
}
private ErrorMessage _handleError(final Exception e) {
log.error(e);
if (StringUtils.containsIgnoreCase(ExceptionUtils.getRootCauseMessage(e), "Broken pipe")) {
return null; //socket is closed, cannot return any response
return null; // socket is closed, cannot return any response
} else {
return new ErrorMessage(e);
}
}
// HELPERS
protected <T extends Response> T prepareResponse(final int page, final int size, final StopWatch stopWatch, final T rsp) {
rsp.getHeader()
.setTime(stopWatch.getTime())
.setPage(page)
.setSize(size);
return rsp;
}
@JsonAutoDetect
public class ErrorMessage {

View File

@ -1,302 +1,345 @@
package eu.dnetlib.openaire.community;
import static eu.dnetlib.openaire.common.ExporterConstants.C;
import static eu.dnetlib.openaire.common.ExporterConstants.C_CP;
import static eu.dnetlib.openaire.common.ExporterConstants.C_O;
import static eu.dnetlib.openaire.common.ExporterConstants.C_PJ;
import static eu.dnetlib.openaire.common.ExporterConstants.C_ZC;
import static eu.dnetlib.openaire.common.ExporterConstants.R;
import static eu.dnetlib.openaire.common.ExporterConstants.W;
import java.util.List;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import static eu.dnetlib.openaire.common.ExporterConstants.*;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
@RestController
@CrossOrigin(origins = { "*" })
@CrossOrigin(origins = {
"*"
})
@ConditionalOnProperty(value = "openaire.exporter.enable.community", havingValue = "true")
@io.swagger.annotations.Api(tags = "OpenAIRE Communities API", description = "the OpenAIRE Community API")
@Tag(name = "OpenAIRE Communities API", description = "the OpenAIRE Community API")
public class CommunityApiController {
@Autowired
private CommunityApiCore communityApiCore;
@RequestMapping(value = "/community/communities", produces = { "application/json" }, method = RequestMethod.GET)
@ApiOperation(
value = "get all community profiles",
notes = "get all community profiles",
tags = { C, R },
response = CommunitySummary[].class)
@RequestMapping(value = "/community/communities", produces = {
"application/json"
}, method = RequestMethod.GET)
@Operation(summary = "get all community profiles", description = "get all community profiles", tags = {
C, R
})
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK", response = CommunitySummary[].class),
@ApiResponse(code = 500, message = "unexpected error", response = CommunityException.class) })
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "500", description = "unexpected error")
})
public List<CommunitySummary> listCommunities() throws CommunityException {
return communityApiCore.listCommunities();
}
@RequestMapping(value = "/community/{id}", produces = { "application/json" }, method = RequestMethod.GET)
@ApiOperation(
value = "get community profile",
notes = "get community profile",
tags = { C, R },
response = CommunityDetails.class)
@RequestMapping(value = "/community/{id}", produces = {
"application/json"
}, method = RequestMethod.GET)
@Operation(summary = "get community profile", description = "get community profile", tags = {
C, R
})
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK", response = CommunityDetails.class),
@ApiResponse(code = 404, message = "not found", response = CommunityNotFoundException.class),
@ApiResponse(code = 500, message = "unexpected error", response = CommunityException.class) })
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "404", description = "not found"),
@ApiResponse(responseCode = "500", description = "unexpected error")
})
public CommunityDetails getCommunity(@PathVariable final String id) throws CommunityException, CommunityNotFoundException {
return communityApiCore.getCommunity(id);
}
@RequestMapping(value = "/community/{id}", produces = { "application/json" }, method = RequestMethod.POST)
@ApiOperation(
value = "update community details",
notes = "update community details",
tags = { C, R })
@RequestMapping(value = "/community/{id}", produces = {
"application/json"
}, method = RequestMethod.POST)
@Operation(summary = "update community details", description = "update community details", tags = {
C, R
})
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK"),
@ApiResponse(code = 404, message = "not found", response = CommunityNotFoundException.class),
@ApiResponse(code = 500, message = "unexpected error", response = CommunityException.class) })
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "404", description = "not found"),
@ApiResponse(responseCode = "500", description = "unexpected error")
})
public void setCommunity(
@PathVariable final String id,
@RequestBody CommunityWritableProperties properties) throws CommunityException, CommunityNotFoundException {
@PathVariable final String id,
@RequestBody final CommunityWritableProperties properties) throws CommunityException, CommunityNotFoundException {
communityApiCore.setCommunity(id, properties);
}
@RequestMapping(value = "/community/{id}/projects", produces = { "application/json" }, method = RequestMethod.GET)
@ApiOperation(
value = "get community projects",
notes = "get community projects",
tags = { C_PJ, R },
response = CommunityProject[].class)
@RequestMapping(value = "/community/{id}/projects", produces = {
"application/json"
}, method = RequestMethod.GET)
@Operation(summary = "get community projects", description = "get community projects", tags = {
C_PJ, R
})
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK", response = CommunityProject[].class),
@ApiResponse(code = 404, message = "not found", response = CommunityNotFoundException.class),
@ApiResponse(code = 500, message = "unexpected error", response = CommunityException.class) })
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "404", description = "not found"),
@ApiResponse(responseCode = "500", description = "unexpected error")
})
public List<CommunityProject> getCommunityProjects(@PathVariable final String id) throws CommunityException, CommunityNotFoundException {
return communityApiCore.getCommunityProjects(id);
}
@RequestMapping(value = "/community/{id}/projects", produces = { "application/json" }, method = RequestMethod.POST)
@ApiOperation(
value = "associate a project to the community",
notes = "associate a project to the community",
tags = { C_PJ, W })
@RequestMapping(value = "/community/{id}/projects", produces = {
"application/json"
}, method = RequestMethod.POST)
@Operation(summary = "associate a project to the community", description = "associate a project to the community", tags = {
C_PJ, W
})
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK"),
@ApiResponse(code = 404, message = "not found", response = CommunityNotFoundException.class),
@ApiResponse(code = 500, message = "unexpected error", response = CommunityException.class) })
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "404", description = "not found"),
@ApiResponse(responseCode = "500", description = "unexpected error")
})
public CommunityProject addCommunityProject(
@PathVariable final String id,
@RequestBody final CommunityProject project) throws CommunityException, CommunityNotFoundException {
@PathVariable final String id,
@RequestBody final CommunityProject project) throws CommunityException, CommunityNotFoundException {
return communityApiCore.addCommunityProject(id, project);
}
@RequestMapping(value = "/community/{id}/projects", produces = { "application/json" }, method = RequestMethod.DELETE)
@ApiOperation(
value = "remove a project from the community",
notes = "remove a project from the community",
tags = { C_PJ, W })
@RequestMapping(value = "/community/{id}/projects", produces = {
"application/json"
}, method = RequestMethod.DELETE)
@Operation(summary = "remove a project from the community", description = "remove a project from the community", tags = {
C_PJ, W
})
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK"),
@ApiResponse(code = 404, message = "not found", response = CommunityNotFoundException.class),
@ApiResponse(code = 500, message = "unexpected error", response = CommunityException.class) })
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "404", description = "not found"),
@ApiResponse(responseCode = "500", description = "unexpected error")
})
public void deleteCommunityProject(
@PathVariable final String id,
@RequestBody final Integer projectId) throws CommunityException, CommunityNotFoundException {
@PathVariable final String id,
@RequestBody final Integer projectId) throws CommunityException, CommunityNotFoundException {
communityApiCore.removeCommunityProject(id, projectId);
}
@RequestMapping(value = "/community/{id}/contentproviders", produces = { "application/json" }, method = RequestMethod.GET)
@ApiOperation(
value = "get the list of content providers associated to a given community",
notes = "get the list of content providers associated to a given community",
tags = { C_CP, R },
response = CommunityContentprovider[].class)
@RequestMapping(value = "/community/{id}/contentproviders", produces = {
"application/json"
}, method = RequestMethod.GET)
@Operation(summary = "get the list of content providers associated to a given community", description = "get the list of content providers associated to a given community", tags = {
C_CP, R
})
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK", response = CommunityContentprovider[].class),
@ApiResponse(code = 404, message = "not found", response = CommunityNotFoundException.class),
@ApiResponse(code = 500, message = "unexpected error", response = CommunityException.class) })
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "404", description = "not found"),
@ApiResponse(responseCode = "500", description = "unexpected error")
})
public List<CommunityContentprovider> getCommunityContentproviders(@PathVariable final String id) throws CommunityException, CommunityNotFoundException {
return communityApiCore.getCommunityContentproviders(id);
}
@RequestMapping(value = "/community/{id}/contentproviders", produces = { "application/json" }, method = RequestMethod.POST)
@ApiOperation(
value = "associate a content provider to the community",
notes = "associate a content provider to the community",
tags = { C_CP, W })
@RequestMapping(value = "/community/{id}/contentproviders", produces = {
"application/json"
}, method = RequestMethod.POST)
@Operation(summary = "associate a content provider to the community", description = "associate a content provider to the community", tags = {
C_CP, W
})
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK"),
@ApiResponse(code = 404, message = "not found", response = CommunityNotFoundException.class),
@ApiResponse(code = 500, message = "unexpected error", response = CommunityException.class) })
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "404", description = "not found"),
@ApiResponse(responseCode = "500", description = "unexpected error")
})
public CommunityContentprovider addCommunityContentprovider(
@PathVariable final String id,
@RequestBody final CommunityContentprovider contentprovider) throws CommunityException, CommunityNotFoundException {
@PathVariable final String id,
@RequestBody final CommunityContentprovider contentprovider) throws CommunityException, CommunityNotFoundException {
return communityApiCore.addCommunityContentprovider(id, contentprovider);
}
@RequestMapping(value = "/community/{id}/contentproviders", produces = { "application/json" }, method = RequestMethod.DELETE)
@ApiOperation(
value = "remove the association between a content provider and the community",
notes = "remove the association between a content provider and the community",
tags = { C_CP, W })
@RequestMapping(value = "/community/{id}/contentproviders", produces = {
"application/json"
}, method = RequestMethod.DELETE)
@Operation(summary = "remove the association between a content provider and the community", description = "remove the association between a content provider and the community", tags = {
C_CP, W
})
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK"),
@ApiResponse(code = 404, message = "not found", response = CommunityNotFoundException.class),
@ApiResponse(code = 500, message = "unexpected error", response = CommunityException.class) })
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "404", description = "not found"),
@ApiResponse(responseCode = "500", description = "unexpected error")
})
public void removeCommunityContentprovider(
@PathVariable final String id,
@RequestBody final Integer contentproviderId) throws CommunityException, CommunityNotFoundException {
@PathVariable final String id,
@RequestBody final Integer contentproviderId) throws CommunityException, CommunityNotFoundException {
communityApiCore.removeCommunityContentProvider(id, contentproviderId);
}
//ADDING CODE FOR COMMUNITY ORGANIZATIONS
// ADDING CODE FOR COMMUNITY ORGANIZATIONS
@RequestMapping(value = "/community/{id}/organizations", produces = { "application/json" }, method = RequestMethod.GET)
@ApiOperation(
value = "get the list of organizations for a given community",
notes = "get the list of organizations for a given community",
tags = { C_O, R },
response = CommunityOrganization[].class)
@RequestMapping(value = "/community/{id}/organizations", produces = {
"application/json"
}, method = RequestMethod.GET)
@Operation(summary = "get the list of organizations for a given community", description = "get the list of organizations for a given community", tags = {
C_O, R
})
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK", response = CommunityContentprovider[].class),
@ApiResponse(code = 404, message = "not found", response = CommunityNotFoundException.class),
@ApiResponse(code = 500, message = "unexpected error", response = CommunityException.class) })
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "404", description = "not found"),
@ApiResponse(responseCode = "500", description = "unexpected error")
})
public List<CommunityOrganization> getCommunityOrganizations(@PathVariable final String id) throws CommunityException, CommunityNotFoundException {
return communityApiCore.getCommunityOrganizations(id);
}
@RequestMapping(value = "/community/{id}/organizations", produces = { "application/json" }, method = RequestMethod.POST)
@ApiOperation(
value = "associate an organization to the community",
notes = "associate an organization to the community",
tags = { C_O, W })
@RequestMapping(value = "/community/{id}/organizations", produces = {
"application/json"
}, method = RequestMethod.POST)
@Operation(summary = "associate an organization to the community", description = "associate an organization to the community", tags = {
C_O, W
})
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK"),
@ApiResponse(code = 404, message = "not found", response = CommunityNotFoundException.class),
@ApiResponse(code = 500, message = "unexpected error", response = CommunityException.class) })
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "404", description = "not found"),
@ApiResponse(responseCode = "500", description = "unexpected error")
})
public CommunityOrganization addCommunityOrganization(
@PathVariable final String id,
@RequestBody final CommunityOrganization organization) throws CommunityException, CommunityNotFoundException {
@PathVariable final String id,
@RequestBody final CommunityOrganization organization) throws CommunityException, CommunityNotFoundException {
return communityApiCore.addCommunityOrganization(id, organization);
}
@RequestMapping(value = "/community/{id}/organizations", produces = { "application/json" }, method = RequestMethod.DELETE)
@ApiOperation(
value = "remove the association between an organization and the community",
notes = "remove the association between an organization and the community",
tags = { C_O, W })
@RequestMapping(value = "/community/{id}/organizations", produces = {
"application/json"
}, method = RequestMethod.DELETE)
@Operation(summary = "remove the association between an organization and the community", description = "remove the association between an organization and the community", tags = {
C_O, W
})
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK"),
@ApiResponse(code = 404, message = "not found", response = CommunityNotFoundException.class),
@ApiResponse(code = 500, message = "unexpected error", response = CommunityException.class) })
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "404", description = "not found"),
@ApiResponse(responseCode = "500", description = "unexpected error")
})
public void removeCommunityOrganization(
@PathVariable final String id,
@RequestBody final Integer organizationId) throws CommunityException, CommunityNotFoundException {
@PathVariable final String id,
@RequestBody final Integer organizationId) throws CommunityException, CommunityNotFoundException {
communityApiCore.removeCommunityOrganization(id, organizationId);
}
//**********************
// **********************
@RequestMapping(value = "/community/{id}/subjects", produces = { "application/json" }, method = RequestMethod.POST)
@ApiOperation(
value = "associate a subject to the community",
notes = "associate a subject to the community",
tags = { C, W })
@RequestMapping(value = "/community/{id}/subjects", produces = {
"application/json"
}, method = RequestMethod.POST)
@Operation(summary = "associate a subject to the community", description = "associate a subject to the community", tags = {
C, W
})
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK"),
@ApiResponse(code = 404, message = "not found", response = CommunityNotFoundException.class),
@ApiResponse(code = 500, message = "unexpected error", response = CommunityException.class) })
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "404", description = "not found"),
@ApiResponse(responseCode = "500", description = "unexpected error")
})
public CommunityDetails addCommunitySubjects(
@PathVariable final String id,
@RequestBody final List<String> subjects) throws CommunityException, CommunityNotFoundException {
@PathVariable final String id,
@RequestBody final List<String> subjects) throws CommunityException, CommunityNotFoundException {
return communityApiCore.addCommunitySubjects(id, subjects);
}
@RequestMapping(value = "/community/{id}/subjects", produces = { "application/json" }, method = RequestMethod.DELETE)
@ApiOperation(
value = "remove subjects from a community",
notes = "remove subjects from a community",
tags = { C, W })
@RequestMapping(value = "/community/{id}/subjects", produces = {
"application/json"
}, method = RequestMethod.DELETE)
@Operation(summary = "remove subjects from a community", description = "remove subjects from a community", tags = {
C, W
})
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK"),
@ApiResponse(code = 404, message = "not found", response = CommunityNotFoundException.class),
@ApiResponse(code = 500, message = "unexpected error", response = CommunityException.class) })
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "404", description = "not found"),
@ApiResponse(responseCode = "500", description = "unexpected error")
})
public CommunityDetails removeCommunitySubjects(
@PathVariable final String id,
@RequestBody final List<String> subjects) throws CommunityException, CommunityNotFoundException {
@PathVariable final String id,
@RequestBody final List<String> subjects) throws CommunityException, CommunityNotFoundException {
return communityApiCore.removeCommunitySubjects(id, subjects);
}
@RequestMapping(value = "/community/{id}/zenodocommunities", produces = { "application/json" }, method = RequestMethod.GET)
@ApiOperation(
value = "get the list of Zenodo communities associated to a given community",
notes = "get the list of Zenodo communities associated to a given community",
tags = { C_ZC, R },
response = CommunityZenodoCommunity[].class)
@RequestMapping(value = "/community/{id}/zenodocommunities", produces = {
"application/json"
}, method = RequestMethod.GET)
@Operation(summary = "get the list of Zenodo communities associated to a given community", description = "get the list of Zenodo communities associated to a given community", tags = {
C_ZC, R
})
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK", response = CommunityZenodoCommunity[].class),
@ApiResponse(code = 404, message = "not found", response = CommunityNotFoundException.class),
@ApiResponse(code = 500, message = "unexpected error", response = CommunityException.class) })
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "404", description = "not found"),
@ApiResponse(responseCode = "500", description = "unexpected error")
})
public List<CommunityZenodoCommunity> getCommunityZenodoCommunities(@PathVariable final String id) throws CommunityException, CommunityNotFoundException {
return communityApiCore.getCommunityZenodoCommunities(id);
}
@RequestMapping(value = "/community/{id}/zenodocommunities", produces = { "application/json" }, method = RequestMethod.POST)
@ApiOperation(
value = "associate a Zenodo community to the community",
notes = "associate a Zenodo community to the community",
tags = { C_ZC, W })
@RequestMapping(value = "/community/{id}/zenodocommunities", produces = {
"application/json"
}, method = RequestMethod.POST)
@Operation(summary = "associate a Zenodo community to the community", description = "associate a Zenodo community to the community", tags = {
C_ZC, W
})
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK"),
@ApiResponse(code = 404, message = "not found", response = CommunityNotFoundException.class),
@ApiResponse(code = 500, message = "unexpected error", response = CommunityException.class) })
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "404", description = "not found"),
@ApiResponse(responseCode = "500", description = "unexpected error")
})
public CommunityZenodoCommunity addCommunityZenodoCommunity(
@PathVariable final String id,
@RequestBody final CommunityZenodoCommunity zenodocommunity) throws CommunityException, CommunityNotFoundException {
@PathVariable final String id,
@RequestBody final CommunityZenodoCommunity zenodocommunity) throws CommunityException, CommunityNotFoundException {
return communityApiCore.addCommunityZenodoCommunity(id, zenodocommunity);
}
@RequestMapping(value = "/community/{id}/zenodocommunities", produces = { "application/json" }, method = RequestMethod.DELETE)
@ApiOperation(
value = "remove a Zenodo community from a community",
notes = "remove a Zenodo community from a community",
tags = { C_ZC, W })
@RequestMapping(value = "/community/{id}/zenodocommunities", produces = {
"application/json"
}, method = RequestMethod.DELETE)
@Operation(summary = "remove a Zenodo community from a community", description = "remove a Zenodo community from a community", tags = {
C_ZC, W
})
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK"),
@ApiResponse(code = 404, message = "not found", response = CommunityNotFoundException.class),
@ApiResponse(code = 500, message = "unexpected error", response = CommunityException.class) })
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "404", description = "not found"),
@ApiResponse(responseCode = "500", description = "unexpected error")
})
public void removeCommunityZenodoCommunity(
@PathVariable final String id,
@RequestBody final Integer zenodoCommId) throws CommunityException, CommunityNotFoundException {
@PathVariable final String id,
@RequestBody final Integer zenodoCommId) throws CommunityException, CommunityNotFoundException {
communityApiCore.removeCommunityZenodoCommunity(id, zenodoCommId);
}
@RequestMapping(value = "/community/{zenodoId}/openairecommunities", produces = { "application/json" }, method = RequestMethod.GET)
@ApiOperation(
value = "get the list of OpenAIRE communities associated to a given Zenodo community",
notes = "get the list of OpenAIRE communities associated to a given Zenodo community",
tags = { C_ZC, R })
@RequestMapping(value = "/community/{zenodoId}/openairecommunities", produces = {
"application/json"
}, method = RequestMethod.GET)
@Operation(summary = "get the list of OpenAIRE communities associated to a given Zenodo community", description = "get the list of OpenAIRE communities associated to a given Zenodo community", tags = {
C_ZC, R
})
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK"),
@ApiResponse(code = 404, message = "not found", response = CommunityNotFoundException.class),
@ApiResponse(code = 500, message = "unexpected error", response = CommunityException.class) })
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "404", description = "not found"),
@ApiResponse(responseCode = "500", description = "unexpected error")
})
public CommunityOpenAIRECommunities getOpenAireCommunities(
@PathVariable final String zenodoId) throws CommunityException, CommunityNotFoundException {
@PathVariable final String zenodoId) throws CommunityException, CommunityNotFoundException {
return communityApiCore.getOpenAIRECommunities(zenodoId);

View File

@ -6,31 +6,31 @@ import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.google.gson.Gson;
import eu.dnetlib.openaire.community.selectioncriteria.SelectionCriteria;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
@JsonAutoDetect
public class CommunityContentprovider {
@ApiModelProperty(value = "OpenAIRE identifier for this content provider, if available", required = false)
@Schema(description = "OpenAIRE identifier for this content provider, if available", required = false)
private String openaireId;
@NotNull
@ApiModelProperty(value = "the community identifier this content provider belongs to", required = true)
@Schema(description = "the community identifier this content provider belongs to", required = true)
private String communityId;
@NotNull
@ApiModelProperty(value = "identifies this content provider within the context it belongs to", required = true)
@Schema(description = "identifies this content provider within the context it belongs to", required = true)
private String id;
@ApiModelProperty(value = "content provider name", required = false)
@Schema(description = "content provider name", required = false)
private String name;
@NotNull
@ApiModelProperty(value = "content provider official name", required = true)
@Schema(description = "content provider official name", required = true)
private String officialname;
// @NotNull
@ApiModelProperty(value = "content provider selection criteria", required = false)
@Schema(description = "content provider selection criteria", required = false)
private SelectionCriteria selectioncriteria;
public String getOpenaireId() {

View File

@ -4,31 +4,33 @@ import java.util.Date;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
@JsonAutoDetect
public class CommunityDetails extends CommunitySummary {
@ApiModelProperty("date of creation for this community")
@Schema(description = "date of creation for this community")
private Date creationDate;
@ApiModelProperty("date of the last update for this communityu")
@Schema(description = "date of the last update for this communityu")
private Date lastUpdateDate;
@ApiModelProperty("list of subjects (keywords) that characterise this community")
@Schema(description = "list of subjects (keywords) that characterise this community")
private List<String> subjects;
public CommunityDetails() {
}
public CommunityDetails() {}
public CommunityDetails(final CommunitySummary summary) {
super(summary);
}
@Override
public Date getCreationDate() {
return creationDate;
}
@Override
public void setCreationDate(final Date creationDate) {
this.creationDate = creationDate;
}
@ -41,11 +43,13 @@ public class CommunityDetails extends CommunitySummary {
this.subjects = subjects;
}
@Override
public Date getLastUpdateDate() {
return lastUpdateDate;
}
public void setLastUpdateDate(Date lastUpdateDate) {
@Override
public void setLastUpdateDate(final Date lastUpdateDate) {
this.lastUpdateDate = lastUpdateDate;
}
}

View File

@ -1,42 +1,43 @@
package eu.dnetlib.openaire.community;
import io.swagger.annotations.ApiModelProperty;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.List;
import javax.validation.constraints.NotNull;
import io.swagger.v3.oas.annotations.media.Schema;
public class CommunityOpenAIRECommunities {
@NotNull
@ApiModelProperty(value = "the zenodo community identifier", required = true)
private String zenodoid;
@NotNull
@Schema(description = "the zenodo community identifier", required = true)
private String zenodoid;
@NotNull
@ApiModelProperty(value = "identifies this zenodo community within the context it belongs to", required = true)
private List<String> openAirecommunitylist;
@NotNull
@Schema(description = "identifies this zenodo community within the context it belongs to", required = true)
private List<String> openAirecommunitylist;
public CommunityOpenAIRECommunities() {
this.zenodoid = "";
openAirecommunitylist=new ArrayList<>();
}
public CommunityOpenAIRECommunities() {
this.zenodoid = "";
openAirecommunitylist = new ArrayList<>();
}
public List<String> getOpenAirecommunitylist() {
return openAirecommunitylist;
}
public List<String> getOpenAirecommunitylist() {
return openAirecommunitylist;
}
public CommunityOpenAIRECommunities setOpenAirecommunitylist(List<String> openAirecommunitylist) {
this.openAirecommunitylist = openAirecommunitylist;
return this;
}
public CommunityOpenAIRECommunities setOpenAirecommunitylist(final List<String> openAirecommunitylist) {
this.openAirecommunitylist = openAirecommunitylist;
return this;
}
public String getZenodoid() {
return zenodoid;
}
public String getZenodoid() {
return zenodoid;
}
public CommunityOpenAIRECommunities setZenodoid(String zenodoid) {
this.zenodoid = zenodoid;
return this;
}
public CommunityOpenAIRECommunities setZenodoid(final String zenodoid) {
this.zenodoid = zenodoid;
return this;
}
}
}

View File

@ -1,75 +1,76 @@
package eu.dnetlib.openaire.community;
import javax.validation.constraints.NotNull;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import io.swagger.annotations.ApiModelProperty;
import javax.validation.constraints.NotNull;
import io.swagger.v3.oas.annotations.media.Schema;
@JsonAutoDetect
public class CommunityOrganization {
@NotNull
@ApiModelProperty(value = "the community identifier this organization belongs to", required = true)
private String communityId;
@NotNull
@ApiModelProperty(value = "name of the organization", required = true)
private String name;
@NotNull
@Schema(description = "the community identifier this organization belongs to", required = true)
private String communityId;
@NotNull
@ApiModelProperty(value = "identifies this organization within the context it belongs to", required = true)
private String id;
@NotNull
@Schema(description = "name of the organization", required = true)
private String name;
@NotNull
@ApiModelProperty(value="url of the logo for this organization", required = true)
private String logo_url;
@NotNull
@Schema(description = "identifies this organization within the context it belongs to", required = true)
private String id;
@NotNull
@Schema(description = "url of the logo for this organization", required = true)
private String logo_url;
@NotNull
@ApiModelProperty(value="website url for this organization", required = true)
private String website_url;
@NotNull
@Schema(description = "website url for this organization", required = true)
private String website_url;
public String getCommunityId() {
return communityId;
}
public String getCommunityId() {
return communityId;
}
public CommunityOrganization setCommunityId(String communityId) {
this.communityId = communityId;
return this;
}
public CommunityOrganization setCommunityId(final String communityId) {
this.communityId = communityId;
return this;
}
public String getName() {
return name;
}
public String getName() {
return name;
}
public CommunityOrganization setName(String name) {
this.name = name;
return this;
}
public CommunityOrganization setName(final String name) {
this.name = name;
return this;
}
public String getId() {
return id;
}
public String getId() {
return id;
}
public CommunityOrganization setId(String id) {
this.id = id;
return this;
}
public CommunityOrganization setId(final String id) {
this.id = id;
return this;
}
public String getLogo_url() {
return logo_url;
}
public String getLogo_url() {
return logo_url;
}
public CommunityOrganization setLogo_url(String logo_url) {
this.logo_url = logo_url;
return this;
}
public CommunityOrganization setLogo_url(final String logo_url) {
this.logo_url = logo_url;
return this;
}
public String getWebsite_url() {
return website_url;
}
public String getWebsite_url() {
return website_url;
}
public CommunityOrganization setWebsite_url(String website_url) {
this.website_url = website_url;
return this;
}
public CommunityOrganization setWebsite_url(final String website_url) {
this.website_url = website_url;
return this;
}
}

View File

@ -1,30 +1,31 @@
package eu.dnetlib.openaire.community;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
@JsonAutoDetect
public class CommunityProject {
@ApiModelProperty(value = "OpenAIRE identifier for this project, if available", required = false)
@Schema(description = "OpenAIRE identifier for this project, if available", required = false)
private String openaireId;
@ApiModelProperty(value = "the community identifier this project belongs to", required = true)
@Schema(description = "the community identifier this project belongs to", required = true)
private String communityId;
@ApiModelProperty(value = "identifies this project within the context it belongs to", required = true)
@Schema(description = "identifies this project within the context it belongs to", required = true)
private String id;
@ApiModelProperty(value = "project name", required = true)
@Schema(description = "project name", required = true)
private String name;
@ApiModelProperty(value = "project acronym", required = false)
@Schema(description = "project acronym", required = false)
private String acronym;
@ApiModelProperty(value = "project funder", required = true)
@Schema(description = "project funder", required = true)
private String funder;
@ApiModelProperty(value = "project grant id", required = true)
@Schema(description = "project grant id", required = true)
private String grantId;
public String getOpenaireId() {

View File

@ -1,17 +1,18 @@
package eu.dnetlib.openaire.community;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
@JsonAutoDetect
public enum CommunityStatus {
@ApiModelProperty("restricted visibility")
@Schema(description = "restricted visibility")
hidden,
@ApiModelProperty("visible only to RCD managers")
@Schema(description = "visible only to RCD managers")
manager,
@ApiModelProperty("visible to RCD managers and to the community users")
@Schema(description = "visible to RCD managers and to the community users")
all
}

View File

@ -4,42 +4,42 @@ import java.util.Date;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
@JsonAutoDetect
public class CommunitySummary {
@ApiModelProperty("identifies the community")
@Schema(description = "identifies the community")
protected String id;
@ApiModelProperty("values for this field reflect the index field _community_ in the index, e.g. 'egi||EGI Federation'")
@Schema(description = "values for this field reflect the index field _community_ in the index, e.g. 'egi||EGI Federation'")
protected String queryId;
@ApiModelProperty("community type")
@Schema(description = "community type")
protected String type;
@ApiModelProperty("community name")
@Schema(description = "community name")
protected String name;
@ApiModelProperty("community short name")
@Schema(description = "community short name")
protected String shortName;
@ApiModelProperty("community creation date")
@Schema(description = "community creation date")
protected Date creationDate;
@ApiModelProperty("community last update date")
@Schema(description = "community last update date")
protected Date lastUpdateDate;
@ApiModelProperty("community description")
@Schema(description = "community description")
protected String description;
@ApiModelProperty("http url for the community logo")
@Schema(description = "http url for the community logo")
protected String logoUrl;
@ApiModelProperty("status of the community, drives its visibility")
@Schema(description = "status of the community, drives its visibility")
protected CommunityStatus status;
@ApiModelProperty("Zenodo community associated to this community")
@Schema(description = "Zenodo community associated to this community")
protected String zenodoCommunity;
public CommunitySummary() {}

View File

@ -3,35 +3,35 @@ package eu.dnetlib.openaire.community;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
@JsonAutoDetect
public class CommunityWritableProperties {
@ApiModelProperty("community name")
@Schema(description = "community name")
private String name;
@ApiModelProperty("community short name")
@Schema(description = "community short name")
private String shortName;
@ApiModelProperty("community description")
@Schema(description = "community description")
private String description;
@ApiModelProperty("http url for the community logo")
@Schema(description = "http url for the community logo")
private String logoUrl;
@ApiModelProperty("list of subjects (keywords) that characterise this community")
@Schema(description = "list of subjects (keywords) that characterise this community")
private List<String> subjects;
@ApiModelProperty("status of the community, drives its visibility")
@Schema(description = "status of the community, drives its visibility")
private CommunityStatus status;
@ApiModelProperty("id of the main Zenodo community")
@Schema(description = "id of the main Zenodo community")
private String mainZenodoCommunity;
public static CommunityWritableProperties fromDetails(final CommunityDetails details) {
CommunityWritableProperties p = new CommunityWritableProperties();
final CommunityWritableProperties p = new CommunityWritableProperties();
p.setName(details.getName());
p.setShortName(details.getShortName());
p.setDescription(details.getDescription());
@ -90,7 +90,11 @@ public class CommunityWritableProperties {
this.status = status;
}
public String getMainZenodoCommunity() { return mainZenodoCommunity; }
public String getMainZenodoCommunity() {
return mainZenodoCommunity;
}
public void setMainZenodoCommunity(String mainZenodoCommunity) { this.mainZenodoCommunity = mainZenodoCommunity; }
public void setMainZenodoCommunity(final String mainZenodoCommunity) {
this.mainZenodoCommunity = mainZenodoCommunity;
}
}

View File

@ -3,45 +3,46 @@ package eu.dnetlib.openaire.community;
import javax.validation.constraints.NotNull;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
@JsonAutoDetect
public class CommunityZenodoCommunity {
@NotNull
@ApiModelProperty(value = "the community identifier this zenodo Community belongs to", required = true)
private String communityId;
@NotNull
@Schema(description = "the community identifier this zenodo Community belongs to", required = true)
private String communityId;
@NotNull
@ApiModelProperty(value = "Zenodo identifier for this community", required = true)
private String zenodoid;
@NotNull
@Schema(description = "Zenodo identifier for this community", required = true)
private String zenodoid;
@NotNull
@ApiModelProperty(value = "identifies this zenodo community within the context it belongs to", required = true)
private String id;
@NotNull
@Schema(description = "identifies this zenodo community within the context it belongs to", required = true)
private String id;
public String getZenodoid() {
return zenodoid;
}
public String getZenodoid() {
return zenodoid;
}
public void setZenodoid(String zenodoid) {
this.zenodoid = zenodoid;
}
public void setZenodoid(final String zenodoid) {
this.zenodoid = zenodoid;
}
public String getId() {
return id;
}
public String getId() {
return id;
}
public void setId(final String id) {
this.id = id;
}
public void setId(final String id) {
this.id = id;
}
public String getCommunityId() {
return communityId;
}
public String getCommunityId() {
return communityId;
}
public void setCommunityId(String communityId) {
this.communityId = communityId;
}
public void setCommunityId(final String communityId) {
this.communityId = communityId;
}
}

View File

@ -3,83 +3,88 @@ package eu.dnetlib.openaire.context;
import java.util.List;
import java.util.Optional;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
@RestController
@CrossOrigin(origins = { "*" })
@CrossOrigin(origins = {
"*"
})
@ConditionalOnProperty(value = "openaire.exporter.enable.context", havingValue = "true")
@io.swagger.annotations.Api(tags = "OpenAIRE Context API", description = "the OpenAIRE Context API")
@Tag(name = "OpenAIRE Context API", description = "the OpenAIRE Context API")
public class ContextApiController {
@Autowired
private ContextApiCore contextApiCore;
@RequestMapping(value = "/contexts", produces = { "application/json" }, method = RequestMethod.GET)
@ApiOperation(
value = "list brief information about all the context profiles",
notes = "list brief information about all the context profiles.",
tags = { },
response = ContextSummary[].class)
@RequestMapping(value = "/contexts", produces = {
"application/json"
}, method = RequestMethod.GET)
@Operation(summary = "list brief information about all the context profiles", description = "list brief information about all the context profiles")
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK", response = ContextSummary[].class),
@ApiResponse(code = 500, message = "unexpected error", response = ContextException.class) })
public List<ContextSummary> listContexts(@RequestParam(required = false, defaultValue = "") List<String> type) throws ContextException {
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "500", description = "unexpected error")
})
public List<ContextSummary> listContexts(@RequestParam(required = false, defaultValue = "") final List<String> type) throws ContextException {
return contextApiCore.listContexts(type);
}
@RequestMapping(value = "/context/{contextId}", produces = { "application/json" }, method = RequestMethod.GET)
@ApiOperation(
value = "list the categories defined within a context",
notes = "list the categories defined within a context",
tags = { },
response = CategorySummary[].class)
@RequestMapping(value = "/context/{contextId}", produces = {
"application/json"
}, method = RequestMethod.GET)
@Operation(summary = "list the categories defined within a context", description = "list the categories defined within a context")
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK", response = CategorySummary[].class),
@ApiResponse(code = 500, message = "unexpected error", response = ContextException.class) })
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "500", description = "unexpected error")
})
public List<CategorySummary> listCategories(
@PathVariable final String contextId,
@RequestParam(required = false, defaultValue = "false") final Boolean all) throws ContextException {
@PathVariable final String contextId,
@RequestParam(required = false, defaultValue = "false") final Boolean all) throws ContextException {
Boolean allFilter = Optional.ofNullable(all).orElse(false);
final Boolean allFilter = Optional.ofNullable(all).orElse(false);
return contextApiCore.listCategories(contextId, allFilter);
}
@RequestMapping(value = "/context/category/{categoryId}", produces = { "application/json" }, method = RequestMethod.GET)
@ApiOperation(
value = "list the concepts defined within a category",
notes = "list the concepts defined within a category",
tags = { },
response = ConceptSummary[].class)
@RequestMapping(value = "/context/category/{categoryId}", produces = {
"application/json"
}, method = RequestMethod.GET)
@Operation(summary = "list the concepts defined within a category", description = "list the concepts defined within a category")
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK", response = ConceptSummary[].class),
@ApiResponse(code = 500, message = "unexpected error", response = ContextException.class) })
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "500", description = "unexpected error")
})
public List<ConceptSummary> listConcepts(
@PathVariable final String categoryId,
@RequestParam(required = false, defaultValue = "false") final Boolean all) throws ContextException {
@PathVariable final String categoryId,
@RequestParam(required = false, defaultValue = "false") final Boolean all) throws ContextException {
Boolean allFilter = Optional.ofNullable(all).orElse(false);
final Boolean allFilter = Optional.ofNullable(all).orElse(false);
return contextApiCore.listConcepts(categoryId, allFilter);
}
@RequestMapping(value = "/context/category/concept/{conceptId}", produces = { "application/json" }, method = RequestMethod.GET)
@ApiOperation(
value = "list the concepts defined within a category",
notes = "list the concepts defined within a category",
tags = { },
response = ConceptSummary[].class)
@RequestMapping(value = "/context/category/concept/{conceptId}", produces = {
"application/json"
}, method = RequestMethod.GET)
@Operation(summary = "list the concepts defined within a category", description = "list the concepts defined within a category")
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK", response = ConceptSummary[].class),
@ApiResponse(code = 500, message = "unexpected error", response = ContextException.class) })
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "500", description = "unexpected error")
})
public List<ConceptSummary> listSubConcepts(
@PathVariable final String conceptId,
@RequestParam(required = false, defaultValue = "false") final Boolean all) throws ContextException {
@PathVariable final String conceptId,
@RequestParam(required = false, defaultValue = "false") final Boolean all) throws ContextException {
Boolean allFilter = Optional.ofNullable(all).orElse(false);
final Boolean allFilter = Optional.ofNullable(all).orElse(false);
return contextApiCore.listSubConcepts(conceptId, allFilter);
}

View File

@ -16,10 +16,11 @@ import org.apache.http.HttpStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@ -34,52 +35,53 @@ import eu.dnetlib.openaire.dsm.domain.ApiDetailsResponse;
import eu.dnetlib.openaire.dsm.domain.DatasourceDetailResponse;
import eu.dnetlib.openaire.dsm.domain.DatasourceDetails;
import eu.dnetlib.openaire.dsm.domain.DatasourceDetailsUpdate;
import eu.dnetlib.openaire.dsm.domain.DatasourceResponse;
import eu.dnetlib.openaire.dsm.domain.DatasourceDetailsWithApis;
import eu.dnetlib.openaire.dsm.domain.DatasourceSnippetResponse;
import eu.dnetlib.openaire.dsm.domain.RegisteredDatasourceInfo;
import eu.dnetlib.openaire.dsm.domain.RequestFilter;
import eu.dnetlib.openaire.dsm.domain.RequestSort;
import eu.dnetlib.openaire.dsm.domain.RequestSortOrder;
import eu.dnetlib.openaire.dsm.domain.Response;
import eu.dnetlib.openaire.dsm.domain.SimpleResponse;
import eu.dnetlib.openaire.vocabularies.Country;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
@RestController
@CrossOrigin(origins = {
"*"
})
@ConditionalOnProperty(value = "openaire.exporter.enable.dsm", havingValue = "true")
@io.swagger.annotations.Api(tags = "OpenAIRE DSM API", description = "the OpenAIRE Datasource Manager API")
@Tag(name = "OpenAIRE DSM API", description = "the OpenAIRE Datasource Manager API")
public class DsmApiController extends AbstractExporterController {
@Autowired
private DsmCore dsmCore;
@RequestMapping(value = "/ds/countries", produces = {
@GetMapping(value = "/ds/countries", produces = {
"application/json"
}, method = RequestMethod.GET)
@ApiOperation(value = "list the datasource countries", notes = "list the datasource countries", tags = {
})
@Operation(summary = "list the datasource countries", description = "list the datasource countries", tags = {
DS, R
}, response = Country[].class)
})
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK", response = Country[].class),
@ApiResponse(code = 500, message = "unexpected error", response = ErrorMessage.class)
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "500", description = "unexpected error")
})
public List<Country> listCountries() throws DsmException {
return dsmCore.listCountries();
}
@RequestMapping(value = "/ds/searchdetails/{page}/{size}", produces = {
@PostMapping(value = "/ds/searchdetails/{page}/{size}", produces = {
"application/json"
}, method = RequestMethod.POST)
@ApiOperation(value = "search datasources", notes = "Returns list of Datasource details.", tags = {
})
@Operation(summary = "search datasources", description = "Returns list of Datasource details.", tags = {
DS, R
}, response = DatasourceDetailResponse.class)
})
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK", response = DatasourceDetailResponse.class),
@ApiResponse(code = 500, message = "unexpected error", response = ErrorMessage.class)
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "500", description = "unexpected error")
})
public DatasourceDetailResponse searchDsDetails(
@RequestParam final RequestSort requestSortBy,
@ -92,15 +94,15 @@ public class DsmApiController extends AbstractExporterController {
return prepareResponse(page, size, stop, rsp);
}
@RequestMapping(value = "/ds/aggregationhistory/{dsId}", produces = {
@GetMapping(value = "/ds/aggregationhistory/{dsId}", produces = {
"application/json"
}, method = RequestMethod.GET)
@ApiOperation(value = "search datasources", notes = "Returns list of Datasource details.", tags = {
})
@Operation(summary = "search datasources", description = "Returns list of Datasource details.", tags = {
DS, R
}, response = AggregationHistoryResponse.class)
})
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK", response = AggregationHistoryResponse.class),
@ApiResponse(code = 500, message = "unexpected error", response = ErrorMessage.class)
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "500", description = "unexpected error")
})
public AggregationHistoryResponse aggregationHistory(@PathVariable final String dsId) throws DsmException {
final StopWatch stop = StopWatch.createStarted();
@ -108,15 +110,15 @@ public class DsmApiController extends AbstractExporterController {
return prepareResponse(0, rsp.getAggregationInfo().size(), stop, rsp);
}
@RequestMapping(value = "/ds/searchsnippet/{page}/{size}", produces = {
@PostMapping(value = "/ds/searchsnippet/{page}/{size}", produces = {
"application/json"
}, method = RequestMethod.POST)
@ApiOperation(value = "search datasources", notes = "Returns list of Datasource basic info.", tags = {
})
@Operation(summary = "search datasources", description = "Returns list of Datasource basic info.", tags = {
DS, R
}, response = DatasourceSnippetResponse.class)
})
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK", response = DatasourceSnippetResponse.class),
@ApiResponse(code = 500, message = "unexpected error", response = ErrorMessage.class)
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "500", description = "unexpected error")
})
public DatasourceSnippetResponse searchSnippet(
@RequestParam final RequestSort requestSortBy,
@ -129,16 +131,16 @@ public class DsmApiController extends AbstractExporterController {
return prepareResponse(page, size, stop, rsp);
}
@RequestMapping(value = "/ds/searchregistered/{page}/{size}", produces = {
@PostMapping(value = "/ds/searchregistered/{page}/{size}", produces = {
"application/json"
}, method = RequestMethod.POST)
@ApiOperation(value = "search among registered datasources", notes = "Returns list of Datasource basic info.", tags = {
})
@Operation(summary = "search among registered datasources", description = "Returns list of Datasource basic info.", tags = {
DS,
R
}, response = DatasourceSnippetResponse.class)
})
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK", response = DatasourceSnippetResponse.class),
@ApiResponse(code = 500, message = "unexpected error", response = ErrorMessage.class)
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "500", description = "unexpected error")
})
public DatasourceSnippetResponse searchRegistered(
@RequestParam final RequestSort requestSortBy,
@ -151,49 +153,49 @@ public class DsmApiController extends AbstractExporterController {
return prepareResponse(page, size, stop, rsp);
}
@RequestMapping(value = "/ds/recentregistered/{size}", produces = {
@GetMapping(value = "/ds/recentregistered/{size}", produces = {
"application/json"
}, method = RequestMethod.GET)
@ApiOperation(value = "return the latest datasources that were registered through Provide", notes = "Returns list of Datasource basic info.", tags = {
})
@Operation(summary = "return the latest datasources that were registered through Provide", description = "Returns list of Datasource basic info.", tags = {
DS,
R
}, response = SimpleResponse.class)
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK", response = DatasourceResponse.class),
@ApiResponse(code = 500, message = "unexpected error", response = ErrorMessage.class)
})
public SimpleResponse<?> recentRegistered(@PathVariable final int size) throws Throwable {
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "500", description = "unexpected error")
})
public SimpleResponse<RegisteredDatasourceInfo> recentRegistered(@PathVariable final int size) throws Throwable {
final StopWatch stop = StopWatch.createStarted();
final SimpleResponse<?> rsp = dsmCore.searchRecentRegistered(size);
final SimpleResponse<RegisteredDatasourceInfo> rsp = dsmCore.searchRecentRegistered(size);
return prepareResponse(1, size, stop, rsp);
}
@RequestMapping(value = "/ds/countregistered", produces = {
@GetMapping(value = "/ds/countregistered", produces = {
"application/json"
}, method = RequestMethod.GET)
@ApiOperation(value = "return the number of datasources registered after the given date", notes = "Returns a number.", tags = {
})
@Operation(summary = "return the number of datasources registered after the given date", description = "Returns a number.", tags = {
DS,
R
}, response = Long.class)
})
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK", response = Long.class),
@ApiResponse(code = 500, message = "unexpected error", response = ErrorMessage.class)
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "500", description = "unexpected error")
})
public Long countRegistered(@RequestParam final String fromDate,
@RequestParam(required = false) final String typologyFilter) throws Throwable {
return dsmCore.countRegisteredAfter(fromDate, typologyFilter);
}
@RequestMapping(value = "/ds/api/{dsId}", produces = {
@GetMapping(value = "/ds/api/{dsId}", produces = {
"application/json"
}, method = RequestMethod.GET)
@ApiOperation(value = "get the list of API for a given datasource", notes = "Returns the list of API for a given datasource.", tags = {
})
@Operation(summary = "get the list of API for a given datasource", description = "Returns the list of API for a given datasource.", tags = {
API,
R
}, response = ApiDetailsResponse.class)
})
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK", response = ApiDetailsResponse.class),
@ApiResponse(code = 500, message = "unexpected error", response = ErrorMessage.class)
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "500", description = "unexpected error")
})
public ApiDetailsResponse getApi(
@PathVariable final String dsId) throws DsmException {
@ -203,15 +205,15 @@ public class DsmApiController extends AbstractExporterController {
return prepareResponse(0, rsp.getApi().size(), stop, rsp);
}
@RequestMapping(value = "/api/baseurl/{page}/{size}", produces = {
@PostMapping(value = "/api/baseurl/{page}/{size}", produces = {
"application/json"
}, method = RequestMethod.POST)
@ApiOperation(value = "search for the list of base URLs of Datasource APIs managed by a user", notes = "Returns the list of base URLs of Datasource APIs managed by a user", tags = {
})
@Operation(summary = "search for the list of base URLs of Datasource APIs managed by a user", description = "Returns the list of base URLs of Datasource APIs managed by a user", tags = {
DS, API, R
}, response = String[].class)
})
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK", response = String[].class),
@ApiResponse(code = 500, message = "unexpected error", response = ErrorMessage.class)
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "500", description = "unexpected error")
})
public List<String> searchBaseUrls(
@RequestBody final RequestFilter requestFilter,
@ -221,27 +223,27 @@ public class DsmApiController extends AbstractExporterController {
return dsmCore.findBaseURLs(requestFilter, page, size);
}
@RequestMapping(value = "/ds/api/{apiId}", method = RequestMethod.DELETE)
@ApiOperation(value = "delete an API", notes = "delete an API, if removable", tags = {
@DeleteMapping(value = "/ds/api/{apiId}")
@Operation(summary = "delete an API", description = "delete an API, if removable", tags = {
API, W
})
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK"),
@ApiResponse(code = 400, message = "Api not found", response = ErrorMessage.class),
@ApiResponse(code = 403, message = "Api not removable", response = ErrorMessage.class),
@ApiResponse(code = 500, message = "DSM Server error", response = ErrorMessage.class)
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "400", description = "Api not found"),
@ApiResponse(responseCode = "403", description = "Api not removable"),
@ApiResponse(responseCode = "500", description = "DSM Server error")
})
public void deleteApi(@PathVariable final String apiId) throws DsmForbiddenException, DsmNotFoundException {
dsmCore.deleteApi(apiId);
}
@RequestMapping(value = "/ds/manage", method = RequestMethod.POST)
@ApiOperation(value = "set the managed status for a given datasource", notes = "set the managed status for a given datasource", tags = {
@PostMapping(value = "/ds/manage")
@Operation(summary = "set the managed status for a given datasource", description = "set the managed status for a given datasource", tags = {
DS, W
})
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK"),
@ApiResponse(code = 500, message = "unexpected error", response = ErrorMessage.class)
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "500", description = "unexpected error")
})
public void setManaged(
@RequestParam final String id,
@ -250,26 +252,26 @@ public class DsmApiController extends AbstractExporterController {
dsmCore.setManaged(id, managed);
}
@RequestMapping(value = "/ds/managed/{id}", method = RequestMethod.GET)
@ApiOperation(value = "get the datasource managed status", notes = "get the datasource managed status", tags = {
@GetMapping(value = "/ds/managed/{id}")
@Operation(summary = "get the datasource managed status", description = "get the datasource managed status", tags = {
DS, R
})
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK"),
@ApiResponse(code = 500, message = "unexpected error", response = ErrorMessage.class)
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "500", description = "unexpected error")
})
public boolean isManaged(@PathVariable final String id) throws DsmException {
return dsmCore.isManaged(id);
}
@RequestMapping(value = "/ds/add", method = RequestMethod.POST)
@ApiOperation(value = "add a new Datasource", notes = "add a new Datasource", tags = {
@PostMapping(value = "/ds/add")
@Operation(summary = "add a new Datasource", description = "add a new Datasource", tags = {
DS, W
})
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK"),
@ApiResponse(code = 400, message = "Malformed request", response = ErrorMessage[].class),
@ApiResponse(code = 500, message = "Unexpected error", response = ErrorMessage.class)
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "400", description = "Malformed request"),
@ApiResponse(responseCode = "500", description = "Unexpected error")
})
public void saveDs(@Valid @RequestBody final DatasourceDetails datasource) throws DsmException {
@ -279,13 +281,30 @@ public class DsmApiController extends AbstractExporterController {
dsmCore.save(datasource);
}
@RequestMapping(value = "/ds/update", method = RequestMethod.POST)
@ApiOperation(value = "update Datasource details", notes = "update Datasource details", tags = {
@PostMapping(value = "/ds/addWithApis")
@Operation(summary = "add a new Datasource and its apis", description = "add a new Datasource and its apis", tags = {
DS, W
})
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK"),
@ApiResponse(code = 500, message = "unexpected error", response = ErrorMessage.class)
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "400", description = "Malformed request"),
@ApiResponse(responseCode = "500", description = "Unexpected error")
})
public void saveDsWithApis(@Valid @RequestBody final DatasourceDetailsWithApis d) throws DsmException {
if (d.getDatasource() == null) { throw new DsmException(HttpStatus.SC_BAD_REQUEST, "Datasource field is null"); }
if (dsmCore.exist(d.getDatasource())) { // TODO further check that the DS doesn't have any API
throw new DsmException(HttpStatus.SC_CONFLICT, String.format("cannot register, datasource already defined '%s'", d.getDatasource().getId()));
}
dsmCore.save(d);
}
@PostMapping(value = "/ds/update")
@Operation(summary = "update Datasource details", description = "update Datasource details", tags = {
DS, W
})
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "500", description = "unexpected error")
})
public void updateDatasource(
@RequestBody final DatasourceDetailsUpdate ds) throws DsmException, DsmNotFoundException {
@ -293,13 +312,13 @@ public class DsmApiController extends AbstractExporterController {
dsmCore.updateDatasource(ds);
}
@RequestMapping(value = "/ds/api/baseurl", method = RequestMethod.POST)
@ApiOperation(value = "update the base URL of a datasource interface", notes = "update the base URL of a datasource interface", tags = {
@PostMapping(value = "/ds/api/baseurl")
@Operation(summary = "update the base URL of a datasource interface", description = "update the base URL of a datasource interface", tags = {
API, W
})
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK"),
@ApiResponse(code = 500, message = "unexpected error", response = ErrorMessage.class)
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "500", description = "unexpected error")
})
public void updateBaseUrl(
@RequestParam final String dsId,
@ -309,13 +328,13 @@ public class DsmApiController extends AbstractExporterController {
dsmCore.updateApiBaseurl(dsId, apiId, baseUrl);
}
@RequestMapping(value = "/ds/api/compliance", method = RequestMethod.POST)
@ApiOperation(value = "update the compatibility of a datasource interface", notes = "update the compatibility of a datasource interface", tags = {
@PostMapping(value = "/ds/api/compliance")
@Operation(summary = "update the compatibility of a datasource interface", description = "update the compatibility of a datasource interface", tags = {
API, W
})
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK"),
@ApiResponse(code = 500, message = "unexpected error", response = ErrorMessage.class)
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "500", description = "unexpected error")
})
public void updateCompliance(
@RequestParam final String dsId,
@ -326,13 +345,13 @@ public class DsmApiController extends AbstractExporterController {
dsmCore.updateApiCompatibility(dsId, apiId, compliance, override);
}
@RequestMapping(value = "/ds/api/oaiset", method = RequestMethod.POST)
@ApiOperation(value = "update the OAI set of a datasource interface", notes = "update the OAI set of a datasource interface", tags = {
@PostMapping(value = "/ds/api/oaiset")
@Operation(summary = "update the OAI set of a datasource interface", description = "update the OAI set of a datasource interface", tags = {
API, W
})
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK"),
@ApiResponse(code = 500, message = "unexpected error", response = ErrorMessage.class)
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "500", description = "unexpected error")
})
public void updateOaiSetl(
@RequestParam final String dsId,
@ -342,13 +361,13 @@ public class DsmApiController extends AbstractExporterController {
dsmCore.updateApiOaiSet(dsId, apiId, oaiSet);
}
@RequestMapping(value = "/ds/api/add", method = RequestMethod.POST)
@ApiOperation(value = "adds a new Interface to one Datasource", notes = "adds an Interface to one Datasource", tags = {
@PostMapping(value = "/ds/api/add")
@Operation(summary = "adds a new Interface to one Datasource", description = "adds an Interface to one Datasource", tags = {
API, W
})
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK"),
@ApiResponse(code = 500, message = "unexpected error", response = ErrorMessage.class)
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "500", description = "unexpected error")
})
public void addApi(@RequestBody final ApiDetails api) throws DsmException {
if (StringUtils.isBlank(api.getDatasource())) { throw new DsmException(HttpStatus.SC_BAD_REQUEST, "missing datasource id"); }
@ -360,48 +379,40 @@ public class DsmApiController extends AbstractExporterController {
@Autowired
private OperationManager operationManager;
@RequestMapping(value = "/dsm/ops", method = RequestMethod.GET)
@ApiOperation(value = "get the number of pending operations", notes = "get the number of pending operations", tags = {
@GetMapping(value = "/dsm/ops")
@Operation(summary = "get the number of pending operations", description = "get the number of pending operations", tags = {
R, M
})
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK"),
@ApiResponse(code = 500, message = "unexpected error", response = ErrorMessage.class)
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "500", description = "unexpected error")
})
public int getOps() throws DsmException {
return operationManager.getOpSize();
}
@RequestMapping(value = "/dsm/killops", method = RequestMethod.POST)
@ApiOperation(value = "interrupts the pending operations", notes = "return the number of interrupted operations", tags = {
@PostMapping(value = "/dsm/killops")
@Operation(summary = "interrupts the pending operations", description = "return the number of interrupted operations", tags = {
W, M
})
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK"),
@ApiResponse(code = 500, message = "unexpected error", response = ErrorMessage.class)
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "500", description = "unexpected error")
})
public int killOps() throws DsmException {
return operationManager.dropAll();
}
@RequestMapping(value = "/dsm/dropcache", method = RequestMethod.POST)
@ApiOperation(value = "drop the caches", notes = "drop the internal caches", tags = {
@PostMapping(value = "/dsm/dropcache")
@Operation(summary = "drop the caches", description = "drop the internal caches", tags = {
W, M
})
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK"),
@ApiResponse(code = 500, message = "unexpected error", response = ErrorMessage.class)
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "500", description = "unexpected error")
})
public void dropCache() throws DsmException {
dsmCore.dropCaches();
}
// HELPERS
private <T extends Response> T prepareResponse(final int page, final int size, final StopWatch stopWatch, final T rsp) {
rsp.getHeader()
.setTime(stopWatch.getTime())
.setPage(page)
.setSize(size);
return rsp;
}
}

View File

@ -0,0 +1,86 @@
package eu.dnetlib.openaire.dsm;
import static eu.dnetlib.openaire.common.ExporterConstants.DS;
import static eu.dnetlib.openaire.common.ExporterConstants.R;
import java.util.List;
import org.apache.commons.lang3.time.StopWatch;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import eu.dnetlib.openaire.common.AbstractExporterController;
import eu.dnetlib.openaire.dsm.dao.ResponseUtils;
import eu.dnetlib.openaire.dsm.domain.SimpleDatasourceInfo;
import eu.dnetlib.openaire.dsm.domain.SimpleResponse;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
@RestController
@CrossOrigin(origins = {
"*"
})
@ConditionalOnProperty(value = "openaire.exporter.enable.dsm", havingValue = "true")
@Tag(name = "OpenAIRE DSM API (version 2.0)", description = "the OpenAIRE Datasource Manager API 2.0")
@RequestMapping("/dsm/2.0")
public class DsmApiControllerV2 extends AbstractExporterController {
@Autowired
private DsmCore dsmCore;
@GetMapping("/recentregistered/{size}")
@Operation(summary = "return the latest datasources that were registered through Provide (v2)", description = "Returns list of Datasource basic info.", tags = {
DS,
R
})
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "500", description = "unexpected error")
})
public SimpleResponse<SimpleDatasourceInfo> recentRegisteredV2(@PathVariable final int size) throws Throwable {
final StopWatch stop = StopWatch.createStarted();
final SimpleResponse<SimpleDatasourceInfo> rsp = dsmCore.searchRecentRegisteredV2(size);
return prepareResponse(1, size, stop, rsp);
}
@GetMapping("/countfirstcollect")
@Operation(summary = "return the number of datasources registered after the given date", description = "Returns a number.", tags = {
DS,
R
})
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "500", description = "unexpected error")
})
public Long countFirstCollectAfter(@RequestParam final String fromDate,
@RequestParam(required = false) final String typologyFilter) throws Throwable {
return dsmCore.countFirstCollect(fromDate, typologyFilter);
}
@GetMapping("/firstCollected")
@Operation(summary = "return the datasources that were collected for the first time after the specified date", description = "Returns list of Datasource basic info.", tags = {
DS,
R
})
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "500", description = "unexpected error")
})
public SimpleResponse<SimpleDatasourceInfo> firstCollectedAfter(@RequestParam final String fromDate,
@RequestParam(required = false) final String typologyFilter) throws Throwable {
final StopWatch stop = StopWatch.createStarted();
final List<SimpleDatasourceInfo> list = dsmCore.getFirstCollectedAfter(fromDate, typologyFilter);
final SimpleResponse<SimpleDatasourceInfo> rsp = ResponseUtils.simpleResponse(list);
return prepareResponse(1, list.size(), stop, rsp);
}
}

View File

@ -14,6 +14,8 @@ import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.transaction.Transactional;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
@ -24,6 +26,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.data.domain.Page;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Component;
import eu.dnetlib.enabling.datasources.common.AggregationInfo;
@ -43,11 +46,13 @@ import eu.dnetlib.openaire.dsm.domain.ApiDetailsResponse;
import eu.dnetlib.openaire.dsm.domain.DatasourceDetailResponse;
import eu.dnetlib.openaire.dsm.domain.DatasourceDetails;
import eu.dnetlib.openaire.dsm.domain.DatasourceDetailsUpdate;
import eu.dnetlib.openaire.dsm.domain.DatasourceDetailsWithApis;
import eu.dnetlib.openaire.dsm.domain.DatasourceSnippetResponse;
import eu.dnetlib.openaire.dsm.domain.RegisteredDatasourceInfo;
import eu.dnetlib.openaire.dsm.domain.RequestFilter;
import eu.dnetlib.openaire.dsm.domain.RequestSort;
import eu.dnetlib.openaire.dsm.domain.RequestSortOrder;
import eu.dnetlib.openaire.dsm.domain.SimpleDatasourceInfo;
import eu.dnetlib.openaire.dsm.domain.SimpleResponse;
import eu.dnetlib.openaire.dsm.domain.db.ApiDbEntry;
import eu.dnetlib.openaire.dsm.domain.db.DatasourceDbEntry;
@ -144,11 +149,12 @@ public class DsmCore {
public ApiDetailsResponse getApis(final String dsId) throws DsmException {
try {
final String eoscType = dsDao.getDs(dsId).getEoscDatasourceType();
final DatasourceDbEntry ds = dsDao.getDs(dsId);
final List<? extends ApiDbEntry> apis = dsDao.getApis(dsId);
final List<ApiDetails> api = apis.stream()
.map(DsmMappingUtils::asDetails)
.map(a -> a.setEoscDatasourceType(eoscType))
.map(a -> a.setEoscDatasourceType(ds.getEoscDatasourceType()))
.map(a -> a.setTypology(ds.getTypology()))
.collect(Collectors.toList());
return ResponseUtils.apiResponse(api, api.size());
} catch (final Throwable e) {
@ -173,12 +179,32 @@ public class DsmCore {
public void save(final DatasourceDetails d) throws DsmException {
try {
dsDao.saveDs(asDbEntry(d));
log.info("DS saved, " + d.getId());
} catch (final Throwable e) {
log.error(ExceptionUtils.getStackTrace(e));
throw e;
}
}
@Transactional
public void save(final DatasourceDetailsWithApis d) throws DsmException {
try {
dsDao.saveDs(asDbEntry(d.getDatasource()));
final List<ApiDetails> apis = d.getApis();
if (apis != null) {
for (final ApiDetails api : apis) {
api.setDatasource(d.getDatasource().getId());
addApi(api);
}
}
} catch (
final Throwable e) {
log.error(ExceptionUtils.getStackTrace(e));
throw e;
}
}
public void updateDatasource(final DatasourceDetailsUpdate d) throws DsmException, DsmNotFoundException {
try {
// initialize with current values from DB
@ -234,6 +260,7 @@ public class DsmCore {
log.info(String.format("missing api id, created '%s'", api.getId()));
}
dsDao.addApi(asDbEntry(api));
log.info("API saved, id: " + api.getId());
}
public void deleteApi(final String apiId) throws DsmForbiddenException, DsmNotFoundException {
@ -250,7 +277,7 @@ public class DsmCore {
// HELPERS //////////////
public SimpleResponse<?> searchRecentRegistered(final int size) throws Throwable {
public SimpleResponse<RegisteredDatasourceInfo> searchRecentRegistered(final int size) throws Throwable {
try {
final String sql =
IOUtils.toString(getClass().getResourceAsStream("/eu/dnetlib/openaire/sql/recent_registered_datasources.sql.st"), Charset.defaultCharset());
@ -293,4 +320,123 @@ public class DsmCore {
return rsp;
}
public SimpleResponse<SimpleDatasourceInfo> searchRecentRegisteredV2(final int size) throws Throwable {
try {
final String sql =
IOUtils.toString(getClass().getResourceAsStream("/eu/dnetlib/openaire/sql/recent_registered_datasources_v2.sql.st"), Charset.defaultCharset());
final List<SimpleDatasourceInfo> list =
jdbcTemplate.query(sql, rowMapperForSimpleDatasourceInfo(), size);
return ResponseUtils.simpleResponse(list);
} catch (final Throwable e) {
log.error("error searching recent datasources", e);
throw e;
}
}
public Long countFirstCollect(final String fromDate, final String typeFilter) throws Throwable {
try {
if (StringUtils.isNotBlank(typeFilter)) {
final String sql =
IOUtils
.toString(getClass().getResourceAsStream("/eu/dnetlib/openaire/sql/count_first_collected_datasources_fromDate_typology.st.sql"), Charset
.defaultCharset());
return jdbcTemplate.queryForObject(sql, Long.class, typeFilter + "%", fromDate);
} else {
final String sql =
IOUtils.toString(getClass().getResourceAsStream("/eu/dnetlib/openaire/sql/count_first_collected_datasources_fromDate.st.sql"), Charset
.defaultCharset());
return jdbcTemplate.queryForObject(sql, Long.class, fromDate);
}
} catch (final Throwable e) {
log.error("error searching datasources using the first collection date", e);
throw e;
}
}
public List<SimpleDatasourceInfo> getFirstCollectedAfter(final String fromDate, final String typeFilter) throws Throwable {
try {
if (StringUtils.isNotBlank(typeFilter)) {
final String sql =
IOUtils
.toString(getClass().getResourceAsStream("/eu/dnetlib/openaire/sql/first_collected_datasources_fromDate_typology.st.sql"), Charset
.defaultCharset());
return jdbcTemplate.query(sql, rowMapperForSimpleDatasourceInfo(), typeFilter + "%", fromDate);
} else {
final String sql =
IOUtils
.toString(getClass().getResourceAsStream("/eu/dnetlib/openaire/sql/first_collected_datasources_fromDate.st.sql"), Charset
.defaultCharset());
return jdbcTemplate.query(sql, rowMapperForSimpleDatasourceInfo(), fromDate);
}
} catch (final Throwable e) {
log.error("error searching datasources using the first collection date", e);
throw e;
}
}
private RowMapper<SimpleDatasourceInfo> rowMapperForSimpleDatasourceInfo() {
return (rs, rowNum) -> {
final SimpleDatasourceInfo info = new SimpleDatasourceInfo();
info.setId(rs.getString("id"));
info.setOfficialName(rs.getString("officialName"));
info.setEnglishName(rs.getString("englishName"));
info.setTypology(rs.getString("typology"));
info.setEoscType(rs.getString("eoscType"));
info.setEoscDatasourceType(rs.getString("eoscDatasourceType"));
info.setRegisteredBy(rs.getString("registeredBy"));
info.setRegistrationDate(rs.getString("registrationDate"));
info.setFirstCollectionDate(rs.getString("firstCollectionDate"));
info.setLastCollectionDate(rs.getString("lastCollectionDate"));
info.setLastCollectionTotal(rs.getLong("lastCollectionTotal"));
final Set<String> compatibilities = new HashSet<>();
for (final String s : (String[]) rs.getArray("compatibilities").getArray()) {
compatibilities.add(s);
}
// The order of the condition is important
if (compatibilities.contains("openaire-cris_1.1")) {
info.setCompatibility("openaire-cris_1.1");
} else if (compatibilities.contains("openaire4.0")) {
info.setCompatibility("openaire4.0");
} else if (compatibilities.contains("driver") && compatibilities.contains("openaire2.0")) {
info.setCompatibility("driver-openaire2.0");
} else if (compatibilities.contains("driver")) {
info.setCompatibility("driver");
} else if (compatibilities.contains("openaire2.0")) {
info.setCompatibility("openaire2.0");
} else if (compatibilities.contains("openaire3.0")) {
info.setCompatibility("openaire3.0");
} else if (compatibilities.contains("openaire2.0_data")) {
info.setCompatibility("openaire2.0_data");
} else if (compatibilities.contains("native")) {
info.setCompatibility("native");
} else if (compatibilities.contains("hostedBy")) {
info.setCompatibility("hostedBy");
} else if (compatibilities.contains("notCompatible")) {
info.setCompatibility("notCompatible");
} else {
info.setCompatibility("UNKNOWN");
}
for (final String s : (String[]) rs.getArray("organizations").getArray()) {
info.getOrganizations().put(StringUtils.substringBefore(s, "@@@").trim(), StringUtils.substringAfter(s, "@@@").trim());
}
return info;
};
}
}

View File

@ -1,5 +1,21 @@
package eu.dnetlib.openaire.dsm.dao;
import java.util.Arrays;
import java.util.List;
import java.util.Map.Entry;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.data.jpa.domain.Specification;
import eu.dnetlib.enabling.datasources.common.DsmRuntimeException;
import eu.dnetlib.openaire.dsm.domain.FilterName;
import eu.dnetlib.openaire.dsm.domain.RequestFilter;
@ -7,15 +23,6 @@ import eu.dnetlib.openaire.dsm.domain.RequestSort;
import eu.dnetlib.openaire.dsm.domain.RequestSortOrder;
import eu.dnetlib.openaire.dsm.domain.db.DatasourceApiDbEntry;
import eu.dnetlib.openaire.dsm.domain.db.DatasourceDbEntry;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.data.jpa.domain.Specification;
import javax.persistence.criteria.*;
import java.util.List;
import java.util.Map.Entry;
public class DatasourceSpecs {
@ -24,39 +31,43 @@ public class DatasourceSpecs {
public static final String WILDCARD = "%";
public static Specification<DatasourceDbEntry> dsRegisteredbyNotNullSpec() {
return (ds, query, cb) -> cb.and(
cb.isNull(ds.get(FilterName.registeredby.name())).not(),
cb.isNull(ds.get("registrationdate")).not());
return (ds, query, cb) -> cb.and(cb.isNull(ds.get(FilterName.registeredby.name())).not(), cb.isNull(ds.get("registrationdate")).not());
}
public static Specification<DatasourceDbEntry> dsSpec(final RequestSort requestSortBy, final RequestSortOrder order, final RequestFilter requestFilter) {
log.debug(String.format("RequestFilter:'%s', RequestSort:'%s', RequestSortOrder:'%s'", requestFilter, requestSortBy, order));
return (ds, query, cb) -> {
final Predicate p = cb.conjunction();
final List<Expression<Boolean>> expressions = p.getExpressions();
expressions.add(cb.equal(ds.get("eoscType"), "Data Source"));
expressions.add(cb.equal(ds.get("dedupMainService"), true));
if (requestFilter != null) {
final List<Expression<Boolean>> expressions = p.getExpressions();
requestFilter.entrySet().stream()
.forEach(e -> {
switch (FilterName.type(e.getKey())) {
requestFilter.entrySet()
.stream()
.forEach(e -> {
switch (FilterName.type(e.getKey())) {
case exact:
expressions.add(exactSearch(ds, cb, e));
case exact:
expressions.add(exactSearch(ds, cb, e));
break;
case search:
expressions.add(likeSearch(ds, cb, e));
break;
case search:
expressions.add(likeSearch(ds, cb, e));
break;
case searchOrgs:
// search by case insensitive organization's country
expressions.add(
cb.equal(
cb.lower(
ds.join("organizations").get(FilterName.country.name())),
getValue(e)));
break;
}
});
break;
case multiSearch:
expressions.add(likeSearchList(ds, cb, e));
break;
case searchOrgs:
// search by case insensitive organization's country
expressions.add(cb.equal(cb.lower(ds.join("organizations").get(FilterName.country.name())), getValue(e)));
break;
}
});
}
if (requestSortBy != null) {
if (order != null) {
@ -83,21 +94,27 @@ public class DatasourceSpecs {
final Predicate p = cb.conjunction();
if (requestFilter != null) {
final List<Expression<Boolean>> expressions = p.getExpressions();
requestFilter.entrySet().stream()
.forEach(e -> {
switch (FilterName.type(e.getKey())) {
requestFilter.entrySet()
.stream()
.forEach(e -> {
switch (FilterName.type(e.getKey())) {
case exact:
expressions.add(exactSearch(api, cb, e));
break;
case search:
case exact:
expressions.add(exactSearch(api, cb, e));
break;
case search:
expressions.add(likeSearch(api, cb, e));
break;
case searchOrgs:
throw new DsmRuntimeException("not implemented");
}
});
expressions.add(likeSearch(api, cb, e));
break;
case multiSearch:
expressions.add(likeSearchList(api, cb, e));
break;
case searchOrgs:
throw new DsmRuntimeException("not implemented");
}
});
}
query.distinct(true);
return p;
@ -108,32 +125,40 @@ public class DatasourceSpecs {
// substring, case insensitive, like based search
private static Predicate likeSearch(final Root<?> r, final CriteriaBuilder cb, final Entry<FilterName, Object> e) {
return cb.like(
cb.lower(
r.get(e.getKey().name())),
WILDCARD + getValue(e) + WILDCARD);
return cb.like(cb.lower(r.get(e.getKey().name())), WILDCARD + getValue(e) + WILDCARD);
}
// search by ID, managed. exact match
// substring, case insensitive, like based search
private static Predicate likeSearchList(final Root<?> r, final CriteriaBuilder cb, final Entry<FilterName, Object> e) {
final String key = e.getKey().name();
final Predicate[] arr =
Arrays.stream(e.getValue().toString().split(","))
.map(String::trim)
.map(String::toLowerCase)
.filter(StringUtils::isNotBlank)
.map(s -> cb.like(cb.lower(r.get(key)), WILDCARD + s + WILDCARD))
.toArray(size -> new Predicate[size]);
return cb.or(arr);
}
// search by ID, managed. exact match
private static Predicate exactSearch(final Root<?> r, final CriteriaBuilder cb, final Entry<FilterName, Object> e) {
return cb.equal(r.get(e.getKey().name()), getValue(e));
}
private static Object getValue(final Entry<FilterName, Object> e) {
if (e.getValue() instanceof String) {
final String s = ((String) e.getValue());
final String s = (String) e.getValue();
if (!e.getKey().equals(FilterName.country)) {
Boolean b = BooleanUtils.toBooleanObject(s);
if (b != null) {
return b;
}
final Boolean b = BooleanUtils.toBooleanObject(s);
if (b != null) { return b; }
}
return e.getKey().equals(FilterName.id) ? s : StringUtils.lowerCase(s);
}
if (e.getValue() instanceof Boolean) {
return e.getValue();
}
if (e.getValue() instanceof Boolean) { return e.getValue(); }
return e.getValue();
}

View File

@ -15,6 +15,7 @@ import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.logging.Log;
@ -148,21 +149,25 @@ public class MongoLoggerClientImpl implements MongoLoggerClient {
AggregationInfo info = null;
final AggregationStage stage = AggregationStage.parse(d.getString("system:wfName"));
final boolean success = isCompletedSuccesfully(d);
switch (stage) {
case COLLECT:
final CollectionInfo cInfo = new CollectionInfo();
cInfo.setAggregationStage(stage);
cInfo.setCollectionMode(getCollectionMode(d));
cInfo.setNumberOfRecords(getNumberOfRecords(d));
cInfo.setNumberOfRecords(success ? getNumberOfRecords(d) : 0);
cInfo.setDate(getDate(d));
cInfo.setCompletedSuccessfully(success);
info = cInfo;
break;
case TRANSFORM:
final TransformationInfo tInfo = new TransformationInfo();
tInfo.setAggregationStage(stage);
tInfo.setNumberOfRecords(getNumberOfRecords(d));
tInfo.setNumberOfRecords(success ? getNumberOfRecords(d) : 0);
tInfo.setDate(getDate(d));
tInfo.setCompletedSuccessfully(success);
info = tInfo;
break;
}
@ -198,8 +203,13 @@ public class MongoLoggerClientImpl implements MongoLoggerClient {
return DateFormatUtils.format(new DateUtils().parse(dateString), DsmMappingUtils.DATE_FORMAT);
}
private boolean isCompletedSuccesfully(final Document d) {
final String boolString = d.getString("system:isCompletedSuccessfully");
return BooleanUtils.toBoolean(boolString);
}
private static Bson getFields() {
return fields(eq("system:wfName", 1), eq("system:node:SELECT_MODE:selection", 1), eq("collectionMode", 1), eq("mainlog:sinkSize", 1), eq("mainlog:writeOps", 1), eq("mainlog:total", 1), eq("system:startHumanDate", 1), eq("system:profileName", 1));
return fields(eq("system:wfName", 1), eq("system:node:SELECT_MODE:selection", 1), eq("collectionMode", 1), eq("mainlog:sinkSize", 1), eq("mainlog:writeOps", 1), eq("mainlog:total", 1), eq("system:startHumanDate", 1), eq("system:profileName", 1), eq("system:isCompletedSuccessfully", 1));
}
private static BasicDBObject dbo(final String key, final Object value) {
@ -207,7 +217,7 @@ public class MongoLoggerClientImpl implements MongoLoggerClient {
}
private Bson queryForAggregationHistory(final String dsId, final String pattern) {
return and(eq("parentDatasourceId", dsId), eq("system:profileFamily", "aggregator"), eq("system:isCompletedSuccessfully", "true"), regex("system:wfName", pattern, "i"));
return and(eq("parentDatasourceId", dsId), eq("system:profileFamily", "aggregator"), regex("system:wfName", pattern, "i"));
}
private synchronized MongoCollection<Document> getCollection() {

View File

@ -52,8 +52,8 @@ public class ResponseUtils {
return header(Lists.newLinkedList(), total);
}
public static SimpleResponse<?> simpleResponse(final List<?> list) {
final SimpleResponse rsp = new SimpleResponse().setResponse(list);;
public static <T> SimpleResponse<T> simpleResponse(final List<T> list) {
final SimpleResponse<T> rsp = new SimpleResponse<T>().setResponse(list);;
rsp.setHeader(header(Lists.newLinkedList(), list.size()));
return rsp;
}

View File

@ -76,7 +76,17 @@ public class DsmMappingUtils {
}
public static ApiDbEntry asDbEntry(final ApiDetails d) {
final ApiDbEntry apiDbEntry = _convert(d, ApiDbEntry.class);
final ApiDbEntry apiDbEntry = new ApiDbEntry();
apiDbEntry.setId(d.getId());
apiDbEntry.setBaseurl(d.getBaseurl());
apiDbEntry.setProtocol(d.getProtocol());
apiDbEntry.setDatasource(d.getDatasource());
apiDbEntry.setContentdescription(d.getContentdescription());
apiDbEntry.setCompatibility(d.getCompatibility());
apiDbEntry.setCompatibilityOverride(d.getCompatibilityOverride());
apiDbEntry.setRemovable(d.getRemovable());
apiDbEntry.setMetadataIdentifierPath(d.getMetadataIdentifierPath());
// Need to complete the references among objects, because you know, referential integrity ...
apiDbEntry.getApiParams().forEach(ap -> ap.getId().setApi(apiDbEntry));

View File

@ -1,29 +1,26 @@
package eu.dnetlib.openaire.dsm.domain;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import eu.dnetlib.enabling.datasources.common.AggregationInfo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.util.List;
@ApiModel
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import eu.dnetlib.enabling.datasources.common.AggregationInfo;
@JsonAutoDetect
public class AggregationHistoryResponse extends Response {
@ApiModelProperty(position = 1)
private List<AggregationInfo> aggregationInfo;
private List<AggregationInfo> aggregationInfo;
public AggregationHistoryResponse(List<AggregationInfo> aggregationInfo) {
super();
this.aggregationInfo = aggregationInfo;
}
public AggregationHistoryResponse(final List<AggregationInfo> aggregationInfo) {
super();
this.aggregationInfo = aggregationInfo;
}
public List<AggregationInfo> getAggregationInfo() {
return aggregationInfo;
}
public List<AggregationInfo> getAggregationInfo() {
return aggregationInfo;
}
public void setAggregationInfo(List<AggregationInfo> aggregationInfo) {
this.aggregationInfo = aggregationInfo;
}
public void setAggregationInfo(final List<AggregationInfo> aggregationInfo) {
this.aggregationInfo = aggregationInfo;
}
}

View File

@ -5,64 +5,48 @@ import java.util.Set;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
@JsonAutoDetect
@ApiModel(value = "Api model", description = "provides information about the datasource API")
@Schema(name = "Api model", description = "provides information about the datasource API")
public class ApiDetails extends ApiIgnoredProperties {
@ApiModelProperty(position = 0)
private String id = null;
@ApiModelProperty(position = 1)
private String protocol = null;
@ApiModelProperty(position = 2)
private String datasource = null;
@ApiModelProperty(position = 3)
private String contentdescription = null;
@ApiModelProperty(position = 4)
private String eoscDatasourceType = null;
@ApiModelProperty(position = 5)
private String compatibility;
@ApiModelProperty(position = 7)
private String compatibilityOverride;
@ApiModelProperty(position = 8)
private Integer lastCollectionTotal;
@ApiModelProperty(position = 9)
private Date lastCollectionDate;
@ApiModelProperty(position = 10)
private Integer lastAggregationTotal;
@ApiModelProperty(position = 11)
private Date lastAggregationDate;
@ApiModelProperty(position = 12)
private Integer lastDownloadTotal;
@ApiModelProperty(position = 13)
private Date lastDownloadDate;
@ApiModelProperty(position = 14)
private String baseurl;
@ApiModelProperty(position = 15)
protected Boolean removable = false;
@ApiModelProperty(position = 16)
private Set<ApiParamDetails> apiParams;
@ApiModelProperty(position = 17)
private String metadataIdentifierPath = "";
private String typology = null;
public String getId() {
return id;
}
@ -214,4 +198,13 @@ public class ApiDetails extends ApiIgnoredProperties {
this.eoscDatasourceType = eoscDatasourceType;
return this;
}
public String getTypology() {
return typology;
}
public ApiDetails setTypology(final String typology) {
this.typology = typology;
return this;
}
}

View File

@ -3,14 +3,13 @@ package eu.dnetlib.openaire.dsm.domain;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@ApiModel
import io.swagger.v3.oas.annotations.media.Schema;
@JsonAutoDetect
public class ApiDetailsResponse extends Response {
@ApiModelProperty(position = 1)
private List<ApiDetails> api;
public List<ApiDetails> getApi() {

View File

@ -3,12 +3,11 @@ package eu.dnetlib.openaire.dsm.domain;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import eu.dnetlib.enabling.datasources.common.AggregationInfo;
import io.swagger.annotations.ApiModel;
import io.swagger.v3.oas.annotations.media.Schema;
/**
* Created by claudio on 29/11/2016.
*/
@ApiModel
@JsonAutoDetect
public class CollectionInfo extends AggregationInfo {

View File

@ -1,13 +1,12 @@
package eu.dnetlib.openaire.dsm.domain;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import io.swagger.annotations.ApiModel;
/**
* Created by claudio on 12/09/16.
*/
@ApiModel
@JsonAutoDetect
public enum CollectionMode {
REFRESH, INCREMENTAL
REFRESH,
INCREMENTAL
}

View File

@ -1,28 +1,24 @@
package eu.dnetlib.openaire.dsm.domain;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.util.List;
@ApiModel
import com.fasterxml.jackson.annotation.JsonAutoDetect;
@JsonAutoDetect
public class DatasourceDetailResponse extends Response {
@ApiModelProperty(position = 1)
private List<DatasourceDetails> datasourceInfo;
private List<DatasourceDetails> datasourceInfo;
public DatasourceDetailResponse(List<DatasourceDetails> datasourceInfo) {
super();
this.datasourceInfo = datasourceInfo;
}
public DatasourceDetailResponse(final List<DatasourceDetails> datasourceInfo) {
super();
this.datasourceInfo = datasourceInfo;
}
public List<DatasourceDetails> getDatasourceInfo() {
return datasourceInfo;
}
public List<DatasourceDetails> getDatasourceInfo() {
return datasourceInfo;
}
public void setDatasourceInfo(List<DatasourceDetails> datasourceInfo) {
this.datasourceInfo = datasourceInfo;
}
public void setDatasourceInfo(final List<DatasourceDetails> datasourceInfo) {
this.datasourceInfo = datasourceInfo;
}
}

View File

@ -9,128 +9,92 @@ import javax.validation.constraints.NotBlank;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
/**
* Created by claudio on 12/09/16.
*/
@JsonAutoDetect
@ApiModel(value = "Datasource model", description = "provides information about the datasource")
@Schema(name = "Datasource model", description = "provides information about the datasource")
public class DatasourceDetails extends DatasourceIgnoredProperties {
@NotBlank
@ApiModelProperty(position = 0)
private String id;
@Transient
@ApiModelProperty(position = 1)
private String openaireId;
@NotBlank
@ApiModelProperty(position = 2)
private String officialname;
@NotBlank
@ApiModelProperty(position = 3)
private String englishname;
@ApiModelProperty(position = 4)
private String websiteurl;
@ApiModelProperty(position = 5)
private String logourl;
@Email
@ApiModelProperty(position = 6)
private String contactemail;
@ApiModelProperty(position = 7)
private Double latitude;
@ApiModelProperty(position = 8)
private Double longitude;
@ApiModelProperty(position = 9)
private String timezone;
@NotBlank
@ApiModelProperty(position = 10)
private String namespaceprefix;
@ApiModelProperty(position = 11)
private String languages;
@ApiModelProperty(position = 12)
private Date dateofvalidation;
@NotBlank
@ApiModelProperty(position = 13)
private String eoscDatasourceType;
@ApiModelProperty(position = 14)
private Date dateofcollection;
@ApiModelProperty(position = 15)
private String platform;
@ApiModelProperty(position = 16)
private String activationId;
@ApiModelProperty(position = 17)
private String description;
@ApiModelProperty(position = 18)
private String issn;
@ApiModelProperty(position = 19)
private String eissn;
@ApiModelProperty(position = 20)
private String lissn;
@Email
@ApiModelProperty(position = 21)
private String registeredby;
@ApiModelProperty(position = 22)
private String subjects;
@ApiModelProperty(position = 23)
protected String aggregator = "OPENAIRE";
@ApiModelProperty(position = 24)
protected String collectedfrom;
@ApiModelProperty(position = 25)
private Boolean managed;
@ApiModelProperty(position = 28)
private Boolean consentTermsOfUse;
@ApiModelProperty(position = 29)
private Boolean fullTextDownload;
@ApiModelProperty(position = 30)
private Date consentTermsOfUseDate;
@ApiModelProperty(position = 31)
private Date lastConsentTermsOfUseDate;
@ApiModelProperty(position = 26)
private Set<OrganizationDetails> organizations;
@ApiModelProperty(position = 27)
private Set<IdentitiesDetails> identities;
@ApiModelProperty(position = 32)
private String status;
@Deprecated
@ApiModelProperty(position = 33)
private String typology;
@ApiModelProperty(position = 34)
private Date registrationdate;
public String getId() {

View File

@ -8,80 +8,59 @@ import javax.validation.constraints.NotBlank;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
/**
* Created by claudio on 12/09/16.
*/
@JsonAutoDetect
@ApiModel(value = "Datasource updatable fields model", description = "provides information about the datasource field that can be updated")
@Schema(name = "Datasource updatable fields model", description = "provides information about the datasource field that can be updated")
public class DatasourceDetailsUpdate {
@NotBlank
@ApiModelProperty(position = 0)
private String id;
@NotBlank
@ApiModelProperty(position = 2)
private String officialname;
@NotBlank
@ApiModelProperty(position = 3)
private String englishname;
@ApiModelProperty(position = 4)
private String websiteurl;
@ApiModelProperty(position = 5)
private String logourl;
@Email
@ApiModelProperty(position = 6)
private String contactemail;
@ApiModelProperty(position = 7)
private Double latitude;
@ApiModelProperty(position = 8)
private Double longitude;
@ApiModelProperty(position = 9)
private String timezone;
@Deprecated
@ApiModelProperty(position = 12)
private String typology;
@ApiModelProperty(position = 13)
private String eoscDatasourceType;
@ApiModelProperty(position = 15)
private String platform;
@ApiModelProperty(position = 17)
private String description;
@Email
@ApiModelProperty(position = 21)
private String registeredby;
@ApiModelProperty(position = 25)
private Boolean managed;
@ApiModelProperty(position = 27)
private Set<IdentitiesDetails> identities;
@ApiModelProperty(position = 28)
private Boolean consentTermsOfUse;
@ApiModelProperty(position = 29)
private Date consentTermsOfUseDate;
@ApiModelProperty(position = 29)
private Date lastConsentTermsOfUseDate;
@ApiModelProperty(position = 31)
private Boolean fullTextDownload;
public String getId() {

View File

@ -0,0 +1,37 @@
package eu.dnetlib.openaire.dsm.domain;
import java.util.ArrayList;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import io.swagger.v3.oas.annotations.media.Schema;
/**
* Created by claudio on 12/09/16.
*/
@JsonAutoDetect
@Schema(name = "Datasource model with apis", description = "provides information about the datasource and its apis")
public class DatasourceDetailsWithApis {
private DatasourceDetails datasource;
private List<ApiDetails> apis = new ArrayList<>();
public DatasourceDetails getDatasource() {
return datasource;
}
public void setDatasource(final DatasourceDetails datasource) {
this.datasource = datasource;
}
public List<ApiDetails> getApis() {
return apis;
}
public void setApis(final List<ApiDetails> apis) {
this.apis = apis;
}
}

View File

@ -54,6 +54,12 @@ public abstract class DatasourceIgnoredProperties {
@JsonIgnore
protected String certificates;
@JsonIgnore
protected String eoscType;
@JsonIgnore
protected Boolean dedupMainService;
public String getOd_contenttypes() {
return od_contenttypes;
}
@ -182,4 +188,20 @@ public abstract class DatasourceIgnoredProperties {
this.certificates = certificates;
}
public String getEoscType() {
return eoscType;
}
public void setEoscType(final String eoscType) {
this.eoscType = eoscType;
}
public Boolean getDedupMainService() {
return dedupMainService;
}
public void setDedupMainService(final Boolean dedupMainService) {
this.dedupMainService = dedupMainService;
}
}

View File

@ -3,39 +3,30 @@ package eu.dnetlib.openaire.dsm.domain;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import eu.dnetlib.enabling.datasources.common.AggregationInfo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
@JsonAutoDetect
@ApiModel(value = "Datasource info model", description = "provides information about the datasource and its aggregation status")
@Schema(name = "Datasource info model", description = "provides information about the datasource and its aggregation status")
public class DatasourceInfo {
@ApiModelProperty(position = 0)
private long indexRecords;
@ApiModelProperty(position = 1)
private long fundedContent;
@ApiModelProperty(position = 2)
private long fulltexts;
@ApiModelProperty(position = 3)
private String lastIndexingDate;
@ApiModelProperty(position = 4)
private String firstHarvestDate;
@ApiModelProperty(position = 5)
private DatasourceDetails datasource;
@ApiModelProperty(position = 6)
private AggregationInfo lastCollection;
@ApiModelProperty(position = 7)
private AggregationInfo lastTransformation;
@ApiModelProperty(position = 8)
private List<AggregationInfo> aggregationHistory;
public DatasourceInfo() {

View File

@ -4,9 +4,7 @@ import java.util.List;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.google.common.collect.Lists;
import io.swagger.annotations.ApiModel;
@ApiModel
@JsonAutoDetect
public class DatasourceResponse<T> extends Response {

View File

@ -1,28 +1,24 @@
package eu.dnetlib.openaire.dsm.domain;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.util.List;
@ApiModel
import com.fasterxml.jackson.annotation.JsonAutoDetect;
@JsonAutoDetect
public class DatasourceSearchResponse extends Response {
@ApiModelProperty(position = 1)
private List<DatasourceInfo> datasourceInfo;
private List<DatasourceInfo> datasourceInfo;
public DatasourceSearchResponse(List<DatasourceInfo> datasourceInfo) {
super();
this.datasourceInfo = datasourceInfo;
}
public DatasourceSearchResponse(final List<DatasourceInfo> datasourceInfo) {
super();
this.datasourceInfo = datasourceInfo;
}
public List<DatasourceInfo> getDatasourceInfo() {
return datasourceInfo;
}
public List<DatasourceInfo> getDatasourceInfo() {
return datasourceInfo;
}
public void setDatasourceInfo(List<DatasourceInfo> datasourceInfo) {
this.datasourceInfo = datasourceInfo;
}
public void setDatasourceInfo(final List<DatasourceInfo> datasourceInfo) {
this.datasourceInfo = datasourceInfo;
}
}

View File

@ -4,23 +4,19 @@ import javax.validation.constraints.NotBlank;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
@JsonAutoDetect
@ApiModel(value = "Datasource model", description = "provides information about the datasource")
@Schema(name = "Datasource model", description = "provides information about the datasource")
public class DatasourceSnippet {
@NotBlank
@ApiModelProperty(position = 0)
private String id;
@NotBlank
@ApiModelProperty(position = 2)
private String officialname;
@NotBlank
@ApiModelProperty(position = 3)
private String englishname;
public String getId() {

View File

@ -8,61 +8,45 @@ import javax.validation.constraints.NotBlank;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
@JsonAutoDetect
@ApiModel(value = "Datasource model", description = "provides extended information about the datasource")
@Schema(name = "Datasource model", description = "provides extended information about the datasource")
public class DatasourceSnippetExtended {
@NotBlank
@ApiModelProperty(position = 0)
private String id;
@NotBlank
@ApiModelProperty(position = 2)
private String officialname;
@NotBlank
@ApiModelProperty(position = 3)
private String englishname;
@ApiModelProperty(position = 4)
private String websiteurl;
@Email
@ApiModelProperty(position = 5)
private String registeredby;
@ApiModelProperty(position = 6)
private Date registrationdate;
@ApiModelProperty(position = 7)
private String eoscDatasourceType;
@ApiModelProperty(position = 8)
private String logoUrl;
@ApiModelProperty(position = 9)
private String description;
@ApiModelProperty(position = 10)
private Boolean consentTermsOfUse;
@ApiModelProperty(position = 11)
private Date consentTermsOfUseDate;
@ApiModelProperty(position = 12)
private Date lastConsentTermsOfUseDate;
@ApiModelProperty(position = 13)
private Boolean fullTextDownload;
@ApiModelProperty(position = 14)
private Set<OrganizationDetails> organizations;
@Deprecated
@ApiModelProperty(position = 15)
private String typology;
public String getId() {

View File

@ -1,28 +1,24 @@
package eu.dnetlib.openaire.dsm.domain;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.util.List;
@ApiModel
import com.fasterxml.jackson.annotation.JsonAutoDetect;
@JsonAutoDetect
public class DatasourceSnippetResponse extends Response {
@ApiModelProperty(position = 1)
private List<DatasourceSnippetExtended> datasourceInfo;
private List<DatasourceSnippetExtended> datasourceInfo;
public DatasourceSnippetResponse(List<DatasourceSnippetExtended> datasourceInfo) {
super();
this.datasourceInfo = datasourceInfo;
}
public DatasourceSnippetResponse(final List<DatasourceSnippetExtended> datasourceInfo) {
super();
this.datasourceInfo = datasourceInfo;
}
public List<DatasourceSnippetExtended> getDatasourceInfo() {
return datasourceInfo;
}
public List<DatasourceSnippetExtended> getDatasourceInfo() {
return datasourceInfo;
}
public void setDatasourceInfo(List<DatasourceSnippetExtended> datasourceInfo) {
this.datasourceInfo = datasourceInfo;
}
public void setDatasourceInfo(final List<DatasourceSnippetExtended> datasourceInfo) {
this.datasourceInfo = datasourceInfo;
}
}

View File

@ -2,10 +2,10 @@ package eu.dnetlib.openaire.dsm.domain;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import io.swagger.annotations.ApiModel;
import io.swagger.v3.oas.annotations.media.Schema;
@JsonAutoDetect
@ApiModel(value = "Filter name", description = "List of the field names used to filter datasources")
@Schema(name = "Filter name", description = "List of the field names used to filter datasources")
public enum FilterName {
id,
@ -16,6 +16,7 @@ public enum FilterName {
websiteurl,
contactemail,
registeredby,
typology,
eoscDatasourceType,
platform, // like match
country; // exact match on related organization
@ -31,9 +32,11 @@ public enum FilterName {
case websiteurl:
case contactemail:
case registeredby:
case eoscDatasourceType:
case typology:
case platform:
return FilterType.search;
case eoscDatasourceType:
return FilterType.multiSearch;
case country:
return FilterType.searchOrgs;
default:

View File

@ -1,5 +1,8 @@
package eu.dnetlib.openaire.dsm.domain;
public enum FilterType {
exact, search, searchOrgs
exact,
search,
searchOrgs,
multiSearch
}

View File

@ -8,29 +8,20 @@ import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.google.common.collect.Lists;
import com.google.gson.GsonBuilder;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@ApiModel
@JsonAutoDetect
public class Header {
@ApiModelProperty(position = 0)
private long total;
@ApiModelProperty(position = 1)
private int page;
@ApiModelProperty(position = 2)
private int size;
@ApiModelProperty(position = 3)
private long time;
@ApiModelProperty(position = 4)
private int statusCode;
@ApiModelProperty(position = 5)
private List<String> errors = Lists.newArrayList();
@JsonIgnore
@ -40,8 +31,7 @@ public class Header {
return new Header();
}
public Header() {
}
public Header() {}
public long getTime() {
return time;
@ -99,8 +89,8 @@ public class Header {
public List<String> getErrors() {
return getExceptions().stream()
.map(Throwable::getMessage)
.collect(Collectors.toList());
.map(Throwable::getMessage)
.collect(Collectors.toList());
}
public Header setErrors(final List<String> errors) {

View File

@ -1,9 +1,7 @@
package eu.dnetlib.openaire.dsm.domain;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import io.swagger.annotations.ApiModel;
@ApiModel
@JsonAutoDetect
public class IdentitiesDetails {

View File

@ -4,28 +4,22 @@ import javax.validation.constraints.NotBlank;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
@JsonAutoDetect
@ApiModel(value = "Organization info model", description = "provides information about the organization")
@Schema(name = "Organization info model", description = "provides information about the organization")
public class OrganizationDetails extends OrganizationIgnoredProperties {
@ApiModelProperty(position = 0)
private String legalshortname;
@NotBlank
@ApiModelProperty(position = 1)
private String legalname;
@ApiModelProperty(position = 2)
private String websiteurl;
@ApiModelProperty(position = 3)
private String logourl;
@NotBlank
@ApiModelProperty(position = 4)
private String country;
public String getLegalshortname() {

View File

@ -4,10 +4,10 @@ import java.util.HashMap;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import io.swagger.annotations.ApiModel;
import io.swagger.v3.oas.annotations.media.Schema;
@JsonAutoDetect
@ApiModel(value = "Request filter", description = "field name and value pairs")
@Schema(name = "Request filter", description = "field name and value pairs")
public class RequestFilter extends HashMap<FilterName, Object> {
/**

View File

@ -1,16 +1,13 @@
package eu.dnetlib.openaire.dsm.domain;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
@JsonAutoDetect
@ApiModel(
value = "Api response model",
description = "Api response model, provides a response header")
@Schema(name = "Api response model", description = "Api response model, provides a response header")
public class Response {
@ApiModelProperty(position = 0)
private Header header;
public Response() {

View File

@ -0,0 +1,129 @@
package eu.dnetlib.openaire.dsm.domain;
import java.util.LinkedHashMap;
import java.util.Map;
public class SimpleDatasourceInfo {
private String id;
private String officialName;
private String englishName;
private Map<String, String> organizations = new LinkedHashMap<>();
@Deprecated
private String typology;
private String eoscType;
private String eoscDatasourceType;
private String registeredBy;
private String registrationDate;
private String compatibility;
private String firstCollectionDate;
private String lastCollectionDate;
private long lastCollectionTotal;
public String getId() {
return id;
}
public void setId(final String id) {
this.id = id;
}
public String getOfficialName() {
return officialName;
}
public void setOfficialName(final String officialName) {
this.officialName = officialName;
}
public String getEnglishName() {
return englishName;
}
public void setEnglishName(final String englishName) {
this.englishName = englishName;
}
public Map<String, String> getOrganizations() {
return organizations;
}
public void setOrganizations(final Map<String, String> organizations) {
this.organizations = organizations;
}
@Deprecated
public String getTypology() {
return typology;
}
@Deprecated
public void setTypology(final String typology) {
this.typology = typology;
}
public String getEoscType() {
return eoscType;
}
public void setEoscType(final String eoscType) {
this.eoscType = eoscType;
}
public String getEoscDatasourceType() {
return eoscDatasourceType;
}
public void setEoscDatasourceType(final String eoscDatasourceType) {
this.eoscDatasourceType = eoscDatasourceType;
}
public String getRegisteredBy() {
return registeredBy;
}
public void setRegisteredBy(final String registeredBy) {
this.registeredBy = registeredBy;
}
public String getRegistrationDate() {
return registrationDate;
}
public void setRegistrationDate(final String registrationDate) {
this.registrationDate = registrationDate;
}
public String getCompatibility() {
return compatibility;
}
public void setCompatibility(final String compatibility) {
this.compatibility = compatibility;
}
public String getFirstCollectionDate() {
return firstCollectionDate;
}
public void setFirstCollectionDate(final String firstCollectionDate) {
this.firstCollectionDate = firstCollectionDate;
}
public String getLastCollectionDate() {
return lastCollectionDate;
}
public void setLastCollectionDate(final String lastCollectionDate) {
this.lastCollectionDate = lastCollectionDate;
}
public long getLastCollectionTotal() {
return lastCollectionTotal;
}
public void setLastCollectionTotal(final long lastCollectionTotal) {
this.lastCollectionTotal = lastCollectionTotal;
}
}

View File

@ -4,14 +4,9 @@ import java.util.List;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@ApiModel
@JsonAutoDetect
public class SimpleResponse<T> extends Response {
@ApiModelProperty(position = 1)
private List<T> response;
public List<T> getResponse() {

View File

@ -3,12 +3,10 @@ package eu.dnetlib.openaire.dsm.domain;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import eu.dnetlib.enabling.datasources.common.AggregationInfo;
import io.swagger.annotations.ApiModel;
/**
* Created by claudio on 29/11/2016.
*/
@ApiModel
@JsonAutoDetect
public class TransformationInfo extends AggregationInfo {

View File

@ -6,8 +6,9 @@ import javax.persistence.Table;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import eu.dnetlib.enabling.datasources.common.ApiParam;
import io.swagger.annotations.ApiModel;
import io.swagger.v3.oas.annotations.media.Schema;
/**
* Created by claudio on 13/04/2017.
@ -15,7 +16,7 @@ import io.swagger.annotations.ApiModel;
@Entity
@Table(name = "dsm_apiparams")
@JsonIgnoreProperties(ignoreUnknown = true)
@ApiModel(value = "Datasource Api params model", description = "describes the datasource api params")
@Schema(name = "Datasource Api params model", description = "describes the datasource api params")
public class ApiParamDbEntry implements ApiParam {
@EmbeddedId
@ -35,10 +36,12 @@ public class ApiParamDbEntry implements ApiParam {
return id;
}
@Override
public String getValue() {
return value;
}
@Override
public void setValue(final String value) {
this.value = value;
}

View File

@ -7,14 +7,12 @@ import javax.persistence.Table;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import eu.dnetlib.enabling.datasources.common.BrowseTerm;
import io.swagger.annotations.ApiModel;
/**
* Created by claudio on 20/04/2017.
*/
@Entity
@Table(name = "browse_countries")
@ApiModel
@JsonAutoDetect
public class CountryTerm implements Comparable<CountryTerm>, BrowseTerm {
@ -27,6 +25,7 @@ public class CountryTerm implements Comparable<CountryTerm>, BrowseTerm {
return term;
}
@Override
public void setTerm(final String term) {
this.term = term;
}
@ -36,6 +35,7 @@ public class CountryTerm implements Comparable<CountryTerm>, BrowseTerm {
return total;
}
@Override
public void setTotal(final long total) {
this.total = total;
}

View File

@ -8,12 +8,12 @@ import javax.persistence.Table;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.annotations.ApiModel;
import io.swagger.v3.oas.annotations.media.Schema;
@Entity
@JsonAutoDetect
@Table(name = "dsm_datasource_api")
@ApiModel(value = "DatasourceApi model", description = "describes a joint view between datasources and their API (1:N)")
@Schema(name = "DatasourceApi model", description = "describes a joint view between datasources and their API (1:N)")
public class DatasourceApiDbEntry {
@Id

View File

@ -19,6 +19,8 @@ import eu.dnetlib.enabling.datasources.common.Datasource;
@Table(name = "dsm_services")
public class DatasourceDbEntry extends Datasource<OrganizationDbEntry, IdentityDbEntry, PidSystemDbEntry> {
public static final String DEFAULT_EOSC_TYPE = "Data Source";
@Transient
private String openaireId;
@ -26,6 +28,12 @@ public class DatasourceDbEntry extends Datasource<OrganizationDbEntry, IdentityD
@Column(name = "_typology_to_remove_")
private String typology;
@Column(name = "eosc_type")
private String eoscType = DEFAULT_EOSC_TYPE;
@Column(name = "dedup_main_service")
private Boolean dedupMainService = true;
public String getOpenaireId() {
return openaireId;
}
@ -43,4 +51,20 @@ public class DatasourceDbEntry extends Datasource<OrganizationDbEntry, IdentityD
public void setTypology(final String typology) {
this.typology = typology;
}
public String getEoscType() {
return eoscType;
}
public void setEoscType(final String eoscType) {
this.eoscType = eoscType;
}
public Boolean getDedupMainService() {
return dedupMainService;
}
public void setDedupMainService(final Boolean dedupMainService) {
this.dedupMainService = dedupMainService;
}
}

View File

@ -2,23 +2,30 @@ package eu.dnetlib.openaire.funders;
import java.util.List;
import eu.dnetlib.openaire.common.AbstractExporterController;
import eu.dnetlib.openaire.funders.domain.ExtendedFunderDetails;
import eu.dnetlib.openaire.funders.domain.FunderDetails;
import eu.dnetlib.openaire.funders.domain.db.FunderDbEntry;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import eu.dnetlib.openaire.common.AbstractExporterController;
import eu.dnetlib.openaire.funders.domain.ExtendedFunderDetails;
import eu.dnetlib.openaire.funders.domain.FunderDetails;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
@RestController
@CrossOrigin(origins = { "*" })
@CrossOrigin(origins = {
"*"
})
@ConditionalOnProperty(value = "openaire.exporter.enable.funders", havingValue = "true")
@io.swagger.annotations.Api(tags = "OpenAIRE funders API", description = "the OpenAIRE funders API")
@Tag(name = "OpenAIRE funders API", description = "the OpenAIRE funders API")
public class FundersApiController extends AbstractExporterController {
private static final Log log = LogFactory.getLog(FundersApiController.class);
@ -26,41 +33,46 @@ public class FundersApiController extends AbstractExporterController {
@Autowired
private FunderDao fDao;
@RequestMapping(value = "/funders", produces = { "application/json" }, method = RequestMethod.GET)
@ApiOperation(
value = "get basic information about funders",
notes = "basic information about funders: id, name, shortname, last update date, registration date",
response = FunderDetails[].class)
@RequestMapping(value = "/funders", produces = {
"application/json"
}, method = RequestMethod.GET)
@Operation(summary = "get basic information about funders", description = "basic information about funders: id, name, shortname, last update date, registration date")
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK", response = FunderDetails[].class),
@ApiResponse(code = 500, message = "unexpected error", response = ErrorMessage.class) })
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "500", description = "unexpected error")
})
public List<FunderDetails> getFunders(
@PathVariable final int page,
@PathVariable final int size) throws FundersApiException {
@PathVariable final int page,
@PathVariable final int size) throws FundersApiException {
return fDao.listFunderDetails(page, size);
}
@RequestMapping(value = "/funder/{id}", produces = { "application/json" }, method = RequestMethod.GET)
@ApiOperation(value = "get the funder details", notes = "complete funder information", response = FunderDbEntry.class)
@RequestMapping(value = "/funder/{id}", produces = {
"application/json"
}, method = RequestMethod.GET)
@Operation(summary = "get the funder details", description = "complete funder information")
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK", response = FunderDbEntry.class),
@ApiResponse(code = 500, message = "unexpected error", response = ErrorMessage.class) })
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "500", description = "unexpected error")
})
public ExtendedFunderDetails getFunderDetails(
@PathVariable final String id) throws FundersApiException {
@PathVariable final String id) throws FundersApiException {
return fDao.getExtendedFunderDetails(id);
}
@RequestMapping(value = "/funder/ids", produces = { "application/json" }, method = RequestMethod.GET)
@ApiOperation(value = "get the list of funder ids", notes = "get the list of funder ids", response = String[].class)
@RequestMapping(value = "/funder/ids", produces = {
"application/json"
}, method = RequestMethod.GET)
@Operation(summary = "get the list of funder ids", description = "get the list of funder ids")
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK", response = String[].class),
@ApiResponse(code = 500, message = "unexpected error", response = ErrorMessage.class) })
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "500", description = "unexpected error")
})
public List<String> getFunderIds(
@PathVariable final int page,
@PathVariable final int size
) throws FundersApiException {
@PathVariable final int page,
@PathVariable final int size) throws FundersApiException {
return fDao.listFunderIds(page, size);
}

View File

@ -19,16 +19,17 @@ import com.google.common.collect.Maps;
import eu.dnetlib.openaire.common.AbstractExporterController;
import eu.dnetlib.openaire.common.ExporterConstants;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
@RestController
@CrossOrigin(origins = {
"*"
})
@ConditionalOnProperty(value = "openaire.exporter.enable.info", havingValue = "true")
@io.swagger.annotations.Api(tags = "OpenAIRE Info API", description = "the OpenAIRE info API")
@Tag(name = "OpenAIRE Info API", description = "the OpenAIRE info API")
public class InfoController extends AbstractExporterController {
private static final Log log = LogFactory.getLog(InfoController.class); // NOPMD by marko on 11/24/08 5:02 PM
@ -41,12 +42,12 @@ public class InfoController extends AbstractExporterController {
@RequestMapping(value = "/info/{infoKey}", produces = {
"application/json"
}, method = RequestMethod.GET)
@ApiOperation(value = "get info date", notes = "get info date", tags = {
@Operation(summary = "get info date", description = "get info date", tags = {
ExporterConstants.R
}, response = LocalDate.class)
})
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK", response = LocalDate.class),
@ApiResponse(code = 500, message = "unexpected error", response = ErrorMessage.class)
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "500", description = "unexpected error")
})
public LocalDate getDate(@PathVariable final String infoKey) {
final JdbcInfoDao.DATE_INFO info = JdbcInfoDao.DATE_INFO.valueOf(infoKey);
@ -57,12 +58,12 @@ public class InfoController extends AbstractExporterController {
@RequestMapping(value = "/info", produces = {
"application/json"
}, method = RequestMethod.GET)
@ApiOperation(value = "get all the info date", notes = "get all the info date", tags = {
@Operation(summary = "get all the info date", description = "get all the info date", tags = {
ExporterConstants.R
}, response = Map.class)
})
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK", response = LocalDate.class),
@ApiResponse(code = 500, message = "unexpected error", response = ErrorMessage.class)
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "500", description = "unexpected error")
})
public Map<String, LocalDate> listInfo() {
final Map<String, LocalDate> map = Maps.newHashMap();
@ -75,12 +76,12 @@ public class InfoController extends AbstractExporterController {
@RequestMapping(value = "/info/keys", produces = {
"application/json"
}, method = RequestMethod.GET)
@ApiOperation(value = "get the available keys", notes = "get the available keys", tags = {
@Operation(summary = "get the available keys", description = "get the available keys", tags = {
ExporterConstants.R
}, response = String.class, responseContainer = "List")
})
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK", response = LocalDate.class),
@ApiResponse(code = 500, message = "unexpected error", response = ErrorMessage.class)
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "500", description = "unexpected error")
})
public List<String> listInfoKeys() {
final List<String> keys = Lists.newArrayList();
@ -93,7 +94,7 @@ public class InfoController extends AbstractExporterController {
@RequestMapping(value = "/info/dropCache", produces = {
"application/json"
}, method = RequestMethod.GET)
@ApiOperation(value = "Drops the info cache", notes = "Drops the info cache", tags = {
@Operation(summary = "Drops the info cache", description = "Drops the info cache", tags = {
ExporterConstants.R
})
public void dropCache() {

View File

@ -8,22 +8,11 @@ import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.zip.ZipOutputStream;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.google.common.xml.XmlEscapers;
import eu.dnetlib.DnetOpenaireExporterProperties;
import eu.dnetlib.DnetOpenaireExporterProperties.Project;
import eu.dnetlib.openaire.common.AbstractExporterController;
import eu.dnetlib.openaire.common.ExporterConstants;
import eu.dnetlib.openaire.project.domain.db.ProjectTsv;
import eu.dnetlib.openaire.project.domain.db.ProjectDetails;
import eu.dnetlib.openaire.project.dao.JdbcApiDao;
import eu.dnetlib.openaire.project.dao.ValueCleaner;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import org.antlr.stringtemplate.StringTemplate;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
@ -38,10 +27,25 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import com.google.common.xml.XmlEscapers;
import eu.dnetlib.DnetOpenaireExporterProperties;
import eu.dnetlib.DnetOpenaireExporterProperties.Project;
import eu.dnetlib.openaire.common.AbstractExporterController;
import eu.dnetlib.openaire.common.ExporterConstants;
import eu.dnetlib.openaire.project.dao.JdbcApiDao;
import eu.dnetlib.openaire.project.dao.ValueCleaner;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
@Controller
@CrossOrigin(origins = { "*" })
@CrossOrigin(origins = {
"*"
})
@ConditionalOnProperty(value = "openaire.exporter.enable.project", havingValue = "true")
@io.swagger.annotations.Api(tags = "OpenAIRE projects API", description = "the OpenAIRE projects API")
@Tag(name = "OpenAIRE projects API", description = "the OpenAIRE projects API")
public class ProjectsController extends AbstractExporterController {
private static final Log log = LogFactory.getLog(ProjectsController.class); // NOPMD by marko on 11/24/08 5:02 PM
@ -58,19 +62,19 @@ public class ProjectsController extends AbstractExporterController {
private ProjectQueryParamsFactory projectQueryParamsFactory;
@RequestMapping(value = "/export/**/project/dspace.do", method = RequestMethod.GET)
@ApiOperation(
value = "DSpace",
notes = "return project information in compatible with the OpenAIRE plugin for DSpace",
tags = { ExporterConstants.DSPACE },
response = String.class)
@Operation(summary = "DSpace", description = "return project information in compatible with the OpenAIRE plugin for DSpace", tags = {
ExporterConstants.DSPACE
})
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK", response = String.class),
@ApiResponse(code = 500, message = "unexpected error", response = ErrorMessage.class) })
public void processDspace(final HttpServletRequest request, final ServletResponse response,
@RequestParam(value = "startFrom", required = false) final String startFrom,
@RequestParam(value = "startUntil", required = false) final String startUntil,
@RequestParam(value = "endFrom", required = false) final String endFrom,
@RequestParam(value = "endUntil", required = false) final String endUntil) throws Exception {
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "500", description = "unexpected error")
})
public void processDspace(final HttpServletRequest request,
final ServletResponse response,
@RequestParam(value = "startFrom", required = false) final String startFrom,
@RequestParam(value = "startUntil", required = false) final String startUntil,
@RequestParam(value = "endFrom", required = false) final String endFrom,
@RequestParam(value = "endUntil", required = false) final String endUntil) throws Exception {
final Project conf = config.getProject();
@ -86,19 +90,19 @@ public class ProjectsController extends AbstractExporterController {
}
@RequestMapping(value = "/export/**/project/eprints.do", method = RequestMethod.GET)
@ApiOperation(
value = "EPrints",
notes = "return project information in compatible with the OpenAIRE plugin for Eprints",
tags = { ExporterConstants.EPRINT },
response = String.class)
@Operation(summary = "EPrints", description = "return project information in compatible with the OpenAIRE plugin for Eprints", tags = {
ExporterConstants.EPRINT
})
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK", response = String.class),
@ApiResponse(code = 500, message = "unexpected error", response = ErrorMessage.class) })
public void processEprints(final HttpServletRequest request, final ServletResponse response,
@RequestParam(value = "startFrom", required = false) final String startFrom,
@RequestParam(value = "startUntil", required = false) final String startUntil,
@RequestParam(value = "endFrom", required = false) final String endFrom,
@RequestParam(value = "endUntil", required = false) final String endUntil) throws Exception {
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "500", description = "unexpected error")
})
public void processEprints(final HttpServletRequest request,
final ServletResponse response,
@RequestParam(value = "startFrom", required = false) final String startFrom,
@RequestParam(value = "startUntil", required = false) final String startUntil,
@RequestParam(value = "endFrom", required = false) final String endFrom,
@RequestParam(value = "endUntil", required = false) final String endUntil) throws Exception {
final ProjectQueryParams params = projectQueryParamsFactory.generateParams(request, startFrom, startUntil, endFrom, endUntil);
response.setContentType("text/html");
@ -110,29 +114,30 @@ public class ProjectsController extends AbstractExporterController {
}
private void doProcess(
final ServletResponse response,
final ProjectQueryParams params,
final String head, final Resource projectTemplate, final String tail,
final ValueCleaner cleaner) throws IOException, SQLException {
final ServletResponse response,
final ProjectQueryParams params,
final String head,
final Resource projectTemplate,
final String tail,
final ValueCleaner cleaner) throws IOException, SQLException {
final StringTemplate st = new StringTemplate(IOUtils.toString(projectTemplate.getInputStream(), UTF8));
try(final OutputStream out = new BufferedOutputStream(response.getOutputStream())) {
try (final OutputStream out = new BufferedOutputStream(response.getOutputStream())) {
dao.streamProjects(obtainQuery(params), out, head, st, tail, cleaner);
}
}
@RequestMapping(value = "/noads/project2tsv.do", method = RequestMethod.GET)
@ApiOperation(
value = "TSV",
notes = "download project information in TSV format",
tags = { ExporterConstants.TSV },
response = ProjectTsv[].class)
@Operation(summary = "TSV", description = "download project information in TSV format", tags = {
ExporterConstants.TSV
})
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK", response = ProjectTsv[].class),
@ApiResponse(code = 500, message = "unexpected error", response = ErrorMessage.class) })
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "500", description = "unexpected error")
})
public void processTsv(final HttpServletResponse response,
@RequestParam(value = "funding", required = true) final String funding,
@RequestParam(value = "article293", required = false) final Boolean article293) throws Exception {
@RequestParam(value = "funding", required = true) final String funding,
@RequestParam(value = "article293", required = false) final Boolean article293) throws Exception {
final String fundingPrefix = getFundingPrefix(funding, null);
@ -140,37 +145,37 @@ public class ProjectsController extends AbstractExporterController {
final String filename = "projects_" + funding + "_" + date + ".tsv";
response.setContentType("text/tab-separated-values");
response.setHeader("Content-Disposition", "attachment; filename=\"" + filename + ".zip\"");
try(final ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(response.getOutputStream()))) {
try (final ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(response.getOutputStream()))) {
dao.processTsvRequest(out, article293, fundingPrefix, filename);
} catch (Throwable e) {
} catch (final Throwable e) {
throw new RuntimeException("Error processing the request", e);
}
}
@RequestMapping(value = "/export/streamProjectDetails.do", method = RequestMethod.GET)
@ApiOperation(
value = "Stream projects",
notes = "stream project information",
tags = { ExporterConstants.STREAMING },
response = ProjectDetails[].class)
@Operation(summary = "Stream projects", description = "stream project information", tags = {
ExporterConstants.STREAMING
})
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK", response = ProjectDetails[].class),
@ApiResponse(code = 500, message = "unexpected error", response = ErrorMessage.class) })
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "500", description = "unexpected error")
})
public void streamProjectDetails(final HttpServletResponse response,
@RequestParam(value = "format", required = true) final String format,
@RequestParam(value = "compress", required = false) final Boolean compress) throws IOException, SQLException {
@RequestParam(value = "format", required = true) final String format,
@RequestParam(value = "compress", required = false) final Boolean compress) throws IOException, SQLException {
if (compress != null && compress) {
response.setHeader("Content-Encoding", "gzip");
}
switch (format) {
case "csv":
response.setContentType("text/csv");
break;
case "json":
response.setContentType("text/plain");
break;
default: throw new IllegalArgumentException("unsupported format: " + format);
case "csv":
response.setContentType("text/csv");
break;
case "json":
response.setContentType("text/plain");
break;
default:
throw new IllegalArgumentException("unsupported format: " + format);
}
dao.processProjectDetails(response.getOutputStream(), format, compress);
@ -190,22 +195,20 @@ public class ProjectsController extends AbstractExporterController {
* if the funding program is not recognized
*/
protected String obtainQuery(final ProjectQueryParams params) throws IllegalArgumentException, IOException {
String funding = params.getFundingProgramme();
String suffix = params.getFundingPath();
final String funding = params.getFundingProgramme();
final String suffix = params.getFundingPath();
final StringTemplate st = new StringTemplate(IOUtils.toString(config.getProject().getProjectsFundingQueryTemplate().getInputStream(), UTF8));
st.setAttribute("fundingprefix", getFundingPrefix(funding, suffix));
String theQuery = setDateParameters(st.toString(), params);
final String theQuery = setDateParameters(st.toString(), params);
log.debug("Generated query: " + theQuery);
return theQuery;
}
private String getFundingPrefix(final String funding, final String suffix) {
final Map<String, String> fundingIds = dao.readFundingpathIds();
if (!fundingIds.containsKey(funding.toUpperCase())) {
throw new IllegalArgumentException("invalid funding " + funding);
}
String fundingPrefix = fundingIds.get(funding.toUpperCase());
if (!fundingIds.containsKey(funding.toUpperCase())) { throw new IllegalArgumentException("invalid funding " + funding); }
final String fundingPrefix = fundingIds.get(funding.toUpperCase());
return StringUtils.isBlank(suffix) ? fundingPrefix : fundingPrefix + "::" + suffix.toUpperCase();
}

View File

@ -2,22 +2,25 @@ package eu.dnetlib.openaire.project.domain.db;
import java.sql.Date;
import java.util.ArrayList;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import org.apache.commons.lang3.StringUtils;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.google.common.base.Splitter;
import com.google.common.collect.Lists;
import io.swagger.annotations.ApiModel;
import org.apache.commons.lang3.StringUtils;
import io.swagger.v3.oas.annotations.media.Schema;
/**
* Created by claudio on 20/09/16.
*/
@Entity
@Table(name = "projects_api")
@ApiModel(value = "Project api model", description = "Project api model used by DSpace and Eprints exporter")
@Schema(name = "Project api model", description = "Project api model used by DSpace and Eprints exporter")
public class ProjectApi {
public static final String INFO_EU_REPO_GRANT_AGREEMENT = "info:eu-repo/grantAgreement/";
@ -35,10 +38,10 @@ public class ProjectApi {
private Date enddate;
private String fundingpathid;
public ProjectApi() { }
public ProjectApi() {}
public String getIdnamespace() {
String res = INFO_EU_REPO_GRANT_AGREEMENT + getFunder()+"/";
String res = INFO_EU_REPO_GRANT_AGREEMENT + getFunder() + "/";
final String fundingProgram = asFundingProgram(getFundingpathid());
if (StringUtils.isNotBlank(fundingProgram)) {
res += fundingProgram;
@ -69,9 +72,12 @@ public class ProjectApi {
private String asFundingProgram(final String fundingpathid) {
final ArrayList<String> strings = Lists.newArrayList(Splitter.on("::").split(fundingpathid));
if(strings.size() <= 1) throw new IllegalStateException("Unexpected funding id: "+fundingpathid);
if(strings.size() == 2) return "";
else return replaceSlash(strings.get(2));
if (strings.size() <= 1) { throw new IllegalStateException("Unexpected funding id: " + fundingpathid); }
if (strings.size() == 2) {
return "";
} else {
return replaceSlash(strings.get(2));
}
}
private String replaceSlash(final String s) {

View File

@ -6,15 +6,16 @@ import java.io.StringWriter;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.List;
import javax.persistence.*;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.google.gson.Gson;
import io.swagger.annotations.ApiModel;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Transient;
import org.hibernate.annotations.Type;
import org.supercsv.cellprocessor.Optional;
import org.supercsv.cellprocessor.ift.CellProcessor;
import org.supercsv.cellprocessor.ift.StringCellProcessor;
import org.supercsv.io.CsvBeanReader;
import org.supercsv.io.CsvBeanWriter;
import org.supercsv.io.ICsvBeanReader;
@ -22,21 +23,26 @@ import org.supercsv.io.ICsvBeanWriter;
import org.supercsv.prefs.CsvPreference;
import org.supercsv.util.CsvContext;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.google.gson.Gson;
import io.swagger.v3.oas.annotations.media.Schema;
/**
* Created by claudio on 04/07/2017.
*/
@Entity
@Table(name = "project_details")
@ApiModel(value = "Project details model", description = "provides project details")
@Schema(name = "Project details model", description = "provides project details")
public class ProjectDetails {
@Transient
@JsonIgnore
private transient static final String[] FIELDS = Arrays.stream(ProjectDetails.class.getDeclaredFields())
.map(Field::getName)
.filter(s -> !s.equals("FIELDS"))
.filter(s -> !s.startsWith("optional"))
.toArray(String[]::new);
.map(Field::getName)
.filter(s -> !s.equals("FIELDS"))
.filter(s -> !s.startsWith("optional"))
.toArray(String[]::new);
@Id
@Column(name = "projectid")
@ -50,8 +56,7 @@ public class ProjectDetails {
@Column(name = "fundingpath", columnDefinition = "text[]")
private String[] fundingPath;
public ProjectDetails() {
}
public ProjectDetails() {}
public String getProjectId() {
return projectId;
@ -74,7 +79,7 @@ public class ProjectDetails {
}
public void setFundingPath(final List<String> fundingPath) {
if(fundingPath != null && !fundingPath.isEmpty()) {
if (fundingPath != null && !fundingPath.isEmpty()) {
this.fundingPath = fundingPath.toArray(new String[fundingPath.size()]);
}
}
@ -85,28 +90,32 @@ public class ProjectDetails {
public static ProjectDetails fromCSV(final String csv) throws IOException {
try (ICsvBeanReader beanReader = new CsvBeanReader(new StringReader(csv), CsvPreference.STANDARD_PREFERENCE)) {
return beanReader.read(ProjectDetails.class, FIELDS, getProcessors(new StringCellProcessor() {
final CellProcessor cp = new CellProcessor() {
@SuppressWarnings("unchecked")
@Override
public Object execute(final Object value, final CsvContext context) {
return new Gson().fromJson(value.toString(), List.class);
public <T> T execute(final Object value, final CsvContext context) {
return (T) new Gson().fromJson(value.toString(), List.class);
}
}));
};
return beanReader.read(ProjectDetails.class, FIELDS, getProcessors(cp));
}
}
/**
* Sets up the processors used for the examples. There are 10 CSV columns, so 10 processors are defined. Empty
* columns are read as null (hence the NotNull() for mandatory columns).
* Sets up the processors used for the examples. There are 10 CSV columns, so 10 processors are defined. Empty columns are read as null
* (hence the NotNull() for mandatory columns).
*
* @return the cell processors
*/
private static CellProcessor[] getProcessors(final CellProcessor fundingPathProcessor) {
return new CellProcessor[] {
new Optional(), // projectId
new Optional(), // acronym
new Optional(), // code
new Optional(), // jsonextrainfo
fundingPathProcessor
new Optional(), // projectId
new Optional(), // acronym
new Optional(), // code
new Optional(), // jsonextrainfo
fundingPathProcessor
};
}
@ -117,12 +126,15 @@ public class ProjectDetails {
public String asCSV() throws IOException {
final StringWriter sb = new StringWriter();
try (ICsvBeanWriter beanWriter = new CsvBeanWriter(sb, CsvPreference.STANDARD_PREFERENCE)) {
beanWriter.write(this, FIELDS, getProcessors(new StringCellProcessor() {
final CellProcessor cp = new CellProcessor() {
@SuppressWarnings("unchecked")
@Override
public Object execute(final Object value, final CsvContext context) {
return new Gson().toJson(value);
public <T> T execute(final Object value, final CsvContext context) {
return (T) new Gson().toJson(value);
}
}));
};
beanWriter.write(this, FIELDS, getProcessors(cp));
beanWriter.flush();
}

View File

@ -2,22 +2,25 @@ package eu.dnetlib.openaire.project.domain.db;
import java.sql.Date;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import org.apache.commons.lang3.StringUtils;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.google.common.collect.Lists;
import io.swagger.annotations.ApiModel;
import org.apache.commons.lang3.StringUtils;
import io.swagger.v3.oas.annotations.media.Schema;
/**
* Created by claudio on 05/07/2017.
*/
@Entity
@Table(name = "projects_tsv")
@ApiModel(value = "Project TSV model", description = "project TSV model description")
@Schema(name = "Project TSV model", description = "project TSV model description")
public class ProjectTsv {
@Id
@ -51,25 +54,14 @@ public class ProjectTsv {
public ProjectTsv() {}
public List<String> asList() {
return Lists.newArrayList(
clean(getCode()),
clean(getAcronym()),
clean(getTitle()),
clean(getCallIdentifier()),
clean(getStartdate() != null ? getStartdate().toString() : ""),
clean(getEnddate() != null ? getEnddate().toString() : ""),
clean(String.valueOf(isOaMandateForPublications())),
clean(String.valueOf(isOaMandateForDatasets())),
clean(getDescription()),
clean(getOrgLegalname()),
clean(getOrgCountry()),
clean(getOrgRole()),
clean(getContactfullname()),
clean(getContactemail()));
return Lists.newArrayList(clean(getCode()), clean(getAcronym()), clean(getTitle()), clean(getCallIdentifier()), clean(getStartdate() != null
? getStartdate().toString()
: ""), clean(getEnddate() != null ? getEnddate().toString() : ""), clean(String.valueOf(isOaMandateForPublications())), clean(String
.valueOf(isOaMandateForDatasets())), clean(getDescription()), clean(getOrgLegalname()), clean(getOrgCountry()), clean(getOrgRole()), clean(getContactfullname()), clean(getContactemail()));
}
private String clean(final String s) {
return StringUtils.isNotBlank(s) ? "\"" + s.replaceAll("\\n|\\t|\\s+", " ").replace("\"","\"\"").trim() + "\"" : "";
return StringUtils.isNotBlank(s) ? "\"" + s.replaceAll("\\n|\\t|\\s+", " ").replace("\"", "\"\"").trim() + "\"" : "";
}
public long getRowid() {

View File

@ -2,6 +2,9 @@
server.servlet.context-path = /openaire
server.port = 8080
server.public_url =
server.public_desc = API Base URL
spring.datasource.driverClassName = org.postgresql.Driver
spring.jpa.database-platform = org.hibernate.dialect.PostgreSQL9Dialect
spring.jpa.show-sql = false

View File

@ -0,0 +1,7 @@
select count(*) as count
from (
select d.id
from dsm_services d left outer join dsm_api a on (d.id = a.service)
group by d.id
having min(a.first_collection_date) >= cast(? as date)
) as t

View File

@ -0,0 +1,8 @@
select count(*) as count
from (
select d.id
from dsm_services d left outer join dsm_api a on (d.id = a.service)
where d._typology_to_remove_ like ?
group by d.id
having min(a.first_collection_date) >= cast(? as date)
) as t

View File

@ -0,0 +1,29 @@
SELECT
s.id AS "id",
s.officialname AS "officialName",
s.englishname AS "englishName",
s._typology_to_remove_ AS "typology",
s.eosc_type AS "eoscType",
s.eosc_datasource_type AS "eoscDatasourceType",
s.registeredby AS "registeredBy",
s.registrationdate::text AS "registrationDate",
MIN(a.first_collection_date) AS "firstCollectionDate",
MAX(a.last_collection_date) AS "lastCollectionDate",
(array_remove(array_agg(a.last_collection_total order by a.last_collection_date desc), NULL))[1] AS "lastCollectionTotal",
array_remove(array_agg(DISTINCT coalesce(a.compatibility_override, a.compatibility)), NULL) AS "compatibilities",
array_remove(array_agg(DISTINCT o.id||' @@@ '||o.legalname), NULL) AS "organizations"
FROM
dsm_services s
left outer join dsm_api a on (s.id = a.service)
left outer join dsm_service_organization dso on (s.id = dso.service)
left outer join dsm_organizations o on (o.id = dso.organization)
GROUP BY
s.id,
s.officialname,
s.englishname,
s._typology_to_remove_,
s.eosc_type,
s.eosc_datasource_type,
s.registeredby,
s.registrationdate
HAVING MIN(a.first_collection_date) >= cast(? as date)

View File

@ -0,0 +1,31 @@
SELECT
s.id AS "id",
s.officialname AS "officialName",
s.englishname AS "englishName",
s._typology_to_remove_ AS "typology",
s.eosc_type AS "eoscType",
s.eosc_datasource_type AS "eoscDatasourceType",
s.registeredby AS "registeredBy",
s.registrationdate::text AS "registrationDate",
MIN(a.first_collection_date) AS "firstCollectionDate",
MAX(a.last_collection_date) AS "lastCollectionDate",
(array_remove(array_agg(a.last_collection_total order by a.last_collection_date desc), NULL))[1] AS "lastCollectionTotal",
array_remove(array_agg(DISTINCT coalesce(a.compatibility_override, a.compatibility)), NULL) AS "compatibilities",
array_remove(array_agg(DISTINCT o.id||' @@@ '||o.legalname), NULL) AS "organizations"
FROM
dsm_services s
left outer join dsm_api a on (s.id = a.service)
left outer join dsm_service_organization dso on (s.id = dso.service)
left outer join dsm_organizations o on (o.id = dso.organization)
WHERE
s._typology_to_remove_ like ?
GROUP BY
s.id,
s.officialname,
s.englishname,
s._typology_to_remove_,
s.eosc_type,
s.eosc_datasource_type,
s.registeredby,
s.registrationdate
HAVING MIN(a.first_collection_date) >= cast(? as date)

View File

@ -1,9 +1,7 @@
select count(d.id) as count
select count(DISTINCT d.id) as count
from
dsm_services d
left outer join dsm_api a on (d.id = a.service)
left outer join dsm_service_organization dso on (d.id = dso.service)
left outer join dsm_organizations o on (o.id = dso.organization)
where
d.registrationdate >= cast(? as date)
and d.registrationdate < a.last_collection_date

View File

@ -1,12 +1,10 @@
select count(d.id) as count
select count(DISTINCT d.id) as count
from
dsm_services d
left outer join dsm_api a on (d.id = a.service)
left outer join dsm_service_organization dso on (d.id = dso.service)
left outer join dsm_organizations o on (o.id = dso.organization)
where
d.registrationdate >= cast(? as date)
and d.eosc_datasource_type like ?
and d._typology_to_remove_ like ?
and d.registrationdate < a.last_collection_date
and d.registeredby is not null
and d.managed = true

View File

@ -0,0 +1,38 @@
SELECT
s.id AS "id",
s.officialname AS "officialName",
s.englishname AS "englishName",
s._typology_to_remove_ AS "typology",
s.eosc_type AS "eoscType",
s.eosc_datasource_type AS "eoscDatasourceType",
s.registeredby AS "registeredBy",
s.registrationdate::text AS "registrationDate",
MIN(a.first_collection_date) AS "firstCollectionDate",
MAX(a.last_collection_date) AS "lastCollectionDate",
(array_remove(array_agg(a.last_collection_total order by a.last_collection_date desc), NULL))[1] AS "lastCollectionTotal",
array_remove(array_agg(DISTINCT coalesce(a.compatibility_override, a.compatibility)), NULL) AS "compatibilities",
array_remove(array_agg(DISTINCT o.id||' @@@ '||o.legalname), NULL) AS "organizations"
FROM
dsm_services s
left outer join dsm_api a on (s.id = a.service)
left outer join dsm_service_organization dso on (s.id = dso.service)
left outer join dsm_organizations o on (o.id = dso.organization)
WHERE
s.registrationdate is not null
and s.registeredby is not null
and s.managed = true
GROUP BY
s.id,
s.officialname,
s.englishname,
s._typology_to_remove_,
s.eosc_type,
s.eosc_datasource_type,
s.registeredby,
s.registrationdate
HAVING
s.registrationdate < max(a.last_collection_date)
and sum(a.last_collection_total) > 0
ORDER BY s.registrationdate desc
LIMIT ?

View File

@ -0,0 +1,24 @@
package eu.dnetlib.openaire.dsm.dao.utils;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import eu.dnetlib.openaire.dsm.domain.ApiDetails;
import eu.dnetlib.openaire.dsm.domain.db.ApiDbEntry;
class DsmMappingUtilsTest {
@BeforeEach
void setUp() throws Exception {}
@Test
void testAsDetailsApiDbEntry() {
final ApiDetails api = new ApiDetails();
api.setId("id:123");
final ApiDbEntry dbEntry = DsmMappingUtils.asDbEntry(api);
assertEquals(api.getId(), dbEntry.getId());
}
}

Some files were not shown because too many files have changed in this diff Show More