/* * Copyright 2016 The Simple File Server Authors * * 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.sfs.vo; import com.google.common.base.Optional; import io.vertx.core.MultiMap; import io.vertx.core.json.JsonArray; import io.vertx.core.json.JsonObject; import org.sfs.SfsRequest; import org.sfs.metadata.Metadata; import java.util.ArrayList; import java.util.Calendar; import java.util.List; import java.util.SortedSet; import static com.google.common.base.Optional.fromNullable; import static com.google.common.base.Preconditions.checkState; import static com.google.common.primitives.Ints.tryParse; import static java.lang.Integer.parseInt; import static java.util.Calendar.getInstance; import static org.sfs.metadata.Metadata.container; import static org.sfs.util.DateFormatter.fromDateTimeString; import static org.sfs.util.DateFormatter.toDateTimeString; import static org.sfs.util.KnownMetadataKeys.X_MAX_OBJECT_REVISIONS; import static org.sfs.util.KnownMetadataKeys.X_SERVER_SIDE_ENCRYPTION; import static org.sfs.util.KnownMetadataKeys.X_TEMP_URL_KEY; import static org.sfs.util.KnownMetadataKeys.X_TEMP_URL_KEY_2; import static org.sfs.util.Limits.MAX_OBJECT_REVISIONS; import static org.sfs.util.Limits.NOT_SET; import static org.sfs.util.NullSafeAscii.equalsIgnoreCase; import static org.sfs.util.SfsHttpHeaders.X_SFS_OBJECT_REPLICAS; import static org.sfs.vo.ObjectPath.fromPaths; public abstract class Container<T extends Container> { private final PersistentAccount parent; private final String id; private final String name; private String nodeId; private Metadata metadata = container(); private String ownerGuid; private Calendar createTs; private Calendar updateTs; private Integer objectReplicas; public Container(PersistentAccount parent, String id) { this.parent = parent; this.id = id; if (this.id != null) { this.name = fromPaths(id).containerName().get(); } else { this.name = null; } } public String getName() { return name; } public String getId() { return id; } public Optional<String> getNodeId() { return fromNullable(nodeId); } public T setNodeId(String nodeId) { this.nodeId = nodeId; return (T) this; } public PersistentAccount getParent() { return parent; } public T setOwnerGuid(String ownerGuid) { this.ownerGuid = ownerGuid; return (T) this; } public List<String> getTempUrlKeys() { List<String> keys = new ArrayList<>(2); SortedSet<String> values = metadata.get(X_TEMP_URL_KEY_2); if (!values.isEmpty()) { keys.add(values.first()); } values = metadata.get(X_TEMP_URL_KEY); if (!values.isEmpty()) { keys.add(values.first()); } if (!keys.isEmpty()) { return keys; } else { return getParent().getTempUrlKeys(); } } public int getMaxObjectRevisions() { SortedSet<String> value = metadata.get(X_MAX_OBJECT_REVISIONS); if (!value.isEmpty()) { Integer maxRevisions = tryParse(value.first()); if (maxRevisions != null) { return maxRevisions; } } return MAX_OBJECT_REVISIONS; } public Optional<String> getOwnerGuid() { return fromNullable(ownerGuid); } public Metadata getMetadata() { return metadata; } public Calendar getCreateTs() { if (createTs == null) createTs = getInstance(); return createTs; } public T setCreateTs(Calendar createTs) { this.createTs = createTs; return (T) this; } public Calendar getUpdateTs() { if (updateTs == null) updateTs = getInstance(); return updateTs; } public T setUpdateTs(Calendar updateTs) { this.updateTs = updateTs; return (T) this; } public boolean getServerSideEncryption() { SortedSet<String> value = metadata.get(X_SERVER_SIDE_ENCRYPTION); if (!value.isEmpty()) { return equalsIgnoreCase("true", value.first()); } return false; } public int getObjectReplicas() { return objectReplicas != null ? NOT_SET : objectReplicas; } public T setObjectReplicas(int objectReplicas) { this.objectReplicas = objectReplicas; return (T) this; } public T merge(JsonObject document) { checkState(getParent().getId().equals(document.getString("account_id"))); setOwnerGuid(document.getString("owner_guid")); JsonArray metadataJsonObject = document.getJsonArray("metadata", new JsonArray()); getMetadata().withJsonObject(metadataJsonObject); setNodeId(document.getString("node_id")); String createTimestamp = document.getString("create_ts"); String updateTimestamp = document.getString("update_ts"); if (createTimestamp != null) { setCreateTs(fromDateTimeString(createTimestamp)); } if (updateTimestamp != null) { setUpdateTs(fromDateTimeString(updateTimestamp)); } setObjectReplicas(document.containsKey("object_replicas") ? document.getInteger("object_replicas") : NOT_SET); return (T) this; } public T merge(SfsRequest httpServerRequest) { MultiMap headers = httpServerRequest.headers(); if (headers.contains(X_SFS_OBJECT_REPLICAS)) { setObjectReplicas(parseInt(headers.get(X_SFS_OBJECT_REPLICAS))); } else { setObjectReplicas(NOT_SET); } getMetadata().withHttpHeaders(headers); return (T) this; } public JsonObject toJsonObject() { JsonObject document = new JsonObject(); document.put("owner_guid", ownerGuid); document.put("account_id", parent.getId()); document.put("metadata", metadata.toJsonObject()); document.put("node_id", nodeId); document.put("create_ts", toDateTimeString(getCreateTs())); document.put("update_ts", toDateTimeString(getUpdateTs())); document.put("object_replicas", objectReplicas); return document; } }