diff --git a/core-java/pom.xml b/core-java/pom.xml
index 8bd4d9b..f992595 100644
--- a/core-java/pom.xml
+++ b/core-java/pom.xml
@@ -68,6 +68,11 @@
org.apache.commons
commons-lang3
+
+ org.commonjava.util
+ http-testserver
+ test
+
\ No newline at end of file
diff --git a/core-java/src/main/java/org/commonjava/indy/client/core/o11y/metric/RequestContextHelper.java b/core-java/src/main/java/org/commonjava/indy/client/core/o11y/metric/RequestContextHelper.java
index 458677a..beea4d5 100644
--- a/core-java/src/main/java/org/commonjava/indy/client/core/o11y/metric/RequestContextHelper.java
+++ b/core-java/src/main/java/org/commonjava/indy/client/core/o11y/metric/RequestContextHelper.java
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2024 Red Hat, Inc.
+ * Copyright (C) 2023 Red Hat, Inc. (https://github.com/Commonjava/indy-client)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/core-java/src/main/java/org/commonjava/indy/client/core/o11y/trace/NameUtils.java b/core-java/src/main/java/org/commonjava/indy/client/core/o11y/trace/NameUtils.java
index 0436aa3..d5a675c 100644
--- a/core-java/src/main/java/org/commonjava/indy/client/core/o11y/trace/NameUtils.java
+++ b/core-java/src/main/java/org/commonjava/indy/client/core/o11y/trace/NameUtils.java
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2024 Red Hat, Inc.
+ * Copyright (C) 2023 Red Hat, Inc. (https://github.com/Commonjava/indy-client)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/core-java/src/main/java/org/commonjava/indy/client/core/o11y/trace/OtelProvider.java b/core-java/src/main/java/org/commonjava/indy/client/core/o11y/trace/OtelProvider.java
index 8a4c88c..a018966 100644
--- a/core-java/src/main/java/org/commonjava/indy/client/core/o11y/trace/OtelProvider.java
+++ b/core-java/src/main/java/org/commonjava/indy/client/core/o11y/trace/OtelProvider.java
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2024 Red Hat, Inc.
+ * Copyright (C) 2023 Red Hat, Inc. (https://github.com/Commonjava/indy-client)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/core-java/src/main/java/org/commonjava/indy/client/core/o11y/trace/SpanClosingResponse.java b/core-java/src/main/java/org/commonjava/indy/client/core/o11y/trace/SpanClosingResponse.java
index c7f4701..a657e9b 100644
--- a/core-java/src/main/java/org/commonjava/indy/client/core/o11y/trace/SpanClosingResponse.java
+++ b/core-java/src/main/java/org/commonjava/indy/client/core/o11y/trace/SpanClosingResponse.java
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2024 Red Hat, Inc.
+ * Copyright (C) 2023 Red Hat, Inc. (https://github.com/Commonjava/indy-client)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/core-java/src/main/java/org/commonjava/indy/client/core/o11y/trace/SpanProvider.java b/core-java/src/main/java/org/commonjava/indy/client/core/o11y/trace/SpanProvider.java
index 6610596..da71f44 100644
--- a/core-java/src/main/java/org/commonjava/indy/client/core/o11y/trace/SpanProvider.java
+++ b/core-java/src/main/java/org/commonjava/indy/client/core/o11y/trace/SpanProvider.java
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2024 Red Hat, Inc.
+ * Copyright (C) 2023 Red Hat, Inc. (https://github.com/Commonjava/indy-client)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/core-java/src/main/java/org/commonjava/indy/client/core/o11y/trace/SpanWrapper.java b/core-java/src/main/java/org/commonjava/indy/client/core/o11y/trace/SpanWrapper.java
index 6207b9b..a8f5ddb 100644
--- a/core-java/src/main/java/org/commonjava/indy/client/core/o11y/trace/SpanWrapper.java
+++ b/core-java/src/main/java/org/commonjava/indy/client/core/o11y/trace/SpanWrapper.java
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2024 Red Hat, Inc.
+ * Copyright (C) 2023 Red Hat, Inc. (https://github.com/Commonjava/indy-client)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/core-java/src/main/java/org/commonjava/indy/client/core/o11y/trace/SpanningHttpFactory.java b/core-java/src/main/java/org/commonjava/indy/client/core/o11y/trace/SpanningHttpFactory.java
index 625167a..d7149c9 100644
--- a/core-java/src/main/java/org/commonjava/indy/client/core/o11y/trace/SpanningHttpFactory.java
+++ b/core-java/src/main/java/org/commonjava/indy/client/core/o11y/trace/SpanningHttpFactory.java
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2024 Red Hat, Inc.
+ * Copyright (C) 2023 Red Hat, Inc. (https://github.com/Commonjava/indy-client)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/core-java/src/main/java/org/commonjava/indy/client/core/o11y/trace/TraceManager.java b/core-java/src/main/java/org/commonjava/indy/client/core/o11y/trace/TraceManager.java
index e6f242a..74d3636 100644
--- a/core-java/src/main/java/org/commonjava/indy/client/core/o11y/trace/TraceManager.java
+++ b/core-java/src/main/java/org/commonjava/indy/client/core/o11y/trace/TraceManager.java
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2024 Red Hat, Inc.
+ * Copyright (C) 2023 Red Hat, Inc. (https://github.com/Commonjava/indy-client)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/core-java/src/main/java/org/commonjava/indy/client/core/o11y/trace/TracerHttpClient.java b/core-java/src/main/java/org/commonjava/indy/client/core/o11y/trace/TracerHttpClient.java
index e238b7e..eae842f 100644
--- a/core-java/src/main/java/org/commonjava/indy/client/core/o11y/trace/TracerHttpClient.java
+++ b/core-java/src/main/java/org/commonjava/indy/client/core/o11y/trace/TracerHttpClient.java
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2024 Red Hat, Inc.
+ * Copyright (C) 2023 Red Hat, Inc. (https://github.com/Commonjava/indy-client)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/core-java/src/main/java/org/commonjava/indy/client/core/util/ThreadContext.java b/core-java/src/main/java/org/commonjava/indy/client/core/util/ThreadContext.java
index baea26e..6c29ea5 100644
--- a/core-java/src/main/java/org/commonjava/indy/client/core/util/ThreadContext.java
+++ b/core-java/src/main/java/org/commonjava/indy/client/core/util/ThreadContext.java
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2024 Red Hat, Inc.
+ * Copyright (C) 2023 Red Hat, Inc. (https://github.com/Commonjava/indy-client)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/core-java/src/test/java/org/commonjava/indy/client/core/AbstractIndyClientTest.java b/core-java/src/test/java/org/commonjava/indy/client/core/AbstractIndyClientTest.java
new file mode 100644
index 0000000..607d9af
--- /dev/null
+++ b/core-java/src/test/java/org/commonjava/indy/client/core/AbstractIndyClientTest.java
@@ -0,0 +1,113 @@
+/**
+ * Copyright (C) 2023 Red Hat, Inc. (https://github.com/Commonjava/indy-client)
+ *
+ * Licensed 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.
+ */
+package org.commonjava.indy.client.core;
+
+import org.apache.commons.io.IOUtils;
+import org.commonjava.indy.client.core.module.IndyStoreQueryClientModule;
+import org.commonjava.indy.client.core.module.IndyStoresClientModule;
+import org.commonjava.indy.client.core.util.UrlUtils;
+import org.commonjava.indy.model.core.Group;
+import org.commonjava.indy.model.core.HostedRepository;
+import org.commonjava.indy.model.core.RemoteRepository;
+import org.commonjava.indy.model.core.StoreKey;
+import org.commonjava.indy.model.core.StoreType;
+import org.commonjava.indy.model.core.io.IndyObjectMapper;
+import org.commonjava.test.http.expect.ExpectationServer;
+import org.commonjava.util.jhttpc.model.SiteConfig;
+import org.commonjava.util.jhttpc.model.SiteConfigBuilder;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.net.URL;
+import java.nio.charset.Charset;
+import java.util.Arrays;
+import java.util.Collection;
+
+import static org.commonjava.indy.client.core.util.UrlUtils.normalizePath;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertNotNull;
+
+public abstract class AbstractIndyClientTest
+{
+ private static final String BASE_STORE_PATH = "/api/admin/stores";
+
+ @Rule
+ public ExpectationServer server = new ExpectationServer();
+
+ private final IndyObjectMapper mapper = new IndyObjectMapper( false );
+
+ private Indy client;
+
+ @Before
+ public void setUp()
+ {
+ final String serviceUrl = UrlUtils.buildUrl( server.getBaseUri(), "api" );
+
+ SiteConfig config = new SiteConfigBuilder( "indy", serviceUrl ).withRequestTimeoutSeconds( 30 )
+ .withMetricEnabled( false )
+ .build();
+ Collection modules =
+ Arrays.asList( new IndyStoresClientModule(), new IndyStoreQueryClientModule() );
+
+ client = getClient( config, modules );
+ }
+
+ protected abstract Indy getClient(SiteConfig siteConfig, Collection modules);
+
+ @Test
+ public void testGetStores()
+ throws Exception
+ {
+ String path = normalizePath( BASE_STORE_PATH, "maven/remote/central" );
+ server.expect( path, 200, readResource( "repo-service/remote-central.json" ) );
+ StoreKey key = StoreKey.fromString( "maven:remote:central" );
+ RemoteRepository remote = client.module( IndyStoresClientModule.class ).load( key, RemoteRepository.class );
+ assertNotNull( remote );
+ assertThat( remote.getKey(), equalTo( key ) );
+ assertThat( remote.getType(), equalTo( StoreType.remote ) );
+
+ path = normalizePath( BASE_STORE_PATH, "maven/hosted/local-deployments" );
+ server.expect( path, 200, readResource( "repo-service/hosted-localdeploy.json" ) );
+ key = StoreKey.fromString( "maven:hosted:local-deployments" );
+ HostedRepository hosted = client.module( IndyStoresClientModule.class ).load( key, HostedRepository.class );
+ assertNotNull( hosted );
+ assertThat( hosted.getKey(), equalTo( key ) );
+ assertThat( hosted.getType(), equalTo( StoreType.hosted ) );
+
+ path = normalizePath( BASE_STORE_PATH, "maven/group/static" );
+ server.expect( path, 200, readResource( "repo-service/group-static.json" ) );
+ key = StoreKey.fromString( "maven:group:static" );
+ Group group = client.module( IndyStoresClientModule.class ).load( key, Group.class );
+ assertNotNull( group );
+ assertThat( group.getKey(), equalTo( key ) );
+ assertThat( group.getType(), equalTo( StoreType.group ) );
+ }
+
+ static String readResource( final String resourcePath )
+ throws IOException
+ {
+ URL url = Thread.currentThread().getContextClassLoader().getResource( resourcePath );
+ if ( url != null )
+ {
+ return IOUtils.toString( url.openStream(), Charset.defaultCharset() );
+ }
+ throw new IOException( String.format( "File not exists: %s", resourcePath ) );
+ }
+
+}
diff --git a/core-java/src/test/java/org/commonjava/indy/client/core/IndyClientWithTraceTest.java b/core-java/src/test/java/org/commonjava/indy/client/core/IndyClientWithTraceTest.java
new file mode 100644
index 0000000..1e1379e
--- /dev/null
+++ b/core-java/src/test/java/org/commonjava/indy/client/core/IndyClientWithTraceTest.java
@@ -0,0 +1,56 @@
+/**
+ * Copyright (C) 2023 Red Hat, Inc. (https://github.com/Commonjava/indy-client)
+ *
+ * Licensed 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.
+ */
+package org.commonjava.indy.client.core;
+
+import org.commonjava.indy.client.core.o11y.trace.ClientTracerConfiguration;
+import org.commonjava.indy.model.core.io.IndyObjectMapper;
+import org.commonjava.util.jhttpc.auth.MemoryPasswordManager;
+import org.commonjava.util.jhttpc.model.SiteConfig;
+
+import java.util.Collection;
+import java.util.Collections;
+
+public class IndyClientWithTraceTest
+ extends AbstractIndyClientTest
+{
+
+ @Override
+ protected Indy getClient( SiteConfig siteConfig, Collection modules )
+ {
+ try
+ {
+
+ final Indy.Builder builder = Indy.builder()
+ .setLocation( siteConfig )
+ .setObjectMapper( new IndyObjectMapper( Collections.emptySet() ) )
+ .setMdcCopyMappings( Collections.emptyMap() )
+ .setModules( modules.toArray( new IndyClientModule[0] ) );
+
+ ClientTracerConfiguration clientTracerConfig = new ClientTracerConfiguration();
+ clientTracerConfig.setEnabled( true );
+ clientTracerConfig.setConsoleTransport( true );
+ builder.setTraceConfiguration( clientTracerConfig );
+ builder.setPasswordManager( new MemoryPasswordManager() );
+
+ return builder.build();
+ }
+ catch ( IndyClientException e )
+ {
+ throw new RuntimeException( e );
+ }
+ }
+
+}
diff --git a/core-java/src/test/java/org/commonjava/indy/client/core/IndyClientWithoutTraceTest.java b/core-java/src/test/java/org/commonjava/indy/client/core/IndyClientWithoutTraceTest.java
new file mode 100644
index 0000000..86e30da
--- /dev/null
+++ b/core-java/src/test/java/org/commonjava/indy/client/core/IndyClientWithoutTraceTest.java
@@ -0,0 +1,48 @@
+/**
+ * Copyright (C) 2023 Red Hat, Inc. (https://github.com/Commonjava/indy-client)
+ *
+ * Licensed 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.
+ */
+package org.commonjava.indy.client.core;
+
+import org.commonjava.indy.model.core.io.IndyObjectMapper;
+import org.commonjava.util.jhttpc.auth.MemoryPasswordManager;
+import org.commonjava.util.jhttpc.model.SiteConfig;
+
+import java.util.Collection;
+import java.util.Collections;
+
+public class IndyClientWithoutTraceTest
+ extends AbstractIndyClientTest
+{
+ @Override
+ protected Indy getClient( SiteConfig siteConfig, Collection modules )
+ {
+ try
+ {
+
+ final Indy.Builder builder = Indy.builder()
+ .setLocation( siteConfig )
+ .setObjectMapper( new IndyObjectMapper( Collections.emptySet() ) )
+ .setMdcCopyMappings( Collections.emptyMap() )
+ .setModules( modules.toArray( new IndyClientModule[0] ) );
+ builder.setPasswordManager( new MemoryPasswordManager() );
+ return builder.build();
+ }
+ catch ( IndyClientException e )
+ {
+ throw new RuntimeException( e );
+ }
+ }
+
+}
diff --git a/core-java/src/test/resources/repo-service/group-static.json b/core-java/src/test/resources/repo-service/group-static.json
new file mode 100644
index 0000000..469f2bf
--- /dev/null
+++ b/core-java/src/test/resources/repo-service/group-static.json
@@ -0,0 +1,17 @@
+{
+ "type" : "group",
+ "key" : "maven:group:static",
+ "description" : "This group provides faster access to static data, that are stored in Indy.",
+ "metadata" : {
+ "changelog" : ""
+ },
+ "disabled" : false,
+ "constituents" : [ "maven:group:builds-untested+shared-imports" ],
+ "name" : "static",
+ "packageType" : "maven",
+ "disable_timeout" : -1,
+ "path_style" : "plain",
+ "authoritative_index" : false,
+ "create_time" : "2019-12-12 21:06:58 +0000",
+ "prepend_constituent" : false
+}
\ No newline at end of file
diff --git a/core-java/src/test/resources/repo-service/hosted-localdeploy.json b/core-java/src/test/resources/repo-service/hosted-localdeploy.json
new file mode 100644
index 0000000..0ff4987
--- /dev/null
+++ b/core-java/src/test/resources/repo-service/hosted-localdeploy.json
@@ -0,0 +1,15 @@
+{
+ "type" : "hosted",
+ "key" : "maven:hosted:local-deployments",
+ "disabled" : false,
+ "snapshotTimeoutSeconds" : 86400,
+ "readonly" : false,
+ "name" : "local-deployments",
+ "packageType" : "maven",
+ "disable_timeout" : 0,
+ "path_style" : "plain",
+ "authoritative_index" : false,
+ "create_time" : "2022-06-29 02:08:33 +0000",
+ "allow_snapshots" : true,
+ "allow_releases" : true
+}
\ No newline at end of file
diff --git a/core-java/src/test/resources/repo-service/remote-central.json b/core-java/src/test/resources/repo-service/remote-central.json
new file mode 100644
index 0000000..aa11cea
--- /dev/null
+++ b/core-java/src/test/resources/repo-service/remote-central.json
@@ -0,0 +1,27 @@
+{
+ "type" : "remote",
+ "key" : "maven:remote:central",
+ "disabled" : false,
+ "host" : "repo.maven.apache.org",
+ "port" : 443,
+ "name" : "central",
+ "packageType" : "maven",
+ "disable_timeout" : 0,
+ "path_style" : "plain",
+ "authoritative_index" : false,
+ "create_time" : "2022-06-29 02:08:33 +0000",
+ "allow_snapshots" : false,
+ "allow_releases" : true,
+ "url" : "https://repo.maven.apache.org/maven2/",
+ "timeout_seconds" : 0,
+ "max_connections" : 30,
+ "ignore_hostname_verification" : false,
+ "nfc_timeout_seconds" : 0,
+ "is_passthrough" : false,
+ "cache_timeout_seconds" : 86400,
+ "metadata_timeout_seconds" : 0,
+ "proxy_port" : 0,
+ "prefetch_priority" : 0,
+ "prefetch_rescan" : false,
+ "prefetch_listing_type" : "html"
+}
\ No newline at end of file