More elegant way to construct the S3 path name with given options
The local variables make this very verbose:
each variable is declared, initialized, re-assigned, and referenced.
(They each appear 3-4 times in the code.)
You could instead accumulate values in a list.

Creating an array that may contain null values,
then filtering out the null values in a second step feels like a waste that's easy to avoid.
You could instead accumulate non-null values in a list.

Using StringJoiner is efficient to join a string from multiple parts.
Then at the end the filePath.toString() + "/" is an inefficient string concatenation that could have been easily avoided by appending an empty string to filePath.

And instead of using StringJoiner, you could use String.join.

Consider this alternative:

private String generateFullQualifiedS3KeyPrefix(DataStream dataStream, Options options) {
    List&lt;String&gt; values = new ArrayList&lt;&gt;();

    if (dataStream != null) {
        values.add(dataStream.getEnvironmentName());
        values.add(dataStream.getApplicationName());
        values.add(dataStream.getStreamName());
    }

    if (options != null) {
        values.add(String.valueOf(options.getYear()));
        values.add(String.format("%02d", options.getMonth()));
        values.add(String.format("%02d", options.getDate()));
        values.add(options.getGroupById());
    }

    values.add("");

    return String.join("/", values);
}