public static boolean isNodeAttributesEquals(
      Set<NodeAttribute> leftNodeAttributes,
      Set<NodeAttribute> rightNodeAttributes) {
    if (leftNodeAttributes == null && rightNodeAttributes == null) {
      return true;
    } else if (leftNodeAttributes == null || rightNodeAttributes == null
        || leftNodeAttributes.size() != rightNodeAttributes.size()) {
      return false;
    }
    return leftNodeAttributes.stream()
        .allMatch(e -> isNodeAttributeIncludes(rightNodeAttributes, e));
  }
@Test
  void testIsNodeAttributesEquals() {
    NodeAttribute nodeAttributeCK1V1 = NodeAttribute
        .newInstance(NodeAttribute.PREFIX_CENTRALIZED, "K1",
            NodeAttributeType.STRING, "V1");
    NodeAttribute nodeAttributeCK1V1Copy = NodeAttribute
        .newInstance(NodeAttribute.PREFIX_CENTRALIZED, "K1",
            NodeAttributeType.STRING, "V1");
    NodeAttribute nodeAttributeDK1V1 = NodeAttribute
        .newInstance(NodeAttribute.PREFIX_DISTRIBUTED, "K1",
            NodeAttributeType.STRING, "V1");
    NodeAttribute nodeAttributeDK1V1Copy = NodeAttribute
        .newInstance(NodeAttribute.PREFIX_DISTRIBUTED, "K1",
            NodeAttributeType.STRING, "V1");
    NodeAttribute nodeAttributeDK2V1 = NodeAttribute
        .newInstance(NodeAttribute.PREFIX_DISTRIBUTED, "K2",
            NodeAttributeType.STRING, "V1");
    NodeAttribute nodeAttributeDK2V2 = NodeAttribute
        .newInstance(NodeAttribute.PREFIX_DISTRIBUTED, "K2",
            NodeAttributeType.STRING, "V2");
    /*
     * equals if set size equals and items are all the same
     */
    assertTrue(NodeLabelUtil.isNodeAttributesEquals(null, null));
    assertTrue(NodeLabelUtil
        .isNodeAttributesEquals(ImmutableSet.of(), ImmutableSet.of()));
    assertTrue(NodeLabelUtil
        .isNodeAttributesEquals(ImmutableSet.of(nodeAttributeCK1V1),
            ImmutableSet.of(nodeAttributeCK1V1Copy)));
    assertTrue(NodeLabelUtil
        .isNodeAttributesEquals(ImmutableSet.of(nodeAttributeDK1V1),
            ImmutableSet.of(nodeAttributeDK1V1Copy)));
    assertTrue(NodeLabelUtil.isNodeAttributesEquals(
        ImmutableSet.of(nodeAttributeCK1V1, nodeAttributeDK1V1),
        ImmutableSet.of(nodeAttributeCK1V1Copy, nodeAttributeDK1V1Copy)));
    /*
     * not equals if set size not equals or items are different
     */
    assertFalse(
        NodeLabelUtil.isNodeAttributesEquals(null, ImmutableSet.of()));
    assertFalse(
        NodeLabelUtil.isNodeAttributesEquals(ImmutableSet.of(), null));
    // different attribute prefix
    assertFalse(NodeLabelUtil
        .isNodeAttributesEquals(ImmutableSet.of(nodeAttributeCK1V1),
            ImmutableSet.of(nodeAttributeDK1V1)));
    // different attribute name
    assertFalse(NodeLabelUtil
        .isNodeAttributesEquals(ImmutableSet.of(nodeAttributeDK1V1),
            ImmutableSet.of(nodeAttributeDK2V1)));
    // different attribute value
    assertFalse(NodeLabelUtil
        .isNodeAttributesEquals(ImmutableSet.of(nodeAttributeDK2V1),
            ImmutableSet.of(nodeAttributeDK2V2)));
    // different set
    assertFalse(NodeLabelUtil
        .isNodeAttributesEquals(ImmutableSet.of(nodeAttributeCK1V1),
            ImmutableSet.of()));
    assertFalse(NodeLabelUtil
        .isNodeAttributesEquals(ImmutableSet.of(nodeAttributeCK1V1),
            ImmutableSet.of(nodeAttributeCK1V1, nodeAttributeDK1V1)));
    assertFalse(NodeLabelUtil.isNodeAttributesEquals(
        ImmutableSet.of(nodeAttributeCK1V1, nodeAttributeDK1V1),
        ImmutableSet.of(nodeAttributeDK1V1)));
  }