Search in sources :

Example 1 with BlobDeduper

use of com.zimbra.cs.store.file.BlobDeduper in project zm-mailbox by Zimbra.

the class DedupeBlobs method handle.

@Override
public Element handle(Element request, Map<String, Object> context) throws ServiceException {
    ZimbraSoapContext zsc = getZimbraSoapContext(context);
    checkRight(zsc, context, null, AdminRight.PR_SYSTEM_ADMIN_ONLY);
    StoreManager sm = StoreManager.getInstance();
    if (!(sm instanceof FileBlobStore)) {
        throw ServiceException.INVALID_REQUEST(sm.getClass().getName() + " is not supported", null);
    }
    DedupeBlobsRequest req = zsc.elementToJaxb(request);
    BlobDeduper deduper = BlobDeduper.getInstance();
    DedupeBlobsResponse resp = new DedupeBlobsResponse();
    // Assemble the list of volumes.
    List<IntIdAttr> volumeList = req.getVolumes();
    List<Short> volumeIds = new ArrayList<Short>();
    if ((req.getAction() == DedupeBlobsRequest.DedupAction.start) || (req.getAction() == DedupeBlobsRequest.DedupAction.reset)) {
        if (volumeList.isEmpty()) {
            // Get all message volume id's.
            for (Volume vol : VolumeManager.getInstance().getAllVolumes()) {
                switch(vol.getType()) {
                    case Volume.TYPE_MESSAGE:
                    case Volume.TYPE_MESSAGE_SECONDARY:
                        volumeIds.add(vol.getId());
                        break;
                }
            }
        } else {
            // Read volume id's from the request.
            for (IntIdAttr attr : volumeList) {
                short volumeId = (short) attr.getId();
                Volume vol = VolumeManager.getInstance().getVolume(volumeId);
                if (vol.getType() == Volume.TYPE_INDEX) {
                    throw ServiceException.INVALID_REQUEST("Index volume " + volumeId + " is not supported", null);
                } else {
                    volumeIds.add(volumeId);
                }
            }
        }
    }
    if (req.getAction() == DedupeBlobsRequest.DedupAction.start) {
        try {
            deduper.process(volumeIds);
        } catch (IOException e) {
            throw ServiceException.FAILURE("error while deduping", e);
        }
    } else if (req.getAction() == DedupeBlobsRequest.DedupAction.stop) {
        deduper.stopProcessing();
    } else if (req.getAction() == DedupeBlobsRequest.DedupAction.reset) {
        if (volumeList.isEmpty()) {
            deduper.resetVolumeBlobs(new ArrayList<Short>());
        } else {
            deduper.resetVolumeBlobs(volumeIds);
        }
    }
    // return the stats for all actions.
    boolean isRunning = deduper.isRunning();
    if (isRunning) {
        resp.setStatus(DedupStatus.running);
    } else {
        resp.setStatus(DedupStatus.stopped);
    }
    Map<Short, String> volumeBlobsProgress = deduper.getVolumeBlobsProgress();
    VolumeIdAndProgress[] blobProgress = new VolumeIdAndProgress[volumeBlobsProgress.size()];
    int i = 0;
    for (Map.Entry<Short, String> entry : volumeBlobsProgress.entrySet()) {
        blobProgress[i++] = new VolumeIdAndProgress(String.valueOf(entry.getKey()), entry.getValue());
    }
    resp.setVolumeBlobsProgress(blobProgress);
    Map<Short, String> blobDigestsProgress = deduper.getBlobDigestsProgress();
    VolumeIdAndProgress[] digestProgress = new VolumeIdAndProgress[blobDigestsProgress.size()];
    i = 0;
    for (Map.Entry<Short, String> entry : blobDigestsProgress.entrySet()) {
        digestProgress[i++] = new VolumeIdAndProgress(String.valueOf(entry.getKey()), entry.getValue());
    }
    resp.setBlobDigestsProgress(digestProgress);
    Pair<Integer, Long> pair = deduper.getCountAndSize();
    resp.setTotalCount(pair.getFirst());
    resp.setTotalSize(pair.getSecond());
    return zsc.jaxbToElement(resp);
}
Also used : DedupeBlobsRequest(com.zimbra.soap.admin.message.DedupeBlobsRequest) BlobDeduper(com.zimbra.cs.store.file.BlobDeduper) ArrayList(java.util.ArrayList) StoreManager(com.zimbra.cs.store.StoreManager) IntIdAttr(com.zimbra.soap.admin.type.IntIdAttr) DedupeBlobsResponse(com.zimbra.soap.admin.message.DedupeBlobsResponse) FileBlobStore(com.zimbra.cs.store.file.FileBlobStore) VolumeIdAndProgress(com.zimbra.soap.admin.type.VolumeIdAndProgress) IOException(java.io.IOException) Volume(com.zimbra.cs.volume.Volume) ZimbraSoapContext(com.zimbra.soap.ZimbraSoapContext) Map(java.util.Map)

Example 2 with BlobDeduper

use of com.zimbra.cs.store.file.BlobDeduper in project zm-mailbox by Zimbra.

the class TestBlobDeduper method testBlobDeduper.

@Test
public void testBlobDeduper() throws Exception {
    StoreManager storeMgr = StoreManager.getInstance();
    TestUtil.assumeTrue(String.format("StoreManager class=%s is not FileBlobStore", storeMgr.getClass().getName()), storeMgr instanceof FileBlobStore);
    DeliveryOptions opt = new DeliveryOptions();
    opt.setFolderId(Mailbox.ID_FOLDER_INBOX);
    String[] paths = new String[5];
    Volume vol = VolumeManager.getInstance().getCurrentMessageVolume();
    for (int i = 0; i < 5; i++) {
        Message msg = mbox.addMessage(null, new ParsedMessage(("From: test@zimbra.com\r\nTo: to1@zimbra.com\r\nSubject: " + TEST_NAME).getBytes(), false), opt, null);
        paths[i] = msg.getBlob().getLocalBlob().getFile().getPath();
    }
    // Make sure inodes are different for paths
    for (int i = 0; i < 4; i++) {
        Assert.assertFalse(IO.fileInfo(paths[i]).getInodeNum() == IO.fileInfo(paths[i + 1]).getInodeNum());
    }
    // wait for a seconds, so that timestamp gets changed.
    Thread.sleep(1000);
    BlobDeduper deduper = BlobDeduper.getInstance();
    List<Short> volumeIds = new ArrayList<Short>();
    volumeIds.add(vol.getId());
    deduper.process(volumeIds);
    while (deduper.isRunning()) {
        // wait until deduper finishes.
        Thread.sleep(1000);
    }
    // Make sure inodes are same for paths
    for (int i = 0; i < 4; i++) {
        Assert.assertTrue(IO.fileInfo(paths[i]).getInodeNum() == IO.fileInfo(paths[i + 1]).getInodeNum());
    }
}
Also used : Message(com.zimbra.cs.mailbox.Message) ParsedMessage(com.zimbra.cs.mime.ParsedMessage) BlobDeduper(com.zimbra.cs.store.file.BlobDeduper) ParsedMessage(com.zimbra.cs.mime.ParsedMessage) ArrayList(java.util.ArrayList) StoreManager(com.zimbra.cs.store.StoreManager) Volume(com.zimbra.cs.volume.Volume) FileBlobStore(com.zimbra.cs.store.file.FileBlobStore) DeliveryOptions(com.zimbra.cs.mailbox.DeliveryOptions) Test(org.junit.Test)

Aggregations

StoreManager (com.zimbra.cs.store.StoreManager)2 BlobDeduper (com.zimbra.cs.store.file.BlobDeduper)2 FileBlobStore (com.zimbra.cs.store.file.FileBlobStore)2 Volume (com.zimbra.cs.volume.Volume)2 ArrayList (java.util.ArrayList)2 DeliveryOptions (com.zimbra.cs.mailbox.DeliveryOptions)1 Message (com.zimbra.cs.mailbox.Message)1 ParsedMessage (com.zimbra.cs.mime.ParsedMessage)1 ZimbraSoapContext (com.zimbra.soap.ZimbraSoapContext)1 DedupeBlobsRequest (com.zimbra.soap.admin.message.DedupeBlobsRequest)1 DedupeBlobsResponse (com.zimbra.soap.admin.message.DedupeBlobsResponse)1 IntIdAttr (com.zimbra.soap.admin.type.IntIdAttr)1 VolumeIdAndProgress (com.zimbra.soap.admin.type.VolumeIdAndProgress)1 IOException (java.io.IOException)1 Map (java.util.Map)1 Test (org.junit.Test)1