@Override public String getRelativePath(String identifier, boolean directory) { if (config.getAccessType() == objectspace) { return identifier; } else { String rootPath = rootSummary.getIdentifier(); String relativePath = identifier; if (identifier.startsWith(rootPath)) relativePath = identifier.substring(rootPath.length()); // remove leading and trailing slashes from relative path if (relativePath.startsWith("/")) relativePath = relativePath.substring(1); if (relativePath.endsWith("/")) relativePath = relativePath.substring(0, relativePath.length() - 1); return relativePath; } }
@Override public Iterable<ObjectSummary> allObjects() { if (config.getAccessType() == AtmosConfig.AccessType.objectspace) throw new UnsupportedOperationException("cannot enumerate objectspace"); // rootSummary is established inside configure(...) if (config.isIncludeTopFolder()) return Collections.singletonList(rootSummary); else return children(rootSummary); }
@Override public String getIdentifier(String relativePath, boolean directory) { if (config.getAccessType() == objectspace) { return relativePath; } else { if (!rootSummary.isDirectory() && relativePath != null && relativePath.length() > 0) throw new RuntimeException("target path is a file, but source is a directory"); // start with path in configuration String rootPath = rootSummary.getIdentifier(); if (relativePath == null) relativePath = ""; // shouldn't happen // remove leading slashes from relative path (there shouldn't be any though) if (relativePath.startsWith("/")) relativePath = relativePath.substring(1); // add trailing slash for directories if (directory) relativePath += "/"; // concatenate return rootPath + relativePath; } }
private ObjectIdentifier getObjectIdentifier(String identifier) { switch (config.getAccessType()) { case namespace: return new ObjectPath(identifier); case objectspace: default: return new ObjectId(identifier); } }
@Override public void configure(SyncStorage source, Iterator<SyncFilter> filters, SyncStorage target) { super.configure(source, filters, target); // The target must be an AtmosTarget plugin configured in // object space mode. if (!(target instanceof AtmosStorage)) { throw new ConfigurationException("This plugin is only compatible with Atmos Targets"); } if (((AtmosStorage) target).getConfig().getAccessType() != AtmosConfig.AccessType.objectspace) { throw new ConfigurationException("When using the Gladinet plugin, the Atmos Target must be in object mode, not namespace mode."); } this.targetAtmos = ((AtmosStorage) target).getAtmos(); if (baseDir == null) baseDir = ""; baseDir = baseDir.replace('\\', '/'); // Normalize it so it doesn't contain leading or trailing // slashes if (baseDir.startsWith("/")) { baseDir = baseDir.substring(1); } if (baseDir.endsWith("/")) { baseDir = baseDir.substring(0, baseDir.length() - 1); } // If a root directory was specified, make sure it exists if (!baseDir.isEmpty()) { String tag = getTag(baseDir); if (tag == null) { throw new ConfigurationException("The Gladinet base directory " + baseDir + " does not exist"); } } }
log.info("Connected to Atmos {} on {}", info.getAtmosVersion(), endpoints); if (config.getAccessType() == namespace) { if (config.getPath() == null) config.setPath("/"); if (!(source instanceof AtmosStorage && ((AtmosStorage) source).getConfig().getAccessType() == objectspace && getConfig().getAccessType() == objectspace)) throw new ConfigurationException("Preserving object IDs is only possible when both the source and target are Atmos using the objectspace access-type");
if (config.getAccessType() == objectspace) { log.debug("{} is a directory, but target is in objectspace, ignoring", identifier); return null; try { ObjectIdentifier targetId = null; if (config.getAccessType() == namespace) targetId = new ObjectPath(identifier);
@Override public SyncObject loadObject(final String identifier) throws ObjectNotFoundException { if (identifier == null) throw new ObjectNotFoundException(); try { if (config.getAccessType() == objectspace && !validObjectId(identifier)) throw new ObjectNotFoundException(identifier); ObjectIdentifier id = getObjectIdentifier(identifier); final com.emc.atmos.api.bean.ObjectMetadata atmosMeta = getAtmosMetadata(id); ObjectMetadata metadata = getSyncMeta(id, atmosMeta); Metadata uidMeta = atmosMeta.getMetadata().get(UID_PROP); String uid = uidMeta == null ? null : uidMeta.getValue(); ObjectAcl acl = getSyncAcl(uid, atmosMeta.getAcl()); LazyValue<InputStream> lazyStream = new LazyValue<InputStream>() { @Override public InputStream get() { return readDataStream(identifier); } }; SyncObject object = new SyncObject(this, getRelativePath(identifier, metadata.isDirectory()), metadata).withAcl(acl) .withLazyStream(lazyStream); object.setProperty(PROP_ATMOS_METADATA, atmosMeta); return object; } catch (AtmosException e) { if (e.getHttpCode() == 404) throw new ObjectNotFoundException(identifier, e); throw e; } }
@Override public void updateObject(String identifier, SyncObject object) { ObjectIdentifier targetId = config.getAccessType() == namespace ? new ObjectPath(identifier) : new ObjectId(identifier); com.emc.atmos.api.bean.ObjectMetadata sourceAtmosMeta = (com.emc.atmos.api.bean.ObjectMetadata) object.getProperty(PROP_ATMOS_METADATA);
Assert.assertEquals("source secret mismatch", sourceSecret, atmosSource.getSecret()); Assert.assertEquals("source path mismatch", sourcePath, atmosSource.getPath()); Assert.assertEquals("source accessType mismatch", sourceAccessType, atmosSource.getAccessType()); Assert.assertTrue("source removeTagsOnDelete should be enabled", atmosSource.isRemoveTagsOnDelete()); Assert.assertEquals("target protocol mismatch", targetProtocol, atmosTarget.getProtocol()); Assert.assertEquals("target secret mismatch", targetSecret, atmosTarget.getSecret()); Assert.assertEquals("target path mismatch", targetPath, atmosTarget.getPath()); Assert.assertEquals("target accessType mismatch", targetAccessType, atmosTarget.getAccessType()); Assert.assertEquals("target wsChecksumType mismatch", targetChecksum, atmosTarget.getWsChecksumType()); Assert.assertTrue("target replaceMetadata should be enabled", atmosTarget.isReplaceMetadata());