diff --git a/README.md b/README.md
index d04e378..6f17e7d 100644
--- a/README.md
+++ b/README.md
@@ -278,6 +278,17 @@ SmartAPI is a set of REST-like APIs that expose many capabilities required to bu
String response = smartConnect.candleData(requestObejct);
}
+
+ /** Search Scrip Data */
+ public void getSearchScrip(SmartConnect smartConnect) throws SmartAPIException{
+ JSONObject payload = new JSONObject();
+ payload.put("exchange", "MCX");
+ payload.put("searchscrip", "Crude");
+ String response = smartConnect.getSearchScrip(payload);
+ }
+
+ /** Logout user. */
+
/** Market Data FULL*/
public void getMarketData(SmartConnect smartConnect) {
diff --git a/pom.xml b/pom.xml
index 3d8d098..198952d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -45,6 +45,8 @@
4.4.0
1.4.0
2.27.2
+ 1.7.32
+ 1.2.6
@@ -165,8 +167,19 @@
wiremock
${wiremock.version}
-
-
+
+ org.slf4j
+ slf4j-api
+ ${slf4j-api.version}
+
+
+ ch.qos.logback
+ logback-classic
+ ${logback-classic.version}
+
+
+
+
diff --git a/src/main/java/com/angelbroking/smartapi/Routes.java b/src/main/java/com/angelbroking/smartapi/Routes.java
index 089317e..352fa11 100644
--- a/src/main/java/com/angelbroking/smartapi/Routes.java
+++ b/src/main/java/com/angelbroking/smartapi/Routes.java
@@ -44,6 +44,7 @@ public Routes() {
put("api.gtt.details", "/rest/secure/angelbroking/gtt/v1/ruleDetails");
put("api.gtt.list", "/rest/secure/angelbroking/gtt/v1/ruleList");
put("api.candle.data", "/rest/secure/angelbroking/historical/v1/getCandleData");
+ put("api.search.script.data", "/rest/secure/angelbroking/order/v1/searchScrip");
put("api.market.data", "/rest/secure/angelbroking/market/v1/quote");
}
};
diff --git a/src/main/java/com/angelbroking/smartapi/SmartConnect.java b/src/main/java/com/angelbroking/smartapi/SmartConnect.java
index efb9c8c..77f1de3 100644
--- a/src/main/java/com/angelbroking/smartapi/SmartConnect.java
+++ b/src/main/java/com/angelbroking/smartapi/SmartConnect.java
@@ -15,6 +15,8 @@
import org.json.JSONException;
import org.json.JSONObject;
+
+
import java.io.IOException;
import java.net.Proxy;
import java.util.List;
@@ -713,6 +715,30 @@ public String candleData(JSONObject params) {
}
/**
+
+ * Get Search Script Data.
+ *
+ * @param payload is Search Script params.
+ * @return returns the details of Search Script data.
+ */
+
+ public String getSearchScrip(JSONObject payload) throws SmartAPIException, IOException {
+ try {
+ String url = routes.get("api.search.script.data");
+ return smartAPIRequestHandler.postRequestJSONObject(this.apiKey, url, payload, accessToken);
+ }catch (IOException ex) {
+ log.error("{} while generating session {}", IO_EXCEPTION_OCCURRED, ex.getMessage());
+ throw new IOException(String.format("%s in generating Session %s", IO_EXCEPTION_ERROR_MSG, ex.getMessage()));
+ } catch (JSONException ex) {
+ log.error("{} while generating session {}", JSON_EXCEPTION_OCCURRED, ex.getMessage());
+ throw new JSONException(String.format("%s in generating Session %s", JSON_EXCEPTION_ERROR_MSG, ex.getMessage()));
+ } catch (SmartAPIException ex) {
+ log.error("{} while generating session {}", SMART_API_EXCEPTION_OCCURRED, ex.toString());
+ throw new SmartAPIException(String.format("%s in generating Session %s", SMART_API_EXCEPTION_ERROR_MSG, ex));
+ }
+ }
+
+/**
* Get Market Data.
*
* @param params is market data params.
@@ -732,6 +758,7 @@ public JSONObject marketData(JSONObject params) throws SmartAPIException, IOExce
} catch (JSONException ex) {
log.error("{} while placing order {}", JSON_EXCEPTION_OCCURRED, ex.getMessage());
throw new JSONException(String.format("%s in placing order %s", JSON_EXCEPTION_ERROR_MSG, ex.getMessage()));
+
}
}
@@ -754,5 +781,6 @@ public JSONObject logout() {
return null;
}
}
+
+}
-}
\ No newline at end of file
diff --git a/src/main/java/com/angelbroking/smartapi/http/SmartAPIRequestHandler.java b/src/main/java/com/angelbroking/smartapi/http/SmartAPIRequestHandler.java
index f32b3a3..a53229a 100644
--- a/src/main/java/com/angelbroking/smartapi/http/SmartAPIRequestHandler.java
+++ b/src/main/java/com/angelbroking/smartapi/http/SmartAPIRequestHandler.java
@@ -1,23 +1,7 @@
package com.angelbroking.smartapi.http;
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.net.InetAddress;
-import java.net.NetworkInterface;
-import java.net.Proxy;
-import java.net.URL;
-import java.util.Enumeration;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-
import com.angelbroking.smartapi.SmartConnect;
import com.angelbroking.smartapi.http.exceptions.SmartAPIException;
-
import okhttp3.FormBody;
import okhttp3.HttpUrl;
import okhttp3.MediaType;
@@ -26,6 +10,20 @@
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.Proxy;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
/**
* Request handler for all Http requests
@@ -374,6 +372,27 @@ public Request createJsonPostRequest(String url, JSONArray jsonArray, String api
return request;
}
+ /**
+ * Makes a POST request.
+ *
+ * @return JSONObject which is received by Smart API Trade.
+ * @param url is the endpoint to which request has to be sent.
+ * @param apiKey is the api key of the Smart API Connect app.
+ * @param accessToken is the access token obtained after successful login
+ * process.
+ * @param params is the map of params which has to be sent in the body.
+ * @throws IOException is thrown when there is a connection related error.
+ * @throws SmartAPIException is thrown for all Smart API Trade related errors.
+ * @throws JSONException is thrown for parsing errors.
+ */
+ public String postRequestJSONObject(String apiKey, String url, JSONObject params, String accessToken)
+ throws IOException, SmartAPIException, JSONException {
+ Request request = createPostRequest(apiKey, url, params, accessToken);
+ Response response = client.newCall(request).execute();
+ String body = response.body().string();
+ return new SmartAPIResponseHandler().handler(response, body);
+ }
+
/**
* Creates a PUT request.
*
diff --git a/src/main/java/com/angelbroking/smartapi/http/SmartAPIResponseHandler.java b/src/main/java/com/angelbroking/smartapi/http/SmartAPIResponseHandler.java
index 3beeaba..1f532a2 100644
--- a/src/main/java/com/angelbroking/smartapi/http/SmartAPIResponseHandler.java
+++ b/src/main/java/com/angelbroking/smartapi/http/SmartAPIResponseHandler.java
@@ -1,7 +1,14 @@
package com.angelbroking.smartapi.http;
import java.io.IOException;
-
+import java.util.List;
+
+import com.angelbroking.smartapi.http.exceptions.ApiKeyException;
+import com.angelbroking.smartapi.models.SearchScripResponseDTO;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import lombok.extern.slf4j.Slf4j;
+import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
@@ -17,22 +24,26 @@
import okhttp3.Response;
+import static com.angelbroking.smartapi.utils.Constants.APIKEY_EXCEPTION_MESSAGE;
+import static com.angelbroking.smartapi.utils.Constants.TOKEN_EXCEPTION_MESSAGE;
+
/**
* Response handler for handling all the responses.
*/
+@Slf4j
public class SmartAPIResponseHandler {
public JSONObject handle(Response response, String body) throws IOException, SmartAPIException, JSONException {
System.out.println("***************************");
if (response.header("Content-Type").contains("json")) {
JSONObject jsonObject = new JSONObject(body);
-
+
// if (jsonObject.optString("data") == null || jsonObject.optString("data") == "") {
- if (!jsonObject.has("status") || jsonObject.has("success")) {
+ if (!jsonObject.has("status") || jsonObject.has("success")) {
if (jsonObject.has("errorcode")) {
throw dealWithException(jsonObject, jsonObject.getString("errorcode"));
} else if (jsonObject.has("errorCode")) {
-
+
throw dealWithException(jsonObject, jsonObject.getString("errorCode"));
}
}
@@ -58,8 +69,9 @@ private SmartAPIException dealWithException(JSONObject jsonObject, String code)
return new TokenException(jsonObject.getString("message"), code);
case "AG8001":
- case "AG8002":
- return new DataException(jsonObject.getString("message"), code);
+ return new TokenException(TOKEN_EXCEPTION_MESSAGE, code);
+ case "AG8002":
+ return new DataException(jsonObject.getString("message"), code);
case "AB1004":
case "AB2000":
@@ -87,10 +99,63 @@ private SmartAPIException dealWithException(JSONObject jsonObject, String code)
case "AB1001":
case "AB1011":
return new PermissionException(jsonObject.getString("message"), code);
-
+ case "AG8004":
+ return new ApiKeyException(APIKEY_EXCEPTION_MESSAGE, code);
default:
return new SmartAPIException(jsonObject.getString("data not found"));
}
}
+ public String handler(Response response, String body) throws SmartAPIException, JSONException, IOException {
+ if (response.code() == 200) {
+ return handleResponse(response,body);
+ } else if (response.code() == 400){
+ log.error("Bad request. Please provide valid input");
+ return "Bad request. Please provide valid input";
+ }else {
+ log.error("Response or response body is null.");
+ throw new IllegalArgumentException("Response or response body is null.");
+ }
+ }
+
+ private String handleResponse(Response response, String body) throws SmartAPIException, IOException {
+ try {
+ JSONObject responseBodyJson = new JSONObject(body);
+ if(responseBodyJson.getBoolean("status")) {
+ JSONArray dataArray = responseBodyJson.optJSONArray("data");
+ if (dataArray != null && dataArray.length() > 0) {
+ List stockDTOList = parseStockDTOList(dataArray);
+
+ StringBuilder result = new StringBuilder();
+ result.append("Search successful. Found ").append(stockDTOList.size()).append(" trading symbols for the given query:\n");
+
+ int index = 1;
+ for (SearchScripResponseDTO stockDTO : stockDTOList) {
+ result.append(index).append(". exchange: ").append(stockDTO.getExchange()).append(", tradingsymbol: ").append(stockDTO.getTradingSymbol()).append(", symboltoken: ").append(stockDTO.getSymbolToken()).append("\n");
+ index++;
+ }
+ return result.toString();
+ } else {
+ return "Search successful. No matching trading symbols found for the given query.";
+ }
+ }else {
+ return String.valueOf(handle(response,body));
+ }
+
+ } catch (JSONException e) {
+ log.error("Error parsing response body as JSON.", e.getMessage());
+ throw new SmartAPIException("Error parsing response body as JSON.");
+ }
+ }
+
+ private List parseStockDTOList(JSONArray dataArray) throws JSONException, SmartAPIException {
+ ObjectMapper objectMapper = new ObjectMapper();
+ try {
+ return objectMapper.readValue(dataArray.toString(), new TypeReference>() {
+ });
+ } catch (IOException e) {
+ log.error("Error parsing JSON data array.", e);
+ throw new SmartAPIException("Error parsing JSON data array.");
+ }
+ }
}
diff --git a/src/main/java/com/angelbroking/smartapi/http/exceptions/ApiKeyException.java b/src/main/java/com/angelbroking/smartapi/http/exceptions/ApiKeyException.java
new file mode 100644
index 0000000..0a7c38f
--- /dev/null
+++ b/src/main/java/com/angelbroking/smartapi/http/exceptions/ApiKeyException.java
@@ -0,0 +1,14 @@
+package com.angelbroking.smartapi.http.exceptions;
+
+/**
+ * Exception raised when invalid API Key is provided for Smart API trade.
+ */
+
+public class ApiKeyException extends SmartAPIException {
+
+ // initialize 2fa exception and call constructor of Base Exception
+ public ApiKeyException(String message, String code){
+ super(message, code);
+ }
+}
+
diff --git a/src/main/java/com/angelbroking/smartapi/models/SearchScripResponseDTO.java b/src/main/java/com/angelbroking/smartapi/models/SearchScripResponseDTO.java
new file mode 100644
index 0000000..6f5ec17
--- /dev/null
+++ b/src/main/java/com/angelbroking/smartapi/models/SearchScripResponseDTO.java
@@ -0,0 +1,18 @@
+package com.angelbroking.smartapi.models;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+
+@Data
+public class SearchScripResponseDTO {
+
+ @JsonProperty("tradingsymbol")
+ private String tradingSymbol;
+
+ @JsonProperty("exchange")
+ private String exchange;
+
+ @JsonProperty("symboltoken")
+ private String symbolToken;
+
+}
diff --git a/src/main/java/com/angelbroking/smartapi/sample/Examples.java b/src/main/java/com/angelbroking/smartapi/sample/Examples.java
index ee64ad0..1c60bd5 100644
--- a/src/main/java/com/angelbroking/smartapi/sample/Examples.java
+++ b/src/main/java/com/angelbroking/smartapi/sample/Examples.java
@@ -272,6 +272,15 @@ public void getCandleData(SmartConnect smartConnect) throws SmartAPIException, I
String response = smartConnect.candleData(requestObejct);
}
+
+ /** Search Scrip Data */
+ public void getSearchScrip(SmartConnect smartConnect) throws SmartAPIException, IOException {
+ JSONObject payload = new JSONObject();
+ payload.put("exchange", "MCX");
+ payload.put("searchscrip", "Crude");
+ smartConnect.getSearchScrip(payload);
+ }
+
/**
* Market Data
* To Retrieve Market Data with different modes use.
@@ -292,6 +301,7 @@ public void getMarketData(SmartConnect smartConnect) throws SmartAPIException, I
}
+
public void tickerUsage(String clientId, String feedToken, String strWatchListScript, String task)
throws SmartAPIException {
diff --git a/src/main/java/com/angelbroking/smartapi/sample/Test.java b/src/main/java/com/angelbroking/smartapi/sample/Test.java
index 92a1316..6ef34e0 100644
--- a/src/main/java/com/angelbroking/smartapi/sample/Test.java
+++ b/src/main/java/com/angelbroking/smartapi/sample/Test.java
@@ -87,9 +87,14 @@ public static void main(String[] args) throws SmartAPIException {
/* System.out.println("Historic candle Data"); */
examples.getCandleData(smartConnect);
+
+ /* System.out.println("Search script api"); */
+ examples.getSearchScrip(smartConnect);
+
/* System.out.println("Market Data"); */
examples.getMarketData(smartConnect);
+
/* System.out.println("logout"); */
examples.logout(smartConnect);
diff --git a/src/main/java/com/angelbroking/smartapi/utils/Constants.java b/src/main/java/com/angelbroking/smartapi/utils/Constants.java
index bbb7618..8f9d212 100644
--- a/src/main/java/com/angelbroking/smartapi/utils/Constants.java
+++ b/src/main/java/com/angelbroking/smartapi/utils/Constants.java
@@ -85,4 +85,8 @@ public class Constants {
public static final String SMART_API_EXCEPTION_OCCURRED = "SmartAPIException occurred ";
public static final String IO_EXCEPTION_OCCURRED = "IOException occurred ";
public static final String JSON_EXCEPTION_OCCURRED = "JSONException occurred ";
+
+ public static final String TOKEN_EXCEPTION_MESSAGE = "Unauthorized access. Please provide a valid or non-expired jwtToken.";
+ public static final String APIKEY_EXCEPTION_MESSAGE = "Invalid or missing api key. Please provide a valid api key.";
+
}
diff --git a/src/test/java/com/angelbroking/smartapi/SmartConnectTest.java b/src/test/java/com/angelbroking/smartapi/SmartConnectTest.java
index 346b276..f72886c 100644
--- a/src/test/java/com/angelbroking/smartapi/SmartConnectTest.java
+++ b/src/test/java/com/angelbroking/smartapi/SmartConnectTest.java
@@ -6,6 +6,7 @@
import lombok.extern.slf4j.Slf4j;
import org.json.JSONArray;
import org.json.JSONException;
+
import org.json.JSONObject;
import org.junit.Before;
import org.junit.Test;
@@ -15,6 +16,12 @@
import java.io.IOException;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+
import static com.angelbroking.smartapi.utils.Constants.IO_EXCEPTION_ERROR_MSG;
import static com.angelbroking.smartapi.utils.Constants.IO_EXCEPTION_OCCURRED;
import static com.angelbroking.smartapi.utils.Constants.JSON_EXCEPTION_ERROR_MSG;
@@ -29,8 +36,7 @@
@RunWith(MockitoJUnitRunner.Silent.class)
@Slf4j
public class SmartConnectTest {
-
- @Mock
+
private SmartAPIRequestHandler smartAPIRequestHandler;
@Mock
@@ -41,6 +47,43 @@ public class SmartConnectTest {
private String apiKey;
private String accessToken;
+ @Mock
+ private SmartConnect smartConnect;
+
+ @Before
+ public void setup() {
+ // Set up any necessary configurations or dependencies
+ }
+
+ @Test
+ public void testGetSearchScript_Success() throws SmartAPIException, IOException {
+ // Mock the necessary objects
+ JSONObject payload = new JSONObject();
+ when(smartConnect.getSearchScrip(payload)).thenReturn("response-data");
+
+ // Call the method under test
+ String result = smartConnect.getSearchScrip(payload);
+ // Assert the result
+ assertEquals("response-data", result);
+
+ }
+
+ @Test(expected = SmartAPIException.class)
+ public void testGetSearchScript_Exception() throws SmartAPIException, IOException {
+ JSONObject payload = new JSONObject();
+ SmartAPIException expectedException = new SmartAPIException("Simulated SmartAPIException");
+ when(smartConnect.getSearchScrip(payload)).thenThrow(expectedException);
+ try {
+ smartConnect.getSearchScrip(payload);
+ } catch (SmartAPIException e) {
+ throw new SmartAPIException(String.format("The operation failed to execute because of a SmartAPIException error in Search scrip api data %s", e));
+ }
+ verify(smartConnect).getSearchScrip(payload);
+ }
+
+
+
+
private static JSONObject createMarketDataResponse() {
JSONObject jsonObject = new JSONObject();
@@ -282,4 +325,5 @@ private JSONObject getMarketDataRequest(String mode) {
return payload;
}
-}
\ No newline at end of file
+}
+