Skip to content

Commit a8fe6a4

Browse files
committed
Add support for Upstox API v2.0
1. Add support for rate limits introduced by Upstox. 2. Introduced 'RetryPolicyFactory' to provide support for retries on failed API requests. 3. Add method for new API endpoint - Fetch Subscribed Symbols. 4. Add support for the new Historical endpoint. 5. WebSocket reconnect feature provided by the OkHTTP library is now disabled by default. 6. Updated Google Guava to '27.0.1-jre'. 7. Updated the tests.
1 parent 18cdb50 commit a8fe6a4

26 files changed

Lines changed: 1014 additions & 263 deletions

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,18 @@ demonstrating the usage of Riko. Feel free to use it as a starter for your own p
1515
<dependency>
1616
<groupId>com.github.rishabh9</groupId>
1717
<artifactId>riko</artifactId>
18-
<version>2.0.2-SNAPSHOT</version>
18+
<version>3.0.0-SNAPSHOT</version>
1919
</dependency>
2020
```
2121

2222
### For Gradle based project
2323
```groovy
2424
dependencies {
25-
implementation 'com.github.rishabh9:riko:2.0.2-SNAPSHOT'
25+
implementation 'com.github.rishabh9:riko:3.0.0-SNAPSHOT'
2626
}
2727
```
2828

2929
### For SBT based project
3030
```scala
31-
libraryDependencies += "com.github.rishabh9" % "riko" % "2.0.2-SNAPSHOT"
31+
libraryDependencies += "com.github.rishabh9" % "riko" % "3.0.0-SNAPSHOT"
3232
```

build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ dependencyManagement {
4747
// GroupId
4848
group = 'com.github.rishabh9'
4949
// Version
50-
version = '2.0.2-SNAPSHOT'
50+
version = '3.0.0-SNAPSHOT'
5151
archivesBaseName = 'riko'
5252

5353
dependencies {
@@ -56,7 +56,7 @@ dependencies {
5656

5757
// These dependencies are used internally, and not exposed to consumers on their own compile classpath.
5858
// Developer's toolkit
59-
implementation 'com.google.guava:guava:23.0'
59+
implementation 'com.google.guava:guava:27.0.1-jre'
6060
implementation 'net.jodah:failsafe:1.1.1'
6161
// Making API calls
6262
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* MIT License
3+
*
4+
* Copyright (c) 2018 Rishabh Joshi
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
25+
package com.github.rishabh9.riko.upstox.common;
26+
27+
import net.jodah.failsafe.RetryPolicy;
28+
29+
import javax.annotation.Nonnull;
30+
import java.util.Optional;
31+
import java.util.concurrent.ScheduledExecutorService;
32+
33+
/**
34+
* A simple factory to create policies for retrying when an API call fails.
35+
* Riko uses the open source <a href="https://github.com/jhalterman/failsafe">Failsafe</a>
36+
* library for implementing retries.
37+
*
38+
* @see RikoRetryPolicyFactory
39+
*/
40+
public interface RetryPolicyFactory {
41+
42+
/**
43+
* @return A {@link RetryPolicy} that expresses when retries should be performed.
44+
* An {@code empty} {@link RetryPolicy} indicates retries should be disabled.
45+
*/
46+
@Nonnull
47+
Optional<RetryPolicy> createRetryPolicy();
48+
49+
/**
50+
* @return A {@link ScheduledExecutorService} to allow for asynchronous executions.
51+
* Cannot be {@code null}.
52+
*/
53+
@Nonnull
54+
ScheduledExecutorService createExecutorService();
55+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* MIT License
3+
*
4+
* Copyright (c) 2018 Rishabh Joshi
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
25+
package com.github.rishabh9.riko.upstox.common;
26+
27+
import net.jodah.failsafe.RetryPolicy;
28+
29+
import java.util.Optional;
30+
import java.util.concurrent.Executors;
31+
import java.util.concurrent.ScheduledExecutorService;
32+
import java.util.concurrent.TimeUnit;
33+
34+
/**
35+
* The Riko's default retry policy factory.
36+
*
37+
* @see RetryPolicyFactory
38+
*/
39+
public class RikoRetryPolicyFactory implements RetryPolicyFactory {
40+
41+
/**
42+
* @return The default {@link RetryPolicy}
43+
*/
44+
@Override
45+
public Optional<RetryPolicy> createRetryPolicy() {
46+
return Optional.of(new RetryPolicy()
47+
.retryOn(Throwable.class)
48+
.withBackoff(1, 5, TimeUnit.SECONDS)
49+
.withMaxRetries(3));
50+
}
51+
52+
/**
53+
* @return The default {@link ScheduledExecutorService} to be used by {@link RetryPolicy}.
54+
*/
55+
@Override
56+
public ScheduledExecutorService createExecutorService() {
57+
return Executors.newScheduledThreadPool(Runtime.getRuntime().availableProcessors());
58+
}
59+
}

src/main/java/com/github/rishabh9/riko/upstox/common/Service.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,13 @@
2727
import com.github.rishabh9.riko.upstox.common.models.ApiCredentials;
2828
import com.github.rishabh9.riko.upstox.common.models.AuthHeaders;
2929
import com.github.rishabh9.riko.upstox.login.models.AccessToken;
30+
import net.jodah.failsafe.RetryPolicy;
3031
import org.apache.logging.log4j.LogManager;
3132
import org.apache.logging.log4j.Logger;
3233

3334
import javax.annotation.Nonnull;
3435
import java.util.Objects;
36+
import java.util.concurrent.ScheduledExecutorService;
3537

3638
/**
3739
* Parent class for every Service class. Holds common methods.
@@ -41,13 +43,20 @@ public abstract class Service {
4143
private static final Logger log = LogManager.getLogger(Service.class);
4244

4345
protected final UpstoxAuthService upstoxAuthService;
46+
protected final RetryPolicy retryPolicy;
47+
protected final ScheduledExecutorService retryExecutor;
4448

4549
/**
4650
* @param upstoxAuthService The service to retrieve authentication details
4751
*/
48-
public Service(@Nonnull final UpstoxAuthService upstoxAuthService) {
52+
public Service(@Nonnull final UpstoxAuthService upstoxAuthService,
53+
@Nonnull final RetryPolicyFactory retryPolicyFactory) {
4954

5055
this.upstoxAuthService = Objects.requireNonNull(upstoxAuthService);
56+
this.retryPolicy = Objects.requireNonNull(retryPolicyFactory).createRetryPolicy()
57+
// The default behaviour is not to re-try.
58+
.orElse(new RetryPolicy().withMaxRetries(0));
59+
this.retryExecutor = Objects.requireNonNull(retryPolicyFactory).createExecutorService();
5160
}
5261

5362
protected <T> T prepareServiceApi(@Nonnull final Class<T> type) {

src/main/java/com/github/rishabh9/riko/upstox/common/ServiceGenerator.java

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ public void rebuildWithUrl(HttpUrl url) {
128128
public <S> S createService(@Nonnull final Class<S> serviceClass) {
129129

130130
log.debug("Creating service without authentication");
131-
return createService(Objects.requireNonNull(serviceClass), null, null);
131+
return createService(Objects.requireNonNull(serviceClass), null);
132132
}
133133

134134
/**
@@ -141,19 +141,14 @@ public <S> S createService(@Nonnull final Class<S> serviceClass) {
141141
* @return The retrofitted service
142142
*/
143143
public <S> S createService(@Nonnull final Class<S> serviceClass,
144-
@Nullable final String username,
145-
@Nullable final String password) {
144+
@Nonnull final String username,
145+
@Nonnull final String password) {
146146

147-
if (!Strings.isNullOrEmpty(username)
148-
&& !Strings.isNullOrEmpty(password)) {
149147
final String authToken = Credentials.basic(username, password);
150148
log.debug("Creating service with Basic authentication");
151149
return createService(
152150
Objects.requireNonNull(serviceClass),
153-
new AuthHeaders(authToken, username));
154-
}
155-
// Setup request headers without any auth
156-
return createService(Objects.requireNonNull(serviceClass), null);
151+
new AuthHeaders(Objects.requireNonNull(authToken), Objects.requireNonNull(username)));
157152
}
158153

159154
/**

src/main/java/com/github/rishabh9/riko/upstox/common/constants/LiveFeedType.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
package com.github.rishabh9.riko.upstox.common.constants;
2626

2727
public final class LiveFeedType {
28-
public static final String LTP = "LTP";
29-
public static final String FULL = "Full";
28+
public static final String LTP = "ltp";
29+
public static final String FULL = "full";
30+
public static final String ALL = "all";
3031
}

src/main/java/com/github/rishabh9/riko/upstox/common/constants/PropertyKeys.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,5 +53,5 @@ public class PropertyKeys {
5353
public static final int RIKO_WS_SERVER_PORT_DEFAULT = 443;
5454

5555
public static final String RIKO_WS_RECONNECT = "riko.ws.reconnect";
56-
public static final String RIKO_WS_RECONNECT_DEFAULT = "true";
56+
public static final String RIKO_WS_RECONNECT_DEFAULT = "false";
5757
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* MIT License
3+
*
4+
* Copyright (c) 2018 Rishabh Joshi
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
25+
package com.github.rishabh9.riko.upstox.common.constants;
26+
27+
public class RateLimits {
28+
public static final double LIVE_FEED_RATE_LIMIT = 1.0D;
29+
public static final double SUBSCRIBE_RATE_LIMIT = 1.0D;
30+
public static final double UNSUBSCRIBE_RATE_LIMIT = 1.0D;
31+
public static final double SYMBOLS_SUBSCRIBED_RATE_LIMIT = 1.0D;
32+
public static final double HISTORICAL_RATE_LIMIT = 10.0D;
33+
public static final double LOGIN_RATE_LIMIT = 1.0D;
34+
public static final double ORDER_HISTORY_RATE_LIMIT = 1.0D;
35+
public static final double ORDER_DETAILS_RATE_LIMIT = 1.0D;
36+
public static final double TRADE_BOOK_RATE_LIMIT = 1.0D;
37+
public static final double TRADE_HISTORY_RATE_LIMIT = 1.0D;
38+
public static final double PLACE_ORDER_RATE_LIMIT = 10.0D;
39+
public static final double MODIFY_ORDER_RATE_LIMIT = 1.0D;
40+
public static final double CANCEL_ORDER_RATE_LIMIT = 1.0D;
41+
public static final double PROFILE_RATE_LIMIT = 1.0D;
42+
public static final double BALANCE_RATE_LIMIT = 1.0D;
43+
public static final double POSITIONS_RATE_LIMIT = 1.0D;
44+
public static final double HOLDINGS_RATE_LIMIT = 1.0D;
45+
public static final double MASTER_CONTRACT_RATE_LIMIT = 1.0D;
46+
public static final double WS_PARAMS_RATE_LIMIT = 1.0D;
47+
public static final double WEB_SOCKET_RATE_LIMIT = 1.0D;
48+
}

src/main/java/com/github/rishabh9/riko/upstox/feed/FeedApi.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
import com.github.rishabh9.riko.upstox.common.models.UpstoxResponse;
2828
import com.github.rishabh9.riko.upstox.feed.models.Feed;
29+
import com.github.rishabh9.riko.upstox.feed.models.Subscription;
2930
import com.github.rishabh9.riko.upstox.feed.models.SubscriptionResponse;
3031
import retrofit2.http.GET;
3132
import retrofit2.http.Path;
@@ -76,4 +77,13 @@ CompletableFuture<UpstoxResponse<SubscriptionResponse>> subscribe(@Path("type")
7677
CompletableFuture<UpstoxResponse<SubscriptionResponse>> unsubscribe(@Path("type") String type,
7778
@Path("exchange") String exchange,
7879
@Query("symbol") String symbolsCsv);
80+
81+
/**
82+
* Get list of symbols subscribed.
83+
*
84+
* @param type 'all' or 'ltp' or 'full'.
85+
* @return A CompletableFuture to execute the request (a)synchronously.
86+
*/
87+
@GET("/live/feed/{type}")
88+
CompletableFuture<UpstoxResponse<Subscription>> symbolsSubscribed(@Path("type") String type);
7989
}

0 commit comments

Comments
 (0)