How to expose outbound metrics for prometheus for the webclient requests? - spring-webflux

Hi I am quite new to prometheus metrics. I need to expose the http_client_requests_seconds_count and http_client_requests_seconds_sum for the requests to the down stream servers.
I have enabled the prometheus in my project by
management:
endpoints:
web:
exposure:
include: health,metrics,prometheus
I have added dependencies as below in my pom.xml
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
<version>${micrometer.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
and I can see the inbound matrix in http://localhost:8092/actuator/prometheus. Like http_server_requests_seconds and others but unable to find the downstream metrics.
I am using spring web-flux reactive framework.

As per this answer: stackoverflow.com/a/58632953 I tried it and found no luck.
The simple answer is just to add AutoWired to WeclientBuilder and build your Webclient out of it.
#Autowired
private WebClient.Builder webClientBuilder;
this.webClientBuilder.baseUrl(host)
.clientConnector(clientHttpConnector)
.build()
.post()
.uri(uri)...
Configure the metrics name in application.yml like below:
management:
metrics:
web:
client:
request:
autotime:
enabled: true
metric-name: Any_Prefix_http_client_requests
server:
request:
autotime:
enabled: true
metric-name: Any_Prefix_http_server_requests
That's it, you will get outbound metrics in /atuator/prometheus....
Thanks! Happy coding

Related

Spring cloud config git refreshRate behaviour

I am trying to setup Spring Cloud Config Server and want to enable auto refresh of properties based on changes to the backing git repository.
Below is the bootstrap.yml of the server.
server:
port: 8080
spring:
application:
name: my-configserver
cloud:
config:
server:
bootstrap: true
git:
uri: /Users/anoop/Documents/centralconfig
refreshRate: 15
searchPaths: {application}/properties
bus:
enabled: true
As per the documentation spring.cloud.config.server.git.refreshRate determines
how often the config server will fetch updated configuration data from
your Git backend
I see that the config clients are not notified of changes, when the configuration changes. I have not configured a git hook for this and was hoping that just setting the property would do the job.
Anoop
Since you have configured the refreshRate property, whenever config client (other applications) call config server to fetch properties (this happens when either the application starts or application calls /actuator/refresh endpoint), they will get properties which were fetched 15 seconds (your refreshRate) old.
By default the refreshRate property is set to 0, meaning any time client applications ask for property config server will fetch latest from GIT.
I don't think there is any property which lets your client apps get notified in case of change/commits in the GIT. This is something your app needs to do by calling actuator/refresh endpoint. This can be done programmatically using some scheduler (though I wouldn't recommend that).
By default, the config client just reads the properties in git repo at startup and not again.
You can actually have a way to workaround by force bean to refresh its configuration from the config server.
First, you need to add #RefreshScope annotation in the bean where config needs to be reloaded.
Second, enable spring boot actuator in application.yml of config client.
# enable dynamic configuration changes using spring boot actuator
management:
endpoints:
web:
exposure:
include: '*'
And then config a scheduled job (by using #Scheduled annotation with fixedRate,...). Of course, fixedRate should conform with refreshRate from config server.
And inside that job, it will execute the request as below:
curl -X POST http://username:password#localhost:8888/refresh
Then your config client will be notified changes in config repo every fixRate interval.
The property spring.cloud.config.server.git.refreshRate is configured in the Config Server and controls how frequently it is going to pull updates, if any, from Git. Otherwise, the Config Server's default behaviour is to connect to the Git repo only when some client requests its configuration.
Git Repo -> Config Server
It has no effect in the communication between the Config Server and its clients.
Config Server -> Spring Boot app (Config Server clients)
Spring Boot apps built with Config Server clients pull all configuration from the Config Server during their startup. To enable them to dynamically change the initially loaded configuration, you need to perform the following steps in your Spring Boot apps aka Config Server clients:
Include Spring Boot Actuator in the classpath, for example using Gradle:
implementation 'org.springframework.boot:spring-boot-starter-actuator'
Enable the actuator refresh endpoint via the management.endpoints.web.exposure.include=refresh property
Annotate the Beans holding the properties in your code with #RefreshScope, for example:
#RefreshScope
#Service
public class BookService {
#Value("${book.default-page-size:20}")
private int DEFAULT_PAGE_SIZE;
//...
}
With the application running, commit some property change into the repo:
git commit -am "Testing property changes"
Trigger the updating process by sending a HTTP POST request to the refresh endpoint, for example (using httpie and assuming your app is running locally at the port 8080:
http post :8080/actuator/refresh
and the response should be something like below indicating which properties, if any, have changed
HTTP/1.1 200
Connection: keep-alive
Content-Type: application/vnd.spring-boot.actuator.v3+json
Date: Wed, 30 Jun 2021 10:18:48 GMT
Keep-Alive: timeout=60
Transfer-Encoding: chunked
[
"config.client.version",
"book.default-page-size"
]

Wildfly 10 - HSQL Datascource - null pointer excception testing connection to database

I would like to know if anybody is aware of the following problem in wildfly 10.
When trying to setup a datasource for HSQL, I was confronted with the problem where for a non xa data source driver, you would expect the configuration element connection-url to be of any use. In particular, this configuration element is of use when you attempt to connect to H2 or oracle.
However, when testing the following configuration I was systematically hitting a null pointer exception on HSQL getConnection.
The hsql modulue is added as jboss module with:
<module xmlns="urn:jboss:module:1.3" name="org.hsql">
<properties>
</properties>
<resources>
<resource-root path="hsqldb-2.3.2.jar"/>
</resources>
<dependencies>
<module name="javax.api"/>
<module name="javax.transaction.api"/>
</dependencies>
</module>
The original configuration of the datasource, the one that does not work was as follows:
<datasource jta="false" jndi-name="java:/jdbc/HSQL_NON_JTA_DS" pool-name="HSQL_NON_JTA_DS" enabled="true" use-ccm="true">
<connection-url>jdbc:hsqldb:hsql://localhost:9001/DATABSE</connection-url>
<datasource-class>org.hsqldb.jdbc.JDBCDataSource</datasource-class>
<driver>hsql</driver>
<security>
<user-name>USER</user-name>
<password>USER</password>
</security>
</datasource>
<driver name="hsql" module="org.hsql">
<datasource-class>org.hsqldb.jdbc.JDBCDataSource</datasource-class>
</driver>
With the following stack trace:
2017-03-01 18:08:47,083 WARN [org.jboss.jca.core.connectionmanager.pool.strategy.OnePool] (thread: management task-6) IJ000604: Throwable while attempting to get a new connection: null: javax.resource.ResourceException: IJ031084: Unable to create connection
at org.jboss.jca.adapters.jdbc.local.LocalManagedConnectionFactory.createLocalManagedConnection(LocalManagedConnectionFactory.java:343)
at org.jboss.jca.adapters.jdbc.local.LocalManagedConnectionFactory.getLocalManagedConnection(LocalManagedConnectionFactory.java:350)
at org.jboss.jca.adapters.jdbc.local.LocalManagedConnectionFactory.createManagedConnection(LocalManagedConnectionFactory.java:285)
at org.jboss.jca.core.connectionmanager.pool.mcp.SemaphoreConcurrentLinkedDequeManagedConnectionPool.createConnectionEventListener(SemaphoreConcurrentLinkedDequeManagedConnectionPool.java:1319)
at org.jboss.jca.core.connectionmanager.pool.mcp.SemaphoreConcurrentLinkedDequeManagedConnectionPool.getConnection(SemaphoreConcurrentLinkedDequeManagedConnectionPool.java:496)
at org.jboss.jca.core.connectionmanager.pool.AbstractPool.internalTestConnection(AbstractPool.java:1061)
at org.jboss.jca.core.connectionmanager.pool.strategy.OnePool.testConnection(OnePool.java:93)
at org.jboss.as.connector.subsystems.common.pool.PoolOperations$TestConnectionInPool.invokeCommandOn(PoolOperations.java:234)
at org.jboss.as.connector.subsystems.common.pool.PoolOperations$1.execute(PoolOperations.java:90)
at org.jboss.as.controller.AbstractOperationContext.executeStep(AbstractOperationContext.java:890)
at org.jboss.as.controller.AbstractOperationContext.processStages(AbstractOperationContext.java:659)
at org.jboss.as.controller.AbstractOperationContext.executeOperation(AbstractOperationContext.java:370)
at org.jboss.as.controller.OperationContextImpl.executeOperation(OperationContextImpl.java:1344)
at org.jboss.as.controller.ModelControllerImpl.internalExecute(ModelControllerImpl.java:392)
at org.jboss.as.controller.ModelControllerImpl.execute(ModelControllerImpl.java:217)
at org.jboss.as.domain.http.server.DomainApiHandler.handleRequest(DomainApiHandler.java:212)
at io.undertow.server.handlers.encoding.EncodingHandler.handleRequest(EncodingHandler.java:72)
at org.jboss.as.domain.http.server.security.SubjectDoAsHandler$1.run(SubjectDoAsHandler.java:72)
at org.jboss.as.domain.http.server.security.SubjectDoAsHandler$1.run(SubjectDoAsHandler.java:68)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.java:422)
at org.jboss.as.controller.AccessAuditContext.doAs(AccessAuditContext.java:92)
at org.jboss.as.domain.http.server.security.SubjectDoAsHandler.handleRequest(SubjectDoAsHandler.java:68)
at org.jboss.as.domain.http.server.security.SubjectDoAsHandler.handleRequest(SubjectDoAsHandler.java:63)
at io.undertow.server.handlers.BlockingHandler.handleRequest(BlockingHandler.java:56)
at org.jboss.as.domain.http.server.DomainApiCheckHandler.handleRequest(DomainApiCheckHandler.java:95)
at io.undertow.security.handlers.AuthenticationCallHandler.handleRequest(AuthenticationCallHandler.java:52)
at io.undertow.server.Connectors.executeRootHandler(Connectors.java:202)
at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:793)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NullPointerException
at org.hsqldb.jdbc.JDBCDataSource.getConnection(Unknown Source)
at org.hsqldb.jdbc.JDBCDataSource.getConnection(Unknown Source)
at org.jboss.jca.adapters.jdbc.local.LocalManagedConnectionFactory.createLocalManagedConnection(LocalManagedConnectionFactory.java:312)
... 31 more
This null pointer exception happend, quite simply because.
In the JDBCDataSource.java of HSQL, the following method was getting a null URL.
Meaning, JBOSS had not picked up the URL on the connection-url and configured on the driver.
private Connection getConnection(String url,
Properties props) throws SQLException {
if (!url.startsWith("jdbc:hsqldb:")) {
url = "jdbc:hsqldb:" + url;
}
return JDBCDriver.getConnection(url, props);
}
NOTE: If you want to debug HSQL you need to use the -debug.jar files that HSQL releases internally.
In any case...
After finding out that the subsytem for data sources is provided by IRON JCAMAR, it was possible to hunt the documentation for extra configuration properties to work-around what should never have been a problem.
Here is the documentation on elements supported for the data-source.
http://www.ironjacamar.org/doc/userguide/1.1/en-US/html_single/index.html#deployingds_descriptor
Ultiamtely, to make the connection work It was necessar to enrich it with the following element.
<connection-property name="url">jdbc:hsqldb:hsql://localhost:9001/DATABSE</connection-property>
Does it make any sense that additional element was necessary? It should have been redundant and unecessary. It is a good thing that custome data source properties are to be supported.
In this case, Is the problem with HSQL or is the problem with JBOSS.
In eery other app server, specifying the connection URL has always worked fine.
To me this appars to be a particular behavior of Wildfly.
This quite a problem since your average documentation on data sources just makes it abundantly clear that the connection-url is the element you do need to configure. In this case, it really is not.
Many thanks for a reply on this.
Looks like configuration issue. Update module name to org.hsqldb in datasource and module.xml file to follow standard module naming conventions. Update directory name from hsql to hsqldb under modules directory. It's all up to you. You can use your custom module naming convention too.
Some of the drivers does not have getURL() method implemented in their datasource classes. So, we have to specify datasource configuration differently for them.
Like Postgres, does not have getURL method. So, we will specify properties like this in our stanalone.xml/domain.xml file.
<xa-datasource-property name="ServerName">DatabaseHostName</xa-datasource-property>
<xa-datasource-property name="PortNumber">DatabasePortName</xa-datasource-property>
<xa-datasource-property name="DatabaseName">DatabaseName</xa-datasource-property>
<xa-datasource-class>com.edb.xa.PGXADataSource</xa-datasource-class>
<driver>postgresql</driver>
<security>
<user-name>database.username</user-name>
<password>database.password</password>
</security>
Whereas in case of Oracle which has getURL method implemented, configuration given below works fine.
<xa-datasource-property name="URL">jdbc:oracle:thin:#database.host:database.port:database.name</xa-datasource-property>
<xa-datasource-class>oracle.jdbc.xa.client.OracleXADataSource</xa-datasource-class>
<driver>oracle</driver>
I am not sure about HSQL driver implementation of getURL API. You can try specifying properties like I mentioned for Postgres and check if it works for your use-case.

ActiveMQ doesn't recognize Stomp: Transport scheme NOT recognized: [stomp+ssl]

I'm trying to set up mcollective/activemq on a puppetmaster (open source puppet). I am having a problem where ActiveMQ does not recognize the Stomp protocol. Here is the relevant snippet in my /etc/activemq/instances-enabled/activemq/activemq.xml file that should enable stomp+ssl:
<transportConnectors>
<transportConnector name="openwire" uri="tcp://0.0.0.0:61616"/>
<transportConnector name="stomp+ssl" uri="stomp+ssl://0.0.0.0:61614?needClientAuth=true&transport.enabledProtocols=TLSv1,TLSv1.1,TLSv1.2"/>
</transportConnectors>
When I start ActiveMQ via service activemq start, I notice that the daemon doesn't end up running (I don't see it as a process). Then I tried running service activemq console activemq, and it looks like the problem is that it can't find the stomp Transport scheme. Here is the first error that I see in the output (and the error persists throughout the output):
ERROR | Failed to start Apache
ActiveMQ ([localhost,
ID:my-servers-hostname.example.com-40447-1475514312306-0:1], java.io.IOException: Transport
Connector could not be registered in
JMX: java.io.IOException: Transport
scheme NOT recognized: [stomp+ssl])
ActiveMQ recognizes openwire just fine. When using openwire+ssl only, without using stomp+ssl, the ActiveMQ daemon starts fine with no errors. However, when I try running mco find, I get an error because it seems that mco is still trying to use stomp+ssl (and ActiveMQ only has openwire+ssl enabled):
error 2016/10/03 17:26:59: activemq.rb:149:in `on_ssl_connectfail' SSL session creation with stomp+ssl://mcollective#localhost:61614 failed: Connection refused - connect(2) for "localhost" port 61614
Perhaps I need to adjust my mco config to use openwire instead of stomp? I wasn't sure where or what file that configuration would be in. Not sure why it doesn't recognize stomp, but I was wondering what my options are here. Is it even possible to use MCollective/ActiveMQ using only openwire+ssl, or is using stomp a requirement if I want to use mco? I don't think this is a port issue, as the relevant ports are open on the server I believe.
Here are the relevant packages/versions installed on my machine:
OS: Ubuntu 16.04 (xenial)
puppet: 4.7.0
ActiveMQ: 5.13.2
ruby-stomp: 1.3.5-1
MCollective (mco) version: 2.9.0
I've run into the same problem with the embedded ActiveMQ server in my project. Turns out I needed to add the following dependencies to my pom.
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-stomp</artifactId>
<version>5.15.0</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-kahadb-store</artifactId>
<version>5.15.0</version>
</dependency>
In your case, I think you need to get hold of those 2 jars and add them to your ActiveMQ installation.
In activemq package provided by ubuntu 16+ library stomp transport was not included. I do not know why.
Yoy can download it manually and place in /usr/share/activemq/lib:
cd /usr/share/activemq/lib
# check your actviemq version before (apt-cache policy activemq) and use the relevant version of library.
wget https://repository.apache.org/content/repositories/releases/org/apache/activemq/activemq-stomp/5.13.5/activemq-stomp-5.13.5.jar
service activemq restart

Arquillian tomee remote

Using Arquillian 1.1.4.Final and Tomee 1.6.0.2
Took the tomee-plus-remote profile setup from the Tomee information about arqullian adapters and put it into the Maven pom.xml (with activeByDefault true).
Goal is to deploy a MQ JCA rar into the remote Tomee and configure a connection factory to MQ.
Set the arqullian.xml initially to:
<container qualifier="tomee" default="true">
<configuration>
<property name="httpPort">-1</property>
<property name="stopPort">-1</property>
</configuration>
</container>
Running via JUnit not sure why the webprofile is initialized and started rather than plus (when I have tomee plus specified in Maven):
Info: Succeeded in installing singleton service
jun 11, 2014 11:07:52 FM org.apache.openejb.config.ConfigurationFactory init
Info: openejb configuration file is 'C:\Users\MYG\AppData\Local\Temp\arquillian-apache-tomee\apache-tomee-webprofile-1.6.0.2\conf\tomee.xml'
Another thing is how to load a tomee.xml configuration. Thought, the "serverXml" in the arquillian.xml (set to src/test/resources/tomee.xml) would work but then everything inside that xml is not recognized as a valid rule. Can't add directives like Deployments as one does with resources. So how to configure the remote tomee from arquillian?
Yeah, tomee.xml was not really designed for arquillian.xml since all its config can be passed to properties attribute of tomee container using properties format
By adding a conf property to the arquillian.xml to for example src/test/conf where there is a tomee.xml file then it is loaded. This must be Tomee thing that I didn't know about until now.

How can the user-agent be changed in Maven?

How can I change the user-agent in Maven? I need to be able to change this to get through the company firewall. I am using version 2.2.1 and I noticed an improvement in the 2.0.10 release notes:
[MNG-3652] - set a user agent for Maven HTTP requests.
Brett Porter posted a blog on Configuring Maven HTTP Connections that describes how you can do this and some other funky things:
<server>
<id>archiva.localhost</id>
<configuration>
<httpHeaders>
<property>
<name>User-Agent</name>
<value>Internal-Build-System/1.0</value>
</property>
</httpHeaders>
</configuration>
</server>
for command line version
try
"-Daether.connector.userAgent=your custom user agent"