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

Executing a URL using RestTemplate

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

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 application 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 {

    // .. scheduledexecutors service code to start the background thread

    // 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) {
        //...       

        // get the block list of hostnames
        Map> coloExceptionList = gson.fromJson(response.split("blocklist=")[1], Map.class);
        List blockList = new ArrayList();
        for(Map.Entry> entry : coloExceptionList.entrySet()) {
            for(String hosts : entry.getValue()) {
                blockList.add(hosts);
            }
        }

        // store the block list of hostnames which I am not supposed to make a call
        // from my main application
        ClientData.replaceBlockedHosts(blockList);
    }
}


Here is my ClientData class. Is it thread-safe? The replaceBlockedHosts method will only be called

Solution

Even if in 1 line

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


effectively consists of 2 operations, so if you want your methods to be atomic you still need synchronization. You could have an interleaving like:

T1 invokes blockHost("123") and executes get()

T2 invokes isHostBlocked("123"), does executes get() and containsKey() and returns false
T1 does put(hostName, hostName);

the result of T1 is wrong because blockHost was invoked before.

I think that you need synchronization, and if you do you can probably avoid using AtomicReference

Off topic - I don't like static things... see this question on SO

Code Snippets

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

Context

StackExchange Code Review Q#51484, answer score: 7

Revisions (0)

No revisions yet.