How to Mock /actuator/health in UnitTest - java

I'm intercepting the actuator/health endpoints in a custom Service by Auto-wiring the HealthContributor interface:
#Service
public class HealthCheckServiceImpl implements HealthIndicator{
#Autowired HealthContributor[] healthContributors;
#Override
public Health health() {
Map<String, String> components = new HashMap<String, String>();
for (HealthContributor healthContributor : healthContributors) {
String componentName =
healthContributor
.getClass()
.getSimpleName()
.replace("HealthIndicator", "")
.replace("HealthCheckIndicator", "");
String status = ((HealthIndicator) (healthContributor)).health().getStatus().toString();
components.put(componentName, status);
}
String healthComponentAsString = components.keySet().stream()
.map(key -> key + "->" + components.get(key))
.collect(Collectors.joining(", "));
Boolean isComponentDown = components.containsValue("DOWN");
if (Boolean.TRUE.equals(isComponentDown)) {
return Health.down().withDetail("Status: One of the API component is down. ","").build();
} else {
return Health.up().withDetail("Status: All API components are Up. ", "").build();
}
}
My question is, How can I mock the status of the components in order to test the health() method behavior.
I have tried
#MockBean
#Qualifier("pingHealthContributor") // intercepting just one component instead of
// HealthContributor[]
HealthContributor healthContributors;
but when I try to use Mockito. when() as follows:
String status="UP";
when(((HealthIndicator) (healthContributors)).health().getStatus().toString()).thenReturn(status);
I get the following error :
java.lang.ClassCastException: class org.springframework.boot.actuate.health.HealthContributor$MockitoMock$297980690 cannot be cast to class org.springframework.boot.actuate.health.HealthIndicator (org.springframework.boot.actuate.health.HealthContributor$MockitoMock$297980690 and org.springframework.boot.actuate.health.HealthIndicator are in unnamed module of loader 'app')
Dependencies
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.23.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

Related

Unable to use full text search with oak lucene

I am trying out jackrabbit oak with lucene in a file node store. The index definition record is created successfully but it seems the index record is not created.
The full project I am working on is here
What I am doing in the code is initializa a repository, create the lucene index definition, add a test data with a single property "name" with value "foo".
Sleep for 5 second for async indexing to complete, then perform the following query in a retry loop
select * from [nt:base] where contains(., 'foo').
No result is returned.
I have tried oak-run console to retrieve lc info on oak:index/lucene directory, it displays no result as well.
This is the main part of the code
public static void main( String[] args ) throws Exception
{
init();
createLuceneIndex();
createTestData();
performQuery();
}
private static void init() throws InvalidFileStoreVersionException, IOException {
LuceneIndexProvider provider = new LuceneIndexProvider();
FileStore fs = FileStoreBuilder.fileStoreBuilder(new File("repository")).build();
nodestore = SegmentNodeStoreBuilders.builder(fs).build();
repository = new Jcr(new Oak(nodestore))
.withAsyncIndexing("async", 3)
.with(new LuceneIndexEditorProvider())
.with((QueryIndexProvider) provider)
.with((Observer)provider)
.withAsyncIndexing()
.createRepository();
}
private static void createLuceneIndex() throws RepositoryException {
Session session = createAdminSession();
Node indexesNode = session.getRootNode().getNode("oak:index");
IndexDefinitionBuilder idxBuilder = new IndexDefinitionBuilder();
IndexRule indexRules = idxBuilder.indexRule("nt:unstructured");
indexRules.sync();
indexRules.property("name").analyzed().nodeScopeIndex();
idxBuilder.async("async");
idxBuilder.includedPaths("/");
Node documentIndex = indexesNode.addNode("lucene", "oak:QueryIndexDefinition");
idxBuilder.build(documentIndex);
session.save();
session.logout();
}
private static void createTestData() throws LoginException, RepositoryException {
Session session = createAdminSession();
Node test = session.getRootNode().addNode("test");
test.setProperty("name", "foo");
session.save();
session.logout();
}
private static void performQuery() throws Exception {
final Session session = createAdminSession();
TimeUnit.MICROSECONDS.sleep(5);
QueryManager qm = session.getWorkspace().getQueryManager();
final Query q = qm.createQuery("select * from [nt:base] where contains(., 'foo')", Query.JCR_SQL2);
new RetryLoop(new RetryLoop.Condition() {
public String getDescription() {
return "Full text query";
}
public boolean isTrue() throws Exception {
QueryResult r = q.execute();
return r.getNodes().hasNext();
}
}, 20, 500);
}
the pom file dependencies
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.jcr</groupId>
<artifactId>jcr</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>org.apache.jackrabbit</groupId>
<artifactId>oak-jcr</artifactId>
<version>1.21-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.jackrabbit</groupId>
<artifactId>oak-core</artifactId>
<version>1.21-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.jackrabbit</groupId>
<artifactId>oak-jcr</artifactId>
<version>1.21-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.jackrabbit</groupId>
<artifactId>oak-segment-tar</artifactId>
<version>1.21-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.jackrabbit</groupId>
<artifactId>oak-lucene</artifactId>
<version>1.21-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.30</version>
</dependency>
<dependency>
<groupId>com.codahale.metrics</groupId>
<artifactId>metrics-core</artifactId>
<version>3.0.2</version>
</dependency>

Springcloud bus custom messages cannot be sent through rabbitmq

When using the springcloud bus, a custom message is created and sent through rabbitmq, but after the message is sent, it does not go to rabbitmq. When you try to call /actuator/bus-refresh, you can see the bus messages emitted from the console page of rabbitmq.
I tried to start a micro service to register a custom event listener but failed to receive it. However, if the sender registers a listener himself, he can receive it but does not send it from rabbitmq.
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
About #RemoteApplicationEventScan annotations, I code all under the same package, so I should be able to scan to TestEvent. I also tried to specify basepackage.
#SpringBootApplication
#RemoteApplicationEventScan
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
#RestController
#RequestMapping("test")
public class TestController {
#Autowired
private ApplicationContext context;
#RequestMapping("test")
public String test() {
final TestEvent testEvent = new TestEvent(this, context.getId(), null,"test");
context.publishEvent(testEvent);
return "success";
}
}
#Data
public class TestEvent extends RemoteApplicationEvent {
private String action;
public TestEvent(Object source, String originService, String destinationService, String action) {
super(source, originService, destinationService);
this.action = action;
}
}
When I called http://localhost:8080/actuator/bus-refresh I can see the information in the rabbitmq.
{" type ":" AckRemoteApplicationEvent ", "timestamp" : 1554350325406, "originService" : "application: 0: b3461fbec3536203a7020ff9d24bb11b", "destinationService" : "* *", "id" : "e6b875bd - 2402-494 - f - a870 - 4917324 d2c5c ackId ", "" :" af93075e - 55 d2-41 f8 - ba27 - e3c80cf19eea ", "ackDestinationService" : "* *", "the event" is: "org. Springframework. Cloud. Bus. Event. RefreshRemoteApplicationEvent"}.
But when I call to http://localhost:8080/test/test, I don't.
I came into the same issue a few days ago and it turned out that it was because the originService was incorrect. passing in context.getId() as originService doesn't work.
Short answer: use org.springframework.cloud.bus.BusProperties#id. You can inject BusProperties to your component. Or you can configure your own spring cloud bus id as stated in the document.
I am not 100% sure this is the proper way. Maybe I missed something in the document. It is just based on what I read from the source code of org.springframework.cloud.bus.BusAutoConfiguration, method acceptLocal.
Hope it works for you.

NPE while receiving messages from Azure Service bus Queue

NPE while receving messages from Queue. ( Only when messages are present in Queue). I feel like there is an issue with de-serializing the messages.
java.lang.NullPointerException
at com.sun.jersey.api.client.ClientResponse.getResponseDate(ClientResponse.java:738)
at com.microsoft.windowsazure.services.servicebus.implementation.ServiceBusRestProxy.receiveMessage(ServiceBusRestProxy.java:288)
at com.microsoft.windowsazure.services.servicebus.implementation.ServiceBusRestProxy.receiveQueueMessage(ServiceBusRestProxy.java:225)
at com.microsoft.windowsazure.services.servicebus.implementation.ServiceBusExceptionProcessor.receiveQueueMessage(ServiceBusExceptionProcessor.java:142)
RECEIVE_AND_DELETE option deletes the messages and throws NPE.
All other operations like create queue , send messages etc working fine. Any thoughts one this ?
Code to receive message
public void receiveMessage(String queueName) {
try {
ReceiveMessageOptions opts = ReceiveMessageOptions.DEFAULT;
opts.setReceiveMode(ReceiveMode.PEEK_LOCK);
while (true) {
ReceiveQueueMessageResult resultQM
= service.receiveQueueMessage(queueName, opts);
BrokeredMessage message = resultQM.getValue();
if (message != null && message.getMessageId() != null) {
log.println("MessageID: " + message.getMessageId());
// Display the queue message.
log.print("From queue: ");
byte[] b = new byte[200];
String s = null;
int numRead = message.getBody().read(b);
while (-1 != numRead) {
s = new String(b);
s = s.trim();
System.out.print(s);
numRead = message.getBody().read(b);
}
log.println("");
log.println("Custom Property: "
+ message.getProperty("MyProperty"));
// Remove message from queue.
log.println("Deleting this message.");
//service.deleteMessage(message);
} else {
log.println("Finishing up - no more messages.");
break;
// Added to handle no more messages.
// Could instead wait for more messages to be added.
}
}
} catch (Exception e) {
log.print(e);
}
}
Even though it was throwing NPE the actual issue was with the missing jar files. Here is the list of jar files
<dependencies>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-svc-mgmt</artifactId>
<version>0.9.7</version>
</dependency>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-svc-mgmt-compute</artifactId>
<version>0.9.7</version>
</dependency>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-svc-mgmt-network</artifactId>
<version>0.9.7</version>
</dependency>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-svc-mgmt-sql</artifactId>
<version>0.9.7</version>
</dependency>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-svc-mgmt-storage</artifactId>
<version>0.9.7</version>
</dependency>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-svc-mgmt-websites</artifactId>
<version>0.9.7</version>
</dependency>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-svc-mgmt-media</artifactId>
<version>0.9.7</version>
</dependency>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-servicebus</artifactId>
<version>0.9.7</version>
</dependency>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-serviceruntime</artifactId>
<version>0.9.7</version>
</dependency>
</dependencies>

PUT and POST not working from J2SE platform (RESTLET Version 3.0-M1)

I'm working on a project with GWT and J2SE clients. The GWT part is working great, but now there are problems with the J2SE client;
"The server understands the content type of the request entity and the
syntax of the request entity is correct but was unable to process the
contained instructions"
"The serialized representation must have this media type:
application/x-java-serialized-object or this one:
application/x-java-serialized-object+xml"
This code was working some months/versions ago... Both PUT and POST produce this error while GET is working. Whats wrong here?
Here's a really simple test case
// Shared Interface
public interface J2SeClientServerResourceInt
{
#Post("json")
public J2seStatusDto postJ2seStatus(J2seStatusDto pJ2seStatusDto);
}
// Java Bean
public class J2seStatusDto implements Serializable
{
private static final long serialVersionUID = 6901448809350740172L;
private String mTest;
public J2seStatusDto()
{
}
public J2seStatusDto(String pTest)
{
setTest(pTest);
}
public String getTest()
{
return mTest;
}
public void setTest(String pTest)
{
mTest = pTest;
}
}
// Server
public class J2seServerResource extends ClaireServerResource implements J2SeServerResourceInt
{
#Override
public J2seStatusDto postJ2seStatusDto(J2seStatusDto pJ2seStatusDto)
{
return pJ2seStatusDto;
}
}
// J2SE Client
public class ClaireJsSeTestClient
{
public static void main(String[] args)
{
Reference lReference = new Reference("http://localhost:8888//rest/j2se");
ClientResource lClientResource = new ClientResource(lReference);
lClientResource.accept(MediaType.APPLICATION_JSON);
J2SeServerResourceInt lJ2SeServerResource = lClientResource.wrap(J2SeServerResourceInt.class);
J2seStatusDto lJ2seStatusDto = new J2seStatusDto("TEST");
J2seStatusDto lJ2seResultDto = lJ2SeServerResource.postJ2seStatusDto(lJ2seStatusDto);
}
}
// Maven J2Se Client
<dependencies>
<dependency>
<groupId>org.restlet.jse</groupId>
<artifactId>org.restlet</artifactId>
<version>3.0-M1</version>
</dependency>
<dependency>
<groupId>org.restlet.jse</groupId>
<artifactId>org.restlet.ext.jackson</artifactId>
<version>3.0-M1</version>
</dependency>
</dependencies>
// Maven GAE Server
<dependency>
<groupId>org.restlet.gae</groupId>
<artifactId>org.restlet</artifactId>
<version>3.0-M1</version>
</dependency>
<dependency>
<groupId>org.restlet.gae</groupId>
<artifactId>org.restlet.ext.servlet</artifactId>
<version>3.0-M1</version>
</dependency>
<dependency>
<groupId>org.restlet.gae</groupId>
<artifactId>org.restlet.ext.jackson</artifactId>
<version>3.0-M1</version>
</dependency>
<dependency>
<groupId>org.restlet.gae</groupId>
<artifactId>org.restlet.ext.gwt</artifactId>
<version>3.0-M1</version>
</dependency>
<dependency>
<groupId>org.restlet.gwt</groupId>
<artifactId>org.restlet</artifactId>
<version>3.0-M1</version>
<scope>compile</scope>
</dependency>
Thierry Boileau fixed our problem (mistake);
https://github.com/restlet/restlet-framework-java/issues/1029#issuecomment-76212062
Due to the constraints of the GAE platform (there is no support of chunked encoding) you have to specify that the request entity is buffered first;
cr.setRequestEntityBuffering(true);
Thanks for the great support at restlet.com

How to test static method invokation in Android?

I have an Android activity and I want to write a unit test, which verifies that in onResume the activity checks whether the Internet is available.
public class MyActivity {
#Override
protected void onResume() {
super.onResume();
setContentView(R.layout.connect_to_server);
// Internet availability check
final IInternetAvailabilityChecker checker = InternetAvailabilityChecker.create(this);
if (!checker.isInternetAvailable())
{
Utils.showMessageBox(this, R.string.app_name,
R.string.internet_not_available);
return;
}
In the test, I want to verify that MyActiviy.onResume calls the InternetAvailabilityChecker.create method.
How can I do it (with any free mocking framework compatible with Android) ?
I tried to use PowerMock for this (see example below), but when I try to run the test, I get errors like MockTest.java:7: package org.powermock.core.classloader.annotations does not exist.
Maven:
<properties>
<powermock.version>1.5.1</powermock.version>
</properties>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>${powermock.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<version>${powermock.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
</dependency>
Unit test:
#RunWith(PowerMockRunner.class)
#PrepareForTest( { InternetAvailabilityChecker.class })
public class MyActivityPowerMockTest {
#Test
#Ignore
public void test()
{
final IInternetAvailabilityChecker checker = mock(IInternetAvailabilityChecker.class);
when(checker.isInternetAvailable()).thenReturn(false);
mockStatic(InternetAvailabilityChecker.class);
expect(InternetAvailabilityChecker.create(any(Activity.class))).andReturn(checker);
replay(InternetAvailabilityChecker.class);
final MyActivity objectUnderTest = new MyActivity();
objectUnderTest.onResume();
// Verify that the method InternetAvailabilityChecker.create was called
verify(InternetAvailabilityChecker.class);
// TODO: Verify that Utils.showMessageBox has been invoked
}
}
You appear to be missing a Maven dependency. According to this query the annotations are supplied by:
org.powermock / powermock-core
org.powermock / powermock-easymock-single-jar-release-full
org.powermock / powermock-mockito-single-jar-release-full

Categories

Resources