Некоторое время назад я решил проблему автоматической покупки домена.
Необходимо было оформить его как библиотеку (jar и файл настроек), которая будет использоваться в корпоративном приложении на Java. Я начал искать DNS-провайдеров с общедоступным API. Хотелось бы, чтобы API были попроще, а домены подешевле — такой баланс найти было непросто.
Было рассмотрено множество вариантов, некоторые из них можно найти здесь: переполнение стека .
Впоследствии я сузил круг до следующих претендентов:
Многие рекомендовали последнее, но это хостинг-провайдер, а мне нужен был только DNS — варианта не покупать там сервер я не нашел.У первого, на мой взгляд, очень удобный API — аутентификация вообще может происходить через HTTP Header. X-DNSimple-токен , но существует и традиционный подход с базовой авторизацией http. Формат запроса очень простой — короткие URL-адреса.
Ответы можно получать в формате JSON (есть и XML) - в целом все радует глаз, кроме цены - .
com домен есть 14 долларов США в год .
Знающие люди поймут, что это недопустимо.
Когда я начал заниматься http://www.namecheap.com/ - все оказалось довольно хорошо.
А со стороны покупателя цены нормальные, на рынке уже больше 10 лет (dnsimple.com через кого дано Дата создания: 07.04.2010 17:32:00 - все равно маловато, плюс домен Идентификаторы, когда я создавал их через API, были около 3000).
А со стороны программиста: запросы в XML, но структура не сильно запутанная.
В аутентификации через параметры в самом URL нет ничего сложного.
Больше всего мне понравилось то, что они были единственными из всех кандидатов, у которых было правильная песочница .
Когда вы регистрируетесь в тестовой среде, на вашем счету есть 9000 долларов США, и вы действительно можете протестировать функции покупки, продления, повторной активации и т. д. для домена.
В DNsimple, например, я не нашел возможности использовать тестовую среду без ввода номера кредитной карты — что это за песочница, которая не может работать без реальных данных? Кроме того, при редактировании записи хоста домена, есть возможность задавать нестандартные значения (не только A, CNAME, AAAA и т.д.) — тоже есть « URL-адрес » — это позволяет сделать редирект со своего домена на определенный 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(); .
}
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 — самый популярный приз в большинстве викторин.
В этом году они решили приурочить Суперкубок.
Я не силен в американском спорте, но решил из любопытства ответить на вопрос.
Номер три звучал примерно так: «В каком году Барт Старр был избран в Зал спортивной славы штата Висконсин» — не долго думая, я зашёл в Википедию посмотреть его биографию.
Отдельным абзацем было написано, что это произошло в 1980 году.
Я в ответ написал эту цифру.
Через час твит с правильным ответом меня немного расстроил - 1981 год. Ну кто бы сомневался, я подумал, что даты в Википедии не точные.
Но все же я решил зайти туда еще раз и посмотреть – расстроился еще больше.
Там действительно был 1981 год. Я подумал, что пора запасаться таблетками для улучшения зрения, повышения внимания и ускорения работы мозга – в общем, всем, что прописывают старикам, и занялся другими делами.
Однако через пару часов от организатора марафона пришел интересный твит примерно такого содержания: «Уважаемые участники, мы считаем НЕДОПУСТИМЫМ редактирование Википедии с целью дезинформации оппонентов – это противоречит духу честной игры.
Любой, кто будет уличен в мошенничестве, будет дисквалифицирован».
Я обрадовалась – значит, лекарства покупать рано.
УПД Спасибо всем, что сообщили о сломанной подсветке.
Теги: #java #dns #Twitter #wikipedia #java
-
Покупка Оборудования
19 Oct, 24 -
Пять Качеств Успешных Новаторов
19 Oct, 24 -
Skype 2.1.0.81 Бета Для Linux
19 Oct, 24 -
Менеджмент 2.0 (Часть 2)
19 Oct, 24