Skip to content

Commit 7c92fd9

Browse files
Luigi Fugarobsbodden
authored andcommitted
feat: Add Azure OpenAI support with Entra ID integration
- Add dynamic support for Azure OpenAI auth via Entra ID or API key fallback - Add Azure Entra ID properties for authentication - Improve transformers embedding model initialization - Centralize Spring AI properties and model creation - Enhance OpenAI configuration with response timeout setting
1 parent 246238c commit 7c92fd9

File tree

7 files changed

+87
-147
lines changed

7 files changed

+87
-147
lines changed

redis-om-spring/pom.xml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
<groupId>com.redis.om</groupId>
99
<artifactId>redis-om-spring</artifactId>
10-
<version>0.9.11-SNAPSHOT</version>
10+
<version>0.9.12-SNAPSHOT</version>
1111
<packaging>jar</packaging>
1212

1313
<name>redis-om-spring</name>
@@ -81,6 +81,7 @@
8181
<djl.version>0.30.0</djl.version>
8282
<junit-bom.version>5.10.2</junit-bom.version>
8383
<spring-ai.version>1.0.0-M6</spring-ai.version>
84+
<azure-identity.version>1.15.4</azure-identity.version>
8485
</properties>
8586

8687
<dependencyManagement>
@@ -235,6 +236,13 @@
235236
<optional>true</optional>
236237
</dependency>
237238
<!-- Spring AI end -->
239+
<!-- Azure Identity begin -->
240+
<dependency>
241+
<groupId>com.azure</groupId>
242+
<artifactId>azure-identity</artifactId>
243+
<version>${azure-identity.version}</version>
244+
</dependency>
245+
<!-- Azure Identity end -->
238246
<dependency>
239247
<groupId>redis.clients</groupId>
240248
<artifactId>jedis</artifactId>

redis-om-spring/src/main/java/com/redis/om/spring/RedisOMAiProperties.java

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ public class RedisOMAiProperties {
1414
private final Djl djl = new Djl();
1515
private final OpenAi openAi = new OpenAi();
1616
private final AzureOpenAi azureOpenAi = new AzureOpenAi();
17+
private final AzureEntraId azureEntraId = new AzureEntraId();
1718
private final VertexAi vertexAi = new VertexAi();
1819
private final Aws aws = new Aws();
1920
private final Ollama ollama = new Ollama();
@@ -38,6 +39,10 @@ public AzureOpenAi getAzureOpenAi() {
3839
return azureOpenAi;
3940
}
4041

42+
public AzureEntraId getAzureEntraId() {
43+
return azureEntraId;
44+
}
45+
4146
public VertexAi getVertexAi() {
4247
return vertexAi;
4348
}
@@ -268,6 +273,63 @@ public void setEndpoint(String endpoint) {
268273
}
269274
}
270275

276+
public static class AzureEntraId {
277+
private boolean enabled = false;
278+
private String apiKey;
279+
private String endpoint;
280+
private String tenantId;
281+
private String clientId;
282+
private String clientSecret;
283+
284+
public String getApiKey() {
285+
return apiKey;
286+
}
287+
288+
public void setApiKey(String apiKey) {
289+
this.apiKey = apiKey;
290+
}
291+
292+
public String getEndpoint() {
293+
return endpoint;
294+
}
295+
296+
public void setEndpoint(String endpoint) {
297+
this.endpoint = endpoint;
298+
}
299+
300+
public boolean isEnabled() {
301+
return enabled;
302+
}
303+
304+
public void setEnabled(boolean enabled) {
305+
this.enabled = enabled;
306+
}
307+
308+
public String getTenantId() {
309+
return tenantId;
310+
}
311+
312+
public void setTenantId(String tenantId) {
313+
this.tenantId = tenantId;
314+
}
315+
316+
public String getClientId() {
317+
return clientId;
318+
}
319+
320+
public void setClientId(String clientId) {
321+
this.clientId = clientId;
322+
}
323+
324+
public String getClientSecret() {
325+
return clientSecret;
326+
}
327+
328+
public void setClientSecret(String clientSecret) {
329+
this.clientSecret = clientSecret;
330+
}
331+
}
332+
271333
public static class VertexAi {
272334
private String apiKey;
273335
private String endpoint;

redis-om-spring/src/main/java/com/redis/om/spring/client/RedisModulesClient.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
import redis.clients.jedis.bloom.commands.TopKFilterCommands;
1818
import redis.clients.jedis.json.commands.RedisJsonCommands;
1919
import redis.clients.jedis.search.RediSearchCommands;
20-
import redis.clients.jedis.bloom.commands.TDigestSketchCommands;
2120

2221
import java.util.Objects;
2322
import java.util.Optional;
@@ -63,10 +62,6 @@ public TopKFilterCommands clientForTopK() {
6362
return unifiedJedis;
6463
}
6564

66-
public TDigestSketchCommands clientForTDigest() {
67-
return unifiedJedis;
68-
}
69-
7065
private UnifiedJedis getUnifiedJedis() {
7166

7267
var sentinelConfiguration = jedisConnectionFactory.getSentinelConfiguration();

redis-om-spring/src/main/java/com/redis/om/spring/ops/RedisModulesOperations.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,4 @@ public CuckooFilterOperations<K> opsForCuckoFilter() {
3535
public TopKOperations<K> opsForTopK() {
3636
return new TopKOperationsImpl<>(client);
3737
}
38-
39-
public TDigestOperations<K> opsForTDigest() {
40-
return new TDigestOperationsImpl<>(client);
41-
}
4238
}
Lines changed: 0 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1,88 +1,5 @@
11
package com.redis.om.spring.ops.pds;
22

3-
import java.util.List;
4-
import java.util.Map;
5-
63
public interface TopKOperations<K> {
7-
/**
8-
* Create a new TopK filter.
9-
*
10-
* @param key The key of the filter
11-
* @param topk Number of top items to keep
12-
* @return Status string reply
13-
*/
14-
String createFilter(K key, long topk);
15-
16-
/**
17-
* Create a new TopK filter with additional parameters.
18-
*
19-
* @param key The key of the filter
20-
* @param topk Number of top items to keep
21-
* @param width Number of counters kept in each array
22-
* @param depth Number of arrays
23-
* @param decay The probability of reducing a counter in an occupied bucket
24-
* @return Status string reply
25-
*/
26-
String createFilter(K key, long topk, long width, long depth, double decay);
27-
28-
/**
29-
* Add one or more items to the filter.
30-
*
31-
* @param key The key of the filter
32-
* @param items Items to add to the filter
33-
* @return List of items dropped from the filter
34-
*/
35-
List<String> add(K key, String... items);
36-
37-
/**
38-
* Increase the score of an item by increment.
39-
*
40-
* @param key The key of the filter
41-
* @param item Item to increment
42-
* @param increment Increment by this much
43-
* @return Item dropped from the filter, or null if no item was dropped
44-
*/
45-
String incrementBy(K key, String item, long increment);
46-
47-
/**
48-
* Increase the score of multiple items by their increments.
49-
*
50-
* @param key The key of the filter
51-
* @param itemIncrementMap Map of item to increment
52-
* @return List of items dropped from the filter
53-
*/
54-
List<String> incrementBy(K key, Map<String, Long> itemIncrementMap);
55-
56-
/**
57-
* Check if items exist in the filter.
58-
*
59-
* @param key The key of the filter
60-
* @param items Items to check
61-
* @return List of boolean values indicating if items exist in the filter
62-
*/
63-
List<Boolean> query(K key, String... items);
64-
65-
/**
66-
* Return the top k items in the filter.
67-
*
68-
* @param key The key of the filter
69-
* @return List of items
70-
*/
71-
List<String> list(K key);
72-
73-
/**
74-
* Return the top k items with their respective counts.
75-
*
76-
* @param key The key of the filter
77-
* @return Map of items to their counts
78-
*/
79-
Map<String, Long> listWithCount(K key);
804

81-
/**
82-
* Get information about the filter.
83-
*
84-
* @param key The key of the filter
85-
* @return Map of information about the filter
86-
*/
87-
Map<String, Object> info(K key);
885
}

redis-om-spring/src/main/java/com/redis/om/spring/ops/pds/TopKOperationsImpl.java

Lines changed: 0 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -2,58 +2,10 @@
22

33
import com.redis.om.spring.client.RedisModulesClient;
44

5-
import java.util.List;
6-
import java.util.Map;
7-
85
public class TopKOperationsImpl<K> implements TopKOperations<K> {
96
final RedisModulesClient client;
107

118
public TopKOperationsImpl(RedisModulesClient client) {
129
this.client = client;
1310
}
14-
15-
@Override
16-
public String createFilter(K key, long topk) {
17-
return client.clientForTopK().topkReserve(key.toString(), topk);
18-
}
19-
20-
@Override
21-
public String createFilter(K key, long topk, long width, long depth, double decay) {
22-
return client.clientForTopK().topkReserve(key.toString(), topk, width, depth, decay);
23-
}
24-
25-
@Override
26-
public List<String> add(K key, String... items) {
27-
return client.clientForTopK().topkAdd(key.toString(), items);
28-
}
29-
30-
@Override
31-
public String incrementBy(K key, String item, long increment) {
32-
return client.clientForTopK().topkIncrBy(key.toString(), item, increment);
33-
}
34-
35-
@Override
36-
public List<String> incrementBy(K key, Map<String, Long> itemIncrementMap) {
37-
return client.clientForTopK().topkIncrBy(key.toString(), itemIncrementMap);
38-
}
39-
40-
@Override
41-
public List<Boolean> query(K key, String... items) {
42-
return client.clientForTopK().topkQuery(key.toString(), items);
43-
}
44-
45-
@Override
46-
public List<String> list(K key) {
47-
return client.clientForTopK().topkList(key.toString());
48-
}
49-
50-
@Override
51-
public Map<String, Long> listWithCount(K key) {
52-
return client.clientForTopK().topkListWithCount(key.toString());
53-
}
54-
55-
@Override
56-
public Map<String, Object> info(K key) {
57-
return client.clientForTopK().topkInfo(key.toString());
58-
}
5911
}

redis-om-spring/src/main/java/com/redis/om/spring/vectorize/EmbeddingModelFactory.java

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.azure.ai.openai.OpenAIClient;
44
import com.azure.ai.openai.OpenAIClientBuilder;
55
import com.azure.core.credential.AzureKeyCredential;
6+
import com.azure.identity.*;
67
import com.redis.om.spring.RedisOMAiProperties;
78
import com.redis.om.spring.annotations.Vectorize;
89
import org.springframework.ai.azure.openai.AzureOpenAiEmbeddingModel;
@@ -106,6 +107,18 @@ public OpenAiEmbeddingModel createOpenAiEmbeddingModel(String model) {
106107
);
107108
}
108109

110+
private OpenAIClient getOpenAIClient() {
111+
OpenAIClientBuilder builder = new OpenAIClientBuilder();
112+
if (properties.getAzureEntraId().isEnabled()) {
113+
builder.credential(new DefaultAzureCredentialBuilder().tenantId(properties.getAzureEntraId().getTenantId()).build())
114+
.endpoint(properties.getAzureEntraId().getEndpoint());
115+
} else {
116+
builder.credential(new AzureKeyCredential(properties.getAzureOpenAi().getApiKey()))
117+
.endpoint(properties.getAzureOpenAi().getEndpoint());
118+
}
119+
return builder.buildClient();
120+
}
121+
109122
public AzureOpenAiEmbeddingModel createAzureOpenAiEmbeddingModel(String deploymentName) {
110123
String apiKey = properties.getAzureOpenAi().getApiKey();
111124
if (!StringUtils.hasText(apiKey)) {
@@ -119,16 +132,13 @@ public AzureOpenAiEmbeddingModel createAzureOpenAiEmbeddingModel(String deployme
119132
properties.getAzureOpenAi().setEndpoint(endpoint);
120133
}
121134

122-
OpenAIClient openAIClientBuilder = new OpenAIClientBuilder()
123-
.credential(new AzureKeyCredential(properties.getAzureOpenAi().getApiKey()))
124-
.endpoint(properties.getAzureOpenAi().getEndpoint())
125-
.buildClient();
135+
OpenAIClient openAIClient = getOpenAIClient();
126136

127-
AzureOpenAiEmbeddingOptions options = AzureOpenAiEmbeddingOptions.builder()
137+
AzureOpenAiEmbeddingOptions options = AzureOpenAiEmbeddingOptions.builder()
128138
.deploymentName(deploymentName)
129139
.build();
130140

131-
return new AzureOpenAiEmbeddingModel(openAIClientBuilder, MetadataMode.EMBED, options);
141+
return new AzureOpenAiEmbeddingModel(openAIClient, MetadataMode.EMBED, options);
132142
}
133143

134144
public VertexAiTextEmbeddingModel createVertexAiTextEmbeddingModel(String model) {

0 commit comments

Comments
 (0)