
org.restcomm.connect.provisioning.number.voxbone.VoxbonePhoneNumberProvisioningManager Maven / Gradle / Ivy
/*
* TeleStax, Open Source Cloud Communications
* Copyright 2011-2015, Telestax Inc and individual contributors
* by the @authors tag.
*
* This program is free software: you can redistribute it and/or modify
* under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation; either version 3 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see
*
*/
package org.restcomm.connect.provisioning.number.voxbone;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.regex.Pattern;
import org.apache.commons.configuration.Configuration;
import org.apache.log4j.Logger;
import org.restcomm.connect.provisioning.number.api.ContainerConfiguration;
import org.restcomm.connect.provisioning.number.api.PhoneNumber;
import org.restcomm.connect.provisioning.number.api.PhoneNumberParameters;
import org.restcomm.connect.provisioning.number.api.PhoneNumberProvisioningManager;
import org.restcomm.connect.provisioning.number.api.PhoneNumberSearchFilters;
import com.google.gson.JsonArray;
import com.google.gson.JsonNull;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.ClientResponse.Status;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.filter.HTTPBasicAuthFilter;
/**
* @author [email protected]
*/
public class VoxbonePhoneNumberProvisioningManager implements PhoneNumberProvisioningManager {
private static final Logger logger = Logger.getLogger(VoxbonePhoneNumberProvisioningManager.class);
private static final String COUNTRY_CODE_PARAM = "countryCodeA3";
private static final String PAGE_SIZE = "pageSize";
private static final String PAGE_NUMBER = "pageNumber";
private static final String CONTENT_TYPE = "application/json";
protected Boolean telestaxProxyEnabled;
protected String uri, username, password;
protected String searchURI, createCartURI, voiceURI, updateURI, cancelURI, countriesURI, listDidsURI;
protected String voiceUriId;
protected Configuration activeConfiguration;
protected ContainerConfiguration containerConfiguration;
public VoxbonePhoneNumberProvisioningManager() {}
/*
* (non-Javadoc)
*
* @see
* PhoneNumberProvisioningManager#init(org.apache.commons.configuration
* .Configuration, boolean)
*/
@Override
public void init(Configuration phoneNumberProvisioningConfiguration, Configuration telestaxProxyConfiguration, ContainerConfiguration containerConfiguration) {
this.containerConfiguration = containerConfiguration;
telestaxProxyEnabled = telestaxProxyConfiguration.getBoolean("enabled", false);
if (telestaxProxyEnabled) {
uri = telestaxProxyConfiguration.getString("uri");
username = telestaxProxyConfiguration.getString("username");
password = telestaxProxyConfiguration.getString("password");
activeConfiguration = telestaxProxyConfiguration;
} else {
Configuration voxboneConfiguration = phoneNumberProvisioningConfiguration.subset("voxbone");
uri = voxboneConfiguration.getString("uri");
username = voxboneConfiguration.getString("username");
password = voxboneConfiguration.getString("password");
activeConfiguration = voxboneConfiguration;
}
searchURI = uri + "/inventory/didgroup";
createCartURI = uri + "/ordering/cart";
voiceURI = uri + "/configuration/voiceuri";
updateURI = uri + "/configuration/configuration";
cancelURI = uri + "/ordering/cancel";
countriesURI = uri + "/inventory/country";
listDidsURI = uri + "/inventory/did";
Configuration callbackUrlsConfiguration = phoneNumberProvisioningConfiguration.subset("callback-urls");
Client jerseyClient = Client.create();
jerseyClient.addFilter(new HTTPBasicAuthFilter(username, password));
WebResource webResource = jerseyClient.resource(voiceURI);
String body = "{\"voiceUri\":{\"voiceUriProtocol\":\"SIP\",\"uri\":\"" + callbackUrlsConfiguration.getString("voice[@url]") + "\"}}";
ClientResponse clientResponse = webResource.accept(CONTENT_TYPE).type(CONTENT_TYPE).put(ClientResponse.class,body);
String voiceURIResponse = clientResponse.getEntity(String.class);
if(logger.isDebugEnabled())
logger.debug("response " + voiceURIResponse);
JsonParser parser = new JsonParser();
JsonObject jsonVoiceURIResponse = parser.parse(voiceURIResponse).getAsJsonObject();
if (clientResponse.getClientResponseStatus() == Status.OK) {
JsonObject voxVoiceURI = jsonVoiceURIResponse.get("voiceUri").getAsJsonObject();
voiceUriId = voxVoiceURI.get("voiceUriId").getAsString();
} else if (clientResponse.getClientResponseStatus() == Status.UNAUTHORIZED) {
JsonObject error = jsonVoiceURIResponse.get("errors").getAsJsonArray().get(0).getAsJsonObject();
throw new IllegalArgumentException(error.get("apiErrorMessage").getAsString());
} else {
webResource = jerseyClient.resource(voiceURI);
clientResponse = webResource.queryParam(PAGE_NUMBER,"0").queryParam(PAGE_SIZE,"300").accept(CONTENT_TYPE).type(CONTENT_TYPE).get(ClientResponse.class);
String listVoiceURIResponse = clientResponse.getEntity(String.class);
if(logger.isDebugEnabled())
logger.debug("response " + listVoiceURIResponse );
JsonObject jsonListVoiceURIResponse = parser.parse(listVoiceURIResponse).getAsJsonObject();
// TODO go through the list of voiceURI id and check which one is matching
JsonObject voxVoiceURI = jsonListVoiceURIResponse.get("voiceUris").getAsJsonArray().get(0).getAsJsonObject();
voiceUriId = voxVoiceURI.get("voiceUriId").getAsString();
}
}
private List toAvailablePhoneNumbers(final JsonArray phoneNumbers, PhoneNumberSearchFilters listFilters) {
Pattern searchPattern = listFilters.getFilterPattern();
final List numbers = new ArrayList();
for (int i = 0; i < phoneNumbers.size(); i++) {
JsonObject number = phoneNumbers.get(i).getAsJsonObject();
if(Integer.parseInt(number.get("stock").toString()) > 0) {
//we only return the number if there is any stock for it
String countryCode = number.get(COUNTRY_CODE_PARAM).getAsString();
String features = null;
if(number.get("features") != null) {
features = number.get("features").toString();
}
boolean isVoiceCapable = true;
boolean isFaxCapable = false;
boolean isSmsCapable = false;
if(features.contains("VoxSMS")) {
isSmsCapable = true;
}
if(features.contains("VoxFax")) {
isFaxCapable = true;
}
String friendlyName = number.get("countryCodeA3").getAsString();
if(number.get("cityName") != null && !(number.get("cityName") instanceof JsonNull)) {
friendlyName = friendlyName + "-" + number.get("cityName").getAsString();
}
if(number.get("areaCode") != null && !(number.get("areaCode") instanceof JsonNull)) {
friendlyName = friendlyName + "-" + number.get("areaCode").getAsString();
}
final PhoneNumber phoneNumber = new PhoneNumber(
friendlyName,
number.get("didGroupId").getAsString(),
null, null, null, null, null, null,
countryCode, null, isVoiceCapable, isSmsCapable, null, isFaxCapable, null);
numbers.add(phoneNumber);
}
}
return numbers;
}
/*
* (non-Javadoc)
*
* @see
* PhoneNumberProvisioningManager#searchForNumbers(java.lang.String,
* java.lang.String, java.util.regex.Pattern, boolean, boolean, boolean, boolean, int, int)
*/
@Override
public List searchForNumbers(String country, PhoneNumberSearchFilters listFilters) {
Locale locale = new Locale("en",country);
String iso3Country = locale.getISO3Country();
if(logger.isDebugEnabled()) {
logger.debug("searchPattern " + listFilters.getFilterPattern());
}
Client jerseyClient = Client.create();
jerseyClient.addFilter(new HTTPBasicAuthFilter(username, password));
WebResource webResource = jerseyClient.resource(searchURI);
// https://developers.voxbone.com/docs/v3/inventory#path__didgroup.html
webResource = webResource.queryParam(COUNTRY_CODE_PARAM,iso3Country);
// Pattern filterPattern = listFilters.getFilterPattern();
// if(filterPattern != null) {
// webResource = webResource.queryParam("cityNamePattern" , filterPattern.toString());
// }
if(listFilters.getAreaCode() != null) {
webResource = webResource.queryParam("areaCode", listFilters.getAreaCode());
}
if(listFilters.getInRateCenter() != null) {
webResource = webResource.queryParam("rateCenter", listFilters.getInRateCenter());
}
if(listFilters.getSmsEnabled() != null) {
webResource = webResource.queryParam("featureIds", "6");
}
if(listFilters.getFaxEnabled() != null) {
webResource = webResource.queryParam("featureIds", "25");
}
if(listFilters.getRangeIndex() != -1) {
webResource = webResource.queryParam(PAGE_NUMBER, "" + listFilters.getRangeIndex());
} else {
webResource = webResource.queryParam(PAGE_NUMBER, "0");
}
if(listFilters.getRangeSize() != -1) {
webResource = webResource.queryParam(PAGE_SIZE, "" + listFilters.getRangeSize());
} else {
webResource = webResource.queryParam(PAGE_SIZE, "50");
}
ClientResponse clientResponse = webResource.accept(CONTENT_TYPE).type(CONTENT_TYPE)
.get(ClientResponse.class);
String response = clientResponse.getEntity(String.class);
if(logger.isDebugEnabled())
logger.debug("response " + response);
JsonParser parser = new JsonParser();
JsonObject jsonResponse = parser.parse(response).getAsJsonObject();
// long count = jsonResponse.getAsJsonPrimitive("count").getAsLong();
// if(logger.isDebugEnabled()) {
// logger.debug("Number of numbers found : "+count);
// }
JsonArray voxboneNumbers = jsonResponse.getAsJsonArray("didGroups");
final List numbers = toAvailablePhoneNumbers(voxboneNumbers, listFilters);
return numbers;
// } else {
// logger.warn("Couldn't reach uri for getting Phone Numbers. Response status was: "+response.getStatusLine().getStatusCode());
// }
//
// return new ArrayList();
}
@Override
public boolean buyNumber(PhoneNumber phoneNumberObject, PhoneNumberParameters phoneNumberParameters) {
String phoneNumber = phoneNumberObject.getPhoneNumber();
Client jerseyClient = Client.create();
jerseyClient.addFilter(new HTTPBasicAuthFilter(username, password));
WebResource webResource = jerseyClient.resource(createCartURI);
ClientResponse clientResponse = webResource.accept(CONTENT_TYPE).type(CONTENT_TYPE).put(ClientResponse.class,"{}");
String createCartResponse = clientResponse.getEntity(String.class);
if(logger.isDebugEnabled())
logger.debug("createCartResponse " + createCartResponse);
JsonParser parser = new JsonParser();
JsonObject jsonCreateCartResponse = parser.parse(createCartResponse).getAsJsonObject();
JsonObject voxCart = jsonCreateCartResponse.get("cart").getAsJsonObject();
String cartIdentifier = voxCart.get("cartIdentifier").getAsString();
try {
Client addToCartJerseyClient = Client.create();
addToCartJerseyClient.addFilter(new HTTPBasicAuthFilter(username, password));
WebResource addToCartWebResource = addToCartJerseyClient.resource(createCartURI + "/" + cartIdentifier + "/product");
String addToCartBody = "{\"didCartItem\":{\"didGroupId\":\"" + phoneNumber + "\",\"quantity\":\"1\"}}";
ClientResponse addToCartResponse = addToCartWebResource.accept(CONTENT_TYPE).type(CONTENT_TYPE).post(ClientResponse.class,addToCartBody);
if (addToCartResponse.getClientResponseStatus() == Status.OK) {
String addToCartResponseString = addToCartResponse.getEntity(String.class);
if(logger.isDebugEnabled())
logger.debug("addToCartResponse " + addToCartResponseString);
JsonObject jsonAddToCartResponse = parser.parse(addToCartResponseString).getAsJsonObject();
if(jsonAddToCartResponse.get("status").getAsString().equalsIgnoreCase("SUCCESS")) {
Client checkoutCartJerseyClient = Client.create();
checkoutCartJerseyClient.addFilter(new HTTPBasicAuthFilter(username, password));
WebResource checkoutCartWebResource = checkoutCartJerseyClient.resource(createCartURI + "/" + cartIdentifier + "/checkout");
ClientResponse checkoutCartResponse = checkoutCartWebResource.queryParam("cartIdentifier", cartIdentifier).accept(CONTENT_TYPE).type(CONTENT_TYPE).get(ClientResponse.class);
if (checkoutCartResponse.getClientResponseStatus() == Status.OK) {
String checkoutCartResponseString = checkoutCartResponse.getEntity(String.class);
if(logger.isDebugEnabled())
logger.debug("checkoutCartResponse " + checkoutCartResponseString);
JsonObject jsonCheckoutCartResponse = parser.parse(checkoutCartResponseString).getAsJsonObject();
if(jsonCheckoutCartResponse.get("status").getAsString().equalsIgnoreCase("SUCCESS")) {
String orderReference = jsonCheckoutCartResponse.get("productCheckoutList").getAsJsonArray().get(0).getAsJsonObject().get("orderReference").getAsString();
Client listDidsJerseyClient = Client.create();
listDidsJerseyClient.addFilter(new HTTPBasicAuthFilter(username, password));
WebResource listDidsWebResource = listDidsJerseyClient.resource(listDidsURI);
ClientResponse listDidsResponse = listDidsWebResource.
queryParam("orderReference", orderReference).
queryParam(PAGE_NUMBER, "0").
queryParam(PAGE_SIZE, "50").
accept(CONTENT_TYPE).
type(CONTENT_TYPE).
get(ClientResponse.class);
if (listDidsResponse.getClientResponseStatus() == Status.OK) {
String listDidsResponseString = listDidsResponse.getEntity(String.class);
if(logger.isDebugEnabled())
logger.debug("listDidsResponse " + listDidsResponseString);
JsonObject jsonListDidsResponse = parser.parse(listDidsResponseString).getAsJsonObject();
JsonObject dids = jsonListDidsResponse.get("dids").getAsJsonArray().get(0).getAsJsonObject();
String didId = dids.get("didId").getAsString();
String e164 = dids.get("e164").getAsString();
phoneNumberObject.setFriendlyName(didId);
phoneNumberObject.setPhoneNumber(e164);
updateNumber(phoneNumberObject, phoneNumberParameters);
} else {
return false;
}
} else {
// Handle not enough credit on the account
return false;
}
} else {
return false;
}
// we always return true as the phone number was bought
return true;
} else {
return false;
}
} else {
if(logger.isDebugEnabled())
logger.debug("Couldn't buy Phone Number " + phoneNumber + ". Response status was: "+ addToCartResponse.getClientResponseStatus());
}
} catch (final Exception e) {
logger.warn("Couldn't reach uri for buying Phone Numbers" + uri, e);
}
return false;
}
@Override
public boolean updateNumber(PhoneNumber phoneNumberObj, PhoneNumberParameters phoneNumberParameters) {
String phoneNumber = phoneNumberObj.getFriendlyName();
Client jerseyClient = Client.create();
jerseyClient.addFilter(new HTTPBasicAuthFilter(username, password));
WebResource webResource = jerseyClient.resource(updateURI);
String body = "{\"didIds\":[\"" + phoneNumber + "\"],\"voiceUriId\":\"" + voiceUriId + "\"}";
ClientResponse clientResponse = webResource.accept(CONTENT_TYPE).type(CONTENT_TYPE).post(ClientResponse.class,body);
String voiceURIResponse = clientResponse.getEntity(String.class);
if(logger.isDebugEnabled())
logger.debug("response " + voiceURIResponse);
// JsonParser parser = new JsonParser();
// JsonObject jsonCreateCartResponse = parser.parse(voiceURIResponse).getAsJsonObject();
if (clientResponse.getClientResponseStatus() == Status.OK) {
return true;
} else {
return false;
}
}
@Override
public boolean cancelNumber(PhoneNumber phoneNumberObj) {
String phoneNumber = phoneNumberObj.getFriendlyName();
Client jerseyClient = Client.create();
jerseyClient.addFilter(new HTTPBasicAuthFilter(username, password));
WebResource webResource = jerseyClient.resource(cancelURI);
String body = "{\"didIds\":[\"" + phoneNumber + "\"]}";
ClientResponse clientResponse = webResource.accept(CONTENT_TYPE).type(CONTENT_TYPE).post(ClientResponse.class,body);
String response = clientResponse.getEntity(String.class);
if(logger.isDebugEnabled())
logger.debug("response " + response);
// JsonParser parser = new JsonParser();
// JsonObject jsonResponse = parser.parse(response).getAsJsonObject();
if (clientResponse.getClientResponseStatus() == Status.OK) {
return true;
} else {
return false;
}
}
@Override
public List getAvailableCountries() {
Client jerseyClient = Client.create();
jerseyClient.addFilter(new HTTPBasicAuthFilter(username, password));
WebResource webResource = jerseyClient.resource(countriesURI);
// http://www.voxbone.com/apidoc/resource_InventoryServiceRest.html#path__country.html
ClientResponse clientResponse = webResource.queryParam(PAGE_NUMBER,"0").queryParam(PAGE_SIZE,"300").accept(CONTENT_TYPE).type(CONTENT_TYPE)
.get(ClientResponse.class);
String response = clientResponse.getEntity(String.class);
if(logger.isDebugEnabled())
logger.debug("response " + response);
JsonParser parser = new JsonParser();
JsonObject jsonResponse = parser.parse(response).getAsJsonObject();
JsonArray voxCountries = jsonResponse.get("countries").getAsJsonArray();
List countries = new ArrayList();
for (int i = 0; i < voxCountries.size(); i++) {
JsonObject country = voxCountries.get(i).getAsJsonObject();
String countryCode = country.get(COUNTRY_CODE_PARAM).getAsString();
countries.add(countryCode);
}
return countries;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy