diff --git a/README.md b/README.md index d3167f9..23ef529 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ## Requirements -- JDK 7 or 8 +- JDK 7+ - Maven 3.x ## How to build the jar diff --git a/pom.xml b/pom.xml index a41fb7c..13c9af8 100644 --- a/pom.xml +++ b/pom.xml @@ -6,58 +6,35 @@ com.smsglobal smglobal-java-client - 1.0-SNAPSHOT + 1.9-SNAPSHOT junit junit - 4.12 + 4.13.2 test - org.apache.httpcomponents - httpclient - 4.3.6 + org.apache.httpcomponents.client5 + httpclient5 + 5.1.3 - org.apache.httpcomponents - fluent-hc - 4.5.2 + org.apache.httpcomponents.client5 + httpclient5-fluent + 5.1.3 - com.google.code.gson - gson - 2.7 + com.fasterxml.jackson.core + jackson-databind + 2.13.3 - javax.xml.bind - jaxb-api - 2.3.0 + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + 2.13.3 - - com.sun.xml.bind - jaxb-core - 2.3.0 - - - com.sun.xml.bind - jaxb-impl - 2.3.0 - - - javax.activation - activation - 1.1.1 - - - - - commons-beanutils - commons-beanutils - 1.9.4 - - @@ -65,7 +42,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.5.1 + 3.8.1 1.8 1.8 diff --git a/src/main/java/com/smsglobal/client/AbstractHasOffsetLimitTotal.java b/src/main/java/com/smsglobal/client/AbstractHasOffsetLimitTotal.java new file mode 100644 index 0000000..8ff0531 --- /dev/null +++ b/src/main/java/com/smsglobal/client/AbstractHasOffsetLimitTotal.java @@ -0,0 +1,39 @@ +package com.smsglobal.client; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public abstract class AbstractHasOffsetLimitTotal { + + @JsonProperty("offset") + protected Integer offset; + + @JsonProperty("limit") + protected Integer limit; + + @JsonProperty("total") + protected Integer total; + + public Integer getOffset() { + return this.offset; + } + + public void setOffset(final Integer offset) { + this.offset = offset; + } + + public Integer getLimit() { + return this.limit; + } + + public void setLimit(final Integer limit) { + this.limit = limit; + } + + public Integer getTotal() { + return this.total; + } + + public void setTotal(final Integer total) { + this.total = total; + } +} diff --git a/src/main/java/com/smsglobal/client/AbstractMessages.java b/src/main/java/com/smsglobal/client/AbstractMessages.java new file mode 100644 index 0000000..c4a83f2 --- /dev/null +++ b/src/main/java/com/smsglobal/client/AbstractMessages.java @@ -0,0 +1,19 @@ +package com.smsglobal.client; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.List; + +public abstract class AbstractMessages extends AbstractHasOffsetLimitTotal { + + @JsonProperty("messages") + protected List messages; + + public List getMessages() { + return this.messages; + } + + public void setMessages(final List messages) { + this.messages = messages; + } +} diff --git a/src/main/java/com/smsglobal/client/AutoTopup.java b/src/main/java/com/smsglobal/client/AutoTopup.java new file mode 100644 index 0000000..a4ea5d1 --- /dev/null +++ b/src/main/java/com/smsglobal/client/AutoTopup.java @@ -0,0 +1,24 @@ +package com.smsglobal.client; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class AutoTopup { + + @JsonProperty("disabled") + protected Boolean disabled; + + public Boolean getDisabled() { + return this.disabled; + } + + public void setDisabled(final Boolean disabled) { + this.disabled = disabled; + } + + @Override + public String toString() { + return "AutoTopup{" + + "disabled=" + this.disabled + + '}'; + } +} diff --git a/src/main/java/com/smsglobal/client/Client.java b/src/main/java/com/smsglobal/client/Client.java deleted file mode 100644 index 24526da..0000000 --- a/src/main/java/com/smsglobal/client/Client.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.smsglobal.client; - -/** - * SMSGlobal Client - */ -public class Client { - - private Transport transport; - - public Client(Transport transport) { - this.transport = transport; - } - - public String sendMessage(Message message) throws Exception { - return transport.sendMessage(message); - } -} diff --git a/src/main/java/com/smsglobal/client/Contact.java b/src/main/java/com/smsglobal/client/Contact.java new file mode 100644 index 0000000..cca37d4 --- /dev/null +++ b/src/main/java/com/smsglobal/client/Contact.java @@ -0,0 +1,120 @@ +package com.smsglobal.client; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class Contact { + + @JsonProperty("id") + protected String id; + + @JsonProperty("name") + protected String name; + + @JsonProperty("phone") + protected String phone; + + @JsonProperty("email") + protected String email; + + @JsonProperty("address") + protected String address; + + @JsonProperty("city") + protected String city; + + @JsonProperty("state") + protected String state; + + @JsonProperty("postcode") + protected String postcode; + + @JsonProperty("country") + protected String country; + + public String getId() { + return this.id; + } + + public void setId(final String id) { + this.id = id; + } + + public String getName() { + return this.name; + } + + public void setName(final String name) { + this.name = name; + } + + public String getPhone() { + return this.phone; + } + + public void setPhone(final String phone) { + this.phone = phone; + } + + public String getEmail() { + return this.email; + } + + public void setEmail(final String email) { + this.email = email; + } + + public String getAddress() { + return this.address; + } + + public void setAddress(final String address) { + this.address = address; + } + + public String getCity() { + return this.city; + } + + public void setCity(final String city) { + this.city = city; + } + + public String getState() { + return this.state; + } + + public void setState(final String state) { + this.state = state; + } + + public String getPostcode() { + return this.postcode; + } + + public void setPostcode(final String postcode) { + this.postcode = postcode; + } + + public String getCountry() { + return this.country; + } + + public void setCountry(final String country) { + this.country = country; + } + + @Override + public String toString() { + return "Contact{" + + "id=" + this.id + + ", name='" + this.name + '\'' + + ", phone='" + this.phone + '\'' + + ", email='" + this.email + '\'' + + ", address='" + this.address + '\'' + + ", city='" + this.city + '\'' + + ", state='" + this.state + '\'' + + ", postcode='" + this.postcode + '\'' + + ", country='" + this.country + '\'' + + '}'; + } +} diff --git a/src/main/java/com/smsglobal/client/ContactGroup.java b/src/main/java/com/smsglobal/client/ContactGroup.java new file mode 100644 index 0000000..4f366bf --- /dev/null +++ b/src/main/java/com/smsglobal/client/ContactGroup.java @@ -0,0 +1,84 @@ +package com.smsglobal.client; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class ContactGroup { + + @JsonProperty("id") + protected String id; + + @JsonProperty("name") + protected String name; + + @JsonProperty("keyword") + protected String keyword; + + @JsonProperty("isGlobal") + protected Boolean global; + + @JsonProperty("contactCount") + protected Integer contactCount; + + @JsonProperty("defaultOrigin") + protected String defaultOrigin; + + public String getId() { + return this.id; + } + + public void setId(final String id) { + this.id = id; + } + + public String getName() { + return this.name; + } + + public void setName(final String name) { + this.name = name; + } + + public String getKeyword() { + return this.keyword; + } + + public void setKeyword(final String keyword) { + this.keyword = keyword; + } + + public Boolean getGlobal() { + return this.global; + } + + public void setGlobal(final Boolean global) { + this.global = global; + } + + public Integer getContactCount() { + return this.contactCount; + } + + public void setContactCount(final Integer contactCount) { + this.contactCount = contactCount; + } + + public String getDefaultOrigin() { + return this.defaultOrigin; + } + + public void setDefaultOrigin(final String defaultOrigin) { + this.defaultOrigin = defaultOrigin; + } + + @Override + public String toString() { + return "ContactGroup{" + + "id=" + this.id + + ", name='" + this.name + '\'' + + ", keyword='" + this.keyword + '\'' + + ", global=" + this.global + + ", contactCount=" + this.contactCount + + ", defaultOrigin='" + this.defaultOrigin + '\'' + + '}'; + } +} diff --git a/src/main/java/com/smsglobal/client/ContactGroups.java b/src/main/java/com/smsglobal/client/ContactGroups.java new file mode 100644 index 0000000..ec5d512 --- /dev/null +++ b/src/main/java/com/smsglobal/client/ContactGroups.java @@ -0,0 +1,29 @@ +package com.smsglobal.client; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.List; + +public class ContactGroups extends AbstractHasOffsetLimitTotal { + + @JsonProperty("group") + protected List contactGroups; + + public List getGroups() { + return this.contactGroups; + } + + public void setGroups(final List contactGroups) { + this.contactGroups = contactGroups; + } + + @Override + public String toString() { + return "ContactGroups{" + + "offset=" + this.offset + + ", limit=" + this.limit + + ", total=" + this.total + + ", contactGroups=" + this.contactGroups + + '}'; + } +} diff --git a/src/main/java/com/smsglobal/client/CreditBalance.java b/src/main/java/com/smsglobal/client/CreditBalance.java new file mode 100644 index 0000000..b8cf483 --- /dev/null +++ b/src/main/java/com/smsglobal/client/CreditBalance.java @@ -0,0 +1,38 @@ +package com.smsglobal.client; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.math.BigDecimal; + +public class CreditBalance { + + @JsonProperty("balance") + protected BigDecimal balance; + + @JsonProperty("currency") + protected String currency; + + public BigDecimal getBalance() { + return this.balance; + } + + public void setBalance(final BigDecimal balance) { + this.balance = balance; + } + + public String getCurrency() { + return this.currency; + } + + public void setCurrency(final String currency) { + this.currency = currency; + } + + @Override + public String toString() { + return "CreditBalance{" + + "balance=" + this.balance + + ", currency='" + this.currency + '\'' + + '}'; + } +} diff --git a/src/main/java/com/smsglobal/client/DedicatedNumbers.java b/src/main/java/com/smsglobal/client/DedicatedNumbers.java new file mode 100644 index 0000000..6a84a79 --- /dev/null +++ b/src/main/java/com/smsglobal/client/DedicatedNumbers.java @@ -0,0 +1,26 @@ +package com.smsglobal.client; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.List; + +public class DedicatedNumbers { + + @JsonProperty("dedicatedNumbers") + protected List dedicatedNumbers; + + public List getDedicatedNumbers() { + return this.dedicatedNumbers; + } + + public void setDedicatedNumbers(final List dedicatedNumbers) { + this.dedicatedNumbers = dedicatedNumbers; + } + + @Override + public String toString() { + return "DedicatedNumbers{" + + "dedicatedNumbers=" + this.dedicatedNumbers + + '}'; + } +} diff --git a/src/main/java/com/smsglobal/client/HttpStatusCodeException.java b/src/main/java/com/smsglobal/client/HttpStatusCodeException.java new file mode 100644 index 0000000..69d37b5 --- /dev/null +++ b/src/main/java/com/smsglobal/client/HttpStatusCodeException.java @@ -0,0 +1,28 @@ +package com.smsglobal.client; + +public class HttpStatusCodeException extends Exception { + + protected final int statusCode; + protected final String reasonPhrase; + protected final String body; + + public HttpStatusCodeException(final int statusCode, final String reasonPhrase, final String body) { + super(statusCode + " " + reasonPhrase + " " + body); + + this.statusCode = statusCode; + this.reasonPhrase = reasonPhrase; + this.body = body; + } + + public int getStatusCode() { + return this.statusCode; + } + + public String getReasonPhrase() { + return this.reasonPhrase; + } + + public String getBody() { + return this.body; + } +} diff --git a/src/main/java/com/smsglobal/client/IncomingMessages.java b/src/main/java/com/smsglobal/client/IncomingMessages.java new file mode 100644 index 0000000..d79ef17 --- /dev/null +++ b/src/main/java/com/smsglobal/client/IncomingMessages.java @@ -0,0 +1,14 @@ +package com.smsglobal.client; + +public class IncomingMessages extends AbstractMessages { + + @Override + public String toString() { + return "IncomingMessages{" + + "offset=" + this.offset + + ", limit=" + this.limit + + ", total=" + this.total + + ", messages=" + this.messages + + '}'; + } +} diff --git a/src/main/java/com/smsglobal/client/LowBalanceAlerts.java b/src/main/java/com/smsglobal/client/LowBalanceAlerts.java new file mode 100644 index 0000000..549077c --- /dev/null +++ b/src/main/java/com/smsglobal/client/LowBalanceAlerts.java @@ -0,0 +1,50 @@ +package com.smsglobal.client; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.math.BigDecimal; + +public class LowBalanceAlerts { + + @JsonProperty("enabled") + protected Boolean enabled; + + @JsonProperty("threshold") + protected BigDecimal threshold; + + @JsonProperty("sendto") + protected String sendto; + + public Boolean getEnabled() { + return this.enabled; + } + + public void setEnabled(final Boolean enabled) { + this.enabled = enabled; + } + + public BigDecimal getThreshold() { + return this.threshold; + } + + public void setThreshold(final BigDecimal threshold) { + this.threshold = threshold; + } + + public String getSendto() { + return this.sendto; + } + + public void setSendto(final String sendto) { + this.sendto = sendto; + } + + @Override + public String toString() { + return "LowBalanceAlerts{" + + "enabled=" + this.enabled + + ", threshold=" + this.threshold + + ", sendto='" + this.sendto + '\'' + + '}'; + } +} diff --git a/src/main/java/com/smsglobal/client/Message.java b/src/main/java/com/smsglobal/client/Message.java index 40cb8ac..822f5b6 100644 --- a/src/main/java/com/smsglobal/client/Message.java +++ b/src/main/java/com/smsglobal/client/Message.java @@ -1,70 +1,186 @@ package com.smsglobal.client; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.time.Instant; /** * SMSGlobal Message */ -@XmlRootElement +@JsonInclude(JsonInclude.Include.NON_NULL) public class Message { - private String origin; - private String destination; - private String message; - private Integer maxSplit; - private Date scheduled; + @JsonProperty("origin") + protected String origin; + + @JsonProperty("destination") + protected String destination; + + @JsonProperty("message") + protected String message; + + @JsonProperty("notifyUrl") + protected String notifyUrl; + + @JsonProperty("incomingUrl") + protected String incomingUrl; + + @JsonProperty("id") + protected String id; + + @JsonProperty("outgoing_id") + protected String outgoingId; + + @JsonProperty("isUnicode") + protected Boolean unicode; + + @JsonProperty("status") + protected MessageStatus status; + + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "uuuu-MM-dd HH:mm:ss Z") + @JsonProperty("dateTime") + protected Instant dateTime; + + @JsonProperty("isMultipart") + protected Boolean multipart; + + @JsonProperty("partNumber") + protected Integer partNumber; + + @JsonProperty("totalParts") + protected Integer totalParts; public Message() { } - public Message(String origin, String destination, String message) { + public Message(final String origin, final String destination, final String message) { this.origin = origin; this.destination = destination; this.message = message; } public String getOrigin() { - return origin; + return this.origin; } - @XmlElement - public void setOrigin(String origin) { + public void setOrigin(final String origin) { this.origin = origin; } public String getDestination() { - return destination; + return this.destination; } - @XmlElement - public void setDestination(String destination) { + public void setDestination(final String destination) { this.destination = destination; } public String getMessage() { - return message; + return this.message; } - @XmlElement - public void setMessage(String message) { + public void setMessage(final String message) { this.message = message; } - public Integer getMaxSplit() { - return maxSplit; + public String getNotifyUrl() { + return this.notifyUrl; + } + + public void setNotifyUrl(final String notifyUrl) { + this.notifyUrl = notifyUrl; + } + + public String getIncomingUrl() { + return this.incomingUrl; + } + + public void setIncomingUrl(final String incomingUrl) { + this.incomingUrl = incomingUrl; + } + + public String getId() { + return this.id; + } + + public void setId(final String id) { + this.id = id; + } + + public String getOutgoingId() { + return this.outgoingId; + } + + public void setOutgoingId(final String outgoingId) { + this.outgoingId = outgoingId; + } + + public Boolean getUnicode() { + return this.unicode; + } + + public void setUnicode(final Boolean unicode) { + this.unicode = unicode; + } + + public MessageStatus getStatus() { + return this.status; + } + + public void setStatus(final MessageStatus status) { + this.status = status; + } + + public Instant getDateTime() { + return this.dateTime; + } + + public void setDateTime(final Instant dateTime) { + this.dateTime = dateTime; + } + + public Boolean getMultipart() { + return this.multipart; + } + + public void setMultipart(final Boolean multipart) { + this.multipart = multipart; + } + + public Integer getPartNumber() { + return this.partNumber; + } + + public void setPartNumber(final Integer partNumber) { + this.partNumber = partNumber; } - public void setMaxSplit(Integer maxSplit) { - this.maxSplit = maxSplit; + public Integer getTotalParts() { + return this.totalParts; } - public Date getScheduled() { - return scheduled; + public void setTotalParts(final Integer totalParts) { + this.totalParts = totalParts; } - public void setScheduled(Date scheduled) { - this.scheduled = scheduled; + @Override + public String toString() { + return "Message{" + + "origin='" + this.origin + '\'' + + ", destination='" + this.destination + '\'' + + ", message='" + this.message + '\'' + + ", notifyUrl='" + this.notifyUrl + '\'' + + ", incomingUrl='" + this.incomingUrl + '\'' + + ", id='" + this.id + '\'' + + ", outgoingId='" + this.outgoingId + '\'' + + ", unicode=" + this.unicode + + ", status=" + this.status + + ", dateTime=" + this.dateTime + + ", multipart=" + this.multipart + + ", partNumber=" + this.partNumber + + ", totalParts=" + this.totalParts + + '}'; } } diff --git a/src/main/java/com/smsglobal/client/MessageStatus.java b/src/main/java/com/smsglobal/client/MessageStatus.java new file mode 100644 index 0000000..c394428 --- /dev/null +++ b/src/main/java/com/smsglobal/client/MessageStatus.java @@ -0,0 +1,19 @@ +package com.smsglobal.client; + +import com.fasterxml.jackson.annotation.JsonEnumDefaultValue; +import com.fasterxml.jackson.annotation.JsonProperty; + +public enum MessageStatus { + + @JsonProperty("delivered") DELIVERED, + @JsonProperty("sent") SENT, + @JsonProperty("scheduled") SCHEDULED, + @JsonProperty("noCredits") NO_CREDITS, + @JsonProperty("invalidNumber") INVALID_NUMBER, + @JsonProperty("undelivered") UNDELIVERED, + @JsonProperty("rejected") REJECTED, + @JsonProperty("expired") EXPIRED, + @JsonProperty("Error 1002") ERROR_1002, + @JsonProperty("Error 255") ERROR_255, + @JsonEnumDefaultValue UNKNOWN +} diff --git a/src/main/java/com/smsglobal/client/Optout.java b/src/main/java/com/smsglobal/client/Optout.java new file mode 100644 index 0000000..9658f16 --- /dev/null +++ b/src/main/java/com/smsglobal/client/Optout.java @@ -0,0 +1,38 @@ +package com.smsglobal.client; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.time.LocalDate; + +public class Optout { + + @JsonProperty("date") + protected LocalDate date; + + @JsonProperty("number") + protected String number; + + public LocalDate getDate() { + return this.date; + } + + public void setDate(final LocalDate date) { + this.date = date; + } + + public String getNumber() { + return this.number; + } + + public void setNumber(final String number) { + this.number = number; + } + + @Override + public String toString() { + return "Optout{" + + "date=" + this.date + + ", number='" + this.number + '\'' + + '}'; + } +} diff --git a/src/main/java/com/smsglobal/client/Optouts.java b/src/main/java/com/smsglobal/client/Optouts.java new file mode 100644 index 0000000..363f0a5 --- /dev/null +++ b/src/main/java/com/smsglobal/client/Optouts.java @@ -0,0 +1,29 @@ +package com.smsglobal.client; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.List; + +public class Optouts extends AbstractHasOffsetLimitTotal { + + @JsonProperty("optouts") + protected List optouts; + + public List getOptouts() { + return this.optouts; + } + + public void setOptouts(final List optouts) { + this.optouts = optouts; + } + + @Override + public String toString() { + return "Optouts{" + + "offset=" + this.offset + + ", limit=" + this.limit + + ", total=" + this.total + + ", optouts=" + this.optouts + + '}'; + } +} diff --git a/src/main/java/com/smsglobal/client/OutgoingMessages.java b/src/main/java/com/smsglobal/client/OutgoingMessages.java new file mode 100644 index 0000000..6a7264d --- /dev/null +++ b/src/main/java/com/smsglobal/client/OutgoingMessages.java @@ -0,0 +1,14 @@ +package com.smsglobal.client; + +public class OutgoingMessages extends AbstractMessages { + + @Override + public String toString() { + return "OutgoingMessages{" + + "offset=" + this.offset + + ", limit=" + this.limit + + ", total=" + this.total + + ", messages=" + this.messages + + '}'; + } +} diff --git a/src/main/java/com/smsglobal/client/Response.java b/src/main/java/com/smsglobal/client/Response.java deleted file mode 100644 index 7b27fe7..0000000 --- a/src/main/java/com/smsglobal/client/Response.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.smsglobal.client; - -/** - * Transport response - */ -public class Response { -} diff --git a/src/main/java/com/smsglobal/client/SharedPools.java b/src/main/java/com/smsglobal/client/SharedPools.java new file mode 100644 index 0000000..8f72f7c --- /dev/null +++ b/src/main/java/com/smsglobal/client/SharedPools.java @@ -0,0 +1,26 @@ +package com.smsglobal.client; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.List; + +public class SharedPools { + + @JsonProperty("SharedPools") + protected List sharedPools; + + public List getSharedPools() { + return this.sharedPools; + } + + public void setSharedPools(final List sharedPools) { + this.sharedPools = sharedPools; + } + + @Override + public String toString() { + return "SharedPools{" + + "sharedPools=" + this.sharedPools + + '}'; + } +} diff --git a/src/main/java/com/smsglobal/client/Transport.java b/src/main/java/com/smsglobal/client/Transport.java deleted file mode 100644 index 8ecc9a5..0000000 --- a/src/main/java/com/smsglobal/client/Transport.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.smsglobal.client; - -/** - * SMSGlobal Transport - */ -public interface Transport { - - String sendMessage(Message message) throws Exception; - -} diff --git a/src/main/java/com/smsglobal/client/VerifiedNumbers.java b/src/main/java/com/smsglobal/client/VerifiedNumbers.java new file mode 100644 index 0000000..f890202 --- /dev/null +++ b/src/main/java/com/smsglobal/client/VerifiedNumbers.java @@ -0,0 +1,26 @@ +package com.smsglobal.client; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.List; + +public class VerifiedNumbers { + + @JsonProperty("numbers") + protected List numbers; + + public List getNumbers() { + return this.numbers; + } + + public void setNumbers(final List numbers) { + this.numbers = numbers; + } + + @Override + public String toString() { + return "VerifiedNumbers{" + + "numbers=" + this.numbers + + '}'; + } +} diff --git a/src/main/java/com/smsglobal/examples/HttpExample.java b/src/main/java/com/smsglobal/examples/HttpExample.java index 7bfbe29..20dc32e 100644 --- a/src/main/java/com/smsglobal/examples/HttpExample.java +++ b/src/main/java/com/smsglobal/examples/HttpExample.java @@ -1,6 +1,5 @@ package com.smsglobal.examples; -import com.smsglobal.client.Client; import com.smsglobal.client.Message; import com.smsglobal.transport.HttpTransport; @@ -9,13 +8,11 @@ */ public class HttpExample { - public static void main(String [ ] args) throws Exception { - Message message = new Message("SGTest", "614xx", "Build url test"); - HttpTransport httpTransport = new HttpTransport("xx", "xx", "https://www.smsglobal.com/http-api.php"); + public static void main(final String[] args) throws Exception { + final Message message = new Message("SGTest", "614xx", "Build url test"); + final HttpTransport httpTransport = new HttpTransport("xx", "xx", "https://www.smsglobal.com/http-api.php"); System.out.println(httpTransport.buildUrl(message)); - Client client = new Client(httpTransport); - String response = client.sendMessage(message); + final String response = httpTransport.sendMessage(message); System.out.println(response); } - } diff --git a/src/main/java/com/smsglobal/examples/RestExample.java b/src/main/java/com/smsglobal/examples/RestExample.java index 8b8cf2c..20f4183 100644 --- a/src/main/java/com/smsglobal/examples/RestExample.java +++ b/src/main/java/com/smsglobal/examples/RestExample.java @@ -1,63 +1,30 @@ package com.smsglobal.examples; -import com.smsglobal.client.Client; import com.smsglobal.client.Message; import com.smsglobal.transport.RestTransport; -import org.apache.commons.beanutils.PropertyUtils; -import org.apache.http.HttpHost; -import org.apache.http.conn.ConnectTimeoutException; -import org.apache.http.conn.ssl.SSLConnectionSocketFactory; -import org.apache.http.conn.ssl.SSLContexts; -import org.apache.http.protocol.HttpContext; - -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLSocket; -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.net.InetSocketAddress; -import java.net.Socket; - /** * Send message via the HTTP transport */ public class RestExample { - public static void main(String [ ] args) throws Exception { - Message message = new Message("SGTest", "61426203571", "Build url test 33"); + public static void main(final String[] args) throws Exception { + final Message message = new Message("SGTest", "61426203571", "Build url test 33"); + final RestTransport restTransport = new RestTransport( + "5d8b1fd934a10e45d8b0476e5e9776da", "3a826f541af41127353d7f87ec73d36b", "https://api.smsglobal.com/v2"); + System.out.println(restTransport.getBaseUrl()); + System.out.println(message); - SSLContext sslcontext = SSLContexts.createSystemDefault(); - SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext) { - @Override - public Socket connectSocket( - int connectTimeout, - Socket socket, - HttpHost host, - InetSocketAddress remoteAddress, - InetSocketAddress localAddress, - HttpContext context) throws IOException, ConnectTimeoutException { - if (socket instanceof SSLSocket) { - try { - ((SSLSocket) socket).setEnabledProtocols(new String[] {"TLSv1.2"}); - PropertyUtils.setProperty(socket, "host", host.getHostName()); - } catch (NoSuchMethodException ex) { - } catch (IllegalAccessException ex) { - } catch (InvocationTargetException ex) { - } - } - return super.connectSocket(connectTimeout, socket, host, remoteAddress, - localAddress, context); - } - }; + System.out.println("sendMessage"); + System.out.println(restTransport.sendMessage(message)); + System.out.println("getOutgoingMessages"); + System.out.println(restTransport.getOutgoingMessages(null, 1000)); - RestTransport restTransport = new RestTransport("5d8b1fd934a10e45d8b0476e5e9776da", "3a826f541af41127353d7f87ec73d36b", "https://api.smsglobal.com/v2", 443,sslsf); - restTransport.setPath("/sms/"); - System.out.println(restTransport.getBaseUrl() + restTransport.getPath()); - System.out.println(restTransport.toXml(message)); - Client client = new Client(restTransport); - String response = client.sendMessage(message); - System.out.println(response); - } + System.out.println("getIncomingMessages"); + System.out.println(restTransport.getIncomingMessages(null, null)); -} + System.out.println("getUserCreditBalance"); + System.out.println(restTransport.getUserCreditBalance()); + } +} \ No newline at end of file diff --git a/src/main/java/com/smsglobal/transport/HttpTransport.java b/src/main/java/com/smsglobal/transport/HttpTransport.java index 8e96fc3..3f19922 100644 --- a/src/main/java/com/smsglobal/transport/HttpTransport.java +++ b/src/main/java/com/smsglobal/transport/HttpTransport.java @@ -1,47 +1,54 @@ package com.smsglobal.transport; import com.smsglobal.client.Message; -import com.smsglobal.client.Transport; -import org.apache.http.client.fluent.Content; -import org.apache.http.client.fluent.Request; -import org.apache.http.client.utils.URIBuilder; +import org.apache.hc.client5.http.fluent.Content; +import org.apache.hc.client5.http.fluent.Request; +import org.apache.hc.core5.net.URIBuilder; +import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; /** * HTTP Transport + * https://www.smsglobal.com/http-api/ */ -public class HttpTransport implements Transport { +public class HttpTransport { - private String action = "sendsms"; - private String username; - private String password; - private String baseUrl; - private URI uri; + public static final String PRODUCTION_URL = "https://www.smsglobal.com/http-api.php"; - public HttpTransport(String username, String password, String baseUrl) throws URISyntaxException { + private static final String SEND_SMS_ACTION = "sendsms"; + + private final String username; + private final String password; + private final String url; + private final URI uri; + + public HttpTransport(final String username, final String password, final String url) throws URISyntaxException { this.username = username; this.password = password; - this.baseUrl = baseUrl; - this.uri = new URI(baseUrl); + this.url = url; + this.uri = new URI(url); } + public HttpTransport(final String username, final String password) throws URISyntaxException { + this(username, password, PRODUCTION_URL); + } - public String sendMessage(Message message) throws Exception { - String url = buildUrl(message); - Content response = Request.Get(url).execute().returnContent(); + public String sendMessage(final Message message) throws IOException { + final String url = buildUrl(message); + final Content response = Request.get(url).execute().returnContent(); return response.asString(); } - public String buildUrl(Message message) { - URIBuilder builder = new URIBuilder(); - builder.setScheme(uri.getScheme()); - builder.setHost(uri.getHost()); - builder.setPath(uri.getPath()); - builder.addParameter("action", action); - builder.addParameter("user", username); - builder.addParameter("password", password); + public String buildUrl(final Message message) { + final URIBuilder builder = new URIBuilder(); + builder.setScheme(this.uri.getScheme()); + builder.setHost(this.uri.getHost()); + builder.setPath(this.uri.getPath()); + builder.addParameter("action", SEND_SMS_ACTION); + builder.addParameter("user", this.username); + builder.addParameter("password", this.password); builder.addParameter("from", message.getOrigin()); builder.addParameter("to", message.getDestination()); builder.addParameter("text", message.getMessage()); @@ -49,35 +56,19 @@ public String buildUrl(Message message) { return builder.toString(); } - public String getBaseUrl() { - return baseUrl; - } - - public void setBaseUrl(String baseUrl) { - this.baseUrl = baseUrl; + public String getUrl() { + return this.url; } public URI getUri() { - return uri; - } - - public void setUri(URI uri) { - this.uri = uri; + return this.uri; } public String getUsername() { - return username; - } - - public void setUsername(String username) { - this.username = username; + return this.username; } public String getPassword() { - return password; - } - - public void setPassword(String password) { - this.password = password; + return this.password; } } diff --git a/src/main/java/com/smsglobal/transport/RestTransport.java b/src/main/java/com/smsglobal/transport/RestTransport.java index dee50ce..0a1fe9c 100644 --- a/src/main/java/com/smsglobal/transport/RestTransport.java +++ b/src/main/java/com/smsglobal/transport/RestTransport.java @@ -1,181 +1,355 @@ package com.smsglobal.transport; -import com.google.gson.Gson; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import com.smsglobal.client.AutoTopup; +import com.smsglobal.client.Contact; +import com.smsglobal.client.ContactGroups; +import com.smsglobal.client.CreditBalance; +import com.smsglobal.client.DedicatedNumbers; +import com.smsglobal.client.HttpStatusCodeException; +import com.smsglobal.client.IncomingMessages; +import com.smsglobal.client.LowBalanceAlerts; import com.smsglobal.client.Message; -import com.smsglobal.client.Transport; - - -import org.apache.http.Header; -import org.apache.http.HttpHost; -import org.apache.http.client.entity.UrlEncodedFormEntity; -import org.apache.http.client.fluent.Content; -import org.apache.http.client.fluent.Request; - -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.client.utils.URIBuilder; -import org.apache.http.conn.ssl.SSLConnectionSocketFactory; -import org.apache.http.entity.ContentType; -import org.apache.http.entity.StringEntity; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClients; - +import com.smsglobal.client.Optouts; +import com.smsglobal.client.OutgoingMessages; +import com.smsglobal.client.SharedPools; +import com.smsglobal.client.VerifiedNumbers; +import org.apache.hc.client5.http.classic.methods.HttpGet; +import org.apache.hc.client5.http.classic.methods.HttpPost; +import org.apache.hc.client5.http.config.RequestConfig; +import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; +import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse; +import org.apache.hc.client5.http.impl.classic.HttpClients; +import org.apache.hc.core5.http.ContentType; +import org.apache.hc.core5.http.HttpHeaders; +import org.apache.hc.core5.http.HttpStatus; +import org.apache.hc.core5.http.NameValuePair; +import org.apache.hc.core5.http.ParseException; +import org.apache.hc.core5.http.io.entity.EntityUtils; +import org.apache.hc.core5.http.io.entity.StringEntity; +import org.apache.hc.core5.http.message.BasicNameValuePair; +import org.apache.hc.core5.net.URIBuilder; +import org.apache.hc.core5.util.Timeout; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; - -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Marshaller; +import java.io.Closeable; import java.io.IOException; -import java.io.StringWriter; - import java.net.URI; import java.net.URISyntaxException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; import java.util.Base64; +import java.util.List; import java.util.Random; +import java.util.concurrent.TimeUnit; /** * REST Transport + * https://www.smsglobal.com/rest-api/ */ -public class RestTransport implements Transport { +public class RestTransport implements Closeable { - private String key; - private String secret; - private String baseUrl; - private URI uri; - private String version; - private String path; - private int port; - private SSLConnectionSocketFactory sslConnectionSocketFactory; + public static final String PRODUCTION_BASE_URL = "https://api.smsglobal.com/v2"; + public static final int DEFAULT_TIMEOUT_MS = 60 * 1000; - public RestTransport() throws IOException { + public static CloseableHttpClient createHttpClient(final Timeout timeout) { + final RequestConfig requestConfig = RequestConfig.custom() + .setConnectionRequestTimeout(timeout) + .setConnectTimeout(timeout) + .setResponseTimeout(timeout) + .build(); + return HttpClients.custom().setDefaultRequestConfig(requestConfig).build(); + } + public static CloseableHttpClient createHttpClient(final int timeoutMs) { + return createHttpClient(Timeout.of(timeoutMs, TimeUnit.MILLISECONDS)); } - public RestTransport(String key, String secret, String baseUrl, int port,SSLConnectionSocketFactory sslsf) throws URISyntaxException, IOException { + public static ObjectMapper createObjectMapper() { + return new ObjectMapper() + .registerModule(new JavaTimeModule()) + .enable(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_USING_DEFAULT_VALUE); + } + + private final String key; + private final String secret; + private final String baseUrl; + private final String host; + private final int port; + private final String version; + private final CloseableHttpClient httpClient; + private final ObjectMapper objectMapper; + private final Random random = new Random(); + + public RestTransport( + final String key, final String secret, final String baseUrl, final CloseableHttpClient httpClient, + final ObjectMapper objectMapper) throws URISyntaxException { + this.key = key; this.secret = secret; + this.baseUrl = baseUrl; + this.httpClient = httpClient; + this.objectMapper = objectMapper; + + final URI uri = new URI(baseUrl); + this.host = uri.getHost(); + int port = uri.getPort(); + if (port <= 0) { + final String scheme = uri.getScheme(); + switch (scheme) { + case "http": + port = 80; + break; + case "https": + port = 443; + break; + default: + throw new IllegalArgumentException(); + } + } else { + throw new IllegalArgumentException(); + } this.port = port; - this.sslConnectionSocketFactory = sslsf; - setBaseUrl(baseUrl); + final String[] paths = uri.getPath().split("/"); + this.version = paths[1]; + } + + public RestTransport( + final String key, final String secret, final CloseableHttpClient httpClient, final ObjectMapper objectMapper) throws URISyntaxException { + this(key, secret, PRODUCTION_BASE_URL, httpClient, objectMapper); } + public RestTransport(final String key, final String secret, final String baseUrl, final CloseableHttpClient httpClient) throws URISyntaxException { + this(key, secret, baseUrl, httpClient, createObjectMapper()); + } + public RestTransport(final String key, final String secret, final CloseableHttpClient httpClient) throws URISyntaxException { + this(key, secret, PRODUCTION_BASE_URL, httpClient, createObjectMapper()); + } - public String sendMessage(Message message) throws Exception { - long timestamp = System.currentTimeMillis() / 1000L; - int nonce = new Random().nextInt(); - String mac = getMac("POST", "/sms/", timestamp, nonce); - String messageXml = toXml(message); + public RestTransport(final String key, final String secret, final String baseUrl, final int timeoutMs) throws URISyntaxException { + this(key, secret, baseUrl, createHttpClient(timeoutMs)); + } - CloseableHttpClient httpclient = HttpClients.custom() - .setSSLSocketFactory(sslConnectionSocketFactory) - .build(); + public RestTransport(final String key, final String secret, final int timeoutMs) throws URISyntaxException { + this(key, secret, PRODUCTION_BASE_URL, createHttpClient(timeoutMs)); + } - HttpPost httpPost = new HttpPost(baseUrl +path); - httpPost.setHeader("Accept", "application/xml"); - httpPost.setHeader("Authorization", getAuthHeader(mac, timestamp, nonce)); - StringEntity entity =new StringEntity(messageXml); - entity.setContentType("application/xml"); - httpPost.setEntity(entity); - CloseableHttpResponse response = httpclient.execute(httpPost); - return response.toString(); + public RestTransport(final String key, final String secret, final String baseUrl) throws URISyntaxException { + this(key, secret, baseUrl, DEFAULT_TIMEOUT_MS); } - public String toXml(Message message) throws JAXBException { - JAXBContext context = JAXBContext.newInstance(Message.class); - Marshaller marshaller = context.createMarshaller(); - marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8"); - marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); - StringWriter stringWriter = new StringWriter(); - marshaller.marshal(message, stringWriter); - return stringWriter.toString(); + public RestTransport(final String key, final String secret) throws URISyntaxException { + this(key, secret, PRODUCTION_BASE_URL); } - public String toJson(Message message) { - Gson gson = new Gson(); - return gson.toJson(message); + public String getHost() { + return this.host; } - public void extractVersion() { - String[] paths = uri.getPath().split("/"); - this.version = paths[1]; + public int getPort() { + return this.port; + } + + public String getBaseUrl() { + return this.baseUrl; } public String getVersion() { - return version; + return this.version; } - public void setVersion(String version) throws URISyntaxException { - this.version = version; - URIBuilder builder = new URIBuilder(baseUrl).setPath(version); - this.baseUrl = builder.toString(); + @Override + public void close() throws IOException { + this.httpClient.close(); } - public String getMac(String httpMethod, String httpPath, long timestamp, int nonce) throws NoSuchAlgorithmException, InvalidKeyException { - Mac mac = Mac.getInstance("HmacSHA256"); - SecretKeySpec secretHash = new SecretKeySpec(secret.getBytes(), "HmacSHA256"); + public String getMac( + final String method, final String pathAndQuery, final long timestamp, final int nonce) throws NoSuchAlgorithmException, InvalidKeyException { + + final Mac mac = Mac.getInstance("HmacSHA256"); + final SecretKeySpec secretHash = new SecretKeySpec(this.secret.getBytes(), "HmacSHA256"); mac.init(secretHash); - String message = timestamp + "\n" + nonce + "\n" + httpMethod + "\n/" + version + httpPath + "\n" + uri.getHost() + "\n" + port + "\n\n"; - return Base64.getEncoder().encodeToString((mac.doFinal(message.getBytes()))); + final String message = timestamp + "\n" + + nonce + "\n" + + method + "\n/" + + this.version + pathAndQuery + "\n" + + this.host + "\n" + + this.port + "\n\n"; + return Base64.getEncoder().encodeToString(mac.doFinal(message.getBytes())); + } + + public String getAuthHeader(final String mac, final long timestamp, final int nonce) { + return "MAC id=\"" + this.key + "\", ts=\"" + timestamp + "\", nonce=\"" + nonce + "\", mac=\"" + mac + "\""; } - public String getAuthHeader(String mac, long timestamp, int nonce) { - return "MAC id=\"" + key + "\", ts=\"" + timestamp + "\", nonce=\"" + nonce + "\", mac=\"" + mac + "\""; + public String getAuthHeader(final String method, final String pathAndQuery) throws NoSuchAlgorithmException, InvalidKeyException { + final long timestamp = System.currentTimeMillis() / 1000L; + final int nonce = this.random.nextInt(); + final String mac = getMac(method, pathAndQuery, timestamp, nonce); + return getAuthHeader(mac, timestamp, nonce); } - public URI getUri() { - return uri; + private static void checkResponse(final CloseableHttpResponse httpResponse) throws HttpStatusCodeException { + final int statusCode = httpResponse.getCode(); + if (statusCode == HttpStatus.SC_OK) { + return; + } + + final String reasonPhrase = httpResponse.getReasonPhrase(); + String body = null; + try { + body = EntityUtils.toString(httpResponse.getEntity()); + } catch (final IOException | ParseException ignored) { + } + + throw new HttpStatusCodeException(statusCode, reasonPhrase, body); } - public void setUri(URI uri) { - this.uri = uri; + private T get( + final String path, final List query, + final Class responseType) throws HttpStatusCodeException, IOException, URISyntaxException, NoSuchAlgorithmException, InvalidKeyException { + + final String pathAndQuery = query != null && !query.isEmpty() ? new URIBuilder(path).addParameters(query).toString() : path; + final HttpGet httpRequest = new HttpGet(new URI(this.baseUrl + pathAndQuery)); + httpRequest.setHeader(HttpHeaders.ACCEPT, ContentType.APPLICATION_JSON.getMimeType()); + httpRequest.setHeader(HttpHeaders.AUTHORIZATION, getAuthHeader(httpRequest.getMethod(), pathAndQuery)); + try (final CloseableHttpResponse httpResponse = this.httpClient.execute(httpRequest)) { + checkResponse(httpResponse); + + return this.objectMapper.readValue(httpResponse.getEntity().getContent(), responseType); + } } - public String getKey() { - return key; + private T get( + final String path, + final Class responseType) throws HttpStatusCodeException, IOException, URISyntaxException, NoSuchAlgorithmException, InvalidKeyException { + + return get(path, null, responseType); } - public void setKey(String key) { - this.key = key; + private T post( + final String path, final List query, final U body, + final Class responseType) throws HttpStatusCodeException, IOException, URISyntaxException, NoSuchAlgorithmException, InvalidKeyException { + + final String bodyJson = this.objectMapper.writeValueAsString(body); + final String pathAndQuery = query != null && !query.isEmpty() ? new URIBuilder(path).addParameters(query).toString() : path; + final HttpPost httpRequest = new HttpPost(new URI(this.baseUrl + pathAndQuery)); + httpRequest.setHeader(HttpHeaders.ACCEPT, ContentType.APPLICATION_JSON.getMimeType()); + httpRequest.setHeader(HttpHeaders.AUTHORIZATION, getAuthHeader(httpRequest.getMethod(), pathAndQuery)); + final StringEntity entity = new StringEntity(bodyJson, ContentType.APPLICATION_JSON); + httpRequest.setEntity(entity); + try (final CloseableHttpResponse httpResponse = this.httpClient.execute(httpRequest)) { + checkResponse(httpResponse); + + return this.objectMapper.readValue(httpResponse.getEntity().getContent(), responseType); + } } - public String getSecret() { - return secret; + private T post( + final String path, final U body, + final Class responseType) throws HttpStatusCodeException, IOException, URISyntaxException, NoSuchAlgorithmException, InvalidKeyException { + + return post(path, null, body, responseType); } - public void setSecret(String secret) { - this.secret = secret; + public AutoTopup getAutoTopup() throws HttpStatusCodeException, IOException, URISyntaxException, NoSuchAlgorithmException, InvalidKeyException { + return get("/auto-topup", AutoTopup.class); } - public String getBaseUrl() { - return baseUrl; + public ContactGroups getContactGroups( + final Integer offset, + final Integer limit) throws HttpStatusCodeException, IOException, URISyntaxException, NoSuchAlgorithmException, InvalidKeyException { + + final List query = offset == null && limit == null ? null : new ArrayList<>(2); + if (offset != null) { + query.add(new BasicNameValuePair("offset", offset.toString())); + } + if (limit != null) { + query.add(new BasicNameValuePair("limit", limit.toString())); + } + return get("/group", query, ContactGroups.class); } - public void setBaseUrl(String baseUrl) throws URISyntaxException { - this.baseUrl = baseUrl; - this.uri = new URI(baseUrl); - extractVersion(); + public DedicatedNumbers getDedicatedNumbers() throws HttpStatusCodeException, IOException, URISyntaxException, NoSuchAlgorithmException, InvalidKeyException { + return get("/dedicated-number", DedicatedNumbers.class); } - public String getPath() { - return path; + public Optouts getOptOuts( + final Integer offset, + final Integer limit) throws HttpStatusCodeException, IOException, URISyntaxException, NoSuchAlgorithmException, InvalidKeyException { + + final List query = offset == null && limit == null ? null : new ArrayList<>(2); + if (offset != null) { + query.add(new BasicNameValuePair("offset", offset.toString())); + } + if (limit != null) { + query.add(new BasicNameValuePair("limit", limit.toString())); + } + return get("/opt-outs", query, Optouts.class); } - public void setPath(String path) { - this.path = path; + public SharedPools getSharedPools() throws HttpStatusCodeException, IOException, URISyntaxException, NoSuchAlgorithmException, InvalidKeyException { + return get("/sharedpool", SharedPools.class); } - public int getPort() { - return port; + public OutgoingMessages getOutgoingMessages( + final Integer offset, + final Integer limit) throws HttpStatusCodeException, IOException, URISyntaxException, NoSuchAlgorithmException, InvalidKeyException { + + final List query = offset == null && limit == null ? null : new ArrayList<>(2); + if (offset != null) { + query.add(new BasicNameValuePair("offset", offset.toString())); + } + if (limit != null) { + query.add(new BasicNameValuePair("limit", limit.toString())); + } + return get("/sms", query, OutgoingMessages.class); } - public void setPort(int port) { - this.port = port; + public OutgoingMessages sendMessage( + final Message message) throws IOException, NoSuchAlgorithmException, InvalidKeyException, HttpStatusCodeException, URISyntaxException { + + return post("/sms", message, OutgoingMessages.class); + } + + public IncomingMessages getIncomingMessages( + final Integer offset, + final Integer limit) throws HttpStatusCodeException, IOException, URISyntaxException, NoSuchAlgorithmException, InvalidKeyException { + + final List query = offset == null && limit == null ? null : new ArrayList<>(2); + if (offset != null) { + query.add(new BasicNameValuePair("offset", offset.toString())); + } + if (limit != null) { + query.add(new BasicNameValuePair("limit", limit.toString())); + } + return get("/sms-incoming", query, IncomingMessages.class); + } + + public Contact getUserBillingDetails() throws HttpStatusCodeException, IOException, URISyntaxException, NoSuchAlgorithmException, InvalidKeyException { + return get("/user/billing-details", Contact.class); + } + + public Contact getUserContactDetails() throws HttpStatusCodeException, IOException, URISyntaxException, NoSuchAlgorithmException, InvalidKeyException { + return get("/user/contact-details", Contact.class); + } + + public CreditBalance getUserCreditBalance() throws HttpStatusCodeException, IOException, URISyntaxException, NoSuchAlgorithmException, InvalidKeyException { + return get("/user/credit-balance", CreditBalance.class); + } + + public LowBalanceAlerts getUserLowBalanceAlerts() throws HttpStatusCodeException, IOException, URISyntaxException, NoSuchAlgorithmException, InvalidKeyException { + return get("/user/low-balance-alerts", LowBalanceAlerts.class); + } + + public VerifiedNumbers getUserVerifiedNumbers() throws HttpStatusCodeException, IOException, URISyntaxException, NoSuchAlgorithmException, InvalidKeyException { + return get("/user/verified-numbers", VerifiedNumbers.class); } } diff --git a/src/main/java/com/smsglobal/transport/SmppTransport.java b/src/main/java/com/smsglobal/transport/SmppTransport.java deleted file mode 100644 index 1073d96..0000000 --- a/src/main/java/com/smsglobal/transport/SmppTransport.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.smsglobal.transport; - -import com.smsglobal.client.Message; -import com.smsglobal.client.Transport; - -/** - * SMPP Transport - */ -public class SmppTransport implements Transport { - public String sendMessage(Message message) throws Exception { - return null; - } -} diff --git a/src/test/java/com/smsglobal/transport/HttpTransportTest.java b/src/test/java/com/smsglobal/transport/HttpTransportTest.java index 406df8c..8c45a0a 100644 --- a/src/test/java/com/smsglobal/transport/HttpTransportTest.java +++ b/src/test/java/com/smsglobal/transport/HttpTransportTest.java @@ -14,22 +14,23 @@ public class HttpTransportTest { @Test public void baseParameters() throws URISyntaxException { - HttpTransport httpTransport = new HttpTransport("jsiuwmkd", "kjas98sk", "https://www.smsglobal.com/http-api.php"); + final HttpTransport httpTransport = new HttpTransport("jsiuwmkd", "kjas98sk", "https://www.smsglobal.com/http-api.php"); assertEquals("jsiuwmkd", httpTransport.getUsername()); assertEquals("kjas98sk", httpTransport.getPassword()); - assertEquals("https://www.smsglobal.com/http-api.php", httpTransport.getBaseUrl()); + assertEquals("https://www.smsglobal.com/http-api.php", httpTransport.getUrl()); } @Test(expected = URISyntaxException.class) public void badUrl() throws URISyntaxException { - HttpTransport httpTransport = new HttpTransport("jsiuwmkd", "kjas98sk", "https://www.smsglobal.com/^^http-api.php"); + final HttpTransport httpTransport = new HttpTransport("jsiuwmkd", "kjas98sk", "https://www.smsglobal.com/^^http-api.php"); } @Test public void buildUrl() throws Exception { - Message message = new Message("SGTest", "61400000000", "Build url test"); - HttpTransport httpTransport = new HttpTransport("jsiuwmkd", "kjas98sk", "https://www.smsglobal.com/http-api.php"); - assertEquals("https://www.smsglobal.com/http-api.php?action=sendsms&user=jsiuwmkd&password=kjas98sk&from=SGTest&to=61400000000&text=Build+url+test", httpTransport.buildUrl(message)); + final Message message = new Message("SGTest", "61400000000", "Build url test"); + final HttpTransport httpTransport = new HttpTransport("jsiuwmkd", "kjas98sk", "https://www.smsglobal.com/http-api.php"); + assertEquals( + "https://www.smsglobal.com/http-api.php?action=sendsms&user=jsiuwmkd&password=kjas98sk&from=SGTest&to=61400000000&text=Build%20url%20test", + httpTransport.buildUrl(message)); } - } \ No newline at end of file diff --git a/src/test/java/com/smsglobal/transport/RestTransportTest.java b/src/test/java/com/smsglobal/transport/RestTransportTest.java index d89dc99..914d11e 100644 --- a/src/test/java/com/smsglobal/transport/RestTransportTest.java +++ b/src/test/java/com/smsglobal/transport/RestTransportTest.java @@ -1,113 +1,47 @@ package com.smsglobal.transport; -import com.smsglobal.client.Message; -import org.apache.commons.beanutils.PropertyUtils; -import org.apache.http.HttpHost; -import org.apache.http.conn.ConnectTimeoutException; -import org.apache.http.conn.ssl.SSLConnectionSocketFactory; -import org.apache.http.conn.ssl.SSLContexts; -import org.apache.http.protocol.HttpContext; - import org.junit.Test; -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLSocket; -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.net.InetSocketAddress; -import java.net.Socket; import java.net.URISyntaxException; -import static org.hamcrest.CoreMatchers.isA; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThat; /** * REST transport test suite */ public class RestTransportTest { - SSLContext sslcontext = SSLContexts.createSystemDefault(); - SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext) { - @Override - public Socket connectSocket( - int connectTimeout, - Socket socket, - HttpHost host, - InetSocketAddress remoteAddress, - InetSocketAddress localAddress, - HttpContext context) throws IOException, ConnectTimeoutException { - if (socket instanceof SSLSocket) { - try { - ((SSLSocket) socket).setEnabledProtocols(new String[] {"TLSv1.2"}); - PropertyUtils.setProperty(socket, "host", host.getHostName()); - } catch (NoSuchMethodException ex) { - } catch (IllegalAccessException ex) { - } catch (InvocationTargetException ex) { - } - } - return super.connectSocket(connectTimeout, socket, host, remoteAddress, - localAddress, context); - } - }; - @Test - public void baseParameters() throws URISyntaxException, IOException { - RestTransport restTransport = new RestTransport("aaaa", "bbbb", "https://api.smsglobal.com/v2", 443,sslsf); + public void baseParameters() throws URISyntaxException { + final RestTransport restTransport = new RestTransport("aaaa", "bbbb", "https://api.smsglobal.com/v2"); assertEquals("base url should be https://api.smsglobal.com/v2", "https://api.smsglobal.com/v2", restTransport.getBaseUrl()); - assertEquals("base scheme should be https", "https", restTransport.getUri().getScheme()); - assertEquals("base host should be api.smsglobal.com", "api.smsglobal.com", restTransport.getUri().getHost()); + assertEquals("base host should be api.smsglobal.com", "api.smsglobal.com", restTransport.getHost()); + assertEquals("base port should be 443", 443, restTransport.getPort()); assertEquals("base version should be v2", "v2", restTransport.getVersion()); - restTransport.setVersion("v1.1"); - assertEquals("base version should be v1.1", "v1.1", restTransport.getVersion()); } @Test - public void version() throws URISyntaxException, IOException { - RestTransport restTransport = new RestTransport("aaaa", "bbbb", "https://api.smsglobal.com/v2", 443,sslsf); - assertEquals("base version should be v2", "v2", restTransport.getVersion()); - restTransport.setVersion("v1.1"); - assertEquals("base version should be v1.1", "v1.1", restTransport.getVersion()); - restTransport.setBaseUrl("https://api.smsglobal.com/v2/some/other.stuff"); + public void version() throws URISyntaxException { + final RestTransport restTransport = new RestTransport("aaaa", "bbbb", "https://api.smsglobal.com/v2"); assertEquals("base version should be v2", "v2", restTransport.getVersion()); } @Test public void getMac() throws Exception { - RestTransport restTransport = new RestTransport("945a7aca9f05a78a194b77f76c6bb653", "a8dfa0dc19c7439914c74c6c92a95d25", "https://api.smsglobal.com/v2", 443,sslsf); - String mac = restTransport.getMac("GET", "/sms/", 1471398353, 1174249); + final RestTransport restTransport = new RestTransport( + "945a7aca9f05a78a194b77f76c6bb653", "a8dfa0dc19c7439914c74c6c92a95d25", "https://api.smsglobal.com/v2"); + final String mac = restTransport.getMac("GET", "/sms/", 1471398353, 1174249); assertEquals("iX34qsNi2hqcoeNVtA/W5D+Hj6eMO3mIThfcYNJPaPM=", mac); } @Test public void getAuthHeader() throws Exception { - RestTransport restTransport = new RestTransport("945a7aca9f05a78a194b77f76c6bb653", "a8dfa0dc19c7439914c74c6c92a95d25", "https://api.smsglobal.com/v2", 443,sslsf); - String mac = restTransport.getMac("GET", "/sms/", 1471398353, 1174249); - String authHeader = restTransport.getAuthHeader(mac, 1471398353, 1174249); - assertEquals("MAC id=\"945a7aca9f05a78a194b77f76c6bb653\", ts=\"1471398353\", nonce=\"1174249\", mac=\"iX34qsNi2hqcoeNVtA/W5D+Hj6eMO3mIThfcYNJPaPM=\"", authHeader); - } - - @Test - public void toXml() throws Exception { - RestTransport transport = new RestTransport(); - Message message = new Message("1111", "2222", "Test message"); - String actual = transport.toXml(message); - String expected = "\n" + - "\n" + - " 2222\n" + - " Test message\n" + - " 1111\n" + - "\n"; - assertEquals(expected, actual); + final RestTransport restTransport = new RestTransport( + "945a7aca9f05a78a194b77f76c6bb653", "a8dfa0dc19c7439914c74c6c92a95d25", "https://api.smsglobal.com/v2"); + final String mac = restTransport.getMac("GET", "/sms/", 1471398353, 1174249); + final String authHeader = restTransport.getAuthHeader(mac, 1471398353, 1174249); + assertEquals( + "MAC id=\"945a7aca9f05a78a194b77f76c6bb653\", ts=\"1471398353\", nonce=\"1174249\", mac=\"iX34qsNi2hqcoeNVtA/W5D+Hj6eMO3mIThfcYNJPaPM=\"", + authHeader); } - - @Test - public void toJson() throws Exception { - RestTransport transport = new RestTransport(); - Message message = new Message("1111", "2222", "Test message"); - String actual = transport.toJson(message); - String expected = "{\"origin\":\"1111\",\"destination\":\"2222\",\"message\":\"Test message\"}"; - assertEquals(expected, actual); - } - } \ No newline at end of file