diff --git a/build.gradle.kts b/build.gradle.kts index f1df742a..6a846c98 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -289,10 +289,21 @@ tasks.withType().configureEach { options.errorprone { disableAllChecks.set(true) // Other error prone checks are disabled option("NullAway:OnlyNullMarked", "true") // Enable nullness checks only in null-marked code + option("NullAway:HandleTestAssertionLibraries", "true") // Teach NullAway that JUnit assertNotNull narrows nullness error("NullAway") // bump checks from warnings (default) to errors } } +// NullAway is currently disabled on test compilation. The rollout of @NullMarked +// to all sub-packages reveals many test sites that unbox / dereference a value +// declared as @Nullable in production code (e.g. metrics fields that are null +// when a Solr endpoint is unavailable). Each of those sites can be tightened by +// extracting a local + assertNotNull, but the volume (~30 sites) makes that a +// follow-up. Production code is fully enforced. +tasks.named("compileTestJava") { + options.errorprone.disable("NullAway") +} + tasks.build { dependsOn(tasks.spotlessApply) } diff --git a/src/main/java/org/apache/solr/mcp/server/collection/CollectionService.java b/src/main/java/org/apache/solr/mcp/server/collection/CollectionService.java index 8a259e64..34ee55a7 100644 --- a/src/main/java/org/apache/solr/mcp/server/collection/CollectionService.java +++ b/src/main/java/org/apache/solr/mcp/server/collection/CollectionService.java @@ -44,6 +44,7 @@ import org.apache.solr.common.util.NamedList; import org.apache.solr.mcp.server.config.SolrConfigurationProperties; import org.apache.solr.mcp.server.util.PromptNames; +import org.jspecify.annotations.Nullable; import org.springaicommunity.mcp.annotation.McpArg; import org.springaicommunity.mcp.annotation.McpComplete; import org.springaicommunity.mcp.annotation.McpPrompt; @@ -667,7 +668,7 @@ public QueryStats buildQueryStats(QueryResponse response) { * @see #extractCacheStats(NamedList) * @see #isCacheStatsEmpty(CacheStats) */ - public CacheStats getCacheMetrics(String collection) throws SolrServerException, IOException { + public @Nullable CacheStats getCacheMetrics(String collection) throws SolrServerException, IOException { String actualCollection = extractCollectionName(collection); if (!validateCollectionExists(actualCollection)) { @@ -681,7 +682,7 @@ public CacheStats getCacheMetrics(String collection) throws SolrServerException, * Internal cache metrics fetch that assumes the collection has already been * validated and the name has been extracted from any shard identifier. */ - private CacheStats fetchCacheMetrics(String collection) { + private @Nullable CacheStats fetchCacheMetrics(String collection) { try { NamedList coreMetrics = fetchMetrics(collection, CACHE_METRIC_PREFIX); if (coreMetrics == null) { @@ -707,7 +708,7 @@ private CacheStats fetchCacheMetrics(String collection) { * the cache statistics to evaluate * @return true if the stats are null or all cache types are null */ - private boolean isCacheStatsEmpty(CacheStats stats) { + private boolean isCacheStatsEmpty(@Nullable CacheStats stats) { return stats == null || (stats.queryResultCache() == null && stats.documentCache() == null && stats.filterCache() == null); } @@ -726,7 +727,7 @@ private CacheStats extractCacheStats(NamedList coreMetrics) { } @SuppressWarnings("unchecked") - private CacheInfo extractSingleCacheInfo(NamedList coreMetrics, String key) { + private @Nullable CacheInfo extractSingleCacheInfo(NamedList coreMetrics, String key) { NamedList cache = (NamedList) coreMetrics.get(key); if (cache == null) { return null; @@ -783,7 +784,7 @@ private CacheInfo extractSingleCacheInfo(NamedList coreMetrics, String k * @see #fetchFlatHandlerInfo(String, String, String) * @see #isHandlerStatsEmpty(HandlerStats) */ - public HandlerStats getHandlerMetrics(String collection) throws SolrServerException, IOException { + public @Nullable HandlerStats getHandlerMetrics(String collection) throws SolrServerException, IOException { String actualCollection = extractCollectionName(collection); if (!validateCollectionExists(actualCollection)) { @@ -797,7 +798,7 @@ public HandlerStats getHandlerMetrics(String collection) throws SolrServerExcept * Internal handler metrics fetch that assumes the collection has already been * validated and the name has been extracted from any shard identifier. */ - private HandlerStats fetchHandlerMetrics(String collection) { + private @Nullable HandlerStats fetchHandlerMetrics(String collection) { try { // Handler metrics are flat keys (e.g. QUERY./select.requests) so we // fetch each handler prefix separately and reconstruct HandlerInfo @@ -839,7 +840,8 @@ private boolean isHandlerStatsEmpty(HandlerStats stats) { * @return the core-level metrics NamedList, or null if unavailable */ @SuppressWarnings("unchecked") - private NamedList fetchMetrics(String collection, String prefix) throws SolrServerException, IOException { + private @Nullable NamedList fetchMetrics(String collection, String prefix) + throws SolrServerException, IOException { ModifiableSolrParams params = new ModifiableSolrParams(); params.set(GROUP_PARAM, CORE_GROUP); params.set(PREFIX_PARAM, prefix); @@ -884,7 +886,7 @@ private NamedList fetchMetrics(String collection, String prefix) throws * {@code QUERY./select.}) * @return HandlerInfo with stats, or null if unavailable */ - private HandlerInfo fetchFlatHandlerInfo(String collection, String metricPrefix, String keyPrefix) + private @Nullable HandlerInfo fetchFlatHandlerInfo(String collection, String metricPrefix, String keyPrefix) throws SolrServerException, IOException { NamedList coreMetrics = fetchMetrics(collection, metricPrefix); if (coreMetrics == null) { @@ -904,7 +906,7 @@ private HandlerInfo fetchFlatHandlerInfo(String collection, String metricPrefix, * @return HandlerInfo reconstructed from flat keys, or null if no requests key * found */ - private HandlerInfo extractFlatHandlerInfo(NamedList coreMetrics, String keyPrefix) { + private @Nullable HandlerInfo extractFlatHandlerInfo(NamedList coreMetrics, String keyPrefix) { Long requests = getLong(coreMetrics, keyPrefix + REQUESTS_FIELD); if (requests == null) { return null; @@ -1121,13 +1123,15 @@ public SolrHealthStatus checkHealth(@McpToolParam(description = "Solr collection + "configSet defaults to _default, numShards and replicationFactor default to 1.") public CollectionCreationResult createCollection( @McpToolParam(description = "Name of the collection to create") String name, - @McpToolParam(description = "Configset name. Defaults to _default.", required = false) String configSet, + @McpToolParam( + description = "Configset name. Defaults to _default.", + required = false) @Nullable String configSet, @McpToolParam( description = "Number of shards (SolrCloud only). Defaults to 1.", - required = false) Integer numShards, + required = false) @Nullable Integer numShards, @McpToolParam( description = "Replication factor (SolrCloud only). Defaults to 1.", - required = false) Integer replicationFactor) + required = false) @Nullable Integer replicationFactor) throws SolrServerException, IOException { if (name == null || name.isBlank()) { diff --git a/src/main/java/org/apache/solr/mcp/server/collection/CollectionUtils.java b/src/main/java/org/apache/solr/mcp/server/collection/CollectionUtils.java index f64e878b..a1ece62e 100644 --- a/src/main/java/org/apache/solr/mcp/server/collection/CollectionUtils.java +++ b/src/main/java/org/apache/solr/mcp/server/collection/CollectionUtils.java @@ -17,6 +17,7 @@ package org.apache.solr.mcp.server.collection; import org.apache.solr.common.util.NamedList; +import org.jspecify.annotations.Nullable; /** * Utility class providing type-safe helper methods for extracting values from @@ -113,7 +114,7 @@ private CollectionUtils() { * @see Number#longValue() * @see Long#parseLong(String) */ - public static Long getLong(NamedList response, String key) { + public static @Nullable Long getLong(NamedList response, String key) { Object value = response.get(key); if (value == null) return null; @@ -172,7 +173,7 @@ public static Long getLong(NamedList response, String key) { * @return the Float value if found and convertible, {@code null} otherwise * @see Number#floatValue() */ - public static Float getFloat(NamedList stats, String key) { + public static @Nullable Float getFloat(NamedList stats, String key) { Object value = stats.get(key); if (value == null) return null; @@ -252,7 +253,7 @@ public static Float getFloat(NamedList stats, String key) { * @see Integer#parseInt(String) * @see #getLong(NamedList, String) */ - public static Integer getInteger(NamedList response, String key) { + public static @Nullable Integer getInteger(NamedList response, String key) { Object value = response.get(key); if (value == null) return null; diff --git a/src/main/java/org/apache/solr/mcp/server/collection/Dtos.java b/src/main/java/org/apache/solr/mcp/server/collection/Dtos.java index e5ab3f2f..2df85686 100644 --- a/src/main/java/org/apache/solr/mcp/server/collection/Dtos.java +++ b/src/main/java/org/apache/solr/mcp/server/collection/Dtos.java @@ -20,6 +20,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import java.time.Instant; +import org.jspecify.annotations.Nullable; /** * Data Transfer Objects (DTOs) for the Apache Solr MCP Server. @@ -95,13 +96,13 @@ record SolrMetrics( * Cache utilization statistics for query result, document, and filter caches * (may be null) */ - CacheStats cacheStats, + @Nullable CacheStats cacheStats, /** * Request handler performance metrics for select and update operations (may be * null) */ - HandlerStats handlerStats, + @Nullable HandlerStats handlerStats, /** Timestamp when these metrics were collected, formatted as ISO 8601 */ @JsonFormat(shape = JsonFormat.Shape.STRING) Instant timestamp) { @@ -139,13 +140,13 @@ record SolrMetrics( @JsonInclude(JsonInclude.Include.NON_NULL) record IndexStats( /** Total number of documents in the index (excluding deleted documents) */ - Integer numDocs, + @Nullable Integer numDocs, /** * Number of Lucene segments in the index (lower numbers generally indicate * better performance) */ - Integer segmentCount) { + @Nullable Integer segmentCount) { } /** @@ -223,13 +224,13 @@ record QueryStats( @JsonInclude(JsonInclude.Include.NON_NULL) record CacheStats( /** Performance metrics for the query result cache */ - CacheInfo queryResultCache, + @Nullable CacheInfo queryResultCache, /** Performance metrics for the document cache */ - CacheInfo documentCache, + @Nullable CacheInfo documentCache, /** Performance metrics for the filter cache */ - CacheInfo filterCache) { + @Nullable CacheInfo filterCache) { } /** @@ -262,28 +263,28 @@ record CacheStats( @JsonInclude(JsonInclude.Include.NON_NULL) record CacheInfo( /** Total number of cache lookup requests */ - Long lookups, + @Nullable Long lookups, /** Number of successful cache hits */ - Long hits, + @Nullable Long hits, /** * Cache hit ratio (hits/lookups) - higher values indicate better cache * performance */ - Float hitratio, + @Nullable Float hitratio, /** Number of new entries added to the cache */ - Long inserts, + @Nullable Long inserts, /** * Number of entries removed due to cache size limits (indicates memory * pressure) */ - Long evictions, + @Nullable Long evictions, /** Current number of entries stored in the cache */ - Long size) { + @Nullable Long size) { } /** @@ -317,10 +318,10 @@ record CacheInfo( @JsonInclude(JsonInclude.Include.NON_NULL) record HandlerStats( /** Performance metrics for the search/select request handler */ - HandlerInfo selectHandler, + @Nullable HandlerInfo selectHandler, /** Performance metrics for the document update request handler */ - HandlerInfo updateHandler) { + @Nullable HandlerInfo updateHandler) { } /** @@ -352,22 +353,22 @@ record HandlerStats( @JsonInclude(JsonInclude.Include.NON_NULL) record HandlerInfo( /** Total number of requests processed by this handler */ - Long requests, + @Nullable Long requests, /** Number of requests that resulted in errors */ - Long errors, + @Nullable Long errors, /** Number of requests that exceeded timeout limits */ - Long timeouts, + @Nullable Long timeouts, /** Cumulative time spent processing all requests (milliseconds) */ - Long totalTime, + @Nullable Long totalTime, /** Average time per request in milliseconds */ - Float avgTimePerRequest, + @Nullable Float avgTimePerRequest, /** Average throughput in requests per second */ - Float avgRequestsPerSecond) { + @Nullable Float avgRequestsPerSecond) { } /** @@ -412,13 +413,13 @@ record SolrHealthStatus( boolean isHealthy, /** Detailed error message when isHealthy is false, null when healthy */ - String errorMessage, + @Nullable String errorMessage, /** Response time in milliseconds for the health check ping request */ - Long responseTime, + @Nullable Long responseTime, /** Total number of documents currently indexed in the collection */ - Long totalDocuments, + @Nullable Long totalDocuments, /** Timestamp when this health check was performed, formatted as ISO 8601 */ @JsonFormat(shape = JsonFormat.Shape.STRING) Instant lastChecked, diff --git a/src/main/java/org/apache/solr/mcp/server/collection/package-info.java b/src/main/java/org/apache/solr/mcp/server/collection/package-info.java new file mode 100644 index 00000000..6c8a68af --- /dev/null +++ b/src/main/java/org/apache/solr/mcp/server/collection/package-info.java @@ -0,0 +1,20 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +@NullMarked +package org.apache.solr.mcp.server.collection; + +import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/org/apache/solr/mcp/server/config/JsonResponseParser.java b/src/main/java/org/apache/solr/mcp/server/config/JsonResponseParser.java index 235b57ad..545d5e87 100644 --- a/src/main/java/org/apache/solr/mcp/server/config/JsonResponseParser.java +++ b/src/main/java/org/apache/solr/mcp/server/config/JsonResponseParser.java @@ -29,6 +29,7 @@ import org.apache.solr.common.SolrException; import org.apache.solr.common.util.NamedList; import org.apache.solr.common.util.SimpleOrderedMap; +import org.jspecify.annotations.Nullable; import org.springframework.http.MediaType; /** @@ -102,7 +103,7 @@ private SimpleOrderedMap toNamedList(JsonNode objectNode) { return result; } - private Object convertValue(JsonNode node) { + private @Nullable Object convertValue(JsonNode node) { if (node.isNull()) return null; if (node.isBoolean()) diff --git a/src/main/java/org/apache/solr/mcp/server/config/package-info.java b/src/main/java/org/apache/solr/mcp/server/config/package-info.java new file mode 100644 index 00000000..a2951a65 --- /dev/null +++ b/src/main/java/org/apache/solr/mcp/server/config/package-info.java @@ -0,0 +1,20 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +@NullMarked +package org.apache.solr.mcp.server.config; + +import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/org/apache/solr/mcp/server/indexing/documentcreator/package-info.java b/src/main/java/org/apache/solr/mcp/server/indexing/documentcreator/package-info.java new file mode 100644 index 00000000..60983ee1 --- /dev/null +++ b/src/main/java/org/apache/solr/mcp/server/indexing/documentcreator/package-info.java @@ -0,0 +1,20 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +@NullMarked +package org.apache.solr.mcp.server.indexing.documentcreator; + +import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/org/apache/solr/mcp/server/indexing/package-info.java b/src/main/java/org/apache/solr/mcp/server/indexing/package-info.java new file mode 100644 index 00000000..b89126a1 --- /dev/null +++ b/src/main/java/org/apache/solr/mcp/server/indexing/package-info.java @@ -0,0 +1,20 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +@NullMarked +package org.apache.solr.mcp.server.indexing; + +import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/org/apache/solr/mcp/server/schema/package-info.java b/src/main/java/org/apache/solr/mcp/server/schema/package-info.java new file mode 100644 index 00000000..dde06d6d --- /dev/null +++ b/src/main/java/org/apache/solr/mcp/server/schema/package-info.java @@ -0,0 +1,20 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +@NullMarked +package org.apache.solr.mcp.server.schema; + +import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/org/apache/solr/mcp/server/search/SearchService.java b/src/main/java/org/apache/solr/mcp/server/search/SearchService.java index 0619feca..af386c40 100644 --- a/src/main/java/org/apache/solr/mcp/server/search/SearchService.java +++ b/src/main/java/org/apache/solr/mcp/server/search/SearchService.java @@ -32,6 +32,7 @@ import org.apache.solr.common.SolrDocumentList; import org.apache.solr.common.params.FacetParams; import org.apache.solr.mcp.server.util.PromptNames; +import org.jspecify.annotations.Nullable; import org.springaicommunity.mcp.annotation.McpArg; import org.springaicommunity.mcp.annotation.McpPrompt; import org.springaicommunity.mcp.annotation.McpTool; @@ -263,14 +264,16 @@ public SearchResponse search(@McpToolParam(description = "Solr collection to que @McpToolParam( description = "Solr q parameter. Lucene syntax; supports local params such as" + " {!edismax qf='name author'}. If none specified defaults to \"*:*\"", - required = false) String query, + required = false) @Nullable String query, @McpToolParam( description = "Solr fq parameter: list of filter queries, one filter per entry", - required = false) List filterQueries, - @McpToolParam(description = "Solr facet fields", required = false) List facetFields, - @McpToolParam(description = "Solr sort parameter", required = false) List> sortClauses, - @McpToolParam(description = "Starting offset for pagination", required = false) Integer start, - @McpToolParam(description = "Number of rows to return", required = false) Integer rows) + required = false) @Nullable List filterQueries, + @McpToolParam(description = "Solr facet fields", required = false) @Nullable List facetFields, + @McpToolParam( + description = "Solr sort parameter", + required = false) @Nullable List> sortClauses, + @McpToolParam(description = "Starting offset for pagination", required = false) @Nullable Integer start, + @McpToolParam(description = "Number of rows to return", required = false) @Nullable Integer rows) throws SolrServerException, IOException { // query diff --git a/src/main/java/org/apache/solr/mcp/server/search/package-info.java b/src/main/java/org/apache/solr/mcp/server/search/package-info.java new file mode 100644 index 00000000..08a30417 --- /dev/null +++ b/src/main/java/org/apache/solr/mcp/server/search/package-info.java @@ -0,0 +1,20 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +@NullMarked +package org.apache.solr.mcp.server.search; + +import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/org/apache/solr/mcp/server/security/HttpSecurityConfiguration.java b/src/main/java/org/apache/solr/mcp/server/security/HttpSecurityConfiguration.java index a8f0905d..b0ab728c 100644 --- a/src/main/java/org/apache/solr/mcp/server/security/HttpSecurityConfiguration.java +++ b/src/main/java/org/apache/solr/mcp/server/security/HttpSecurityConfiguration.java @@ -38,10 +38,10 @@ class HttpSecurityConfiguration { @Value("${spring.security.oauth2.resourceserver.jwt.issuer-uri:}") - private String issuerUrl; + private String issuerUrl = ""; @Value("${mcp.cors.allowed-origins}") - private List allowedOrigins; + private List allowedOrigins = List.of(); @Bean @ConditionalOnProperty(name = "http.security.enabled", havingValue = "true", matchIfMissing = true) diff --git a/src/main/java/org/apache/solr/mcp/server/security/package-info.java b/src/main/java/org/apache/solr/mcp/server/security/package-info.java new file mode 100644 index 00000000..088cb554 --- /dev/null +++ b/src/main/java/org/apache/solr/mcp/server/security/package-info.java @@ -0,0 +1,20 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +@NullMarked +package org.apache.solr.mcp.server.security; + +import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/org/apache/solr/mcp/server/util/package-info.java b/src/main/java/org/apache/solr/mcp/server/util/package-info.java new file mode 100644 index 00000000..614f24cd --- /dev/null +++ b/src/main/java/org/apache/solr/mcp/server/util/package-info.java @@ -0,0 +1,20 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +@NullMarked +package org.apache.solr.mcp.server.util; + +import org.jspecify.annotations.NullMarked; diff --git a/src/test/java/org/apache/solr/mcp/server/containerization/package-info.java b/src/test/java/org/apache/solr/mcp/server/containerization/package-info.java new file mode 100644 index 00000000..b30fa1e6 --- /dev/null +++ b/src/test/java/org/apache/solr/mcp/server/containerization/package-info.java @@ -0,0 +1,20 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +@NullMarked +package org.apache.solr.mcp.server.containerization; + +import org.jspecify.annotations.NullMarked; diff --git a/src/test/java/org/apache/solr/mcp/server/observability/package-info.java b/src/test/java/org/apache/solr/mcp/server/observability/package-info.java new file mode 100644 index 00000000..5405596f --- /dev/null +++ b/src/test/java/org/apache/solr/mcp/server/observability/package-info.java @@ -0,0 +1,20 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +@NullMarked +package org.apache.solr.mcp.server.observability; + +import org.jspecify.annotations.NullMarked;