Update to spring boot 3 and java 17

This commit is contained in:
Konstantinos Triantafyllou 2024-10-16 23:55:37 +03:00
parent 968209e78e
commit b551d8fc72
20 changed files with 204 additions and 403 deletions

View File

@ -1,13 +1,14 @@
# Irish Monitor Service # Irish Monitor Service
Irish Monitor Service is a service that integrates both OpenAIRE Login API and Irish Monitor Service is a service that integrates both OpenAIRE Login API and
OpenAIRE Monitor API and provide all functionalities for National Open Access Monitor, Ireland. OpenAIRE Monitor API and provide all functionalities for National Open Access Monitor, Ireland.
## Maven ## Maven
Java Version: 1.8, Sprint boot Version: 1.5.8.RELEASE Java Version: 1.8, Sprint boot Version: 1.5.8.RELEASE
This service has dependencies downloaded from [D4Science Nexus repository](https://maven.research-infrastructures.eu/nexus/content/repositories/dnet45-releases), This service has dependencies downloaded
from [D4Science Nexus repository](https://maven.research-infrastructures.eu/nexus/content/repositories/dnet45-releases),
so there is a definition of this repository inside [pom.xml](pom.xml). so there is a definition of this repository inside [pom.xml](pom.xml).
### Install ### Install
@ -21,17 +22,20 @@ so there is a definition of this repository inside [pom.xml](pom.xml).
cd /etc/systemd/system cd /etc/systemd/system
sudo vim service-name.service sudo vim service-name.service
2. Add the following content by replacing () accordingly. 2. Add the following content by replacing <port> and <folder-name> accordingly.
[Unit] [Unit]
Description=service-name Description=irish-monitor-service
After=syslog.target After=syslog.target
[Service] [Service]
User=root User=root
ExecStart=(/home/user/spring-boot/)irish-monitor-service.war (--spring.profiles.active=swagger) --server.port=(port) (--server.context-path=/irish-monitor-service) --spring.config.location=file:///(home/user/spring-boot/config/application.properties) Environment="PORT=<port>"
Environment="SERVICE_NAME=irish-monitor-service"
Environment="PROPERTIES_FOLDER=<folder-name>"
ExecStart=/bin/sh -c "java -jar /srv/spring-boot/${PORT}/${SERVICE_NAME}.war --server.port=${PORT} --server.servlet.context-path=/${SERVICE_NAME} --spring.config.location=file:///srv/spring-boot/${PROPERTIES_FOLDER}/dnet-override.properties"
SuccessExitStatus=143 SuccessExitStatus=143
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target
@ -56,57 +60,55 @@ so there is a definition of this repository inside [pom.xml](pom.xml).
In order to configure this service you have to set the following properties: In order to configure this service you have to set the following properties:
stats-tool.rfo=<StatsToolURL>?json=<JsonQuery> stats-tool.host=<stats-tool-url> # Stats tool URL with json param e.g https://stats.madgik.di.uoa.gr/stats-api/raw?json=
stats-tool.rpo=<StatsToolURL>?json=<JsonQuery>
stats-tool.repository=<StatsToolURL>?json=<JsonQuery>
## Authentication / Authorization
## Login core This dependency provides the Authentication and Authorization functionality.
This dependency provides the Authentication and Authorization functionality.
In order to configure it you have to set the following properties: In order to configure it you have to set the following properties:
authentication.domain=<Domain> authorization.security.redis.host=<redis-ip> # Default localhost
authentication.oidc.home=<API_URL>/openid_connect_login authorization.security.redis.port=<redis-port> # Default 6379
authentication.oidc.scope=openid,profile,email,eduperson_entitlement,orcid authorization.security.redis.password=<redis-password> # Default ""
authentication.oidc.id=<ProviderClientId> authorization.security.domain=<domain-suffix> # e.g openaire.eu Default: di.uoa.gr
authentication.oidc.secret=<ProviderClientSecret> authorization.security.session=<session-cookie-name> # Default openAIRESession
authentication.oidc.issuer=https://aai.openaire.eu/auth/realms/openaire
authentication.oidc.redirect=<API_URL>/redirect authentication.client.name= # Required - Name of the provider - default value: openaire
authentication.session=irishSession authentication.client.issuer= # Required - Issuer url - default value: https://aai.openaire.eu/auth/realms/openaire
authentication.redirect=<DefaultRedirectURL> authentication.client.scope= # Required - scope properties of the provider - default value: openid,profile,email,eduperson_entitlement
authentication.redis.host=<RedisHost> authentication.client.id= # Required - Client id - default value: -
authentication.redis.port=<RedisPort> authentication.client.secret= # Required - Client secret - default value: -
authentication.redis.passwork=<RedisPassword> authentication.client.redirect= # Required - Redirect endpoint of the service: {baseURL}/login-service/redirect
authentication.authorities-mapper=irish.eduperson_entitlement // DO NOT CHANGE authentication.client.logout= # Optional - If custom logout endpoint is needed. (Needs a redirect param at the end)
authentication.keycloak=true authentication.redirect= # Required - Set the default redirect URL after a successful login / logout
authentication.accessToken= # Optional - Name of access token cookie, default value: AccessToken
authentication.authorities-mapper= # Optional - Add the field of User Info provider endpoint that containes authorities. e.g. eduperson_entitlement (Don't forget to include it scope)
## Monitor Service ## Monitor Service
This dependency provides the main service functionality This dependency provides the main service functionality
in order to create/edit/delete monitor profiles and their content. in order to create/edit/delete monitor profiles and their content.
In order to configure it you have to set the following properties: In order to configure it you have to set the following properties:
monitorservice.mongodb.host=<MongoHost> monitor-service.mongodb.host # Required - Host of mongo server - Default: localhost
monitorservice.mongodb.port=<MongoPort> monitor-service.mongodb.database # Required - Database name
monitorservice.mongodb.database=<DatabaseName> monitor-service.mongodb.username # Optional - Username if needed
monitorservice.mongodb.username=<MongoUser> monitor-service.mongodb.password # Optional - Password if needed
monitorservice.mongodb.password=<MongoPassword> monitor-service.mongodb.port # Required - Mongo server port - Default: 27017
## Admin Tools Library (integrated in Monitor Service) ## Admin Tools Library (integrated in Monitor Service)
This dependency provides utilities to store dynamic HTML content, This dependency provides utilities to store dynamic HTML content,
send Email and verify Google recaptcha. In order to configure it send Email and verify Google recaptcha. In order to configure it
you have to set the following properties: you have to set the following properties:
admintoolslibrary.mail.from = <Email> admintoolslibrary.google.secret= # Required - Google secret of recaptcha client
admintoolslibrary.mail.username = <Email> admintoolslibrary.mail.host # Required - Mail host name
admintoolslibrary.mail.password = <EmailPassword> admintoolslibrary.mail.port # Required - Mail port
admintoolslibrary.mail.host = <EmailHost> admintoolslibrary.mail.from # Required - From email address
admintoolslibrary.mail.port = <EmailPort> admintoolslibrary.mail.protocol # Required - Mail protocol
admintoolslibrary.mail.auth = true admintoolslibrary.mail.defaultEncoding # Required - Default Encoding - default value: UTF-8
admintoolslibrary.mail.sslProtocols = TLSv1.2 admintoolslibrary.mail.sslProtocols # Optional - If ssl Protocols are needed (comma separated)
admintoolslibrary.mail.defaultEncoding=UTF-8 admintoolslibrary.mail.auth # Required (boolean) - If authentication is required for mail account - default value: false
admintoolslibrary.mail.protocol=<EmailProtocol> admintoolslibrary.mail.username # Required (if auth = true) - Username of mail account
admintoolslibrary.mail.testConnection=false admintoolslibrary.mail.password # Required (if auth = true) - Password of mail account
admintoolslibrary.google.secret = <GoogleSecret>

43
pom.xml
View File

@ -3,7 +3,7 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>irish-monitor-service</artifactId> <artifactId>irish-monitor-service</artifactId>
<version>1.0.5-SNAPSHOT</version> <version>2.0.0-SNAPSHOT</version>
<packaging>war</packaging> <packaging>war</packaging>
<name>irish-monitor-service</name> <name>irish-monitor-service</name>
<scm> <scm>
@ -13,7 +13,7 @@
<parent> <parent>
<groupId>eu.dnetlib</groupId> <groupId>eu.dnetlib</groupId>
<artifactId>uoa-spring-boot-parent</artifactId> <artifactId>uoa-spring-boot-parent</artifactId>
<version>1.0.0</version> <version>2.0.3</version>
</parent> </parent>
<properties> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@ -22,31 +22,16 @@
<maven.build.timestamp.format>E MMM dd HH:mm:ss z yyyy</maven.build.timestamp.format> <maven.build.timestamp.format>E MMM dd HH:mm:ss z yyyy</maven.build.timestamp.format>
</properties> </properties>
<dependencies> <dependencies>
<dependency>
<dependency> <!-- this dependency includes dependency to uoa-monitor-service-library -->
<groupId>eu.dnetlib</groupId> <groupId>eu.dnetlib</groupId>
<artifactId>uoa-monitor-service</artifactId> <artifactId>uoa-monitor-service</artifactId>
<version>1.1.15</version> <version>2.0.0-BETA</version>
<classifier>library</classifier> <classifier>library</classifier>
</dependency> </dependency>
<dependency> <dependency>
<groupId>eu.dnetlib</groupId> <groupId>eu.dnetlib</groupId>
<artifactId>uoa-login-core</artifactId> <artifactId>uoa-login-core</artifactId>
<version>2.1.1</version> <version>3.0.5</version>
</dependency>
<!--swagger-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger-version}</version>
</dependency>
<!--swagger official ui-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger-version}</version>
</dependency> </dependency>
</dependencies> </dependencies>
<repositories> <repositories>
@ -68,35 +53,17 @@
<plugin> <plugin>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId> <artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot-version}</version>
<configuration> <configuration>
<mainClass>eu.dnetlib.irishmonitorservice.IrishMonitorServiceApplication</mainClass> <mainClass>eu.dnetlib.irishmonitorservice.IrishMonitorServiceApplication</mainClass>
<executable>true</executable> <executable>true</executable>
</configuration> </configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin> </plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId> <artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin> </plugin>
</plugins> </plugins>
<finalName>irish-monitor-service</finalName> <finalName>irish-monitor-service</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build> </build>
</project> </project>

View File

@ -2,8 +2,7 @@ package eu.dnetlib.irishmonitorservice;
import eu.dnetlib.authentication.configuration.AuthenticationConfiguration; import eu.dnetlib.authentication.configuration.AuthenticationConfiguration;
import eu.dnetlib.irishmonitorservice.configuration.GlobalVars; import eu.dnetlib.irishmonitorservice.configuration.GlobalVars;
import eu.dnetlib.irishmonitorservice.configuration.properties.APIProperties; import eu.dnetlib.irishmonitorservice.configuration.properties.Properties;
import eu.dnetlib.irishmonitorservice.configuration.properties.StatsToolProperties;
import eu.dnetlib.uoamonitorservice.UoaMonitorServiceConfiguration; import eu.dnetlib.uoamonitorservice.UoaMonitorServiceConfiguration;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
@ -22,7 +21,7 @@ import org.springframework.scheduling.annotation.EnableScheduling;
@PropertySource("classpath:irishmonitorservice.properties"), @PropertySource("classpath:irishmonitorservice.properties"),
@PropertySource(value = "classpath:dnet-override.properties", ignoreResourceNotFound = true) @PropertySource(value = "classpath:dnet-override.properties", ignoreResourceNotFound = true)
}) })
@EnableConfigurationProperties({GlobalVars.class, APIProperties.class, StatsToolProperties.class}) @EnableConfigurationProperties({GlobalVars.class, Properties.class})
@EnableCaching @EnableCaching
@EnableScheduling @EnableScheduling
@Import({UoaMonitorServiceConfiguration.class, AuthenticationConfiguration.class}) @Import({UoaMonitorServiceConfiguration.class, AuthenticationConfiguration.class})

View File

@ -1,8 +1,7 @@
package eu.dnetlib.irishmonitorservice; package eu.dnetlib.irishmonitorservice;
import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.support.SpringBootServletInitializer; import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
//import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
public class ServletInitializer extends SpringBootServletInitializer { public class ServletInitializer extends SpringBootServletInitializer {

View File

@ -4,7 +4,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.Date; import java.util.Date;
@ConfigurationProperties("irishmonitorservice.globalVars") @ConfigurationProperties("irish-monitor-service.global-vars")
public class GlobalVars { public class GlobalVars {
public static Date date = new Date(); public static Date date = new Date();
private Date buildDate; private Date buildDate;

View File

@ -1,120 +0,0 @@
package eu.dnetlib.irishmonitorservice.configuration;
import eu.dnetlib.irishmonitorservice.configuration.properties.APIProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.schema.ModelRef;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Parameter;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.Collections;
import java.util.List;
/**
* Swagger configuration class
*/
@Configuration
@Profile({"swagger"})
@EnableSwagger2
public class SwaggerConfig extends WebMvcConfigurerAdapter {
private final APIProperties apiProperties;
@Autowired
public SwaggerConfig(APIProperties apiProperties) {
this.apiProperties = apiProperties;
}
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
// .globalOperationParameters(globalParameterList())
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("eu.dnetlib.irishmonitorservice.controllers"))
.paths(PathSelectors.any())
.build();
}
@Bean
public Docket createRestApiMonitorLibrary() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.groupName("Monitor Library")
.select()
.apis(RequestHandlerSelectors.basePackage("eu.dnetlib.uoamonitorservice.controllers"))
.paths(PathSelectors.any())
.build();
}
@Bean
public Docket createRestApiLibrary() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.groupName("Library")
.select()
.apis(RequestHandlerSelectors.basePackage("eu.dnetlib.uoaadmintoolslibrary.controllers"))
.paths(PathSelectors.any())
.build();
}
@Bean
public Docket createRestApiAuthorizationLibrary() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.groupName("Authorization Library")
.select()
.apis(RequestHandlerSelectors.basePackage("eu.dnetlib.uoaauthorizationlibrary.controllers"))
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title(this.apiProperties.getTitle())
.description(this.apiProperties.getDescription())
.version(this.apiProperties.getVersion())
.build();
}
private List<Parameter> globalParameterList() {
Parameter authTokenHeader = new ParameterBuilder()
.name("Session") // name of the header
.modelRef(new ModelRef("string")) // data-type of the header
.required(false)
.parameterType("header")
.description("Session ID")
.build();
return Collections.singletonList(authTokenHeader);
}
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addRedirectViewController("/v2/api-docs", "/v2/api-docs");
registry.addRedirectViewController("/swagger-resources/configuration/ui", "/swagger-resources/configuration/ui");
registry.addRedirectViewController("/swagger-resources/configuration/security", "/swagger-resources/configuration/security");
registry.addRedirectViewController("/swagger-resources", "/swagger-resources");
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/swagger-ui.html**").addResourceLocations("classpath:/META-INF/resources/swagger-ui.html");
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
}
}

View File

@ -1,15 +1,15 @@
package eu.dnetlib.irishmonitorservice.configuration.mongo; package eu.dnetlib.irishmonitorservice.configuration.mongo;
import com.mongodb.MongoClient; import com.mongodb.MongoClientSettings;
import com.mongodb.MongoCredential; import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress; import com.mongodb.ServerAddress;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import eu.dnetlib.uoamonitorservice.configuration.properties.MongoConfig; import eu.dnetlib.uoamonitorservice.configuration.properties.MongoConfig;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
import java.util.Collections; import java.util.Collections;
@ -18,27 +18,30 @@ import java.util.Collections;
@EnableMongoRepositories(basePackages = {"eu.dnetlib.irishmonitorservice.dao"}, mongoTemplateRef = "mongoIrishTemplate") @EnableMongoRepositories(basePackages = {"eu.dnetlib.irishmonitorservice.dao"}, mongoTemplateRef = "mongoIrishTemplate")
public class IrishMongoConnection { public class IrishMongoConnection {
@Autowired private final MongoConfig mongoConfig;
private MongoConfig mongoConfig;
@Bean @Autowired
public MongoDbFactory mongoDbFactory() { public IrishMongoConnection(MongoConfig mongoConfig) {
return new SimpleMongoDbFactory(getMongoClient(), mongoConfig.getDatabase()); this.mongoConfig = mongoConfig;
} }
@Bean(name = "mongoIrishTemplate") @Bean(name = "mongoIrishTemplate")
public MongoTemplate getMongoTemplate() { public MongoTemplate getMongoTemplate() {
return new MongoTemplate(mongoDbFactory()); return new MongoTemplate(getMongoClient(), mongoConfig.getDatabase());
} }
private MongoClient getMongoClient() { private MongoClient getMongoClient() {
if(mongoConfig.getUsername() != null && mongoConfig.getPassword() != null){ MongoClientSettings.Builder builder = MongoClientSettings.builder()
return new MongoClient(Collections.singletonList( .applyToClusterSettings(b -> b.hosts(Collections.singletonList(new ServerAddress(mongoConfig.getHost(), mongoConfig.getPort()))));
new ServerAddress(mongoConfig.getHost(), mongoConfig.getPort())), if(mongoConfig.getUsername() != null && mongoConfig.getPassword() != null) {
Collections.singletonList(MongoCredential.createCredential(mongoConfig.getUsername(), mongoConfig.getDatabase(), mongoConfig.getPassword().toCharArray()))); MongoCredential credential = MongoCredential.createCredential(
} else { mongoConfig.getUsername(),
return new MongoClient(Collections.singletonList(new ServerAddress(mongoConfig.getHost(), mongoConfig.getPort()))); mongoConfig.getDatabase(),
mongoConfig.getPassword().toCharArray()
);
builder.credential(credential);
} }
return MongoClients.create(builder.build());
} }

View File

@ -1,38 +0,0 @@
package eu.dnetlib.irishmonitorservice.configuration.properties;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties("api")
public class APIProperties {
private String title;
private String description;
private String version;
public APIProperties() {
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
}

View File

@ -3,13 +3,13 @@ package eu.dnetlib.irishmonitorservice.configuration.properties;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties("stats-tool") @ConfigurationProperties("stats-tool")
public class StatsToolProperties { public class Properties {
private String host; private String host;
private Indicators rpo; private Indicators rpo;
private Indicators rfo; private Indicators rfo;
private Indicators repository; private Indicators repository;
public StatsToolProperties() { public Properties() {
} }
public String getHost() { public String getHost() {

View File

@ -1,47 +1,37 @@
package eu.dnetlib.irishmonitorservice.controllers; package eu.dnetlib.irishmonitorservice.controllers;
import eu.dnetlib.irishmonitorservice.configuration.GlobalVars; import eu.dnetlib.irishmonitorservice.services.DeployService;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
@RestController @RestController
@CrossOrigin(origins = "*")
public class IrishServiceCheckDeployController { public class IrishServiceCheckDeployController {
private final Logger log = LogManager.getLogger(this.getClass()); private final Logger log = LogManager.getLogger(this.getClass());
private final DeployService service;
@Autowired @Autowired
private GlobalVars globalVars; public IrishServiceCheckDeployController(DeployService service) {
this.service = service;
}
@RequestMapping(value = {"", "/health_check"}, method = RequestMethod.GET) @RequestMapping(value = {"", "/health_check"}, method = RequestMethod.GET)
public String hello() { public ResponseEntity<String> hello() {
log.debug("Hello from irish-monitor-service!"); log.debug("Hello from irish-monitor-service!");
return "Hello from irish-monitor-service!"; return ResponseEntity.ok("Hello from irish-monitor-service!");
} }
@PreAuthorize("hasAnyAuthority(@AuthorizationService.PORTAL_ADMIN)") @PreAuthorize("hasAnyAuthority(@AuthorizationService.PORTAL_ADMIN)")
@RequestMapping(value = "/health_check/advanced", method = RequestMethod.GET) @RequestMapping(value = "/health_check/advanced", method = RequestMethod.GET)
public Map<String, String> checkEverything() { public ResponseEntity<Map<String, String>> checkEverything() {
Map<String, String> response = new HashMap<>(); return ResponseEntity.ok(this.service.getProperties());
if(globalVars.date != null) {
response.put("Date of deploy", globalVars.date.toString());
}
if(globalVars.getBuildDate() != null) {
response.put("Date of build", globalVars.getBuildDate());
}
if(globalVars.getVersion() != null) {
response.put("Version", globalVars.getVersion());
}
return response;
} }
} }

View File

@ -4,13 +4,13 @@ import eu.dnetlib.irishmonitorservice.entities.SortBy;
import eu.dnetlib.irishmonitorservice.entities.StakeholderExtended; import eu.dnetlib.irishmonitorservice.entities.StakeholderExtended;
import eu.dnetlib.irishmonitorservice.services.StakeholderExtendedService; import eu.dnetlib.irishmonitorservice.services.StakeholderExtendedService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.util.List; import java.util.List;
@RestController @RestController
@CrossOrigin(origins = "*")
@RequestMapping("extended") @RequestMapping("extended")
public class StakeholderExtendedController { public class StakeholderExtendedController {
private final StakeholderExtendedService service; private final StakeholderExtendedService service;
@ -21,12 +21,12 @@ public class StakeholderExtendedController {
} }
@RequestMapping(value = "", method = RequestMethod.GET) @RequestMapping(value = "", method = RequestMethod.GET)
public List<StakeholderExtended> getStakeholders(@RequestParam("type") String type, @RequestParam(value = "sort", required = false) SortBy sort) throws UnsupportedEncodingException { public ResponseEntity<List<StakeholderExtended>> getStakeholders(@RequestParam("type") String type, @RequestParam(value = "sort", required = false) SortBy sort) throws UnsupportedEncodingException {
return this.service.sortBy(this.service.getVisibleStakeholdersExtended(type), sort); return ResponseEntity.ok(this.service.sortBy(this.service.getVisibleStakeholdersExtended(type), sort));
} }
@RequestMapping(value = "/{stakeholderId}", method = RequestMethod.GET) @RequestMapping(value = "/{stakeholderId}", method = RequestMethod.GET)
public StakeholderExtended getStakeholder(@PathVariable String stakeholderId) throws UnsupportedEncodingException { public ResponseEntity<StakeholderExtended> getStakeholder(@PathVariable String stakeholderId) throws UnsupportedEncodingException {
return this.service.getStakeholderExtended(stakeholderId); return ResponseEntity.ok(this.service.getStakeholderExtended(stakeholderId));
} }
} }

View File

@ -2,65 +2,45 @@ package eu.dnetlib.irishmonitorservice.controllers;
import eu.dnetlib.irishmonitorservice.dao.UserProfileDAO; import eu.dnetlib.irishmonitorservice.dao.UserProfileDAO;
import eu.dnetlib.irishmonitorservice.entities.UserProfile; import eu.dnetlib.irishmonitorservice.entities.UserProfile;
import eu.dnetlib.uoaadmintoolslibrary.handlers.ContentNotFoundException; import eu.dnetlib.uoaadmintoolslibrary.utils.RolesUtils;
import eu.dnetlib.uoaadmintoolslibrary.handlers.ForbiddenException; import eu.dnetlib.uoaauthorizationlibrary.authorization.exceptions.http.NotFoundException;
import eu.dnetlib.uoaadmintoolslibrary.handlers.utils.RolesUtils;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*; 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;
@RestController @RestController
@CrossOrigin(origins = "*")
@RequestMapping("/user") @RequestMapping("/user")
@PreAuthorize("isAuthenticated()") @PreAuthorize("isAuthenticated()")
public class UserProfileController { public class UserProfileController {
private final Logger log = LogManager.getLogger(this.getClass()); private final Logger log = LogManager.getLogger(this.getClass());
@Autowired private final RolesUtils rolesUtils;
private RolesUtils rolesUtils; private final UserProfileDAO dao;
@Autowired @Autowired
private UserProfileDAO userDAO; public UserProfileController(RolesUtils rolesUtils, UserProfileDAO dao) {
this.rolesUtils = rolesUtils;
this.dao = dao;
}
@RequestMapping(value = "/save", method = RequestMethod.POST) @RequestMapping(value = "/save", method = RequestMethod.POST)
public UserProfile saveUserProfile(@RequestBody UserProfile userProfile) { public ResponseEntity<UserProfile> saveUserProfile(@RequestBody UserProfile userProfile) {
String aaiId = rolesUtils.getAaiId(); userProfile.setAaiId(rolesUtils.getAaiId());
UserProfile existingUserProfile = userDAO.findByAaiId(aaiId); if(dao.findByAaiId(userProfile.getAaiId()).isPresent()) {
if(existingUserProfile != null) { userProfile.setId(dao.findByAaiId(userProfile.getAaiId()).get().getId());
userProfile.setId(existingUserProfile.getId());
} }
userProfile.setAaiId(aaiId); // users can only save/ update their own profiles return ResponseEntity.ok(dao.save(userProfile));
return userDAO.save(userProfile);
} }
// @RequestMapping(value = "/delete/{aaiId}", method = RequestMethod.DELETE)
// public Boolean deleteUserProfileByAaiId(@PathVariable("aaiId") String aaiId) {
// // maybe portal admin could delete any user profile?
//
// String currentAaiId = rolesUtils.getAaiId();
// if(aaiId != null && currentAaiId.equals(aaiId)) {
// throw new ForbiddenException("User with id: "+currentAaiId + " has not access to update user with id: "+aaiId);
// }
// UserProfile user = userDAO.findByAaiId(aaiId);
// if(user == null) {
// // EXCEPTION - Entity Not Found
// throw new ContentNotFoundException("Delete user profile: No user profile found for : " + aaiId);
// } else {
// userDAO.delete(user.getId());
// }
// return true;
// }
@RequestMapping(value = "", method = RequestMethod.GET) @RequestMapping(value = "", method = RequestMethod.GET)
public UserProfile getUserProfile() { public ResponseEntity<UserProfile> getUserProfile() {
String aaiId = rolesUtils.getAaiId(); return ResponseEntity.ok(this.dao.findByAaiId(this.rolesUtils.getAaiId())
UserProfile user = userDAO.findByAaiId(aaiId); .orElseThrow(() -> new NotFoundException("No user profile found for: " + this.rolesUtils.getAaiId())));
if(user == null) {
// EXCEPTION - Entity Not Found
throw new ContentNotFoundException("No user profile found for: " + aaiId);
}
return user;
} }
} }

View File

@ -1,20 +0,0 @@
package eu.dnetlib.irishmonitorservice.dao;
import eu.dnetlib.irishmonitorservice.entities.UserProfile;
import org.springframework.data.mongodb.repository.MongoRepository;
import java.util.List;
public interface MongoDBUserProfileDAO extends UserProfileDAO, MongoRepository<UserProfile, String> {
List<UserProfile> findAll();
UserProfile findById(String Id);
UserProfile findByAaiId(String aaiId);
UserProfile save(UserProfile user);
void deleteAll();
void delete(String id);
}

View File

@ -1,19 +1,13 @@
package eu.dnetlib.irishmonitorservice.dao; package eu.dnetlib.irishmonitorservice.dao;
import eu.dnetlib.irishmonitorservice.entities.UserProfile; import eu.dnetlib.irishmonitorservice.entities.UserProfile;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;
import java.util.List; import java.util.List;
import java.util.Optional;
public interface UserProfileDAO { @Repository
List<UserProfile> findAll(); public interface UserProfileDAO extends MongoRepository<UserProfile, String> {
Optional<UserProfile> findByAaiId(String aaiId);
UserProfile findById(String Id);
UserProfile findByAaiId(String aaiId);
UserProfile save(UserProfile user);
void deleteAll();
void delete(String id);
} }

View File

@ -2,14 +2,15 @@ package eu.dnetlib.irishmonitorservice.security;
import com.google.gson.JsonArray; import com.google.gson.JsonArray;
import com.nimbusds.jwt.JWT; import com.nimbusds.jwt.JWT;
import eu.dnetlib.authentication.security.DefaultAuthoritiesMapper;
import eu.dnetlib.authentication.security.OpenAIREAuthoritiesMapper;
import eu.dnetlib.authentication.utils.AuthoritiesMapper; import eu.dnetlib.authentication.utils.AuthoritiesMapper;
import eu.dnetlib.uoaauthorizationlibrary.security.AuthorizationService; import eu.dnetlib.uoaauthorizationlibrary.authorization.security.AuthorizationService;
import org.mitre.openid.connect.client.OIDCAuthoritiesMapper;
import org.mitre.openid.connect.model.UserInfo;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.oauth2.core.oidc.user.OidcUser;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.Collection; import java.util.Collection;
@ -19,7 +20,7 @@ import java.util.stream.Collectors;
@ConditionalOnProperty( @ConditionalOnProperty(
value = "authentication.authorities-mapper", value = "authentication.authorities-mapper",
havingValue = "irish.eduperson_entitlement") havingValue = "irish.eduperson_entitlement")
public class IrishAuthoritiesMapper implements OIDCAuthoritiesMapper { public class IrishAuthoritiesMapper extends OpenAIREAuthoritiesMapper {
private final String domain = "IRISH_"; private final String domain = "IRISH_";
private final AuthorizationService authorizationService; private final AuthorizationService authorizationService;
@ -29,11 +30,8 @@ public class IrishAuthoritiesMapper implements OIDCAuthoritiesMapper {
} }
@Override @Override
public Collection<? extends GrantedAuthority> mapAuthorities(JWT jwtToken, UserInfo userInfo) { public Collection<? extends GrantedAuthority> mapAuthorities(OidcUser oidcUser) {
JsonArray entitlements = userInfo.getSource().getAsJsonArray("eduperson_entitlement"); return super.mapAuthorities(oidcUser).stream().filter(this::filter).map(this::map).collect(Collectors.toSet());
return AuthoritiesMapper.map(entitlements).stream()
.filter(this::filter)
.map(this::map).collect(Collectors.toSet());
} }

View File

@ -1,12 +1,10 @@
package eu.dnetlib.irishmonitorservice.services; package eu.dnetlib.irishmonitorservice.services;
import eu.dnetlib.irishmonitorservice.entities.Data;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache; import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager; import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -30,20 +28,16 @@ public class CacheService {
} }
public List<List<List<String>>> getResponse(String type) throws UnsupportedEncodingException { public List<List<List<String>>> getResponse(String type) throws UnsupportedEncodingException {
switch (type) { return switch (type) {
case "funder": case "funder" -> this.statsToolService.getFunders();
return this.statsToolService.getFunders(); case "organization" -> this.statsToolService.getOrganizations();
case "organization": case "datasource" -> this.statsToolService.getDataSources();
return this.statsToolService.getOrganizations(); default -> null;
case "datasource": };
return this.statsToolService.getDataSources();
default:
return null;
}
} }
@Scheduled(cron = "0 0 0 * * *") // Reset cache every day at 00:00 @Scheduled(cron = "0 0 0 * * *") // Reset cache every day at 00:00
public void clearCache() throws UnsupportedEncodingException { public void clearCache() {
this.cacheManager.getCache("funder"); this.cacheManager.getCache("funder");
this.cacheManager.getCache("organization"); this.cacheManager.getCache("organization");
this.cacheManager.getCache("datasource"); this.cacheManager.getCache("datasource");

View File

@ -0,0 +1,47 @@
package eu.dnetlib.irishmonitorservice.services;
import eu.dnetlib.irishmonitorservice.configuration.mongo.IrishMongoConnection;
import eu.dnetlib.irishmonitorservice.configuration.properties.Properties;
import eu.dnetlib.uoamonitorservice.configuration.GlobalVars;
import org.bson.Document;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
@Service
public class DeployService {
private final IrishMongoConnection mongoConnection;
private final Properties properties;
private final GlobalVars globalVars;
@Autowired
public DeployService(IrishMongoConnection mongoConnection, Properties properties, GlobalVars globalVars) {
this.mongoConnection = mongoConnection;
this.properties = properties;
this.globalVars = globalVars;
}
public Map<String, String> getProperties() {
Map<String, String> response = new HashMap<>();
MongoTemplate mt = mongoConnection.getMongoTemplate();
Document ping = new Document("ping", 1);
try {
Document answer = mt.executeCommand(ping);
response.put("Mongo try: error", String.valueOf(answer.getDouble("ok") == 1.0));
} catch (Exception e) {
response.put("Mongo catch: error", e.getMessage());
}
response.put("stats-tool.host", properties.getHost());
response.put("Date of deploy", GlobalVars.date.toString());
if (globalVars.getBuildDate() != null) {
response.put("Date of build", globalVars.getBuildDate());
}
if (globalVars.getVersion() != null) {
response.put("Version", globalVars.getVersion());
}
return response;
}
}

View File

@ -1,7 +1,7 @@
package eu.dnetlib.irishmonitorservice.services; package eu.dnetlib.irishmonitorservice.services;
import eu.dnetlib.irishmonitorservice.configuration.properties.Indicators; import eu.dnetlib.irishmonitorservice.configuration.properties.Indicators;
import eu.dnetlib.irishmonitorservice.configuration.properties.StatsToolProperties; import eu.dnetlib.irishmonitorservice.configuration.properties.Properties;
import eu.dnetlib.irishmonitorservice.entities.Data; import eu.dnetlib.irishmonitorservice.entities.Data;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
@ -17,6 +17,7 @@ import org.springframework.web.util.UriComponentsBuilder;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.URI; import java.net.URI;
import java.net.URLDecoder; import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -24,28 +25,31 @@ import java.util.List;
public class StatsToolService { public class StatsToolService {
private final Logger logger = LogManager.getLogger(StatsToolService.class); private final Logger logger = LogManager.getLogger(StatsToolService.class);
@Autowired private final Properties properties;
private StatsToolProperties properties; private final RestTemplate restTemplate;
@Autowired @Autowired
private RestTemplate restTemplate; public StatsToolService(Properties properties, RestTemplate restTemplate) {
this.properties = properties;
this.restTemplate = restTemplate;
}
@Cacheable(value = "funder") @Cacheable(value = "funder")
public List<List<List<String>>> getFunders() throws UnsupportedEncodingException { public List<List<List<String>>> getFunders() {
return this.getData(this.properties.getRfo()); return this.getData(this.properties.getRfo());
} }
@Cacheable(value = "organization") @Cacheable(value = "organization")
public List<List<List<String>>> getOrganizations() throws UnsupportedEncodingException { public List<List<List<String>>> getOrganizations() {
return this.getData(this.properties.getRpo()); return this.getData(this.properties.getRpo());
} }
@Cacheable(value = "datasource") @Cacheable(value = "datasource")
public List<List<List<String>>> getDataSources() throws UnsupportedEncodingException { public List<List<List<String>>> getDataSources() {
return this.getData(this.properties.getRepository()); return this.getData(this.properties.getRepository());
} }
public List<List<List<String>>> getData(Indicators indicators) throws UnsupportedEncodingException { public List<List<List<String>>> getData(Indicators indicators) {
List<List<List<String>>> data = new ArrayList<>(); List<List<List<String>>> data = new ArrayList<>();
if(indicators != null) { if(indicators != null) {
data.add(this.getData(properties.getHost(), indicators.getPublications())); data.add(this.getData(properties.getHost(), indicators.getPublications()));
@ -55,11 +59,11 @@ public class StatsToolService {
return data; return data;
} }
private List<List<String>> getData(String service, String json) throws UnsupportedEncodingException { private List<List<String>> getData(String service, String json) {
if(service == null || json == null) { if(service == null || json == null) {
return new ArrayList<>(); return new ArrayList<>();
} else { } else {
URI uri = UriComponentsBuilder.fromUriString(service + URLDecoder.decode(json, "UTF-8")).build().encode().toUri(); URI uri = UriComponentsBuilder.fromUriString(service + URLDecoder.decode(json, StandardCharsets.UTF_8)).build().encode().toUri();
try { try {
ResponseEntity<Data> response = restTemplate.getForEntity(uri, Data.class); ResponseEntity<Data> response = restTemplate.getForEntity(uri, Data.class);
if(response.getStatusCode() == HttpStatus.OK) { if(response.getStatusCode() == HttpStatus.OK) {

View File

@ -1,4 +1,3 @@
#static properties # temp until refactoring the code in admin tools library
api.title = Irish Monitor Service Documentation Swagger spring.main.allow-circular-references=true
api.description = Irish Monitor Service is a service that integrates both OpenAIRE login and OpenAIRE Monitor API and provide all functionalities for National Open Access Monitor, Ireland
api.version = ${project.version}

View File

@ -1,7 +1,10 @@
irishmonitorservice.globalVars.buildDate=@timestamp@ irish-monitor-service.global-vars.buildDate=@timestamp@
irishmonitorservice.globalVars.version=@version@ irish-monitor-service.global-vars.version=@version@
api.title = Irish Monitor Service Documentation Swagger
api.description = Irish Monitor Service is a service that integrates both OpenAIRE login and OpenAIRE Monitor API and provide all functionalities for National Open Access Monitor, Ireland
api.version = ${project.version}
stats-tool.host=https://stats.madgik.di.uoa.gr/stats-api/raw?json=
stats-tool.rfo.publications=%7B%22orderBy%22%3A%22yAxis%22%2C%22verbose%22%3Afalse%2C%22series%22%3A%5B%7B%22query%22%3A%7B%22parameters%22%3A%5B%5D%2C%22select%22%3A%5B%7B%22field%22%3A%22publication%22%2C%22aggregate%22%3A%22count%22%7D%2C%7B%22field%22%3A%22publication.project.funder.id%22%2C%22aggregate%22%3Anull%7D%5D%2C%22filters%22%3A%5B%7B%22groupFilters%22%3A%5B%7B%22field%22%3A%22publication.project.funder.country%22%2C%22type%22%3A%22%3D%22%2C%22values%22%3A%5B%22IE%22%5D%7D%5D%2C%22op%22%3A%22AND%22%7D%5D%2C%22entity%22%3A%22publication%22%2C%22profile%22%3A%22ie_monitor%22%2C%22useCache%22%3Afalse%7D%7D%5D%7D stats-tool.rfo.publications=%7B%22orderBy%22%3A%22yAxis%22%2C%22verbose%22%3Afalse%2C%22series%22%3A%5B%7B%22query%22%3A%7B%22parameters%22%3A%5B%5D%2C%22select%22%3A%5B%7B%22field%22%3A%22publication%22%2C%22aggregate%22%3A%22count%22%7D%2C%7B%22field%22%3A%22publication.project.funder.id%22%2C%22aggregate%22%3Anull%7D%5D%2C%22filters%22%3A%5B%7B%22groupFilters%22%3A%5B%7B%22field%22%3A%22publication.project.funder.country%22%2C%22type%22%3A%22%3D%22%2C%22values%22%3A%5B%22IE%22%5D%7D%5D%2C%22op%22%3A%22AND%22%7D%5D%2C%22entity%22%3A%22publication%22%2C%22profile%22%3A%22ie_monitor%22%2C%22useCache%22%3Afalse%7D%7D%5D%7D
stats-tool.rpo.publications=%7B%22orderBy%22%3A%22yAxis%22%2C%22verbose%22%3Afalse%2C%22series%22%3A%5B%7B%22query%22%3A%7B%22parameters%22%3A%5B%5D%2C%22select%22%3A%5B%7B%22field%22%3A%22publication%22%2C%22aggregate%22%3A%22count%22%7D%2C%7B%22field%22%3A%22publication.organization.id%22%2C%22aggregate%22%3Anull%7D%5D%2C%22filters%22%3A%5B%7B%22groupFilters%22%3A%5B%7B%22field%22%3A%22publication.organization.country%22%2C%22type%22%3A%22%3D%22%2C%22values%22%3A%5B%22IE%22%5D%7D%5D%2C%22op%22%3A%22AND%22%7D%5D%2C%22entity%22%3A%22publication%22%2C%22profile%22%3A%22ie_monitor%22%2C%22useCache%22%3Afalse%7D%7D%5D%7D stats-tool.rpo.publications=%7B%22orderBy%22%3A%22yAxis%22%2C%22verbose%22%3Afalse%2C%22series%22%3A%5B%7B%22query%22%3A%7B%22parameters%22%3A%5B%5D%2C%22select%22%3A%5B%7B%22field%22%3A%22publication%22%2C%22aggregate%22%3A%22count%22%7D%2C%7B%22field%22%3A%22publication.organization.id%22%2C%22aggregate%22%3Anull%7D%5D%2C%22filters%22%3A%5B%7B%22groupFilters%22%3A%5B%7B%22field%22%3A%22publication.organization.country%22%2C%22type%22%3A%22%3D%22%2C%22values%22%3A%5B%22IE%22%5D%7D%5D%2C%22op%22%3A%22AND%22%7D%5D%2C%22entity%22%3A%22publication%22%2C%22profile%22%3A%22ie_monitor%22%2C%22useCache%22%3Afalse%7D%7D%5D%7D