Некоторое время назад я решал задачу автоматической покупки домена. Нужно было оформить в виде библиотеки (jar и файл настроек), которая использовалась бы в корпоративном приложении на Java. Я начал поиски DNS провайдеров с public API. Желательно, чтобы API были попроще, и домены подешевле — такой баланс оказалось не просто найти.
Было рассмотрено много вариантов, некоторые из которых можно найти тут: stackoverflow. В последствии, я сузил круг до следующих претендентов:
Последний многие советовали, но это хостинг провайдер, а мне нужен был только ДНС – возможности не покупать сервер я там не нашел.
Первый имеет, на мой взгляд, очень удобный API – аутентификация может проходить вообще через HTTP Header X-DNSimple-Token, но есть и традиционный подход с http basic authorization. Формат запроса очень прост – короткие урлы. Ответы можно получать в JSON (XML тоже доступен) – вобщем все радует глаз, кроме цены — .com домен там стоит $14/y. Знающие люди поймут, что это неприемлимо.
Когда начал разбираться с http://www.namecheap.com/ — все оказалось довольно не плохо. И со стороны покупателя — цены в норме, на рынке он больше 10 лет (dnsimple.com через who is дал Creation date: 07 Apr 2010 17:32:00 – мелковат еще, плюс ID доменов, когда я создавал их через API был в районе 3000). И со стороны программиста: запросы в XML, но структура не сильно запутанная. Аутентификация через параметры в самом урле – ничего сложного.
Что мне больше всего понравилось – у них единственных из всех кандидатов оказался правильный sandbox. При регистрации в тестовом окружении у тебя на счету $9000 и ты можешь реально потестировать функции покупки, renew, reactivate и т.д. для домена. В DNsimple, к примеру, я не нашел возможности пользоваться тестовым окружением без того, чтоб вводить номер кредитки – а что это за sandbox, который не может работать без реальных данных?
Кроме того у них при редактировании host records домена есть возможность задать нестандартные значения (не только A, CNAME, AAAA, etc.) – есть еще “URL” – это позволяет делать редирект с вашего домена на некий урл (произвольный), а это как раз требовалось для задачи, и в случае отсутствия такой опции было бы необходимо что-то придумывать со стороны сервера заказчика. Такая фича есть далеко не у всех DNS провайдеров.
И еще этот провайдер довольно часто раздает купоны со скидкой (в API есть возможность использовать эти купоны) и организовывает акции (об одной из них – в конце статьи). Например недавно там были скидки для всех кто переводит свои домены от GoDaddy, в связи с SOPA-позициями последнего.
Полностью он выложен в свободном доступе: github.com кому надо пользуйтесь (заказчику по барабану).
Интерфейс DNSProvider имеет конкретную реализацию: NamecheapProvider, где присутствуют основные функции для работы с доменами – покупка, обновление записей, реактивация. Есть пакет моделей, где находятся объекты основных сущностей: Domain, DomainRecord, RecordType. Все остальное это классы запросов, и xml парсеры ответов.
Базовый класс запроса:
Каждый класс запроса реализует свою getCommand, которая соответствует его назначению:
Интерфейс парсера:
И пример реализации для получения списка доменов из вашего аккаунта:
Друг с другом запрос и разбор ответа сводит класс на дженериках:
Который принимает их через параметры и возвращает результат разбора xml ответа.
Для расширения функциональности нужно добавить функцию в интерфейс, создать класс запроса, класс парсера ответа, и объединить их через вызов ProviderOperator в соотв. функции NamecheapProvider.
www.namecheap.com имеет традицию – каждый год они организовывают твиттер-марафон на определенную тему. В течение 48 часов задаются 48 вопросов. Каждый час дается правильный ответ на предыдущий вопрос и задается следующий. Победителям деньги на счет (для покупки доменов) и пара iPad2 – самый ходовой приз большинства викторин. В этом году марафон решили приурочить к суперкубку. Я в американских видах спорта не силен, но решил для интереса ответить на какой-нибудь вопрос. Номер третий звучал примерно так:
«In what year was Bart Starr elected to the Wisconsin Athletic Hall of Fame»
— не долго думая, пошел в википедию смотреть его биографию. Отдельным обзацом было написано, что это произошло в 1980. Я твитнул это число в ответ. Через час твит с правильным ответом меня немного расстроил – 1981. Ну кто бы сомневался, подумал я, что в википедии даты не точные. Но все-таки решил зайти туда снова и посмотреть – расстроился еще больше. Там было действительно написано 1981. Я подумал, что пора затариваться таблетками для улучшения зрения, повышения внимания и ускорения работы мозга – вобщем все что прописывают старикам, и занялся другими делами.
Однако через пару часов от организатора марафона поступил интересный твит, приблизительно такого содержания:
«Уважаемые участники, мы считаем НЕДОПУСТИМЫМ редактировать википедию, чтобы дезинформировать соперников – это противоречит духу fair play. Уличенный в мошенничестве будет дисквалифицирован»
Я обрадовался — значит рано покупать лекарства.
UPD Всем спасибо за сообщение о поломанной подсветке.
Было рассмотрено много вариантов, некоторые из которых можно найти тут: stackoverflow. В последствии, я сузил круг до следующих претендентов:
Последний многие советовали, но это хостинг провайдер, а мне нужен был только ДНС – возможности не покупать сервер я там не нашел.
Первый имеет, на мой взгляд, очень удобный API – аутентификация может проходить вообще через HTTP Header X-DNSimple-Token, но есть и традиционный подход с http basic authorization. Формат запроса очень прост – короткие урлы. Ответы можно получать в JSON (XML тоже доступен) – вобщем все радует глаз, кроме цены — .com домен там стоит $14/y. Знающие люди поймут, что это неприемлимо.
Когда начал разбираться с http://www.namecheap.com/ — все оказалось довольно не плохо. И со стороны покупателя — цены в норме, на рынке он больше 10 лет (dnsimple.com через who is дал Creation date: 07 Apr 2010 17:32:00 – мелковат еще, плюс ID доменов, когда я создавал их через API был в районе 3000). И со стороны программиста: запросы в XML, но структура не сильно запутанная. Аутентификация через параметры в самом урле – ничего сложного.
Что мне больше всего понравилось – у них единственных из всех кандидатов оказался правильный sandbox. При регистрации в тестовом окружении у тебя на счету $9000 и ты можешь реально потестировать функции покупки, renew, reactivate и т.д. для домена. В DNsimple, к примеру, я не нашел возможности пользоваться тестовым окружением без того, чтоб вводить номер кредитки – а что это за sandbox, который не может работать без реальных данных?
Кроме того у них при редактировании host records домена есть возможность задать нестандартные значения (не только A, CNAME, AAAA, etc.) – есть еще “URL” – это позволяет делать редирект с вашего домена на некий урл (произвольный), а это как раз требовалось для задачи, и в случае отсутствия такой опции было бы необходимо что-то придумывать со стороны сервера заказчика. Такая фича есть далеко не у всех DNS провайдеров.
И еще этот провайдер довольно часто раздает купоны со скидкой (в API есть возможность использовать эти купоны) и организовывает акции (об одной из них – в конце статьи). Например недавно там были скидки для всех кто переводит свои домены от GoDaddy, в связи с SOPA-позициями последнего.
Перейдем к коду
Полностью он выложен в свободном доступе: github.com кому надо пользуйтесь (заказчику по барабану).
Интерфейс DNSProvider имеет конкретную реализацию: NamecheapProvider, где присутствуют основные функции для работы с доменами – покупка, обновление записей, реактивация. Есть пакет моделей, где находятся объекты основных сущностей: Domain, DomainRecord, RecordType. Все остальное это классы запросов, и xml парсеры ответов.
Базовый класс запроса:
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 class has its own command - his purpose params.add(new BasicNameValuePair("Command", getCommand())); } protected abstract String getCommand(); .... }
Каждый класс запроса реализует свою getCommand, которая соответствует его назначению:
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"; } }
Интерфейс парсера:
public interface XmlResponseParser<T> { T parse(String xml); }
И пример реализации для получения списка доменов из вашего аккаунта:
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); } } }
Друг с другом запрос и разбор ответа сводит класс на дженериках:
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; } }
Который принимает их через параметры и возвращает результат разбора xml ответа.
Для расширения функциональности нужно добавить функцию в интерфейс, создать класс запроса, класс парсера ответа, и объединить их через вызов ProviderOperator в соотв. функции NamecheapProvider.
Напоследок интересная история
www.namecheap.com имеет традицию – каждый год они организовывают твиттер-марафон на определенную тему. В течение 48 часов задаются 48 вопросов. Каждый час дается правильный ответ на предыдущий вопрос и задается следующий. Победителям деньги на счет (для покупки доменов) и пара iPad2 – самый ходовой приз большинства викторин. В этом году марафон решили приурочить к суперкубку. Я в американских видах спорта не силен, но решил для интереса ответить на какой-нибудь вопрос. Номер третий звучал примерно так:
«In what year was Bart Starr elected to the Wisconsin Athletic Hall of Fame»
— не долго думая, пошел в википедию смотреть его биографию. Отдельным обзацом было написано, что это произошло в 1980. Я твитнул это число в ответ. Через час твит с правильным ответом меня немного расстроил – 1981. Ну кто бы сомневался, подумал я, что в википедии даты не точные. Но все-таки решил зайти туда снова и посмотреть – расстроился еще больше. Там было действительно написано 1981. Я подумал, что пора затариваться таблетками для улучшения зрения, повышения внимания и ускорения работы мозга – вобщем все что прописывают старикам, и занялся другими делами.
Однако через пару часов от организатора марафона поступил интересный твит, приблизительно такого содержания:
«Уважаемые участники, мы считаем НЕДОПУСТИМЫМ редактировать википедию, чтобы дезинформировать соперников – это противоречит духу fair play. Уличенный в мошенничестве будет дисквалифицирован»
Я обрадовался — значит рано покупать лекарства.
UPD Всем спасибо за сообщение о поломанной подсветке.
