@Override public Distribution initialize() { return new Distribution(method, false); }
@Override public Void call() throws BackgroundException { try { if(null == distribution.getId()) { log.debug(String.format("No existing distribution found for method %s", distribution.getMethod())); if(distribution.getMethod().equals(Distribution.STREAMING)) { distribution.setId(createStreamingDistribution(container, distribution).getId()); else if(distribution.getMethod().equals(Distribution.DOWNLOAD)) { distribution.setId(createDownloadDistribution(container, distribution).getId()); else if(distribution.getMethod().equals(Distribution.CUSTOM) || distribution.getMethod().equals(Distribution.WEBSITE_CDN)) { distribution.setId(createCustomDistribution(container, distribution).getId()); if(distribution.getMethod().equals(Distribution.DOWNLOAD)) { distribution.setEtag(updateDownloadDistribution(container, distribution).getETag()); else if(distribution.getMethod().equals(Distribution.STREAMING)) { distribution.setEtag(updateStreamingDistribution(container, distribution).getETag()); else if(distribution.getMethod().equals(Distribution.CUSTOM) || distribution.getMethod().equals(Distribution.WEBSITE_CDN)) { distribution.setEtag(updateCustomDistribution(container, distribution).getETag());
/** * @param file File in origin container * @return CNAME to distribution */ private List<DescriptiveUrl> toCnameUrl(final Path file) { final List<DescriptiveUrl> urls = new ArrayList<DescriptiveUrl>(); for(String cname : distribution.getCNAMEs()) { final StringBuilder b = new StringBuilder(); b.append(String.format("%s://%s", distribution.getMethod().getScheme(), cname)).append(distribution.getMethod().getContext()); if(StringUtils.isNotEmpty(containerService.getKey(file))) { b.append(Path.DELIMITER).append(URIEncoder.encode(containerService.getKey(file))); } urls.add(new DescriptiveUrl(URI.create(b.toString()).normalize(), DescriptiveUrl.Type.cname, MessageFormat.format(LocaleFactory.localizedString("{0} URL"), LocaleFactory.localizedString(distribution.getMethod().toString(), "S3")))); } return urls; } }
protected void deleteDownloadDistribution(final Path container, final Distribution distribution) throws BackgroundException { final URI origin = this.getOrigin(container, distribution.getMethod()); if(log.isDebugEnabled()) { log.debug(String.format("Update %s distribution with origin %s", distribution.getMethod().toString(), origin)); } final AmazonCloudFront client = client(container); client.deleteDistribution(new DeleteDistributionRequest(distribution.getId(), distribution.getEtag())); }
protected UpdateDistributionResult updateCustomDistribution(final Path container, final Distribution distribution) throws BackgroundException { final URI origin = this.getOrigin(container, distribution.getMethod()); if(log.isDebugEnabled()) { log.debug(String.format("Update %s distribution with origin %s", distribution.getMethod().toString(), origin)); } final AmazonCloudFront client = client(container); final GetDistributionConfigResult response = client.getDistributionConfig(new GetDistributionConfigRequest(distribution.getId())); final DistributionConfig config = response.getDistributionConfig() .withEnabled(distribution.isEnabled()) .withDefaultRootObject(distribution.getIndexDocument() != null ? distribution.getIndexDocument() : StringUtils.EMPTY) .withAliases(new Aliases().withItems(distribution.getCNAMEs()).withQuantity(distribution.getCNAMEs().length)); // Make bucket name fully qualified final String loggingTarget = ServiceUtils.generateS3HostnameForBucket(distribution.getLoggingContainer(), false, new S3Protocol().getDefaultHostname()); if(log.isDebugEnabled()) { log.debug(String.format("Set logging target for %s to %s", distribution, loggingTarget)); } config.setLogging(new LoggingConfig() .withEnabled(distribution.isLogging()) .withIncludeCookies(true) .withBucket(loggingTarget) .withPrefix(preferences.getProperty("cloudfront.logging.prefix")) ); return client.updateDistribution(new UpdateDistributionRequest(config, distribution.getId(), response.getETag())); }
final GetStreamingDistributionConfigResult response = client.getStreamingDistributionConfig(new GetStreamingDistributionConfigRequest(summary.getId())); final StreamingDistributionConfig configuration = response.getStreamingDistributionConfig(); final Distribution distribution = new Distribution(this.getOrigin(container, method), method, summary.isEnabled()); distribution.setId(summary.getId()); distribution.setDeployed("Deployed".equals(summary.getStatus())); distribution.setUrl(URI.create(String.format("%s://%s%s", method.getScheme(), summary.getDomainName(), method.getContext()))); distribution.setSslUrl(method.equals(Distribution.DOWNLOAD) || method.equals(Distribution.CUSTOM) ? URI.create(String.format("https://%s%s", summary.getDomainName(), method.getContext())) : null); distribution.setReference(configuration.getCallerReference()); distribution.setEtag(response.getETag()); distribution.setStatus(LocaleFactory.localizedString(summary.getStatus(), "S3")); distribution.setCNAMEs(configuration.getAliases().getItems().toArray(new String[configuration.getAliases().getItems().size()])); distribution.setLogging(configuration.getLogging().isEnabled()); distribution.setLoggingContainer(StringUtils.isNotBlank(configuration.getLogging().getBucket()) ? ServiceUtils.findBucketNameInHostname(configuration.getLogging().getBucket(), new S3Protocol().getDefaultHostname()) : null); if(this.getFeature(Purge.class, method) != null) { distribution.setInvalidationStatus(this.readInvalidationStatus(client, distribution)); distribution.setContainers(new S3BucketListService(session, new S3LocationFeature.S3Region(session.getHost().getRegion())).list( new Path(String.valueOf(Path.DELIMITER), EnumSet.of(Path.Type.volume, Path.Type.directory)), new DisabledListProgressListener()).toList());
final CDNContainer info = session.getClient().getCDNContainerInfo(regionService.lookup(container), container.getName()); final Distribution distribution = new Distribution(regionService.lookup(container).getStorageUrl(container.getName()), method, info.isEnabled()); distribution.setId(info.getName()); distribution.setStatus(info.isEnabled() ? LocaleFactory.localizedString("CDN Enabled", "Mosso") : LocaleFactory.localizedString("CDN Disabled", "Mosso")); if(StringUtils.isNotBlank(info.getCdnURL())) { distribution.setUrl(URI.create(info.getCdnURL())); distribution.setSslUrl(URI.create(info.getSslURL())); distribution.setStreamingUrl(URI.create(info.getStreamingURL())); distribution.setiOSstreamingUrl(URI.create(info.getiOSStreamingURL())); distribution.setLogging(info.getRetainLogs()); distribution.setLoggingContainer(".CDN_ACCESS_LOGS"); final ContainerMetadata metadata = session.getClient().getContainerMetaData(regionService.lookup(container), container.getName()); if(metadata.getMetaData().containsKey("X-Container-Meta-Web-Index")) { distribution.setIndexDocument(metadata.getMetaData().get("X-Container-Meta-Web-Index")); distribution.setContainers(Collections.singletonList(new Path("/.CDN_ACCESS_LOGS", EnumSet.of(Path.Type.volume, Path.Type.directory)))); return distribution; final Distribution distribution = new Distribution(regionService.lookup(container).getStorageUrl(container.getName()), method, false); distribution.setStatus(LocaleFactory.localizedString("CDN Disabled", "Mosso")); return distribution;
@Override public Distribution read(final Path file, final Distribution.Method method, final LoginCallback prompt) throws BackgroundException { final Path container = containerService.getContainer(file); final URI origin = URI.create(String.format("%s://%s.%s", method.getScheme(), container.getName(), this.getHostname())); try { final WebsiteConfig configuration = session.getClient().getWebsiteConfigImpl(container.getName()); final Distribution distribution = new Distribution( origin, method, configuration.isWebsiteConfigActive()); distribution.setUrl(URI.create(String.format("%s://%s.%s", method.getScheme(), container.getName(), this.getHostname()))); distribution.setStatus(LocaleFactory.localizedString("Deployed", "S3")); distribution.setIndexDocument(configuration.getIndexDocumentSuffix()); final DistributionLogging logging = this.getFeature(DistributionLogging.class, method); if(logging != null) { final LoggingConfiguration c = new GoogleStorageLoggingFeature(session).getConfiguration(container); distribution.setLogging(c.isEnabled()); distribution.setLoggingContainer(c.getLoggingTarget()); distribution.setContainers(new S3BucketListService(session).list( new Path(String.valueOf(Path.DELIMITER), EnumSet.of(Path.Type.volume, Path.Type.directory)), new DisabledListProgressListener()).toList()); } return distribution; } catch(ServiceException e) { // Not found. Website configuration is disabled. final Distribution distribution = new Distribution(origin, method, false); distribution.setStatus(e.getErrorMessage()); distribution.setUrl(URI.create(String.format("%s://%s.%s", method.getScheme(), container.getName(), this.getHostname()))); return distribution; } }
final DistributionConfiguration cdn = session.getFeature(DistributionConfiguration.class); distributionEnableButton.setTitle(MessageFormat.format(LocaleFactory.localizedString("Enable {0} Distribution", "Status"), cdn.getName(distribution.getMethod()))); distributionEnableButton.setState(distribution.isEnabled() ? NSCell.NSOnState : NSCell.NSOffState); distributionStatusField.setAttributedStringValue(NSMutableAttributedString.create(distribution.getStatus(), TRUNCATE_MIDDLE_ATTRIBUTES)); distributionLoggingButton.setState(distribution.isLogging() ? NSCell.NSOnState : NSCell.NSOffState); final List<Path> containers = distribution.getContainers(); if(!containers.isEmpty()) { distributionLoggingPopup.removeAllItems(); if(StringUtils.isNotBlank(distribution.getLoggingContainer())) { distributionLoggingPopup.selectItemWithTitle(distribution.getLoggingContainer()); distributionAnalyticsSetupUrlField.setAttributedStringValue( HyperlinkAttributedStringFactory.create(analyticsFeature.getSetup(cdn.getHostname(), distribution.getMethod().getScheme(), file, credentials)) ); final String[] cnames = distribution.getCNAMEs(); if(0 == cnames.length) { distributionCnameField.setStringValue(StringUtils.EMPTY); if(cdn.getFeature(Index.class, distribution.getMethod()) != null) { for(Path next : distribution.getRootDocuments()) { if(next.isFile()) { distributionDefaultRootPopup.addItemWithTitle(next.getName());
@Action public void distributionApplyButtonClicked(final ID sender) { if(this.toggleDistributionSettings(false)) { final Distribution.Method method = Distribution.Method.forName(distributionDeliveryPopup.selectedItem().representedObject()); final Distribution configuration = new Distribution(method, distributionEnableButton.state() == NSCell.NSOnState); configuration.setIndexDocument(distributionDefaultRootPopup.selectedItem().representedObject()); configuration.setLogging(distributionLoggingButton.state() == NSCell.NSOnState); configuration.setLoggingContainer(distributionLoggingPopup.selectedItem().representedObject()); configuration.setCNAMEs(StringUtils.split(distributionCnameField.stringValue())); controller.background(new WorkerBackgroundAction<Boolean>(controller, session, new WriteDistributionWorker(files, prompt, configuration) { @Override public void cleanup(final Boolean result) { // Refresh the current distribution status distributionStatusButtonClicked(sender); } })); } }
@Override public Distribution read(final Path container, final Distribution.Method method, final LoginCallback prompt) throws BackgroundException { if(method.equals(Distribution.WEBSITE)) { try { final WebsiteConfig configuration = session.getClient().getWebsiteConfig(container.getName()); final Distribution distribution = new Distribution(this.getOrigin(container, method), method, configuration.isWebsiteConfigActive()); distribution.setStatus(LocaleFactory.localizedString("Deployed", "S3")); // http://example-bucket.s3-website-us-east-1.amazonaws.com/ distribution.setUrl(URI.create(String.format("%s://%s", method.getScheme(), this.getWebsiteHostname(container)))); distribution.setIndexDocument(configuration.getIndexDocumentSuffix()); distribution.setContainers(new S3BucketListService(session, new S3LocationFeature.S3Region(session.getHost().getRegion())).list( new Path(String.valueOf(Path.DELIMITER), EnumSet.of(Path.Type.volume, Path.Type.directory)), new DisabledListProgressListener()).toList()); return distribution; } catch(ServiceException e) { // Not found. Website configuration not enabled. final Distribution distribution = new Distribution(this.getOrigin(container, method), method, false); distribution.setStatus(e.getErrorMessage()); distribution.setUrl(URI.create(String.format("%s://%s", method.getScheme(), this.getWebsiteHostname(container)))); return distribution; } } else { return super.read(container, method, prompt); } }
@Override public void write(final Path file, final Distribution distribution, final LoginCallback prompt) throws BackgroundException { final Path container = containerService.getContainer(file); try { if(distribution.isEnabled()) { String suffix = "index.html"; if(StringUtils.isNotBlank(distribution.getIndexDocument())) { suffix = PathNormalizer.name(distribution.getIndexDocument()); } // Enable website endpoint session.getClient().setWebsiteConfigImpl(container.getName(), new GSWebsiteConfig(suffix)); final DistributionLogging logging = this.getFeature(DistributionLogging.class, distribution.getMethod()); if(logging != null) { new GoogleStorageLoggingFeature(session).setConfiguration(container, new LoggingConfiguration( distribution.isEnabled(), distribution.getLoggingContainer())); } } else { // Disable website endpoint session.getClient().setWebsiteConfigImpl(container.getName(), new GSWebsiteConfig()); } } catch(ServiceException e) { throw new S3ExceptionMappingService().map("Cannot write website configuration", e); } }
@Override public void write(final Path container, final Distribution distribution, final LoginCallback prompt) throws BackgroundException { if(distribution.getMethod().equals(Distribution.WEBSITE)) { try { if(distribution.isEnabled()) { String suffix = "index.html"; if(StringUtils.isNotBlank(distribution.getIndexDocument())) { suffix = PathNormalizer.name(distribution.getIndexDocument()); } // Enable website endpoint session.getClient().setWebsiteConfig(container.getName(), new S3WebsiteConfig(suffix)); } else { // Disable website endpoint session.getClient().deleteWebsiteConfig(container.getName()); } } catch(S3ServiceException e) { throw new S3ExceptionMappingService().map("Cannot write website configuration", e); } } else { super.write(container, distribution, prompt); } }
final Path container = containerService.getContainer(file); try { if(StringUtils.isNotBlank(configuration.getIndexDocument())) { session.getClient().updateContainerMetadata(regionService.lookup(container), container.getName(), Collections.singletonMap("X-Container-Meta-Web-Index", configuration.getIndexDocument())); container.getName(), -1, configuration.isEnabled(), configuration.isLogging());
@Override public DescriptiveUrlBag toUrl(final Path file) { final DescriptiveUrlBag list = new DescriptiveUrlBag(); list.add(new DescriptiveUrl(this.toUrl(file, distribution.getOrigin()), DescriptiveUrl.Type.origin, MessageFormat.format(LocaleFactory.localizedString("{0} URL"), LocaleFactory.localizedString("Origin", "Info")))); if(distribution.getUrl() != null) { list.add(new DescriptiveUrl(this.toUrl(file, distribution.getUrl()), DescriptiveUrl.Type.cdn, MessageFormat.format(LocaleFactory.localizedString("{0} URL"), LocaleFactory.localizedString(distribution.getMethod().toString(), "S3")))); } if(distribution.getSslUrl() != null) { list.add(new DescriptiveUrl(this.toUrl(file, distribution.getSslUrl()), DescriptiveUrl.Type.cdn, String.format("%s (SSL)", MessageFormat.format(LocaleFactory.localizedString("{0} URL"), LocaleFactory.localizedString(distribution.getMethod().toString(), "S3"))))); } if(distribution.getStreamingUrl() != null) { list.add(new DescriptiveUrl(this.toUrl(file, distribution.getStreamingUrl()), DescriptiveUrl.Type.cdn, String.format("%s (Streaming)", MessageFormat.format(LocaleFactory.localizedString("{0} URL"), LocaleFactory.localizedString(distribution.getMethod().toString(), "S3"))))); } if(distribution.getiOSstreamingUrl() != null) { list.add(new DescriptiveUrl(this.toUrl(file, distribution.getiOSstreamingUrl()), DescriptiveUrl.Type.cdn, String.format("%s (iOS Streaming)", MessageFormat.format(LocaleFactory.localizedString("{0} URL"), LocaleFactory.localizedString(distribution.getMethod().toString(), "S3"))))); } list.addAll(this.toCnameUrl(file)); return list; }
@Override public DescriptiveUrlBag toUrl(final Path file) { final Distribution distribution = new Distribution(URI.create(String.format("%s://%s.%s", Distribution.DOWNLOAD.getScheme(), containerService.getContainer(file).getName(), this.getHostname())), Distribution.DOWNLOAD, false); distribution.setUrl(URI.create(String.format("%s://%s.%s", Distribution.DOWNLOAD.getScheme(), containerService.getContainer(file).getName(), this.getHostname()))); return new DistributionUrlProvider(distribution).toUrl(file); }
@Override public Distribution run(final Session<?> session) throws BackgroundException { final DistributionConfiguration cdn = session.getFeature(DistributionConfiguration.class); for(Path file : this.getContainers(files)) { if(this.isCanceled()) { throw new ConnectionCanceledException(); } final Distribution distribution = cdn.read(file, method, prompt); if(cdn.getFeature(Index.class, distribution.getMethod()) != null) { // Make sure container items are cached for default root object. distribution.setRootDocuments(session.getFeature(ListService.class).list(containerService.getContainer(file), new DisabledListProgressListener()).toList()); } return distribution; } return this.initialize(); }
/** * @param file File in origin container * @param origin Distribution URL * @return URL to file in distribution */ private URI toUrl(final Path file, final URI origin) { final StringBuilder b = new StringBuilder(String.format("%s://%s", origin.getScheme(), origin.getHost())); if(distribution.getMethod().equals(Distribution.CUSTOM)) { b.append(Path.DELIMITER).append(URIEncoder.encode(PathRelativizer.relativize(origin.getRawPath(), file.getAbsolute()))); } else { if(StringUtils.isNotEmpty(origin.getRawPath())) { b.append(origin.getRawPath()); } if(StringUtils.isNotEmpty(containerService.getKey(file))) { b.append(Path.DELIMITER).append(URIEncoder.encode(containerService.getKey(file))); } } return URI.create(b.toString()).normalize(); }
@Override protected Map<Path, Distribution> operate(final PasswordCallback callback, final Path file) throws BackgroundException { final DistributionConfiguration feature = session.getFeature(DistributionConfiguration.class); if(null == feature) { return Collections.emptyMap(); } final AttributedList<Path> containers = new S3BucketListService(session, new S3LocationFeature.S3Region(session.getHost().getRegion())).list(file, new DisabledListProgressListener()); final Map<Path, Distribution> distributions = new ConcurrentHashMap<>(); for(Path container : containers) { for(Distribution.Method method : feature.getMethods(container)) { if(Distribution.WEBSITE.equals(method)) { continue; } if(Distribution.WEBSITE_CDN.equals(method)) { continue; } final Distribution distribution = feature.read(container, method, new DisabledLoginCallback()); if(distribution.isEnabled()) { if(log.isInfoEnabled()) { log.info(String.format("Cache distribution %s", distribution)); } distributions.put(container, distribution); } } } return distributions; } }
final URI origin = this.getOrigin(container, distribution.getMethod()); if(log.isDebugEnabled()) { log.debug(String.format("Update %s distribution with origin %s", distribution.getMethod().toString(), origin)); final GetDistributionConfigResult response = client.getDistributionConfig(new GetDistributionConfigRequest(distribution.getId())); final DistributionConfig config = response.getDistributionConfig() .withEnabled(distribution.isEnabled()) .withDefaultRootObject(distribution.getIndexDocument()) .withAliases(new Aliases().withItems(distribution.getCNAMEs()).withQuantity(distribution.getCNAMEs().length)); if(distribution.isLogging()) { final String loggingTarget = ServiceUtils.generateS3HostnameForBucket(distribution.getLoggingContainer(), false, new S3Protocol().getDefaultHostname()); if(log.isDebugEnabled()) { .withEnabled(distribution.isLogging()) .withIncludeCookies(true) .withBucket(loggingTarget) ); return client.updateDistribution(new UpdateDistributionRequest(config, distribution.getId(), response.getETag()));