1 package ch
.cyberduck
.core
.openstack
;
4 * Copyright (c) 2013 David Kocher. All rights reserved.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * Bug fixes, suggestions and comments should be sent to:
18 * feedback@cyberduck.ch
21 import ch
.cyberduck
.core
.AttributedList
;
22 import ch
.cyberduck
.core
.DefaultIOExceptionMappingService
;
23 import ch
.cyberduck
.core
.DisabledLoginCallback
;
24 import ch
.cyberduck
.core
.ListProgressListener
;
25 import ch
.cyberduck
.core
.Path
;
26 import ch
.cyberduck
.core
.PathAttributes
;
27 import ch
.cyberduck
.core
.RootListService
;
28 import ch
.cyberduck
.core
.cdn
.Distribution
;
29 import ch
.cyberduck
.core
.cdn
.DistributionConfiguration
;
30 import ch
.cyberduck
.core
.exception
.BackgroundException
;
31 import ch
.cyberduck
.core
.preferences
.Preferences
;
32 import ch
.cyberduck
.core
.preferences
.PreferencesFactory
;
33 import ch
.cyberduck
.core
.threading
.ThreadPool
;
35 import org
.apache
.commons
.lang3
.StringUtils
;
36 import org
.apache
.log4j
.Logger
;
38 import java
.io
.IOException
;
39 import java
.util
.ArrayList
;
40 import java
.util
.EnumSet
;
41 import java
.util
.List
;
43 import ch
.iterate
.openstack
.swift
.Client
;
44 import ch
.iterate
.openstack
.swift
.exception
.GenericException
;
45 import ch
.iterate
.openstack
.swift
.model
.Container
;
46 import ch
.iterate
.openstack
.swift
.model
.ContainerInfo
;
47 import ch
.iterate
.openstack
.swift
.model
.Region
;
52 public class SwiftContainerListService
implements RootListService
{
53 private static final Logger log
= Logger
.getLogger(SwiftContainerListService
.class);
55 private final ThreadPool pool
= new ThreadPool("cdn");
57 private SwiftSession session
;
59 private Preferences preferences
60 = PreferencesFactory
.get();
66 private SwiftLocationFeature
.SwiftRegion region
;
68 public SwiftContainerListService(final SwiftSession session
, final SwiftLocationFeature
.SwiftRegion region
) {
70 PreferencesFactory
.get().getBoolean("openstack.cdn.preload"),
71 PreferencesFactory
.get().getBoolean("openstack.container.size.preload"));
74 public SwiftContainerListService(final SwiftSession session
, final SwiftLocationFeature
.SwiftRegion region
,
75 final boolean cdn
, final boolean size
) {
76 this.session
= session
;
83 public List
<Path
> list(final ListProgressListener listener
) throws BackgroundException
{
84 if(log
.isDebugEnabled()) {
85 log
.debug(String
.format("List containers for %s", session
));
88 final List
<Path
> containers
= new ArrayList
<Path
>();
89 final int limit
= preferences
.getInteger("openstack.list.container.limit");
90 final Client client
= session
.getClient();
91 for(final Region r
: client
.getRegions()) {
92 if(region
.getIdentifier() != null) {
93 if(!StringUtils
.equals(r
.getRegionId(), region
.getIdentifier())) {
94 log
.warn(String
.format("Skip region %s", r
));
98 // List all containers
99 List
<Container
> chunk
;
100 String marker
= null;
102 chunk
= client
.listContainers(r
, limit
, marker
);
103 for(final Container f
: chunk
) {
104 final PathAttributes attributes
= new PathAttributes();
105 attributes
.setRegion(f
.getRegion().getRegionId());
106 containers
.add(new Path(String
.format("/%s", f
.getName()),
107 EnumSet
.of(Path
.Type
.volume
, Path
.Type
.directory
), attributes
));
108 marker
= f
.getName();
110 listener
.chunk(new Path(String
.valueOf(Path
.DELIMITER
), EnumSet
.of(Path
.Type
.volume
, Path
.Type
.directory
)),
111 new AttributedList
<Path
>(containers
));
113 while(!chunk
.isEmpty());
115 final DistributionConfiguration feature
= session
.getFeature(DistributionConfiguration
.class);
116 if(feature
!= null) {
117 for(final Path container
: containers
) {
118 pool
.execute(new Runnable() {
121 for(Distribution
.Method method
: feature
.getMethods(container
)) {
123 final Distribution distribution
= feature
.read(container
, method
, new DisabledLoginCallback());
124 if(log
.isInfoEnabled()) {
125 log
.info(String
.format("Cached distribution %s", distribution
));
128 catch(BackgroundException e
) {
129 log
.warn(String
.format("Failure caching CDN configuration for container %s %s", container
, e
.getMessage()));
138 for(final Path container
: containers
) {
139 pool
.execute(new Runnable() {
143 final ContainerInfo info
= client
.getContainerInfo(r
, container
.getName());
144 container
.attributes().setSize(info
.getTotalSize());
146 catch(IOException e
) {
147 log
.warn(String
.format("Failure reading info for container %s %s", container
, e
.getMessage()));
156 catch(GenericException e
) {
157 throw new SwiftExceptionMappingService().map("Listing directory {0} failed", e
,
158 new Path(String
.valueOf(Path
.DELIMITER
), EnumSet
.of(Path
.Type
.volume
, Path
.Type
.directory
)));
160 catch(IOException e
) {
161 throw new DefaultIOExceptionMappingService().map(e
);
164 // Shutdown gracefully