@Override
  public void initialize() throws StoreException {
    synchronized (storeWriteLock) {
      if (started) {
        throw new StoreException("Store already started", StoreErrorCodes.StoreAlreadyStarted);
      }
      if(initialized) {
        throw new StoreException("Store already initialized", StoreErrorCodes.StoreAlreadyInitialized);
      }
      try {
        // Check if the data dir exist. If it does not exist, create it
        File dataFile = new File(dataDir);
        if (!dataFile.exists()) {
          logger.info("Store : {} data directory not found. creating it", dataDir);
          boolean created = dataFile.mkdir();
          if (!created) {
            throw new StoreException("Failed to create directory for data dir " + dataDir,
                StoreErrorCodes.InitializationError);
          }
        }
        if (!dataFile.isDirectory() || !dataFile.canRead()) {
          throw new StoreException(dataFile.getAbsolutePath() + " is either not a directory or is not readable",
              StoreErrorCodes.InitializationError);
        }
        // check the file system before we do any file write.
        checkIfStoreIsStale();

        // lock the directory
        fileLock = new FileLock(new File(dataDir, LockFile));
        if (!fileLock.tryLock()) {
          throw new StoreException(
              "Failed to acquire lock on file " + dataDir + ". Another process or thread is using this directory.",
              StoreErrorCodes.InitializationError);
        }

        storeDescriptor = new StoreDescriptor(dataDir, config);

        log = new Log(dataDir, capacityInBytes, diskSpaceAllocator, config, metrics, diskMetrics, false);
        compactor = new BlobStoreCompactor(dataDir, storeId, factory, config, metrics, storeUnderCompactionMetrics,
            diskIOScheduler, diskSpaceAllocator, log, time, sessionId, storeDescriptor.getIncarnationId(),
            accountService, remoteTokenTracker, diskMetrics, false);
        fileStore.start(log.getSegmentSize());
        //Clean up temporary Staging Directory created by FileStore
        if(config.storeDeleteFileCopyTemporaryDirectoryOnRestart && fileStore.isRunning()){
          fileStore.cleanUpStagingDirectory(dataDir, config.storeFileCopyTemporaryDirectoryName, storeId);
        }

        initialized = true;
      } catch (Exception e) {
        if (fileLock != null) {
          // Release the file lock
          try {
            fileLock.unlock();
          } catch (Exception lockException) {
            logger.error("Failed to unlock file lock for dir " + dataDir, lockException);
          }
        }
        String err = String.format("Error while starting store for dir %s due to %s", dataDir, e.getMessage());
        throw new StoreException(err, e, StoreErrorCodes.InitializationError);
      }
    }
  }
Constructor for BlobStore, used in ambry-tools

@param storeId                     id of the BlobStore
@param config                      the settings for store configuration.
@param taskScheduler               the {@link ScheduledExecutorService} for executing background tasks.
@param longLivedTaskScheduler      the {@link ScheduledExecutorService} for executing long period background
                                   tasks.
@param diskManager                 the {@link DiskManager} object
@param diskIOScheduler             schedules disk IO operations.
@param diskSpaceAllocator          allocates log segment files.
@param metrics                     the {@link StorageManagerMetrics} instance to use.
@param storeUnderCompactionMetrics the {@link StoreMetrics} object used by stores created for compaction.
@param dataDir                     directory that will be used by the BlobStore for data
@param capacityInBytes             capacity of the BlobStore
@param factory                     the {@link StoreKeyFactory} for parsing store keys.
@param recovery                    the {@link MessageStoreRecovery} instance to use.
@param hardDelete                  the {@link MessageStoreHardDelete} instance to use.
@param time                        the {@link Time} instance to use.
@param indexPersistScheduler       a dedicated {@link ScheduledExecutorService} for persisting index segments.
ambry-store/src/main/java/com/github/ambry/store/BlobStore.java