HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaMinor

Constructing a URL for execution using RestTemplate

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
resttemplateconstructingforusingurlexecution

Problem

I am working on a project in which I construct a URL with a valid hostname (but not a blocked hostname) and then execute that URL using RestTemplate from my main thread. I also have a single background thread in my application which parses the data from the URL and extracts the block list of hostnames from it.

If any block list of hostnames is present, then I won't make a call to that hostname from the main thread and I will try making a call to another hostname. By block list, I mean whenever any server is down, its hostname is on the block list.

Here is my background thread code. It will get the data from my service URL and keep on running every 10 minutes once my application has started up. It will then parse the data coming from the URL and store it in a ClientData class variable.

```
public class TempScheduler {

private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);

public void startScheduler() {
final ScheduledFuture taskHandle = scheduler.scheduleAtFixedRate(new Runnable() {
public void run() {
try {
callServiceURL();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}, 0, 10, TimeUnit.MINUTES);
}
}

// call the service and get the data and then parse
// the response.
private void callServiceURL() {
String url = "url";
RestTemplate restTemplate = new RestTemplate();
String response = restTemplate.getForObject(url, String.class);
parseResponse(response);

}

// parse the response and store it in a variable
private void parseResponse(String response) {
//...
Map> primaryTables = null;
Map> secondaryTables = null;
Map> tertiaryTables = null;

//...

// store the data in ClientData class variables if anything has changed

Solution

For adding and removing single host names, I would use a simple ConcurrentHashMap without the AtomicReference. Initialize it with an empty map and drop the additional latch.

Update: I really doubt you need to replace the list of hosts all at once, but here's the combined form anyway:

private static final AtomicReference> blockedHosts = 
        new AtomicReference>(new ConcurrentHashMap());

public static boolean isHostBlocked(String hostName) {
    return blockedHosts.get().containsKey(hostName);
}

public static void blockHost(String hostName) {
    blockedHosts.get().put(hostName, hostName);
}

public static void unblockHost(String hostName) {
    blockedHosts.get().remove(hostName);
}

public static void replaceBlockedHosts(List hostNames) {
    ConcurrentHashMap newBlockedHosts = new ConcurrentHashMap<>();
    for (String hostName : hostNames) {
        newBlockedHosts.put(hostName, hostName);
    }
    blockedHosts.set(newBlockedHosts);
}

Code Snippets

private static final AtomicReference<ConcurrentHashMap<String, String>> blockedHosts = 
        new AtomicReference<ConcurrentHashMap<String, String>>(new ConcurrentHashMap<String, String>());

public static boolean isHostBlocked(String hostName) {
    return blockedHosts.get().containsKey(hostName);
}

public static void blockHost(String hostName) {
    blockedHosts.get().put(hostName, hostName);
}

public static void unblockHost(String hostName) {
    blockedHosts.get().remove(hostName);
}

public static void replaceBlockedHosts(List<String> hostNames) {
    ConcurrentHashMap<String, String> newBlockedHosts = new ConcurrentHashMap<>();
    for (String hostName : hostNames) {
        newBlockedHosts.put(hostName, hostName);
    }
    blockedHosts.set(newBlockedHosts);
}

Context

StackExchange Code Review Q#51028, answer score: 5

Revisions (0)

No revisions yet.