YahooFinanceSessionService.java
package com.tdmconsult.ete.services.yahoo;
import java.net.URI;
import java.util.Objects;
import lombok.RequiredArgsConstructor;
import org.jspecify.annotations.Nullable;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.stereotype.Service;
import org.springframework.web.client.DefaultResponseErrorHandler;
@Service
@RequiredArgsConstructor
public class YahooFinanceSessionService {
private final RestTemplateBuilder builder;
private final YahooFinanceProperties yahooProperties;
@Nullable
private YahooSession session;
public record YahooSession(
String crumb,
String cookie) {
}
public synchronized YahooSession getSession() {
if (session != null) {
return session;
}
final var restTemplateWithErrorHandlerDeactivated = builder
.errorHandler(new DefaultResponseErrorHandler() {
@Override
public boolean hasError(final ClientHttpResponse response) {
return false;
}
})
.build();
final var authHeaders = new HttpHeaders();
authHeaders.set("User-Agent", "Mozilla/5.0");
final var cookieResponse =
restTemplateWithErrorHandlerDeactivated.exchange(
URI.create(yahooProperties.authurl()),
HttpMethod.GET,
new HttpEntity<>(authHeaders),
Void.class);
final var cookies = cookieResponse.getHeaders().get(HttpHeaders.SET_COOKIE);
if (cookies == null || cookies.isEmpty()) {
throw new IllegalStateException("Yahoo %s did not return a cookie".formatted(yahooProperties.authurl()));
}
final var cookie = cookies.getFirst().split(";", 2)[0];
final var headers = new HttpHeaders();
headers.set("User-Agent", "Mozilla/5.0");
headers.add(HttpHeaders.COOKIE, cookie);
final var crumbResponse =
restTemplateWithErrorHandlerDeactivated.exchange(
URI.create(yahooProperties.baseurl() + "/v1/test/getcrumb"),
HttpMethod.GET,
new HttpEntity<>(headers),
String.class);
session = new YahooSession(
Objects.requireNonNull(crumbResponse.getBody(), "expecting crumb response body to be non-empty"),
cookie
);
return session;
}
public synchronized void invalidateSession() {
session = null;
}
}