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