diff --git a/apps/dhp-broker-application/src/main/java/eu/dnetlib/broker/LiteratureBrokerServiceConfiguration.java b/apps/dhp-broker-application/src/main/java/eu/dnetlib/broker/LiteratureBrokerServiceConfiguration.java index 351fb623..a92f8862 100644 --- a/apps/dhp-broker-application/src/main/java/eu/dnetlib/broker/LiteratureBrokerServiceConfiguration.java +++ b/apps/dhp-broker-application/src/main/java/eu/dnetlib/broker/LiteratureBrokerServiceConfiguration.java @@ -4,6 +4,7 @@ import org.elasticsearch.client.RestHighLevelClient; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.EnableCaching; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.data.elasticsearch.client.ClientConfiguration; import org.springframework.data.elasticsearch.client.RestClients; @@ -25,6 +26,7 @@ import springfox.documentation.swagger2.annotations.EnableSwagger2; @EnableElasticsearchRepositories(basePackageClasses = { Event.class, Notification.class }) +@ComponentScan(basePackages = "eu.dnetlib") public class LiteratureBrokerServiceConfiguration extends AbstractElasticsearchConfiguration { @Autowired diff --git a/apps/dhp-broker-public-application/src/main/java/eu/dnetlib/broker/BrokerConfiguration.java b/apps/dhp-broker-public-application/src/main/java/eu/dnetlib/broker/BrokerConfiguration.java index d8c43662..b4721971 100644 --- a/apps/dhp-broker-public-application/src/main/java/eu/dnetlib/broker/BrokerConfiguration.java +++ b/apps/dhp-broker-public-application/src/main/java/eu/dnetlib/broker/BrokerConfiguration.java @@ -4,6 +4,7 @@ import org.elasticsearch.client.RestHighLevelClient; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.EnableCaching; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.data.elasticsearch.client.ClientConfiguration; import org.springframework.data.elasticsearch.client.RestClients; @@ -25,6 +26,7 @@ import springfox.documentation.swagger2.annotations.EnableSwagger2; @EnableElasticsearchRepositories(basePackageClasses = { Event.class, Notification.class }) +@ComponentScan(basePackages = "eu.dnetlib") public class BrokerConfiguration extends AbstractElasticsearchConfiguration { @Autowired diff --git a/apps/dnet-orgs-database-application/src/main/java/eu/dnetlib/organizations/MainApplication.java b/apps/dnet-orgs-database-application/src/main/java/eu/dnetlib/organizations/MainApplication.java index 7e24b9d0..f75b9eef 100644 --- a/apps/dnet-orgs-database-application/src/main/java/eu/dnetlib/organizations/MainApplication.java +++ b/apps/dnet-orgs-database-application/src/main/java/eu/dnetlib/organizations/MainApplication.java @@ -3,6 +3,7 @@ package eu.dnetlib.organizations; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCaching; +import org.springframework.context.annotation.ComponentScan; import org.springframework.scheduling.annotation.EnableScheduling; import eu.dnetlib.common.app.AbstractDnetApp; @@ -16,6 +17,7 @@ import springfox.documentation.swagger2.annotations.EnableSwagger2; @EnableSwagger2 @EnableCaching @EnableScheduling +@ComponentScan(basePackages = "eu.dnetlib") public class MainApplication extends AbstractDnetApp { public static void main(final String[] args) { diff --git a/apps/dnet-orgs-database-application/src/main/java/eu/dnetlib/organizations/MockSecurityConfig.java b/apps/dnet-orgs-database-application/src/main/java/eu/dnetlib/organizations/MockSecurityConfig.java index 17fc36c2..dccbd71b 100644 --- a/apps/dnet-orgs-database-application/src/main/java/eu/dnetlib/organizations/MockSecurityConfig.java +++ b/apps/dnet-orgs-database-application/src/main/java/eu/dnetlib/organizations/MockSecurityConfig.java @@ -49,7 +49,7 @@ public class MockSecurityConfig extends WebSecurityConfigurerAdapter { .hasAnyRole(OpenOrgsConstants.VALID_ROLES) .antMatchers("/registration_api/**") .hasRole(OpenOrgsConstants.NOT_AUTORIZED_ROLE) - .antMatchers("/common/**", "/resources/**", "/webjars/**", "/metrics", "/health", "/dbmodel/**") + .antMatchers("/common/**", "/resources/**", "/webjars/**", "/metrics", "/health", "/kpis", "/dbmodel/**") .permitAll() .antMatchers("/oa_api/**") .permitAll() diff --git a/apps/dnet-orgs-database-application/src/main/java/eu/dnetlib/organizations/OAuth2WebSecurityConfig.java b/apps/dnet-orgs-database-application/src/main/java/eu/dnetlib/organizations/OAuth2WebSecurityConfig.java index 7125793a..2ff636dc 100644 --- a/apps/dnet-orgs-database-application/src/main/java/eu/dnetlib/organizations/OAuth2WebSecurityConfig.java +++ b/apps/dnet-orgs-database-application/src/main/java/eu/dnetlib/organizations/OAuth2WebSecurityConfig.java @@ -62,7 +62,7 @@ public class OAuth2WebSecurityConfig extends WebSecurityConfigurerAdapter { .hasAnyRole(OpenOrgsConstants.VALID_ROLES) .antMatchers("/registration_api/**") .hasRole(OpenOrgsConstants.NOT_AUTORIZED_ROLE) - .antMatchers("/", "/common/**", "/resources/**", "/webjars/**", "/metrics", "/health", "/dbmodel/**") + .antMatchers("/", "/common/**", "/resources/**", "/webjars/**", "/metrics", "/health", "/kpis", "/dbmodel/**") .permitAll() .antMatchers("/oa_api/**") .hasIpAddress(openaireApiValidSubnet) diff --git a/apps/dnet-orgs-database-application/src/main/java/eu/dnetlib/organizations/metrics/ValidOrganizationsMetric.java b/apps/dnet-orgs-database-application/src/main/java/eu/dnetlib/organizations/metrics/ValidOrganizationsMetric.java index f36af5a7..1bb57699 100644 --- a/apps/dnet-orgs-database-application/src/main/java/eu/dnetlib/organizations/metrics/ValidOrganizationsMetric.java +++ b/apps/dnet-orgs-database-application/src/main/java/eu/dnetlib/organizations/metrics/ValidOrganizationsMetric.java @@ -7,8 +7,8 @@ import eu.dnetlib.common.metrics.MetricInfo; import eu.dnetlib.organizations.repository.OrganizationRepository; import eu.dnetlib.organizations.utils.OrganizationStatus; -@Component("valid_organizations_total") -public class ValidOrganizationsMetric extends MetricInfo { +@Component("openorgs_valid_organizations") +public class ValidOrganizationsMetric implements MetricInfo { @Autowired private OrganizationRepository organizationRepository; diff --git a/libs/dnet-apps-common/src/main/java/eu/dnetlib/common/metrics/KpiMetricsController.java b/libs/dnet-apps-common/src/main/java/eu/dnetlib/common/metrics/KpiMetricsController.java new file mode 100644 index 00000000..ed8e0e09 --- /dev/null +++ b/libs/dnet-apps-common/src/main/java/eu/dnetlib/common/metrics/KpiMetricsController.java @@ -0,0 +1,32 @@ +package eu.dnetlib.common.metrics; + +import static org.springframework.http.HttpHeaders.CONTENT_TYPE; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; + +import io.prometheus.client.exporter.common.TextFormat; + +@Controller +public class KpiMetricsController { + + @Autowired + private MetricUtils metricUtils; + + @ResponseBody + @RequestMapping(value = "/kpis", method = RequestMethod.GET, produces = "*/*") + public ResponseEntity kpiMetrics(@RequestHeader(value = "Accept", required = false, defaultValue = "") final String accept) { + + final String contentType = TextFormat.chooseContentType(accept); + final String result = metricUtils.output(contentType); + + return ResponseEntity.ok() + .header(CONTENT_TYPE, contentType) + .body(result); + } +} diff --git a/libs/dnet-apps-common/src/main/java/eu/dnetlib/common/metrics/MetricInfo.java b/libs/dnet-apps-common/src/main/java/eu/dnetlib/common/metrics/MetricInfo.java index a8f59312..86c55243 100644 --- a/libs/dnet-apps-common/src/main/java/eu/dnetlib/common/metrics/MetricInfo.java +++ b/libs/dnet-apps-common/src/main/java/eu/dnetlib/common/metrics/MetricInfo.java @@ -1,34 +1,7 @@ package eu.dnetlib.common.metrics; -import javax.annotation.PostConstruct; +public abstract interface MetricInfo { -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.beans.factory.BeanNameAware; - -import io.micrometer.core.instrument.Metrics; - -public abstract class MetricInfo implements BeanNameAware { - - private static final Log log = LogFactory.getLog(MetricInfo.class); - - private String beanName; - - abstract public double obtainValue(); - - public String getBeanName() { - return beanName; - } - - @Override - public void setBeanName(final String beanName) { - this.beanName = beanName; - } - - @PostConstruct - public void register() { - log.info("Prometheus - new metric registered: " + getBeanName()); - Metrics.gauge(getBeanName(), this, o -> obtainValue()); - } + double obtainValue(); } diff --git a/libs/dnet-apps-common/src/main/java/eu/dnetlib/common/metrics/MetricUtils.java b/libs/dnet-apps-common/src/main/java/eu/dnetlib/common/metrics/MetricUtils.java new file mode 100644 index 00000000..81dd6924 --- /dev/null +++ b/libs/dnet-apps-common/src/main/java/eu/dnetlib/common/metrics/MetricUtils.java @@ -0,0 +1,56 @@ +package eu.dnetlib.common.metrics; + +import java.io.IOException; +import java.io.StringWriter; +import java.io.Writer; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import javax.annotation.PostConstruct; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import io.micrometer.core.instrument.Metrics; +import io.prometheus.client.Collector.MetricFamilySamples; +import io.prometheus.client.GaugeMetricFamily; +import io.prometheus.client.exporter.common.TextFormat; + +@Component +public class MetricUtils { + + @Autowired(required = false) + private Map kpiMetrics; + + private static final Log log = LogFactory.getLog(MetricUtils.class); + + @PostConstruct + public void registerToMainEndpoint() { + if (kpiMetrics != null) { + kpiMetrics.forEach((k, v) -> Metrics.gauge(k, v, o -> o.obtainValue())); + log.info("KPI METRICS REGISTERED: " + StringUtils.join(kpiMetrics.keySet(), ", ")); + } + } + + public String output(final String contentType) { + + try { + final List samples = new ArrayList<>(); + if (kpiMetrics != null) { + kpiMetrics.forEach((k, v) -> samples.add(new GaugeMetricFamily(k, "", v.obtainValue()))); + } + final Writer writer = new StringWriter(); + TextFormat.writeFormat(contentType, writer, Collections.enumeration(samples)); + return writer.toString(); + } catch (final IOException e) { + // This actually never happens since StringWriter::write() doesn't throw any IOException + throw new RuntimeException("Writing metrics failed", e); + } + } + +} diff --git a/libs/dnet-broker-apps-common/src/main/java/eu/dnetlib/broker/common/metrics/LastUpdateMetric.java b/libs/dnet-broker-apps-common/src/main/java/eu/dnetlib/broker/common/metrics/LastUpdateMetric.java index a5fea312..e04ec5ec 100644 --- a/libs/dnet-broker-apps-common/src/main/java/eu/dnetlib/broker/common/metrics/LastUpdateMetric.java +++ b/libs/dnet-broker-apps-common/src/main/java/eu/dnetlib/broker/common/metrics/LastUpdateMetric.java @@ -6,7 +6,7 @@ import org.springframework.stereotype.Component; import eu.dnetlib.common.metrics.MetricInfo; @Component("provide_broker_last_metrics_updater_run_timestamp_seconds") -public class LastUpdateMetric extends MetricInfo { +public class LastUpdateMetric implements MetricInfo { @Autowired private MetricsCacheUtils metricsCacheUtils; diff --git a/libs/dnet-broker-apps-common/src/main/java/eu/dnetlib/broker/common/metrics/TotalDatasourcesWithEventsMetric.java b/libs/dnet-broker-apps-common/src/main/java/eu/dnetlib/broker/common/metrics/TotalDatasourcesWithEventsMetric.java index 031935f7..28f213d6 100644 --- a/libs/dnet-broker-apps-common/src/main/java/eu/dnetlib/broker/common/metrics/TotalDatasourcesWithEventsMetric.java +++ b/libs/dnet-broker-apps-common/src/main/java/eu/dnetlib/broker/common/metrics/TotalDatasourcesWithEventsMetric.java @@ -6,7 +6,7 @@ import org.springframework.stereotype.Component; import eu.dnetlib.common.metrics.MetricInfo; @Component("provide_broker_datasources_with_events") -public class TotalDatasourcesWithEventsMetric extends MetricInfo { +public class TotalDatasourcesWithEventsMetric implements MetricInfo { @Autowired private MetricsCacheUtils metricsCacheUtils; diff --git a/libs/dnet-broker-apps-common/src/main/java/eu/dnetlib/broker/common/metrics/TotalDatasourcesWithSubscriptionsMetric.java b/libs/dnet-broker-apps-common/src/main/java/eu/dnetlib/broker/common/metrics/TotalDatasourcesWithSubscriptionsMetric.java index 6c8f257d..0bc432e3 100644 --- a/libs/dnet-broker-apps-common/src/main/java/eu/dnetlib/broker/common/metrics/TotalDatasourcesWithSubscriptionsMetric.java +++ b/libs/dnet-broker-apps-common/src/main/java/eu/dnetlib/broker/common/metrics/TotalDatasourcesWithSubscriptionsMetric.java @@ -6,7 +6,7 @@ import org.springframework.stereotype.Component; import eu.dnetlib.common.metrics.MetricInfo; @Component("provide_broker_datasources_with_subscriptions") -public class TotalDatasourcesWithSubscriptionsMetric extends MetricInfo { +public class TotalDatasourcesWithSubscriptionsMetric implements MetricInfo { @Autowired private MetricsCacheUtils metricsCacheUtils; diff --git a/libs/dnet-broker-apps-common/src/main/java/eu/dnetlib/broker/common/metrics/TotalEventsMetric.java b/libs/dnet-broker-apps-common/src/main/java/eu/dnetlib/broker/common/metrics/TotalEventsMetric.java index 3b063b9d..756eadb2 100644 --- a/libs/dnet-broker-apps-common/src/main/java/eu/dnetlib/broker/common/metrics/TotalEventsMetric.java +++ b/libs/dnet-broker-apps-common/src/main/java/eu/dnetlib/broker/common/metrics/TotalEventsMetric.java @@ -6,7 +6,7 @@ import org.springframework.stereotype.Component; import eu.dnetlib.common.metrics.MetricInfo; @Component("provide_broker_events") -public class TotalEventsMetric extends MetricInfo { +public class TotalEventsMetric implements MetricInfo { @Autowired private MetricsCacheUtils metricsCacheUtils; diff --git a/libs/dnet-broker-apps-common/src/main/java/eu/dnetlib/broker/common/metrics/TotalNotificationsMetric.java b/libs/dnet-broker-apps-common/src/main/java/eu/dnetlib/broker/common/metrics/TotalNotificationsMetric.java index 33c66d0e..856e2219 100644 --- a/libs/dnet-broker-apps-common/src/main/java/eu/dnetlib/broker/common/metrics/TotalNotificationsMetric.java +++ b/libs/dnet-broker-apps-common/src/main/java/eu/dnetlib/broker/common/metrics/TotalNotificationsMetric.java @@ -6,7 +6,7 @@ import org.springframework.stereotype.Component; import eu.dnetlib.common.metrics.MetricInfo; @Component("provide_broker_notifications") -public class TotalNotificationsMetric extends MetricInfo { +public class TotalNotificationsMetric implements MetricInfo { @Autowired private MetricsCacheUtils metricsCacheUtils; diff --git a/libs/dnet-broker-apps-common/src/main/java/eu/dnetlib/broker/common/metrics/TotalSubscribersMetric.java b/libs/dnet-broker-apps-common/src/main/java/eu/dnetlib/broker/common/metrics/TotalSubscribersMetric.java index 0c6bf341..12388382 100644 --- a/libs/dnet-broker-apps-common/src/main/java/eu/dnetlib/broker/common/metrics/TotalSubscribersMetric.java +++ b/libs/dnet-broker-apps-common/src/main/java/eu/dnetlib/broker/common/metrics/TotalSubscribersMetric.java @@ -6,7 +6,7 @@ import org.springframework.stereotype.Component; import eu.dnetlib.common.metrics.MetricInfo; @Component("provide_broker_subscribers") -public class TotalSubscribersMetric extends MetricInfo { +public class TotalSubscribersMetric implements MetricInfo { @Autowired private MetricsCacheUtils metricsCacheUtils; diff --git a/libs/dnet-broker-apps-common/src/main/java/eu/dnetlib/broker/common/metrics/TotalSubscriptionsMetric.java b/libs/dnet-broker-apps-common/src/main/java/eu/dnetlib/broker/common/metrics/TotalSubscriptionsMetric.java index 8ee6bf25..91f737a2 100644 --- a/libs/dnet-broker-apps-common/src/main/java/eu/dnetlib/broker/common/metrics/TotalSubscriptionsMetric.java +++ b/libs/dnet-broker-apps-common/src/main/java/eu/dnetlib/broker/common/metrics/TotalSubscriptionsMetric.java @@ -6,7 +6,7 @@ import org.springframework.stereotype.Component; import eu.dnetlib.common.metrics.MetricInfo; @Component("provide_broker_subscriptions") -public class TotalSubscriptionsMetric extends MetricInfo { +public class TotalSubscriptionsMetric implements MetricInfo { @Autowired private MetricsCacheUtils metricsCacheUtils;