View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.eclipse.aether.internal.impl;
20  
21  import java.io.File;
22  import java.io.IOException;
23  import java.net.URI;
24  import java.util.Arrays;
25  import java.util.Collection;
26  import java.util.HashMap;
27  import java.util.List;
28  import java.util.Set;
29  
30  import org.eclipse.aether.DefaultRepositorySystemSession;
31  import org.eclipse.aether.RepositoryEvent;
32  import org.eclipse.aether.RepositoryEvent.EventType;
33  import org.eclipse.aether.internal.impl.filter.DefaultRemoteRepositoryFilterManager;
34  import org.eclipse.aether.internal.impl.filter.Filters;
35  import org.eclipse.aether.internal.test.util.TestFileUtils;
36  import org.eclipse.aether.internal.test.util.TestLocalRepositoryManager;
37  import org.eclipse.aether.internal.test.util.TestUtils;
38  import org.eclipse.aether.metadata.DefaultMetadata;
39  import org.eclipse.aether.metadata.Metadata;
40  import org.eclipse.aether.repository.LocalMetadataRegistration;
41  import org.eclipse.aether.repository.RemoteRepository;
42  import org.eclipse.aether.resolution.MetadataRequest;
43  import org.eclipse.aether.resolution.MetadataResult;
44  import org.eclipse.aether.spi.connector.ArtifactDownload;
45  import org.eclipse.aether.spi.connector.MetadataDownload;
46  import org.eclipse.aether.spi.connector.filter.RemoteRepositoryFilterSource;
47  import org.eclipse.aether.transfer.MetadataNotFoundException;
48  import org.junit.jupiter.api.AfterEach;
49  import org.junit.jupiter.api.BeforeEach;
50  import org.junit.jupiter.api.Test;
51  
52  import static org.junit.jupiter.api.Assertions.*;
53  
54  /**
55   */
56  public class DefaultMetadataResolverTest {
57  
58      private DefaultMetadataResolver resolver;
59  
60      private StubRepositoryConnectorProvider connectorProvider;
61  
62      private RemoteRepository repository;
63  
64      private DefaultRepositorySystemSession session;
65  
66      private Metadata metadata;
67  
68      private RecordingRepositoryConnector connector;
69  
70      private TestLocalRepositoryManager lrm;
71  
72      private HashMap<String, RemoteRepositoryFilterSource> remoteRepositoryFilterSources;
73  
74      private DefaultRemoteRepositoryFilterManager remoteRepositoryFilterManager;
75  
76      private RecordingRepositoryListener listener;
77  
78      @BeforeEach
79      void setup() throws Exception {
80          remoteRepositoryFilterSources = new HashMap<>();
81          remoteRepositoryFilterManager = new DefaultRemoteRepositoryFilterManager(remoteRepositoryFilterSources);
82  
83          session = TestUtils.newSession();
84          lrm = (TestLocalRepositoryManager) session.getLocalRepositoryManager();
85          connectorProvider = new StubRepositoryConnectorProvider();
86          resolver = new DefaultMetadataResolver(
87                  new StubRepositoryEventDispatcher(),
88                  new StaticUpdateCheckManager(true),
89                  connectorProvider,
90                  new StubRemoteRepositoryManager(),
91                  new StubSyncContextFactory(),
92                  new DefaultOfflineController(),
93                  remoteRepositoryFilterManager);
94          repository = new RemoteRepository.Builder(
95                          "test-DMRT",
96                          "default",
97                          TestFileUtils.createTempDir().toURI().toURL().toString())
98                  .build();
99          metadata = new DefaultMetadata("gid", "aid", "ver", "maven-metadata.xml", Metadata.Nature.RELEASE_OR_SNAPSHOT);
100         connector = new RecordingRepositoryConnector();
101         connectorProvider.setConnector(connector);
102 
103         listener = new RecordingRepositoryListener();
104         session.setRepositoryListener(listener);
105     }
106 
107     @AfterEach
108     void teardown() throws Exception {
109         TestFileUtils.deleteFile(new File(new URI(repository.getUrl())));
110         TestFileUtils.deleteFile(session.getLocalRepository().getBasedir());
111     }
112 
113     @Test
114     void testNoRepositoryFailing() {
115         MetadataRequest request = new MetadataRequest(metadata, null, "");
116         List<MetadataResult> results = resolver.resolveMetadata(session, Arrays.asList(request));
117 
118         assertEquals(1, results.size());
119 
120         MetadataResult result = results.get(0);
121         assertSame(request, result.getRequest());
122         assertNotNull(
123                 result.getException(),
124                 "" + (result.getMetadata() != null ? result.getMetadata().getFile() : result.getMetadata()));
125         assertEquals(MetadataNotFoundException.class, result.getException().getClass());
126 
127         assertNull(result.getMetadata());
128     }
129 
130     @Test
131     void testResolve() throws IOException {
132         connector.setExpectGet(metadata);
133 
134         // prepare "download"
135         File file = new File(
136                 session.getLocalRepository().getBasedir(),
137                 session.getLocalRepositoryManager().getPathForRemoteMetadata(metadata, repository, ""));
138 
139         TestFileUtils.writeString(file, file.getAbsolutePath());
140 
141         MetadataRequest request = new MetadataRequest(metadata, repository, "");
142         List<MetadataResult> results = resolver.resolveMetadata(session, Arrays.asList(request));
143 
144         assertEquals(1, results.size());
145 
146         MetadataResult result = results.get(0);
147         assertSame(request, result.getRequest());
148         assertNull(result.getException());
149         assertNotNull(result.getMetadata());
150         assertNotNull(result.getMetadata().getFile());
151 
152         assertEquals(file, result.getMetadata().getFile());
153         assertEquals(metadata, result.getMetadata().setFile(null));
154 
155         connector.assertSeenExpected();
156         Set<Metadata> metadataRegistration =
157                 ((TestLocalRepositoryManager) session.getLocalRepositoryManager()).getMetadataRegistration();
158         assertTrue(metadataRegistration.contains(metadata));
159         assertEquals(1, metadataRegistration.size());
160 
161         List<RepositoryEvent> events =
162                 listener.getEvents(EventType.METADATA_DOWNLOADING, EventType.METADATA_DOWNLOADED);
163         assertEquals(2, events.size());
164         assertSame(events.get(0).getTrace(), events.get(1).getTrace());
165 
166         RepositoryEvent event = events.get(0);
167         assertEquals(EventType.METADATA_DOWNLOADING, event.getType());
168         assertEquals(metadata, event.getMetadata());
169 
170         event = events.get(1);
171         assertEquals(EventType.METADATA_DOWNLOADED, event.getType());
172         assertEquals(metadata, event.getMetadata());
173         assertNull(event.getException());
174         assertNotNull(event.getFile());
175     }
176 
177     @Test
178     void testRemoveMetadataIfMissing() throws IOException {
179         connector = new RecordingRepositoryConnector() {
180 
181             @Override
182             public void get(
183                     Collection<? extends ArtifactDownload> artifactDownloads,
184                     Collection<? extends MetadataDownload> metadataDownloads) {
185                 super.get(artifactDownloads, metadataDownloads);
186                 for (MetadataDownload d : metadataDownloads) {
187                     d.setException(new MetadataNotFoundException(metadata, repository));
188                 }
189             }
190         };
191         connectorProvider.setConnector(connector);
192 
193         File file = new File(
194                 session.getLocalRepository().getBasedir(),
195                 session.getLocalRepositoryManager().getPathForRemoteMetadata(metadata, repository, ""));
196         TestFileUtils.writeString(file, file.getAbsolutePath());
197         metadata.setFile(file);
198 
199         MetadataRequest request = new MetadataRequest(metadata, repository, "");
200         request.setDeleteLocalCopyIfMissing(true);
201 
202         List<MetadataResult> results = resolver.resolveMetadata(session, Arrays.asList(request));
203         assertEquals(1, results.size());
204         MetadataResult result = results.get(0);
205 
206         assertNotNull(result.getException());
207         assertFalse(file.exists());
208     }
209 
210     @Test
211     void testOfflineSessionResolveMetadataMissing() {
212         session.setOffline(true);
213         MetadataRequest request = new MetadataRequest(metadata, repository, "");
214         List<MetadataResult> results = resolver.resolveMetadata(session, Arrays.asList(request));
215 
216         assertEquals(1, results.size());
217 
218         MetadataResult result = results.get(0);
219         assertSame(request, result.getRequest());
220         assertNotNull(result.getException());
221         assertNull(result.getMetadata());
222 
223         connector.assertSeenExpected();
224     }
225 
226     @Test
227     void testOfflineSessionResolveMetadata() throws IOException {
228         session.setOffline(true);
229 
230         String path = session.getLocalRepositoryManager().getPathForRemoteMetadata(metadata, repository, "");
231         File file = new File(session.getLocalRepository().getBasedir(), path);
232         TestFileUtils.writeString(file, file.getAbsolutePath());
233 
234         // set file to use in TestLRM find()
235         metadata = metadata.setFile(file);
236 
237         MetadataRequest request = new MetadataRequest(metadata, repository, "");
238         List<MetadataResult> results = resolver.resolveMetadata(session, Arrays.asList(request));
239 
240         assertEquals(1, results.size());
241         MetadataResult result = results.get(0);
242         assertSame(request, result.getRequest());
243         assertNull(result.getException(), String.valueOf(result.getException()));
244         assertNotNull(result.getMetadata());
245         assertNotNull(result.getMetadata().getFile());
246 
247         assertEquals(file, result.getMetadata().getFile());
248         assertEquals(metadata.setFile(null), result.getMetadata().setFile(null));
249 
250         connector.assertSeenExpected();
251     }
252 
253     @Test
254     void testFavorLocal() throws IOException {
255         lrm.add(session, new LocalMetadataRegistration(metadata));
256         String path = session.getLocalRepositoryManager().getPathForLocalMetadata(metadata);
257         File file = new File(session.getLocalRepository().getBasedir(), path);
258         TestFileUtils.writeString(file, file.getAbsolutePath());
259 
260         MetadataRequest request = new MetadataRequest(metadata, repository, "");
261         request.setFavorLocalRepository(true);
262 
263         resolver = new DefaultMetadataResolver(
264                 new StubRepositoryEventDispatcher(),
265                 new StaticUpdateCheckManager(true, true),
266                 connectorProvider,
267                 new StubRemoteRepositoryManager(),
268                 new StubSyncContextFactory(),
269                 new DefaultOfflineController(),
270                 remoteRepositoryFilterManager);
271 
272         List<MetadataResult> results = resolver.resolveMetadata(session, Arrays.asList(request));
273 
274         assertEquals(1, results.size());
275         MetadataResult result = results.get(0);
276         assertSame(request, result.getRequest());
277         assertNull(result.getException(), String.valueOf(result.getException()));
278 
279         connector.assertSeenExpected();
280     }
281 
282     @Test
283     void testResolveAlwaysAcceptFilter() throws IOException {
284         remoteRepositoryFilterSources.put("filter1", Filters.neverAcceptFrom("invalid repo id"));
285         remoteRepositoryFilterSources.put("filter2", Filters.alwaysAccept());
286         connector.setExpectGet(metadata);
287 
288         // prepare "download"
289         File file = new File(
290                 session.getLocalRepository().getBasedir(),
291                 session.getLocalRepositoryManager().getPathForRemoteMetadata(metadata, repository, ""));
292 
293         TestFileUtils.writeString(file, file.getAbsolutePath());
294 
295         MetadataRequest request = new MetadataRequest(metadata, repository, "");
296         List<MetadataResult> results = resolver.resolveMetadata(session, Arrays.asList(request));
297 
298         assertEquals(1, results.size());
299 
300         MetadataResult result = results.get(0);
301         assertSame(request, result.getRequest());
302         assertNull(result.getException());
303         assertNotNull(result.getMetadata());
304         assertNotNull(result.getMetadata().getFile());
305 
306         assertEquals(file, result.getMetadata().getFile());
307         assertEquals(metadata, result.getMetadata().setFile(null));
308 
309         connector.assertSeenExpected();
310         Set<Metadata> metadataRegistration =
311                 ((TestLocalRepositoryManager) session.getLocalRepositoryManager()).getMetadataRegistration();
312         assertTrue(metadataRegistration.contains(metadata));
313         assertEquals(1, metadataRegistration.size());
314     }
315 
316     @Test
317     void testResolveNeverAcceptFilter() throws IOException {
318         remoteRepositoryFilterSources.put("filter1", Filters.neverAcceptFrom("invalid repo id"));
319         remoteRepositoryFilterSources.put("filter2", Filters.neverAccept());
320         // connector.setExpectGet( metadata ); // should not see it
321 
322         // prepare "download"
323         File file = new File(
324                 session.getLocalRepository().getBasedir(),
325                 session.getLocalRepositoryManager().getPathForRemoteMetadata(metadata, repository, ""));
326 
327         TestFileUtils.writeString(file, file.getAbsolutePath());
328 
329         MetadataRequest request = new MetadataRequest(metadata, repository, "");
330         List<MetadataResult> results = resolver.resolveMetadata(session, Arrays.asList(request));
331 
332         assertEquals(1, results.size());
333 
334         MetadataResult result = results.get(0);
335         assertSame(request, result.getRequest());
336         assertNotNull(result.getException());
337         assertTrue(result.getException() instanceof MetadataNotFoundException);
338         assertEquals("never-accept", result.getException().getMessage());
339         assertNull(result.getMetadata());
340 
341         connector.assertSeenExpected();
342     }
343 
344     @Test
345     void testResolveAlwaysAcceptFromRepoFilter() throws IOException {
346         remoteRepositoryFilterSources.put("filter1", Filters.alwaysAcceptFrom(repository.getId()));
347         connector.setExpectGet(metadata);
348 
349         // prepare "download"
350         File file = new File(
351                 session.getLocalRepository().getBasedir(),
352                 session.getLocalRepositoryManager().getPathForRemoteMetadata(metadata, repository, ""));
353 
354         TestFileUtils.writeString(file, file.getAbsolutePath());
355 
356         MetadataRequest request = new MetadataRequest(metadata, repository, "");
357         List<MetadataResult> results = resolver.resolveMetadata(session, Arrays.asList(request));
358 
359         assertEquals(1, results.size());
360 
361         MetadataResult result = results.get(0);
362         assertSame(request, result.getRequest());
363         assertNull(result.getException());
364         assertNotNull(result.getMetadata());
365         assertNotNull(result.getMetadata().getFile());
366 
367         assertEquals(file, result.getMetadata().getFile());
368         assertEquals(metadata, result.getMetadata().setFile(null));
369 
370         connector.assertSeenExpected();
371         Set<Metadata> metadataRegistration =
372                 ((TestLocalRepositoryManager) session.getLocalRepositoryManager()).getMetadataRegistration();
373         assertTrue(metadataRegistration.contains(metadata));
374         assertEquals(1, metadataRegistration.size());
375     }
376 
377     @Test
378     void testResolveNeverAcceptFromRepoFilter() throws IOException {
379         remoteRepositoryFilterSources.put("filter1", Filters.neverAcceptFrom(repository.getId()));
380         // connector.setExpectGet( metadata ); // should not see it
381 
382         // prepare "download"
383         File file = new File(
384                 session.getLocalRepository().getBasedir(),
385                 session.getLocalRepositoryManager().getPathForRemoteMetadata(metadata, repository, ""));
386 
387         TestFileUtils.writeString(file, file.getAbsolutePath());
388 
389         MetadataRequest request = new MetadataRequest(metadata, repository, "");
390         List<MetadataResult> results = resolver.resolveMetadata(session, Arrays.asList(request));
391 
392         assertEquals(1, results.size());
393 
394         MetadataResult result = results.get(0);
395         assertSame(request, result.getRequest());
396         assertNotNull(result.getException());
397         assertTrue(result.getException() instanceof MetadataNotFoundException);
398         assertEquals("never-accept-" + repository.getId(), result.getException().getMessage());
399         assertNull(result.getMetadata());
400 
401         connector.assertSeenExpected();
402     }
403 }