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,7 +58,8 @@ public abstract class AbstractExporterController {
@ResponseStatus(HttpStatus.BAD_REQUEST)
public List<ErrorMessage> processValidationError(final MethodArgumentNotValidException e) {
return e.getBindingResult()
.getFieldErrors().stream()
.getFieldErrors()
.stream()
.map(fe -> new ErrorMessage(
String.format("field '%s'", fe.getField()),
String.format("rejected value '%s'", fe.getRejectedValue()),
@ -61,12 +70,21 @@ public abstract class AbstractExporterController {
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,92 +1,113 @@
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 {
@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 {
@ -94,15 +115,17 @@ public class CommunityApiController {
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 {
@ -110,29 +133,32 @@ public class CommunityApiController {
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 {
@ -140,15 +166,17 @@ public class CommunityApiController {
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 {
@ -156,31 +184,34 @@ public class CommunityApiController {
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 {
@ -188,32 +219,36 @@ public class CommunityApiController {
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 {
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 {
@ -221,15 +256,17 @@ public class CommunityApiController {
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 {
@ -237,29 +274,32 @@ public class CommunityApiController {
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 {
@ -268,15 +308,17 @@ public class CommunityApiController {
}
@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 {
@ -285,16 +327,17 @@ public class CommunityApiController {
}
@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 {

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,31 +1,32 @@
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)
@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)
@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<>();
openAirecommunitylist = new ArrayList<>();
}
public List<String> getOpenAirecommunitylist() {
return openAirecommunitylist;
}
public CommunityOpenAIRECommunities setOpenAirecommunitylist(List<String> openAirecommunitylist) {
public CommunityOpenAIRECommunities setOpenAirecommunitylist(final List<String> openAirecommunitylist) {
this.openAirecommunitylist = openAirecommunitylist;
return this;
}
@ -34,7 +35,7 @@ public class CommunityOpenAIRECommunities {
return zenodoid;
}
public CommunityOpenAIRECommunities setZenodoid(String zenodoid) {
public CommunityOpenAIRECommunities setZenodoid(final String zenodoid) {
this.zenodoid = zenodoid;
return this;
}

View File

@ -1,38 +1,39 @@
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)
@Schema(description = "the community identifier this organization belongs to", required = true)
private String communityId;
@NotNull
@ApiModelProperty(value = "name of the organization", required = true)
@Schema(description = "name of the organization", required = true)
private String name;
@NotNull
@ApiModelProperty(value = "identifies this organization within the context it belongs to", required = true)
@Schema(description = "identifies this organization within the context it belongs to", required = true)
private String id;
@NotNull
@ApiModelProperty(value="url of the logo for this organization", required = true)
@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)
@Schema(description = "website url for this organization", required = true)
private String website_url;
public String getCommunityId() {
return communityId;
}
public CommunityOrganization setCommunityId(String communityId) {
public CommunityOrganization setCommunityId(final String communityId) {
this.communityId = communityId;
return this;
}
@ -41,7 +42,7 @@ public class CommunityOrganization {
return name;
}
public CommunityOrganization setName(String name) {
public CommunityOrganization setName(final String name) {
this.name = name;
return this;
}
@ -50,7 +51,7 @@ public class CommunityOrganization {
return id;
}
public CommunityOrganization setId(String id) {
public CommunityOrganization setId(final String id) {
this.id = id;
return this;
}
@ -59,7 +60,7 @@ public class CommunityOrganization {
return logo_url;
}
public CommunityOrganization setLogo_url(String logo_url) {
public CommunityOrganization setLogo_url(final String logo_url) {
this.logo_url = logo_url;
return this;
}
@ -68,7 +69,7 @@ public class CommunityOrganization {
return website_url;
}
public CommunityOrganization setWebsite_url(String website_url) {
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,28 +3,29 @@ 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)
@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)
@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)
@Schema(description = "identifies this zenodo community within the context it belongs to", required = true)
private String id;
public String getZenodoid() {
return zenodoid;
}
public void setZenodoid(String zenodoid) {
public void setZenodoid(final String zenodoid) {
this.zenodoid = zenodoid;
}
@ -40,7 +41,7 @@ public class CommunityZenodoCommunity {
return communityId;
}
public void setCommunityId(String 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 {
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 {
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 {
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,18 +31,21 @@ 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();
if (requestFilter != null) {
final List<Expression<Boolean>> expressions = p.getExpressions();
requestFilter.entrySet().stream()
expressions.add(cb.equal(ds.get("eoscType"), "Data Source"));
expressions.add(cb.equal(ds.get("dedupMainService"), true));
if (requestFilter != null) {
requestFilter.entrySet()
.stream()
.forEach(e -> {
switch (FilterName.type(e.getKey())) {
@ -46,14 +56,15 @@ public class DatasourceSpecs {
case search:
expressions.add(likeSearch(ds, cb, e));
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)));
expressions.add(cb.equal(cb.lower(ds.join("organizations").get(FilterName.country.name())), getValue(e)));
break;
}
});
@ -83,7 +94,8 @@ public class DatasourceSpecs {
final Predicate p = cb.conjunction();
if (requestFilter != null) {
final List<Expression<Boolean>> expressions = p.getExpressions();
requestFilter.entrySet().stream()
requestFilter.entrySet()
.stream()
.forEach(e -> {
switch (FilterName.type(e.getKey())) {
@ -94,6 +106,11 @@ public class DatasourceSpecs {
expressions.add(likeSearch(api, cb, e));
break;
case multiSearch:
expressions.add(likeSearchList(api, cb, e));
break;
case searchOrgs:
throw new DsmRuntimeException("not implemented");
}
@ -108,10 +125,22 @@ 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);
}
// 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
@ -121,19 +150,15 @@ public class DatasourceSpecs {
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,20 +1,17 @@
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;
public AggregationHistoryResponse(List<AggregationInfo> aggregationInfo) {
public AggregationHistoryResponse(final List<AggregationInfo> aggregationInfo) {
super();
this.aggregationInfo = aggregationInfo;
}
@ -23,7 +20,7 @@ public class AggregationHistoryResponse extends Response {
return aggregationInfo;
}
public void setAggregationInfo(List<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,19 +1,15 @@
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;
public DatasourceDetailResponse(List<DatasourceDetails> datasourceInfo) {
public DatasourceDetailResponse(final List<DatasourceDetails> datasourceInfo) {
super();
this.datasourceInfo = datasourceInfo;
}
@ -22,7 +18,7 @@ public class DatasourceDetailResponse extends Response {
return datasourceInfo;
}
public void setDatasourceInfo(List<DatasourceDetails> 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,19 +1,15 @@
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;
public DatasourceSearchResponse(List<DatasourceInfo> datasourceInfo) {
public DatasourceSearchResponse(final List<DatasourceInfo> datasourceInfo) {
super();
this.datasourceInfo = datasourceInfo;
}
@ -22,7 +18,7 @@ public class DatasourceSearchResponse extends Response {
return datasourceInfo;
}
public void setDatasourceInfo(List<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,19 +1,15 @@
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;
public DatasourceSnippetResponse(List<DatasourceSnippetExtended> datasourceInfo) {
public DatasourceSnippetResponse(final List<DatasourceSnippetExtended> datasourceInfo) {
super();
this.datasourceInfo = datasourceInfo;
}
@ -22,7 +18,7 @@ public class DatasourceSnippetResponse extends Response {
return datasourceInfo;
}
public void setDatasourceInfo(List<DatasourceSnippetExtended> 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;

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,14 +33,14 @@ 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 {
@ -41,26 +48,31 @@ public class FundersApiController extends AbstractExporterController {
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 {
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 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,15 +62,15 @@ 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,
@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,
@ -86,15 +90,15 @@ 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,
@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,
@ -112,24 +116,25 @@ public class ProjectsController extends AbstractExporterController {
private void doProcess(
final ServletResponse response,
final ProjectQueryParams params,
final String head, final Resource projectTemplate, final String tail,
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 {
@ -140,22 +145,21 @@ 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 {
@ -170,7 +174,8 @@ public class ProjectsController extends AbstractExporterController {
case "json":
response.setContentType("text/plain");
break;
default: throw new IllegalArgumentException("unsupported format: " + format);
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,12 +23,17 @@ 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
@ -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,18 +90,22 @@ 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
*/
@ -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