Coverage Report - org.kuali.maven.plugins.dnsme.DNSMEClient
 
Classes in this File Line Coverage Branch Coverage Complexity
DNSMEClient
14%
21/150
4%
2/48
2.4
DNSMEClient$1
0%
0/1
N/A
2.4
DNSMEClient$2
100%
1/1
N/A
2.4
 
 1  
 package org.kuali.maven.plugins.dnsme;
 2  
 
 3  
 import java.io.UnsupportedEncodingException;
 4  
 import java.lang.reflect.Type;
 5  
 import java.net.URLEncoder;
 6  
 import java.util.ArrayList;
 7  
 import java.util.Collections;
 8  
 import java.util.List;
 9  
 
 10  
 import org.apache.commons.httpclient.HttpMethod;
 11  
 import org.apache.commons.httpclient.NameValuePair;
 12  
 import org.apache.commons.httpclient.methods.EntityEnclosingMethod;
 13  
 import org.apache.commons.httpclient.methods.PostMethod;
 14  
 import org.apache.commons.httpclient.methods.PutMethod;
 15  
 import org.kuali.maven.plugins.dnsme.beans.Account;
 16  
 import org.kuali.maven.plugins.dnsme.beans.Domain;
 17  
 import org.kuali.maven.plugins.dnsme.beans.DomainNames;
 18  
 import org.kuali.maven.plugins.dnsme.beans.Record;
 19  
 import org.kuali.maven.plugins.dnsme.beans.RecordComparator;
 20  
 import org.kuali.maven.plugins.dnsme.beans.RecordType;
 21  
 import org.kuali.maven.plugins.dnsme.beans.Search;
 22  
 
 23  
 import com.google.gson.Gson;
 24  
 import com.google.gson.reflect.TypeToken;
 25  
 
 26  
 public class DNSMEClient {
 27  
 
 28  
     public static final int HTTP_OK = 200;
 29  
     public static final int HTTP_CREATED = 201;
 30  
 
 31  
     String restApiUrl;
 32  
     Account account;
 33  1
     Gson gson = new Gson();
 34  1
     HttpUtil http = new HttpUtil();
 35  1
     DNSMEUtil dnsme = new DNSMEUtil();
 36  
 
 37  
     public static DNSMEClient getInstance(Account account, String restApiUrl) {
 38  1
         return new DNSMEClient(account, restApiUrl);
 39  
     }
 40  
 
 41  
     private DNSMEClient(Account account, String restApiUrl) {
 42  1
         super();
 43  1
         this.account = account;
 44  1
         this.restApiUrl = restApiUrl;
 45  1
     }
 46  
 
 47  
     public List<Domain> getDomains() {
 48  0
         String url = this.restApiUrl + "/domains";
 49  0
         String json = getJson(url, HTTP_OK);
 50  0
         DomainNames domainNames = gson.fromJson(json, DomainNames.class);
 51  0
         return getDomains(domainNames);
 52  
     }
 53  
 
 54  
     public Domain getDomain(String name) {
 55  0
         List<Domain> domains = getDomains();
 56  0
         for (Domain domain : domains) {
 57  0
             if (domain.getName().equalsIgnoreCase(name)) {
 58  0
                 return domain;
 59  
             }
 60  
         }
 61  0
         return null;
 62  
     }
 63  
 
 64  
     public Domain addDomain(Domain domain) {
 65  1
         String url = this.restApiUrl + "/domains/" + domain.getName();
 66  1
         PutMethod method = new PutMethod(url);
 67  1
         return addOrUpdateObject(url, HTTP_CREATED, domain, method);
 68  
     }
 69  
 
 70  
     public void deleteDomain(Domain domain) {
 71  0
         String url = this.restApiUrl + "/domains/" + domain.getName();
 72  0
         deleteObject(url);
 73  0
     }
 74  
 
 75  
     protected String getQueryString(Search search) {
 76  0
         List<NameValuePair> pairs = getPairs(search);
 77  0
         StringBuilder sb = new StringBuilder();
 78  0
         for (int i = 0; i < pairs.size(); i++) {
 79  0
             NameValuePair pair = pairs.get(i);
 80  0
             if (i == 0) {
 81  0
                 sb.append("?");
 82  
             } else {
 83  0
                 sb.append("&");
 84  
             }
 85  0
             sb.append(pair.getName() + "=" + encode(pair.getValue()));
 86  
         }
 87  0
         return sb.toString();
 88  
     }
 89  
 
 90  
     protected List<NameValuePair> getPairs(Search search) {
 91  0
         List<NameValuePair> pairs = new ArrayList<NameValuePair>();
 92  0
         addIfNotNull(pairs, getPair("name", search.getName()));
 93  0
         addIfNotNull(pairs, getPair("nameContains", search.getNameContains()));
 94  0
         addIfNotNull(pairs, getPair("value", search.getValue()));
 95  0
         addIfNotNull(pairs, getPair("valueContains", search.getValueContains()));
 96  0
         addIfNotNull(pairs, getPair("gtdLocation", search.getGtdLocation()));
 97  0
         addIfNotNull(pairs, getPair("type", search.getType()));
 98  0
         return pairs;
 99  
     }
 100  
 
 101  
     protected void addIfNotNull(List<NameValuePair> pairs, NameValuePair pair) {
 102  0
         if (pair == null) {
 103  0
             return;
 104  
         } else {
 105  0
             pairs.add(pair);
 106  
         }
 107  0
     }
 108  
 
 109  
     protected NameValuePair getPair(String name, Object value) {
 110  0
         if (value == null) {
 111  0
             return null;
 112  
         } else {
 113  0
             return new NameValuePair(name, value.toString());
 114  
         }
 115  
     }
 116  
 
 117  
     protected String encode(String value) {
 118  
         try {
 119  0
             return URLEncoder.encode(value, "UTF-8");
 120  0
         } catch (UnsupportedEncodingException e) {
 121  0
             throw new DNSMEException(e);
 122  
         }
 123  
     }
 124  
 
 125  
     public Record getRecord(Domain domain, Search search) {
 126  0
         List<Record> records = getRecords(domain, search);
 127  0
         if (records.size() != 1) {
 128  0
             throw new DNSMEException("Search criteria must match exactly 1 record but it matched " + records.size()
 129  
                     + " records");
 130  
         } else {
 131  0
             return records.get(0);
 132  
         }
 133  
     }
 134  
 
 135  
     public List<Record> getRecords(Domain domain, Search search) {
 136  0
         String url = this.restApiUrl + "/domains/" + domain.getName() + "/records";
 137  0
         if (search != null) {
 138  0
             url += getQueryString(search);
 139  
         }
 140  0
         String json = getJson(url, HTTP_OK);
 141  0
         List<Record> records = getRecords(json);
 142  0
         for (Record record : records) {
 143  0
             record.setDomain(domain);
 144  
         }
 145  0
         return records;
 146  
     }
 147  
 
 148  
     public Record getRecord(Domain domain, String name) {
 149  0
         Search search = new Search();
 150  0
         search.setName(name);
 151  0
         return getRecord(domain, search);
 152  
     }
 153  
 
 154  
     public Record getRecord(Domain domain, int recordId) {
 155  0
         String url = this.restApiUrl + "/domains/" + domain.getName() + "/records/" + recordId;
 156  0
         String resultJson = getJson(url, HTTP_OK);
 157  0
         Record resultRecord = (Record) gson.fromJson(resultJson, Record.class);
 158  0
         return resultRecord;
 159  
     }
 160  
 
 161  
     protected void validateForUpdate(Record record) {
 162  0
         if (record.getId() == null && record.getName() == null) {
 163  0
             throw new DNSMEException("Either or id or name must have a value when updating");
 164  
         }
 165  0
     }
 166  
 
 167  
     public void updateRecord(Domain domain, Record record) {
 168  0
         validateForUpdate(record);
 169  0
         if (record.getId() == null) {
 170  0
             Record existingRecord = getRecord(domain, record.getName());
 171  0
             record.setId(existingRecord.getId());
 172  
         }
 173  0
         validateRecord(record);
 174  0
         String url = this.restApiUrl + "/domains/" + domain.getName() + "/records/" + record.getId();
 175  0
         PutMethod method = new PutMethod(url);
 176  0
         addOrUpdateObject(url, HTTP_OK, record, method);
 177  0
     }
 178  
 
 179  
     public Record addRecord(Domain domain, Record record) {
 180  0
         String url = this.restApiUrl + "/domains/" + domain.getName() + "/records";
 181  0
         if (record.getId() != null) {
 182  0
             throw new DNSMEException("id must be null when adding");
 183  
         }
 184  0
         validateRecord(record);
 185  0
         PostMethod method = new PostMethod(url);
 186  0
         return addOrUpdateObject(url, HTTP_CREATED, record, method);
 187  
     }
 188  
 
 189  
     public void deleteRecord(Domain domain, int recordId) {
 190  0
         String url = this.restApiUrl + "/domains/" + domain.getName() + "/records/" + recordId;
 191  0
         deleteObject(url);
 192  0
     }
 193  
 
 194  
     public void deleteRecord(Domain domain, String name) {
 195  0
         Record record = getRecord(domain, name);
 196  0
         deleteRecord(domain, record.getId());
 197  0
     }
 198  
 
 199  
     protected void deleteObject(String url) {
 200  0
         HttpMethod method = dnsme.getDeleteMethod(account, url);
 201  0
         HttpRequestResult result = http.executeMethod(method);
 202  0
         validateResult(result, HTTP_OK);
 203  0
     }
 204  
 
 205  
     public List<Record> getCNAMERecords(Domain domain) {
 206  0
         Search search = new Search();
 207  0
         search.setType(RecordType.CNAME);
 208  0
         List<Record> records = getRecords(domain, search);
 209  0
         Collections.sort(records, new RecordComparator());
 210  0
         return records;
 211  
     }
 212  
 
 213  
     protected void validateRecord(Record record) {
 214  0
         StringBuilder sb = new StringBuilder();
 215  0
         if (record.getName() == null) {
 216  0
             sb.append("Name must not be null\n");
 217  
         }
 218  0
         if (record.getData() == null) {
 219  0
             sb.append("Data must not be null\n");
 220  
         }
 221  0
         if (record.getTtl() == null) {
 222  0
             sb.append("TTL must not be null\n");
 223  
         }
 224  0
         if (record.getType() == null) {
 225  0
             sb.append("Type must not be null\n");
 226  
         }
 227  0
         if (sb.length() > 0) {
 228  0
             throw new DNSMEException(sb.toString());
 229  
         }
 230  0
     }
 231  
 
 232  
     protected <T> T addOrUpdateObject(String url, int statusCode, T object, EntityEnclosingMethod method) {
 233  1
         String json = gson.toJson(object);
 234  1
         dnsme.updateMethod(account, json, method);
 235  1
         String resultJson = getJson(url, method, statusCode);
 236  
         @SuppressWarnings("unchecked")
 237  0
         T resultObject = (T) gson.fromJson(resultJson, object.getClass());
 238  0
         return resultObject;
 239  
     }
 240  
 
 241  
     public List<Record> getRecords(Domain domain) {
 242  0
         return getRecords(domain, null);
 243  
     }
 244  
 
 245  
     protected String getJson(String url, HttpMethod method, int successCode) {
 246  1
         HttpRequestResult result = http.executeMethod(method);
 247  1
         validateResult(result, successCode);
 248  0
         return result.getResponseBody();
 249  
     }
 250  
 
 251  
     protected String getJson(String url, int successCode) {
 252  0
         HttpMethod method = dnsme.getGetMethod(account, url);
 253  0
         return getJson(url, method, successCode);
 254  
     }
 255  
 
 256  
     protected List<Record> getRecords(String json) {
 257  0
         Type recordsListType = new TypeToken<List<Record>>() {
 258  
         }.getType();
 259  
 
 260  
         @SuppressWarnings("unchecked")
 261  0
         List<Record> records = (List<Record>) gson.fromJson(json, recordsListType);
 262  0
         if (records == null) {
 263  0
             return new ArrayList<Record>();
 264  
         } else {
 265  0
             return records;
 266  
         }
 267  
     }
 268  
 
 269  
     protected void validateResult(HttpRequestResult result, int statusCode) {
 270  1
         switch (result.getType()) {
 271  
         case EXCEPTION:
 272  0
             throw new DNSMEException(result.getException());
 273  
         case TIMEOUT:
 274  0
             throw new DNSMEException("Operation timed out");
 275  
         case COMPLETED:
 276  1
             int code = result.getStatusCode();
 277  1
             if (statusCode == result.getStatusCode()) {
 278  0
                 return;
 279  
             } else {
 280  1
                 String errorText = result.getResponseBody();
 281  1
                 throw new DNSMEException("Invalid http status '" + code + ":" + result.getStatusText()
 282  
                         + "' Expected: '" + statusCode + "'  Error:" + errorText);
 283  
             }
 284  
         default:
 285  0
             throw new DNSMEException("Unknown result type: " + result.getType());
 286  
         }
 287  
     }
 288  
 
 289  
     protected List<Domain> getDomains(DomainNames domainNames) {
 290  0
         if (domainNames.getList() == null) {
 291  0
             return new ArrayList<Domain>();
 292  
         }
 293  0
         List<String> names = domainNames.getList();
 294  0
         List<Domain> domains = new ArrayList<Domain>();
 295  0
         for (String name : names) {
 296  0
             Domain domain = new Domain();
 297  0
             domain.setAccount(account);
 298  0
             domain.setName(name);
 299  0
             domains.add(domain);
 300  0
         }
 301  0
         return domains;
 302  
     }
 303  
 }