Some time ago I solved the problem of automatic domain purchase. It was necessary to arrange in the form of a library (jar and settings file) that would be used in a corporate Java application. I started searching for DNS providers with the public API. It is desirable that the API were simpler, and the domains are cheaper - such a balance was not easy to find.
Many options have been considered, some of which can be found here:
stackoverflow . Subsequently, I narrowed the circle to the following applicants:
Many have advised the latter, but this is a hosting provider, and I only needed CSN - I did not find the opportunity not to buy a server there.
The first has, in my opinion, a very convenient API - authentication can generally take place through HTTP Header
X-DNSimple-Token , but there is also a traditional approach with http basic authorization. Request format is very simple - short URLs. Answers can be received in JSON (XML is also available) - in general, everything pleases the eye, except for the price - the
.com domain there costs
$ 14 / y . Knowledgeable people will realize that this is unacceptable.
When I started to deal with
http://www.namecheap.com/ , everything turned out to be pretty good. And on the buyer's side, prices are normal, it has been on the market for more than 10 years (dnsimple.com through who is given Creation date: 07 Apr 2010 17:32:00 - it’s still small, plus the ID of the domains when I created them through the API was about 3000). And from the programmer: requests in XML, but the structure is not very confusing. Authentication through the parameters in the URL itself - nothing complicated.
')
What I liked most was that the only candidates among them were the
correct sandbox . When you register in a test environment, you have $ 9000 in your account and you can actually test the functions of purchase, renew, reactivate, etc. for the domain. In DNsimple, for example, I did not find an opportunity to use the test environment without entering a credit card number - and what is this sandbox that cannot work without real data?
In addition, when editing the
host records of the domain, it is possible to set non-standard values (not just A, CNAME, AAAA, etc.) - there is also a “
URL ” - this allows you to redirect from your domain to a certain URL (arbitrary), and this is how once it was required for the task, and in the absence of such an option, it would be necessary to invent something from the server of the customer. Not all DNS providers have this feature.
And this provider often distributes coupons at a discount (
there is an opportunity to use these coupons in the API ) and organizes promotions (one of them is at the end of the article). For example, recently there were discounts for everyone who transfers their domains from GoDaddy, in connection with the SOPA-positions of the latter.
Let's go to the code
It is fully laid out in the public domain:
github.com who needs to use (the customer on the drum).
The DNSProvider interface has a specific implementation: NamecheapProvider, where the main functions for working with domains are present: purchase, update of records, reactivation. There is a package of models where the objects of the main entities are located: Domain, DomainRecord, RecordType. All the rest are query classes, and xml response parsers.
Base request class:
public abstract class DNSBaseRequest { private List<NameValuePair> params = new ArrayList<NameValuePair>(); protected DNSBaseRequest(Properties properties) { params.add(new BasicNameValuePair("ApiUser", properties.getProperty("api.login"))); params.add(new BasicNameValuePair("ApiKey", properties.getProperty("api.key"))); params.add(new BasicNameValuePair("UserName", properties.getProperty("api.login"))); params.add(new BasicNameValuePair("ClientIp", properties.getProperty("client.ip")));
Each request class implements its own
getCommand , which corresponds to its purpose:
public class DomainReactivateRequest extends DNSBaseRequest{ public DomainReactivateRequest(String domainName, Properties properties) { super(properties); addParam(new BasicNameValuePair("DomainName", domainName)); } @Override protected String getCommand() { return "namecheap.domains.reactivate"; } }
Parser Interface:
public interface XmlResponseParser<T> { T parse(String xml); }
And an example implementation for getting a list of domains from your account:
public class DomainsListParser extends DefaultHandler implements XmlResponseParser<ArrayList<Domain>> { private static final Logger log = LoggerFactory.getLogger(DomainsListParser.class); private SAXParser parser; private ArrayList<Domain> result; public DomainsListParser() throws Exception{ SAXParserFactory factory = SAXParserFactory.newInstance(); parser = factory.newSAXParser(); result = new ArrayList<Domain>(); } public ArrayList<Domain> parse(String xml) { try { parser.parse(new InputSource(new StringReader(xml)), this); } catch(Exception e){ log.error("Error in parsing string.", e); } return result; } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if ("Domain".equalsIgnoreCase(qName)){ Domain domain = new Domain(Long.parseLong(attributes.getValue("ID")), attributes.getValue("Name")); domain.setCreateDate(attributes.getValue("Created")); domain.setExpireDate(attributes.getValue("Expires")); result.add(domain); } } }
Each other's request and analysis of the response reduces the class to generics:
public class ProviderOperator { private static final Logger log = LoggerFactory.getLogger(ProviderOperator.class); private DNSRequestProcessor dnsRequestProcessor; public ProviderOperator(DNSRequestProcessor dnsRequestProcessor) { this.dnsRequestProcessor = dnsRequestProcessor; } public <T, S extends T> T process(DNSBaseRequest dnsRequest, XmlResponseParser<T> parser, S defaultResult) { T result = defaultResult; try { String xml = dnsRequestProcessor.get(dnsRequest); log.debug("Response: {}", xml); result = parser.parse(xml); } catch (Exception e) { log.error("Error in parse", e); } return result; } }
Which takes them through parameters and returns the result of parsing the xml response.
To extend the functionality, you need to add a function to the interface, create a request class, a response parser class, and combine them via a call to ProviderOperator in acc. NamecheapProvider functions.
Finally, an interesting story
www.namecheap.com has a tradition - every year they organize a twitter marathon on a specific topic. 48 questions are asked within 48 hours. Every hour the correct answer to the previous question is given and the next one is asked. The winners have money to their account (for the purchase of domains) and a pair of iPad2 - the most popular prize of most quizzes. This year, the marathon decided to coincide with the super bowl. I am not strong in American sports, but I decided to answer some question for interest. Number three sounded like this:
"In what year was the Bart Starr elected to the Wisconsin Athletic Hall of Fame"- without hesitation, I went to Wikipedia to watch his biography. Separately, it was written that it happened in 1980. I tweeted that number in response. An hour later, a tweet with the correct answer upset me a little - 1981. Well, who would doubt, I thought that the dates in Wikipedia are not exact. But still decided to go there again and see - even more upset. 1981. It was really written there. I thought that it was time to pack up pills to improve vision, increase attention and speed up the work of the brain - in general, everything that is prescribed to the elderly, and was busy with other things.
However, after a couple of hours, an interesting tweet came from the marathon organizer, approximately of the following content:
“Dear participants, we consider it inappropriate to edit Wikipedia to misinform opponents - this is contrary to the spirit of fair play. Convicted of fraud will be disqualified "I was delighted - it means early to buy medicines.
UPD Thank you all for the message about the broken backlight.