/*
* Copyright 2014 Alexey Plotnik
*
* 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.stem.db;
import com.google.common.annotations.VisibleForTesting;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.stem.domain.BlobDescriptor;
import org.stem.domain.ExtendedBlobDescriptor;
import org.stem.transport.ops.DeleteBlobMessage;
import org.stem.transport.ops.ReadBlobMessage;
import org.stem.transport.ops.WriteBlobMessage;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class StorageService {
private static final Logger logger = LoggerFactory.getLogger(StorageService.class);
public static final StorageService instance = new StorageService();
private final Map<UUID, WriteController> wControllers;
private final Map<UUID, ReadController> rControllers;
public StorageService() {
wControllers = new HashMap<>(Layout.getInstance().getMountPoints().size());
rControllers = new HashMap<>(Layout.getInstance().getMountPoints().size());
}
@VisibleForTesting
public int getWriteCandidates(UUID disk) {
return wControllers.get(disk).getWriteCandidates();
}
public ExtendedBlobDescriptor write(WriteBlobMessage message) {
ExtendedBlobDescriptor descriptor = writeOnDisk(message);
updateRemoteIndex(descriptor);
return descriptor;
}
public byte[] read(ReadBlobMessage message) {
ReadController controller = rControllers.get(message.disk); // TODO: if not found?
return controller.read(message.fatFileIndex, message.offset, message.length);
}
public void delete(DeleteBlobMessage message) {
ReadController controller = rControllers.get(message.disk); // TODO: find by message directly
ExtendedBlobDescriptor desc = controller.delete(message.fatFileIndex, message.offset);
StorageNodeDescriptor.getMetaStoreClient().deleteReplica(desc.getKey(), message.disk);
}
private void updateRemoteIndex(ExtendedBlobDescriptor descriptor) {
try {
StorageNodeDescriptor.getMetaStoreClient().updateMeta(descriptor);
} catch (Exception e) {
throw new RuntimeException("Error writing index to meta store");
}
}
private ExtendedBlobDescriptor writeOnDisk(WriteBlobMessage message) {
try {
WriteController wc = wControllers.get(message.disk);
if (null == wc)
throw new RuntimeException(String.format("Mount point %s can not be found", message.disk));
BlobDescriptor descriptor = wc.write(message);
ExtendedBlobDescriptor extDescriptor = new ExtendedBlobDescriptor(message.key, message.getBlobSize(), message.disk, descriptor);
return extDescriptor;
} catch (Exception e) {
logger.error("Error writing blob on disk", e);
throw new RuntimeException(e);
}
}
public void submitFF(FatFile ff, MountPoint mp) {
assert ff.isBlank(); // TODO: normal check with Exception throw
WriteController controller = wControllers.get(mp.uuid);
if (null == controller)
throw new RuntimeException("shit happens"); // TODO: shit is bad
controller.submitBlankFF(ff);
}
public void init() {
for (MountPoint mp : Layout.getInstance().getMountPoints().values()) {
WriteController wc = new WriteController(mp);
ReadController rc = new ReadController(mp);
wControllers.put(mp.uuid, wc);
rControllers.put(mp.uuid, rc);
}
}
}