diff --git a/README.md b/README.md index e594336..d6e4b43 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,27 @@ the different api endpoints. It can be done as follows: This instance can then used to query the different endpoints and obtain responses. Different types of queries are available for different scenarios. Illustrations of each are specified below: +### Offers Query (WIP) +This is a new feature planned for API v3 and under development. As of now, it is not available for public consumption. +If anyone is interested to understand the details please contact bala@indix.com. + +The following example shows how to query for offers. It retrieves a list of offers matching the given sql query. + +```java + try { + SqlQuery sqlQuery = QueryFactory.newSqlQuery() + .withSql("select salePrice from offers where salePrice > 100"); + + OffersResult or = indixApiClient.getOffers(sqlQuery); + System.out.println(or.getCount()); + for (Offer o : or.getOffers()) { + System.out.println("\t" + o.getSalePrice()); + } + } finally { + indixApiClient.close(); + } +``` + ### Metadata Query The following example shows how to list all stores, along with their IDs, matching the query term @@ -89,7 +110,7 @@ query parameters with their offers and catalog info across stores } ``` -### Search Query +### Product Details Query The following example shows how to search for product details of a particular product with given mpid. It returns summary information for a product. diff --git a/pom.xml b/pom.xml index 5c484a1..b1a0444 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ com.indix.api apiv2-java-client - 1.1.0 + 1.1.0-SNAPSHOT jar Indix API-V2 Java Client Java client which is used to access API V2 endpoints diff --git a/src/main/java/com/indix/client/IndixApiClient.java b/src/main/java/com/indix/client/IndixApiClient.java index 3944205..2e742c7 100644 --- a/src/main/java/com/indix/client/IndixApiClient.java +++ b/src/main/java/com/indix/client/IndixApiClient.java @@ -5,5 +5,5 @@ /** * Indix Api Client */ -public interface IndixApiClient extends SearchApi, ProductDetailsApi, MetadataApi, SuggestionsApi, BulkQueryApi, Closeable { +public interface IndixApiClient extends SearchApi, ProductDetailsApi, MetadataApi, SuggestionsApi, BulkQueryApi, OffersApi, Closeable { } diff --git a/src/main/java/com/indix/client/OffersApi.java b/src/main/java/com/indix/client/OffersApi.java new file mode 100644 index 0000000..0d81ebc --- /dev/null +++ b/src/main/java/com/indix/client/OffersApi.java @@ -0,0 +1,18 @@ +package com.indix.client; + +import com.indix.exception.IndixApiException; +import com.indix.models.offersResult.OffersResult; +import com.indix.query.SqlQuery; + +import java.io.IOException; +import java.net.URISyntaxException; + +public interface OffersApi { + /** + * Offers - Retrieves a list of offers matching the given sql query + * @param query Instance of {@link SqlQuery} + * @return {@link OffersResult} + * @throws {@link IndixApiException} + */ + OffersResult getOffers(SqlQuery query) throws IndixApiException, IOException, URISyntaxException; +} diff --git a/src/main/java/com/indix/client/impl/IndixApiClientImpl.java b/src/main/java/com/indix/client/impl/IndixApiClientImpl.java index 7595c8a..94d5389 100644 --- a/src/main/java/com/indix/client/impl/IndixApiClientImpl.java +++ b/src/main/java/com/indix/client/impl/IndixApiClientImpl.java @@ -14,6 +14,7 @@ import com.indix.models.metadataResult.BrandsResult; import com.indix.models.metadataResult.CategoriesResult; import com.indix.models.metadataResult.StoresResult; +import com.indix.models.offersResult.OffersResult; import com.indix.models.productDetailsResult.*; import com.indix.models.searchResult.*; import com.indix.models.suggestions.SuggestionsResult; @@ -150,6 +151,12 @@ private String executePOST(String resource, Query searchQuery, File file) return httpClient.POST(uri, params, file); } + private String executePOST(String resource, SqlQuery sqlQuery) + throws URISyntaxException, IOException, IndixApiException { + URI uri = buildURI(resource, sqlQuery); + return httpClient.POST(uri, sqlQuery.getContent()); + } + static String buildPath(String... pathFragments) { StringBuilder sb = new StringBuilder(); @@ -184,6 +191,10 @@ private static String buildBulkJobDownloadPath(String resource, String jobId) { return buildPath(resource, jobId, DOWNLOAD_PATH); } + private static String buildOffersResourcePath() { + return buildPath(VERSION_3, OFFERS_RESOURCE); + } + // response handlers // /** @@ -632,6 +643,30 @@ public JobInfo postBulkJob(ProductsViewType productsViewType, BulkProductsQuery } } + /** + * Posts the sql query for processing + * + * @param query Instance of {@link SqlQuery} with appropriate parameters + * @return {@link OffersResult} + * @throws {@link IndixApiException} + */ + public OffersResult getOffers(SqlQuery query) + throws IndixApiException, IOException, URISyntaxException { + String resource = buildOffersResourcePath(); + try { + String content = executePOST(resource, query); + IndixApiResponse offersResponse = jsonMapper.readValue(content, + new TypeReference>() {}); + return offersResponse.getResult(); + } catch (IndixApiException iae) { + logger.error("getOffers failed: " + iae.getMessage()); + throw iae; + } catch (JsonProcessingException e) { + logger.error("getOffers failed: " + e.getMessage()); + throw new InternalServerException(e); + } + } + /** * Posts a bulk job for the appropriate resource type for lookup cases * diff --git a/src/main/java/com/indix/client/impl/IndixApiConstants.java b/src/main/java/com/indix/client/impl/IndixApiConstants.java index 8f73faa..41fe744 100644 --- a/src/main/java/com/indix/client/impl/IndixApiConstants.java +++ b/src/main/java/com/indix/client/impl/IndixApiConstants.java @@ -7,6 +7,7 @@ class IndixApiConstants { static final String SCHEME = "https"; static final String HOST = "api.indix.com"; static final String VERSION = "v2"; + static final String VERSION_3 = "v3"; static final String BULK = "bulk"; static final String JOB_VIEW = "jobs"; @@ -14,6 +15,7 @@ class IndixApiConstants { static final String LOOKUP_VIEW = "lookup"; static final String PRODUCTS_RESOURCE = "products"; + static final String OFFERS_RESOURCE = "offers"; static final String STORES_RESOURCE = buildPath(VERSION, "stores"); static final String BRANDS_RESOURCE = buildPath(VERSION, "brands"); static final String CATEGORIES_RESOURCE = buildPath(VERSION, "categories"); diff --git a/src/main/java/com/indix/httpClient/HttpClient.java b/src/main/java/com/indix/httpClient/HttpClient.java index 5d01edc..e19d1ba 100644 --- a/src/main/java/com/indix/httpClient/HttpClient.java +++ b/src/main/java/com/indix/httpClient/HttpClient.java @@ -32,5 +32,10 @@ public interface HttpClient extends Closeable { */ String POST(URI uri, List params , File file) throws IOException, IndixApiException; + /** + * Executes a string entity (mime type as text/plain) POST request and retrieves the response body as String + */ + String POST(URI uri, String content) throws IOException, IndixApiException; + void close() throws IOException; } diff --git a/src/main/java/com/indix/httpClient/impl/HttpClientImpl.java b/src/main/java/com/indix/httpClient/impl/HttpClientImpl.java index 8f69702..658a696 100644 --- a/src/main/java/com/indix/httpClient/impl/HttpClientImpl.java +++ b/src/main/java/com/indix/httpClient/impl/HttpClientImpl.java @@ -10,6 +10,8 @@ import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpRequestBase; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; import org.apache.http.entity.mime.HttpMultipartMode; import org.apache.http.entity.mime.MultipartEntityBuilder; import org.apache.http.entity.mime.content.FileBody; @@ -21,6 +23,7 @@ import java.io.IOException; import java.io.InputStream; import java.net.URI; +import java.nio.charset.StandardCharsets; import java.util.List; /** @@ -175,6 +178,29 @@ public String POST(URI uri, List params, File file) throws IOExce } } + /** + * Executes HTTP POST request, processing content as string entity + * + * @param uri - The URI against which the request is to be sent + * @param content - The body to be sent as text/plain mime type + * @return the response to the request + * @throws IOException + * @throws {@link IndixApiException} + */ + public String POST(URI uri, String content) throws IOException, IndixApiException { + // build post request + // + HttpPost httpPost = new HttpPost(uri); + ContentType contentType = ContentType.create(ContentType.TEXT_PLAIN.getMimeType(), StandardCharsets.UTF_8); + httpPost.setEntity(new StringEntity(content, contentType)); + + // process request + // + try(CloseableHttpResponse response = getResponse(httpPost)) { + return EntityUtils.toString(response.getEntity()); + } + } + /** * Close the particular http client instance */ diff --git a/src/main/java/com/indix/models/offer/Offer.java b/src/main/java/com/indix/models/offer/Offer.java new file mode 100644 index 0000000..d1adc50 --- /dev/null +++ b/src/main/java/com/indix/models/offer/Offer.java @@ -0,0 +1,72 @@ +package com.indix.models.offer; + +import java.util.List; + +public class Offer { + + private double minSalePrice; + private double minListPrice; + private String availability; + private String fulfilledBy; + private String pid; + private String productUrl; + private String imageUrl; + private List additionalImageUrls; + private String seller; + private List mpns; + private List upcs; + private String sku; + private long lastRecordedAt; + + public String getPid() { + return pid; + } + + public String getProductUrl() { + return productUrl; + } + + public String getImageUrl() { + return imageUrl; + } + + public List getAdditionalImageUrls() { + return additionalImageUrls; + } + + public String getSeller() { + return seller; + } + + public List getMpns() { + return mpns; + } + + public List getUpcs() { + return upcs; + } + + public String getSku() { + return sku; + } + + public long getLastRecordedAt() { + return lastRecordedAt; + } + + public double getMinSalePrice() { + return minSalePrice; + } + + public double getMinListPrice() { + return minListPrice; + } + + public String getAvailability() { + return availability; + } + + public String getFulfilledBy() { + return fulfilledBy; + } +} diff --git a/src/main/java/com/indix/models/offersResult/OffersResult.java b/src/main/java/com/indix/models/offersResult/OffersResult.java new file mode 100644 index 0000000..6a0c8f0 --- /dev/null +++ b/src/main/java/com/indix/models/offersResult/OffersResult.java @@ -0,0 +1,18 @@ +package com.indix.models.offersResult; + +import com.indix.models.offer.Offer; + +import java.util.List; + +public class OffersResult { + private int count; + private List offers; + + public int getCount() { + return count; + } + + public List getOffers() { + return offers; + } +} diff --git a/src/main/java/com/indix/query/QueryFactory.java b/src/main/java/com/indix/query/QueryFactory.java index 63d747c..a4fd618 100644 --- a/src/main/java/com/indix/query/QueryFactory.java +++ b/src/main/java/com/indix/query/QueryFactory.java @@ -9,6 +9,13 @@ public static SearchQuery newSearchQuery() { return new SearchQuery(); } + /** + * @return {@link SqlQuery} + */ + public static SqlQuery newSqlQuery() { + return new SqlQuery(); + } + /** * @return {@link ProductDetailsQuery} */ diff --git a/src/main/java/com/indix/query/SqlQuery.java b/src/main/java/com/indix/query/SqlQuery.java new file mode 100644 index 0000000..2fb5820 --- /dev/null +++ b/src/main/java/com/indix/query/SqlQuery.java @@ -0,0 +1,28 @@ +package com.indix.query; + +public class SqlQuery extends QueryBase { + String sql; + + public SqlQuery() { + super(); + sql = ""; + } + + /** + * provide the sql query + * @param sql input sql string + * @return sql query + */ + public SqlQuery withSql(String sql) { + this.sql = sql; + return this; + } + + /** + * retrieve content + * @return string content + */ + public String getContent() { + return sql; + } +} diff --git a/src/test/java/com/indix/client/MockExceptionHttpClient.java b/src/test/java/com/indix/client/MockExceptionHttpClient.java index 8bebc67..3c19900 100644 --- a/src/test/java/com/indix/client/MockExceptionHttpClient.java +++ b/src/test/java/com/indix/client/MockExceptionHttpClient.java @@ -57,6 +57,10 @@ public String POST(URI uri, List nameValuePair, File file) throws return null; } + public String POST(URI uri, String content) throws IOException, IndixApiException { + return null; + } + public void close() throws IOException { } diff --git a/src/test/java/com/indix/client/MockResourceHttpClient.java b/src/test/java/com/indix/client/MockResourceHttpClient.java index 8f14f06..752cb44 100644 --- a/src/test/java/com/indix/client/MockResourceHttpClient.java +++ b/src/test/java/com/indix/client/MockResourceHttpClient.java @@ -35,6 +35,10 @@ public String POST(URI uri, List nameValuePair, File file) throws return ResourceUtils.getTestResource(getClass().getClassLoader(), resourceName); } + public String POST(URI uri, String content) throws IOException, IndixApiException { + return ResourceUtils.getTestResource(getClass().getClassLoader(), resourceName); + } + public void close() throws IOException { }