Compare commits

...

2 Commits

7 changed files with 65 additions and 14 deletions

View File

@ -22,6 +22,7 @@
*/ */
package com.iluwatar.ambassador; package com.iluwatar.ambassador;
import com.iluwatar.ambassador.util.RandomProvider;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -31,9 +32,10 @@ import static java.lang.Thread.sleep;
* A remote legacy application represented by a Singleton implementation. * A remote legacy application represented by a Singleton implementation.
*/ */
public class RemoteService implements RemoteServiceInterface { public class RemoteService implements RemoteServiceInterface {
static final int THRESHOLD = 200;
private static final Logger LOGGER = LoggerFactory.getLogger(RemoteService.class); private static final Logger LOGGER = LoggerFactory.getLogger(RemoteService.class);
private static RemoteService service = null; private static RemoteService service = null;
private final RandomProvider randomProvider;
static synchronized RemoteService getRemoteService() { static synchronized RemoteService getRemoteService() {
if (service == null) { if (service == null) {
@ -42,24 +44,33 @@ public class RemoteService implements RemoteServiceInterface {
return service; return service;
} }
private RemoteService() {} private RemoteService() {
this(Math::random);
}
/**
* This constuctor is used for testing purposes only.
*/
RemoteService(RandomProvider randomProvider) {
this.randomProvider = randomProvider;
}
/** /**
* Remote function takes a value and multiplies it by 10 taking a random amount of time. * Remote function takes a value and multiplies it by 10 taking a random amount of time.
* Will sometimes return -1. This imitates connectivity issues a client might have to account for. * Will sometimes return -1. This imitates connectivity issues a client might have to account for.
* @param value integer value to be multiplied. * @param value integer value to be multiplied.
* @return if waitTime is more than 200ms, it returns value * 10, otherwise -1. * @return if waitTime is less than {@link RemoteService#THRESHOLD}, it returns value * 10,
* otherwise {@link RemoteServiceInterface#FAILURE}.
*/ */
@Override @Override
public long doRemoteFunction(int value) { public long doRemoteFunction(int value) {
long waitTime = (long) Math.floor(Math.random() * 1000); long waitTime = (long) Math.floor(randomProvider.random() * 1000);
try { try {
sleep(waitTime); sleep(waitTime);
} catch (InterruptedException e) { } catch (InterruptedException e) {
LOGGER.error("Thread sleep state interrupted", e); LOGGER.error("Thread sleep state interrupted", e);
} }
return waitTime >= 200 ? value * 10 : -1; return waitTime <= THRESHOLD ? value * 10 : FAILURE;
} }
} }

View File

@ -26,6 +26,7 @@ package com.iluwatar.ambassador;
* Interface shared by ({@link RemoteService}) and ({@link ServiceAmbassador}). * Interface shared by ({@link RemoteService}) and ({@link ServiceAmbassador}).
*/ */
interface RemoteServiceInterface { interface RemoteServiceInterface {
int FAILURE = -1;
long doRemoteFunction(int value) throws Exception; long doRemoteFunction(int value) throws Exception;
} }

View File

@ -59,15 +59,15 @@ public class ServiceAmbassador implements RemoteServiceInterface {
private long safeCall(int value) { private long safeCall(int value) {
int retries = 0; int retries = 0;
long result = -1; long result = FAILURE;
for (int i = 0; i < RETRIES; i++) { for (int i = 0; i < RETRIES; i++) {
if (retries >= RETRIES) { if (retries >= RETRIES) {
return -1; return FAILURE;
} }
if ((result = checkLatency(value)) == -1) { if ((result = checkLatency(value)) == FAILURE) {
LOGGER.info("Failed to reach remote: (" + (i + 1) + ")"); LOGGER.info("Failed to reach remote: (" + (i + 1) + ")");
retries++; retries++;
try { try {

View File

@ -0,0 +1,8 @@
package com.iluwatar.ambassador.util;
/**
* An interface for randomness. Useful for testing purposes.
*/
public interface RandomProvider {
double random();
}

View File

@ -24,6 +24,8 @@ package com.iluwatar.ambassador;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertTrue;
/** /**
* Test for {@link Client} * Test for {@link Client}
*/ */
@ -35,6 +37,6 @@ public class ClientTest {
Client client = new Client(); Client client = new Client();
long result = client.useService(10); long result = client.useService(10);
assert result == 100 || result == -1; assertTrue(result == 100 || result == RemoteService.FAILURE);
} }
} }

View File

@ -22,16 +22,43 @@
*/ */
package com.iluwatar.ambassador; package com.iluwatar.ambassador;
import com.iluwatar.ambassador.util.RandomProvider;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
/** /**
* Test for {@link RemoteService} * Test for {@link RemoteService}
*/ */
public class RemoteServiceTest { public class RemoteServiceTest {
@Test @Test
public void test() { public void testFailedCall() {
long result = RemoteService.getRemoteService().doRemoteFunction(10); RemoteService remoteService = new RemoteService(
assert result == 100 || result == -1; new StaticRandomProvider(0.21));
long result = remoteService.doRemoteFunction(10);
assertEquals(RemoteServiceInterface.FAILURE, result);
}
@Test
public void testSuccessfulCall() {
RemoteService remoteService = new RemoteService(
new StaticRandomProvider(0.2));
long result = remoteService.doRemoteFunction(10);
assertEquals(100, result);
}
private class StaticRandomProvider implements RandomProvider {
private double value;
StaticRandomProvider(double value) {
this.value = value;
}
@Override
public double random() {
return value;
}
} }
} }

View File

@ -24,6 +24,8 @@ package com.iluwatar.ambassador;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertTrue;
/** /**
* Test for {@link ServiceAmbassador} * Test for {@link ServiceAmbassador}
*/ */
@ -32,6 +34,6 @@ public class ServiceAmbassadorTest {
@Test @Test
public void test() { public void test() {
long result = new ServiceAmbassador().doRemoteFunction(10); long result = new ServiceAmbassador().doRemoteFunction(10);
assert result == 100 || result == -1; assertTrue(result == 100 || result == RemoteServiceInterface.FAILURE);
} }
} }