@Override
  public WorkerIdentity get() {
    // Look at configurations first
    if (mConf.isSetByUser(PropertyKey.WORKER_IDENTITY_UUID)) {
      String uuidStr = mConf.getString(PropertyKey.WORKER_IDENTITY_UUID);
      final WorkerIdentity workerIdentity = WorkerIdentity.ParserV1.INSTANCE.fromUUID(uuidStr);
      LOG.debug("Loaded worker identity from configuration: {}", workerIdentity);
      return workerIdentity;
    }

    // Try loading from the identity file
    String filePathStr = mConf.getString(PropertyKey.WORKER_IDENTITY_UUID_FILE_PATH);
    final Path idFile = Paths.get(filePathStr);
    try (BufferedReader reader = Files.newBufferedReader(idFile)) {
      List<String> nonCommentLines = reader.lines()
          .filter(line -> !line.startsWith("#"))
          .filter(line -> !line.trim().isEmpty())
          .collect(Collectors.toList());
      if (nonCommentLines.size() > 0) {
        if (nonCommentLines.size() > 1) {
          LOG.warn("Multiple worker identities configured in {}, only the first one will be used",
              idFile);
        }
        String uuidStr = nonCommentLines.get(0);
        final WorkerIdentity workerIdentity = WorkerIdentity.ParserV1.INSTANCE.fromUUID(uuidStr);
        LOG.debug("Loaded worker identity from file {}: {}",
            idFile, workerIdentity);
        return workerIdentity;
      }
    } catch (FileNotFoundException | NoSuchFileException ignored) {
      // if not existent, proceed to auto generate one
      LOG.debug("Worker identity file {} not found", idFile);
    } catch (IOException e) {
      // in case of other IO error, better stop worker from starting up than use a new identity
      throw new RuntimeException(
          String.format("Failed to read worker identity from identity file %s", idFile), e);
    }

    // No identity is supplied by the user
    // Assume this is the first time the worker starts up, and generate a new one
    LOG.debug("Auto generating new worker identity as no identity is supplied by the user");
    UUID generatedId = mUUIDGenerator.get();
    WorkerIdentity identity = WorkerIdentity.ParserV1.INSTANCE.fromUUID(generatedId);
    LOG.debug("Generated worker identity as {}", identity);
    try (BufferedWriter writer = Files.newBufferedWriter(idFile, StandardCharsets.UTF_8,
        StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE)) {
      writer.write("# Worker identity automatically generated at ");
      writer.write(OffsetDateTime.now().format(DateTimeFormatter.RFC_1123_DATE_TIME));
      writer.newLine();
      writer.write(generatedId.toString());
      writer.newLine();
    } catch (Exception e) {
      LOG.warn("Failed to persist automatically generated worker identity ({}) to {}, "
          + "this worker will lose its identity after restart", identity, idFile, e);
    }
    try {
      // set the file to be read-only
      Set<PosixFilePermission> permSet = Files.getPosixFilePermissions(idFile);
      Set<PosixFilePermission> nonWritablePermSet = Sets.filter(permSet,
          perm -> perm != PosixFilePermission.OWNER_WRITE
              && perm != PosixFilePermission.GROUP_WRITE
              && perm != PosixFilePermission.OTHERS_WRITE);
      Files.setPosixFilePermissions(idFile, nonWritablePermSet);
    } catch (Exception e) {
      LOG.warn("Failed to set identity file to be read-only", e);
    }
    return identity;
  }
@Test
  public void preferExplicitConfigurationFirst() throws Exception {
    AlluxioProperties props = new AlluxioProperties();
    props.put(PropertyKey.WORKER_IDENTITY_UUID, mReferenceUuid.toString(), Source.RUNTIME);
    props.set(PropertyKey.WORKER_IDENTITY_UUID_FILE_PATH, mUuidFilePath.toString());
    try (BufferedWriter fout = Files.newBufferedWriter(mUuidFilePath, StandardCharsets.UTF_8,
        StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE)) {
      fout.write(mDifferentUuid.toString());
      fout.newLine();
    }
    AlluxioConfiguration conf = new InstancedConfiguration(props);
    WorkerIdentityProvider provider = new WorkerIdentityProvider(conf);
    WorkerIdentity identity = provider.get();
    assertEquals(mReferenceUuid, WorkerIdentity.ParserV1.INSTANCE.toUUID(identity));
    assertNotEquals(mDifferentUuid, WorkerIdentity.ParserV1.INSTANCE.toUUID(identity));
  }