[hsync] BasicOzoneClientAdapterImpl#isFileClosed using OFSPath which is an Utility class for OFS not O3FS

What changes were proposed in this pull request?
In BasicOzoneClientAdapterImpl#isFileClosed we use OFSPath to check if the path was a key, but it Utility class for OFS not O3FS. That is to say, the pathStr doen't include volume and bucket but the OFSPath still setting the first two levels of directories or key as volume and bucket. If the path was less than two level it comes out an error.
https://github.com/apache/ozone/blob/HDDS-7593/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/ozone/BasicOzoneClientAdapterImpl.java#L774
What is the link to the Apache JIRA
https://issues.apache.org/jira/browse/HDDS-10781
How was this patch tested?
There are some existing lease recovery tests.

Thanks @chungen0126 for the fix.
Why is this targeted at feature branch HDDS-7593?  isFileClosed is already on master, it was added for HDDS-8436.  It should be fixed on master first.
Also, can you please check if similar usage of OFSPath related to snapshots should/can be replaced?
https://github.com/apache/ozone/blob/fe1b5b63353819acf393398b64ab4152c7e8d51f/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/ozone/BasicOzoneClientAdapterImpl.java#L601
https://github.com/apache/ozone/blob/fe1b5b63353819acf393398b64ab4152c7e8d51f/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/ozone/BasicOzoneClientAdapterImpl.java#L610
https://github.com/apache/ozone/blob/fe1b5b63353819acf393398b64ab4152c7e8d51f/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/ozone/BasicOzoneClientAdapterImpl.java#L620
https://github.com/apache/ozone/blob/fe1b5b63353819acf393398b64ab4152c7e8d51f/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/ozone/BasicOzoneClientAdapterImpl.java#L665

Why is this targeted at feature branch HDDS-7593? isFileClosed is already on master, it was added for HDDS-8436. It should be fixed on master first.

Should I close this pr and create a new one for master?

Also, can you please check if similar usage of OFSPath related to snapshots should/can be replaced?
https://github.com/apache/ozone/blob/fe1b5b63353819acf393398b64ab4152c7e8d51f/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/ozone/BasicOzoneClientAdapterImpl.java#L601
https://github.com/apache/ozone/blob/fe1b5b63353819acf393398b64ab4152c7e8d51f/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/ozone/BasicOzoneClientAdapterImpl.java#L610
https://github.com/apache/ozone/blob/fe1b5b63353819acf393398b64ab4152c7e8d51f/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/ozone/BasicOzoneClientAdapterImpl.java#L620
https://github.com/apache/ozone/blob/fe1b5b63353819acf393398b64ab4152c7e8d51f/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/ozone/BasicOzoneClientAdapterImpl.java#L665

I fixed those APIs make them create/rename snapshots for the root bucket and add test for them. I'm confused that should them have permission to access snapshots for other buckets.

Should I close this pr and create a new one for master?

Not necessary.  If you agree with the move to master, the base PR's branch can be changed.
https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/changing-the-base-branch-of-a-pull-request

Looks correct to me. Can you add a small test here
https://github.com/apache/ozone/blob/21068a3871f4ddebc1bf2780813e5e72eaea2ab7/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/fs/ozone/AbstractOzoneFileSystemTestWithFSO.java#L498

I put the source in the second layer folder to test for this bug.

Should I close this pr and create a new one for master?

Not necessary. If you agree with the move to master, the PR's base branch can be changed.
https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/changing-the-base-branch-of-a-pull-request

Sure.

@chungen0126 sorry, looks like GitHub does not realize only 2 commits are targeted at master:
* d76c7ef733 add test
* 6180d45b79 [hsync] BasicOzoneClientAdapterImpl#isFileClosed using OFSPath which is an Utility class for OFS not O3FS

Can you please rebase these onto master and push to your fork?  Let me know if you need help with that.

Done. Am I doing the right thing?

@adoroszlai Sorry, I might have done something wrong. Could you please tell me how to correct it?

@chungen0126
Start interactive rebase:
git rebase --interactive origin/master

Delete all commits from the editor except:
d76c7ef733 add test
6180d45b79 [hsync] BasicOzoneClientAdapterImpl#isFileClosed using OFSPath which is an Utility class for OFS not O3FS

Save and exit the editor.
Verify the log:
git log --oneline --decorate | head

should be something like:
57423154ba (HEAD -> HDDS-10781) add test
7cc1c0c89a [hsync] BasicOzoneClientAdapterImpl#isFileClosed using OFSPath which is an Utility class for OFS not O3FS
8d2569da59 (origin/master, origin/HEAD, master) HDDS-10097. Intermittent ManagedChannel not shutdown properly in TestWatchForCommit (#6620)
4e9dc2faae HDDS-10798. OMLeaderNotReadyException exception on switch leader (#6626)
...

I think I've already done. Thanks.

Should I force push or push a new branch for new pull request, thanks?

@chungen0126 force push is better in this case than a new PR

Thanks a lot @chungen0126 for updating the patch to cover snapshot-specific methods and rebasing for master.

Thanks @chungen0126 for the fix, @jojochuang for the review.


Bot gets stuck in a loop replying to itself

Description
We have a bot set up that listens for when posted messages that contain a link to a Trac ticket, and responds with a summary of the ticket. The response contains the title of the ticket as a clickable link. Since the text contains a link to Trac, the bot then responds to itself and gets stuck in a loop.
Code posted below. It's entirely possible I'm doing something wrong.
What type of issue is this? (place an x in one of the [ ])

[X] bug
[ ] enhancement (feature request)
[ ] question
[ ] documentation related
[ ] testing related
[ ] discussion

Requirements (place an x in each of the [ ])

[X] I've read and understood the Contributing guidelines and have done my best effort to follow them.
[X] I've read and agree to the Code of Conduct.
[X] I've searched for any related issues and avoided creating a duplicate issue.

Bug Report
Reproducible in:
slackclient version: 1.3.1
python version: 3.6
OS version(s): FreeBSD
Steps to reproduce:

Paste a Trac link in Slack (e.g. https://trac.sixfeetup.com/website/ticket/45)
bot responds
bot responds to itself
and so on

Expected result:
Bot would respond once
Actual result:
Bot is stuck in a loop
Attachments:
import json
import re
import time
import requests

try:
    from urllib.parse import urlparse
except ImportError:
    from urlparse import urlparse

from slackclient import SlackClient

with open('slack-creds.txt') as f:
    BOT_ID = f.readline().strip()
    SLACK_BOT_TOKEN = f.readline().strip()

# constants
AT_BOT = "<@" + BOT_ID + ">:"

# instantiate Slack client
slack_client = SlackClient(SLACK_BOT_TOKEN)

def handle_links(links, channel, ts, text):
    """
        Receives commands directed at the bot and determines if they
        are valid commands. If so, then acts on the commands. If not,
        returns back what it needs for clarification.
    """
    for link in links:
        url = urlparse(link)
        path = url.path[1:].split('/')
        if 'ticket' not in path or len(path) is not 3:
            # we don't have a ticket link
            continue
        trac_url = url.scheme + "://" + url.netloc + '/' + path[0] + '/rpc'
        trac_ticket = int(path[2])
        r = requests.put(
            trac_url,
            json={'method': 'ticket.get', 'params': [trac_ticket]}
        )
        if r.json().get('error'):
            slack_client.api_call(
                "chat.postMessage",
                channel=channel,
                text="Sorry, got a bad ticket #{}".format(trac_ticket),
                as_user=True)
            continue

        slack_client.api_call(
            "chat.postMessage",
            channel=channel,
            text=link,
            as_user="true")

def parse_slack_output(slack_rtm_output):
    """
        The Slack Real Time Messaging API is an events firehose.
        this parsing function returns None unless a message is
        directed at the Bot, based on its ID.
    """
    output_list = slack_rtm_output
    if output_list and len(output_list) > 0:
        for output in output_list:
            if not output or BOT_ID in output.get('user', ''):
                continue
            if 'text' in output and 'https://trac.sixfeetup.com' in output['text']:
                trac_links = re.findall(
                    r"\<([a-zA-Z/][^\>]*?|\!--.*?--)\>", output['text']
                )
                return trac_links, output['channel'], output['ts'], output['text']
    return None, None, None, None

if __name__ == "__main__":
    READ_WEBSOCKET_DELAY = 1  # 1 second delay between reading from firehose
    if slack_client.rtm_connect():
        print("TracBot connected and running!")
        while True:
            links, channel, ts, text = parse_slack_output(slack_client.rtm_read())
            if links and channel:
                handle_links(links, channel, ts, text)
            time.sleep(READ_WEBSOCKET_DELAY)
    else:
        print("Connection failed. Invalid Slack token or bot ID?")

Nevermind, I realized this wasn't actually hooked up to the Events API and doing a loop at the bottom of the file