Skip to content

Commit 31e29b1

Browse files
adityamparikhclaude
andcommitted
chore(merge): resolve conflicts with upstream/main
Merge upstream/main into solrj-10 branch, keeping SolrJ 10 API changes (HttpJdkSolrClient, ResponseParser package move, getContentTypes) while adopting upstream cleanups (consolidated parameterized tests, try-with-resources, removed standalone Solr code, spring-ai 1.1.3). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: adityamparikh <aditya.m.parikh@gmail.com>
2 parents c4efd20 + dbecfb3 commit 31e29b1

28 files changed

Lines changed: 92 additions & 276 deletions

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,6 @@ out/
4040
.env
4141
.auth-token
4242
*.token
43+
44+
### Claude Code worktrees ###
45+
.worktrees/

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ MCP tools.
274274
275275
### Quick Setup
276276
277-
1. **Configure Auth0** (see detailed guide: [docs/AUTH0_SETUP.md](docs/AUTH0_SETUP.md))
277+
1. **Configure Auth0** (see detailed guide: [security-docs/AUTH0_SETUP.md](security-docs/AUTH0_SETUP.md))
278278
- Create an Auth0 Application (Machine to Machine)
279279
- Create an Auth0 API with your audience identifier
280280
- Note your Domain, Client ID, Client Secret, and Audience
@@ -304,7 +304,7 @@ MCP tools.
304304
http://localhost:8080/mcp
305305
```
306306
307-
For complete setup instructions, see [docs/AUTH0_SETUP.md](docs/AUTH0_SETUP.md)
307+
For complete setup instructions, see [security-docs/AUTH0_SETUP.md](security-docs/AUTH0_SETUP.md)
308308
309309
## Available MCP tools
310310
@@ -378,7 +378,7 @@ The `solr://{collection}/schema` resource supports autocompletion for the `{coll
378378
379379
## Documentation
380380
381-
- [Auth0 Setup (OAuth2 configuration)](docs/AUTH0_SETUP.md)
381+
- [Auth0 Setup (OAuth2 configuration)](security-docs/AUTH0_SETUP.md)
382382
383383
## Contributing
384384

build.gradle.kts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,12 @@ jib {
417417
environment =
418418
mapOf(
419419
// Disable Spring Boot Docker Compose support when running in container
420+
// Docker Compose integration is disabled in the container image.
421+
// It is only useful for local development (HTTP profile) where
422+
// the host has Docker and a compose.yaml. Inside a container,
423+
// Docker Compose cannot start sibling containers without a
424+
// Docker socket mount, so it must be turned off.
425+
// The application-stdio.properties also disables it for STDIO mode.
420426
"SPRING_DOCKER_COMPOSE_ENABLED" to "false",
421427
)
422428

dev-docs/DEVELOPMENT.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,12 @@ java -jar build/libs/solr-mcp-1.0.0-SNAPSHOT.jar
6565
#### HTTP Mode
6666

6767
```bash
68-
./gradlew bootRun --args='--spring.profiles.active=http'
68+
PROFILES=http ./gradlew bootRun
6969
```
7070

71+
Spring Boot Docker Compose will automatically start the services declared in `compose.yaml`
72+
(Solr, ZooKeeper, and optionally LGTM for observability) before the application starts.
73+
7174
The server will start on http://localhost:8080
7275

7376
### Environment Variables
@@ -131,7 +134,7 @@ The [MCP Inspector](https://github.com/modelcontextprotocol/inspector) provides
131134

132135
```bash
133136
# Start the server in HTTP mode
134-
./gradlew bootRun --args='--spring.profiles.active=http'
137+
PROFILES=http ./gradlew bootRun
135138

136139
# In another terminal, start MCP Inspector
137140
npx @modelcontextprotocol/inspector

dev-docs/TROUBLESHOOTING.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ rm -rf .gradle
275275

276276
1. **Verify server is running in HTTP mode**
277277
```bash
278-
./gradlew bootRun --args='--spring.profiles.active=http'
278+
PROFILES=http ./gradlew bootRun
279279
```
280280

281281
2. **Check port is correct**
@@ -408,7 +408,7 @@ If you're still having issues:
408408
./gradlew bootRun 2>&1 | tee server.log
409409

410410
# HTTP mode - Spring Boot logging
411-
./gradlew bootRun --args='--spring.profiles.active=http'
411+
PROFILES=http ./gradlew bootRun
412412
```
413413

414414
### Solr Logs

gradle/libs.versions.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
[versions]
22
# Build plugins
3-
spring-boot = "3.5.8"
3+
spring-boot = "3.5.11"
44
spring-dependency-management = "1.1.7"
55
errorprone-plugin = "4.2.0"
66
jib = "3.4.5"
77
spotless = "7.0.2"
88

99
# Main dependencies
10-
spring-ai = "1.1.2"
10+
spring-ai = "1.1.3"
1111
solr = "10.0.0"
1212
commons-csv = "1.10.0"
1313
jspecify = "1.0.0"
Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -287,15 +287,7 @@ OAUTH2_ISSUER_URI=https://your-tenant.auth0.com/
287287
The application must run in `http` profile to enable OAuth2 security:
288288

289289
```bash
290-
# Option 1: Using environment variable
291-
export PROFILES=http
292-
./gradlew bootRun
293-
294-
# Option 2: Using Spring Boot argument
295-
./gradlew bootRun --args='--spring.profiles.active=http'
296-
297-
# Option 3: Using Gradle property
298-
./gradlew bootRun -Dspring.profiles.active=http
290+
PROFILES=http ./gradlew bootRun
299291
```
300292

301293
### Application Configuration Details

keycloak.md renamed to security-docs/keycloak.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ docker run -d --name keycloak \
7474

7575
# 3. Run Solr MCP Server with security enabled
7676
export PROFILES=http
77-
export SECURITY_ENABLED=true
77+
export HTTP_SECURITY_ENABLED=true
7878
export OAUTH2_ISSUER_URI=http://localhost:8180/realms/solr-mcp
7979
./gradlew bootRun
8080
```
@@ -168,7 +168,7 @@ The Solr MCP Server is pre-configured to work with any OAuth2/OIDC provider. Upd
168168

169169
```properties
170170
# Security toggle - set to true to enable OAuth2 authentication
171-
spring.security.enabled=${SECURITY_ENABLED:true}
171+
http.security.enabled=${HTTP_SECURITY_ENABLED:true}
172172

173173
# Keycloak OAuth2 Configuration
174174
# Format: https://<keycloak-host>/realms/<realm-name>
@@ -183,7 +183,7 @@ No code changes are required—the existing `McpServerConfiguration` handles JWT
183183

184184
```bash
185185
export PROFILES=http
186-
export SECURITY_ENABLED=true
186+
export HTTP_SECURITY_ENABLED=true
187187
export OAUTH2_ISSUER_URI=http://localhost:8180/realms/solr-mcp
188188
./gradlew bootRun
189189
```
@@ -192,7 +192,7 @@ export OAUTH2_ISSUER_URI=http://localhost:8180/realms/solr-mcp
192192

193193
```bash
194194
export PROFILES=http
195-
export SECURITY_ENABLED=false
195+
export HTTP_SECURITY_ENABLED=false
196196
./gradlew bootRun
197197
```
198198

@@ -422,7 +422,7 @@ import org.springframework.security.oauth2.server.resource.authentication.JwtAut
422422
import org.springframework.security.oauth2.server.resource.authentication.JwtGrantedAuthoritiesConverter;
423423

424424
@Bean
425-
@ConditionalOnProperty(name = "spring.security.enabled", havingValue = "true", matchIfMissing = true)
425+
@ConditionalOnProperty(name = "http.security.enabled", havingValue = "true", matchIfMissing = true)
426426
public JwtAuthenticationConverter jwtAuthenticationConverter() {
427427
JwtGrantedAuthoritiesConverter grantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter();
428428
// Keycloak stores realm roles in realm_access.roles
@@ -439,7 +439,7 @@ Wire it into the security filter chain:
439439

440440
```java
441441
@Bean
442-
@ConditionalOnProperty(name = "spring.security.enabled", havingValue = "true", matchIfMissing = true)
442+
@ConditionalOnProperty(name = "http.security.enabled", havingValue = "true", matchIfMissing = true)
443443
SecurityFilterChain securityFilterChain(HttpSecurity http, JwtAuthenticationConverter jwtAuthenticationConverter) throws Exception {
444444
return http
445445
.authorizeHttpRequests(auth -> {

src/main/java/org/apache/solr/mcp/server/Main.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,6 @@
9797
* <li>Monitor application logs for connection and performance issues
9898
* </ul>
9999
*
100-
* @version 1.0.0
101-
* @since 1.0.0
102100
* @see SearchService
103101
* @see IndexingService
104102
* @see CollectionService

src/main/java/org/apache/solr/mcp/server/collection/CollectionService.java

Lines changed: 15 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -30,18 +30,14 @@
3030
import org.apache.solr.client.solrj.SolrClient;
3131
import org.apache.solr.client.solrj.SolrRequest;
3232
import org.apache.solr.client.solrj.SolrServerException;
33-
import org.apache.solr.client.solrj.impl.CloudSolrClient;
3433
import org.apache.solr.client.solrj.request.CollectionAdminRequest;
35-
import org.apache.solr.client.solrj.request.CoreAdminRequest;
3634
import org.apache.solr.client.solrj.request.GenericSolrRequest;
3735
import org.apache.solr.client.solrj.request.LukeRequest;
3836
import org.apache.solr.client.solrj.request.SolrQuery;
3937
import org.apache.solr.client.solrj.response.CollectionAdminResponse;
40-
import org.apache.solr.client.solrj.response.CoreAdminResponse;
4138
import org.apache.solr.client.solrj.response.LukeResponse;
4239
import org.apache.solr.client.solrj.response.QueryResponse;
4340
import org.apache.solr.client.solrj.response.SolrPingResponse;
44-
import org.apache.solr.common.params.CoreAdminParams;
4541
import org.apache.solr.common.params.ModifiableSolrParams;
4642
import org.apache.solr.common.util.NamedList;
4743
import org.apache.solr.mcp.server.config.SolrConfigurationProperties;
@@ -67,8 +63,8 @@
6763
* <strong>Core Capabilities:</strong>
6864
*
6965
* <ul>
70-
* <li><strong>Collection Discovery</strong>: Lists available collections with
71-
* automatic SolrCloud vs standalone detection
66+
* <li><strong>Collection Discovery</strong>: Lists available collections using
67+
* the SolrCloud Collections API
7268
* <li><strong>Performance Monitoring</strong>: Comprehensive metrics collection
7369
* including index, query, cache, and handler statistics
7470
* <li><strong>Health Monitoring</strong>: Real-time health checks with
@@ -100,7 +96,6 @@
10096
*
10197
* <ul>
10298
* <li><strong>SolrCloud</strong>: Distributed mode using Collections API
103-
* <li><strong>Standalone</strong>: Single-node mode using Core Admin API
10499
* </ul>
105100
*
106101
* <p>
@@ -126,8 +121,6 @@
126121
* SolrHealthStatus health = collectionService.checkHealth("my_collection");
127122
* }</pre>
128123
*
129-
* @version 1.0.0
130-
* @since 1.0.0
131124
* @see SolrMetrics
132125
* @see SolrHealthStatus
133126
* @see org.apache.solr.client.solrj.SolrClient
@@ -319,23 +312,16 @@ public List<String> completeCollectionForSchema() {
319312
}
320313

321314
/**
322-
* Lists all available Solr collections in the cluster.
315+
* Lists all available Solr collections in the SolrCloud cluster.
323316
*
324317
* <p>
325-
* This method automatically detects the Solr deployment type and uses the
326-
* appropriate API:
327-
*
328-
* <ul>
329-
* <li><strong>SolrCloud</strong>: Uses Collections API to list distributed
330-
* collections
331-
* <li><strong>Standalone</strong>: Uses Core Admin API to list individual
332-
* collections
333-
* </ul>
318+
* This method uses the SolrCloud Collections API to retrieve the list of
319+
* available collections. Standalone Solr instances are not supported.
334320
*
335321
* <p>
336-
* In SolrCloud environments, the returned names may include shard identifiers
337-
* (e.g., "films_shard1_replica_n1"). Use {@link #extractCollectionName(String)}
338-
* to get the base collection name if needed.
322+
* The returned names may include shard identifiers (e.g.,
323+
* "films_shard1_replica_n1"). Use {@link #extractCollectionName(String)} to get
324+
* the base collection name if needed.
339325
*
340326
* <p>
341327
* <strong>Error Handling:</strong>
@@ -356,27 +342,16 @@ public List<String> completeCollectionForSchema() {
356342
* @return a list of collection names, or an empty list if unable to retrieve
357343
* them
358344
* @see CollectionAdminRequest.List
359-
* @see CoreAdminRequest
360345
*/
361346
@McpTool(name = "list-collections", description = "List solr collections")
362347
public List<String> listCollections() {
363348
try {
364-
if (solrClient instanceof CloudSolrClient) {
365-
// For SolrCloud - use Collections API
366-
CollectionAdminRequest.List request = new CollectionAdminRequest.List();
367-
CollectionAdminResponse response = request.process(solrClient);
349+
CollectionAdminRequest.List request = new CollectionAdminRequest.List();
350+
CollectionAdminResponse response = request.process(solrClient);
368351

369-
@SuppressWarnings("unchecked")
370-
List<String> collections = (List<String>) response.getResponse().get(COLLECTIONS_KEY);
371-
return collections != null ? collections : new ArrayList<>();
372-
} else {
373-
// For standalone Solr - use Core Admin API
374-
CoreAdminRequest coreAdminRequest = new CoreAdminRequest();
375-
coreAdminRequest.setAction(CoreAdminParams.CoreAdminAction.STATUS);
376-
CoreAdminResponse coreResponse = coreAdminRequest.process(solrClient);
377-
378-
return new ArrayList<>(coreResponse.getCoreStatus().keySet());
379-
}
352+
@SuppressWarnings("unchecked")
353+
List<String> collections = (List<String>) response.getResponse().get(COLLECTIONS_KEY);
354+
return collections != null ? collections : new ArrayList<>();
380355
} catch (SolrServerException | IOException _) {
381356
return new ArrayList<>();
382357
}
@@ -951,9 +926,8 @@ String extractCollectionName(String collectionOrShard) {
951926
* </ol>
952927
*
953928
* <p>
954-
* This dual approach ensures compatibility with both standalone Solr (which
955-
* returns collection names directly) and SolrCloud (which may return shard
956-
* names).
929+
* This dual approach ensures compatibility with SolrCloud environments where
930+
* shard names may be returned alongside collection names.
957931
*
958932
* <p>
959933
* <strong>Error Handling:</strong>

0 commit comments

Comments
 (0)