-
Notifications
You must be signed in to change notification settings - Fork 3.9k
File Watcher Authorization Server Interceptor #9775
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
defd3b2
to
6f7fef0
Compare
* @return an object that caller should close when the file refreshes are not needed | ||
*/ | ||
public Closeable scheduleRefreshes(long period, TimeUnit unit) | ||
throws IOException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Intent two more spaces, since it is a line continuation. Ditto for create().
(Or don't wrap the line)
Logger.getLogger(FileWatcherAuthorizationServerInterceptor.class.getName()); | ||
|
||
private volatile AuthorizationServerInterceptor internalAuthzServerInterceptor; | ||
private final ScheduledExecutorService scheduledExecutorService = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have the user pass this in to scheduleRefreshes()
. For reference, see AdvancedTlsX509TrustManager.updateTrustCredentialsFromFile()
.
Then, in the tests pass FakeClock. That will then allow you to modify the policy file, forwardTime() (commonly we do this in two phases, forward time too little, check the behavior is still the old behavior, then forward time the small remaining amount), and then check the interceptor behavior changed. You wouldn't need testCallback
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good. Updated the code to use FakeClock.
Thank you for the review! I have all the comments. @ejona86 PTAL
private Thread testCallback; | ||
|
||
private FileWatcherAuthorizationServerInterceptor(File policyFile) | ||
throws IllegalArgumentException, IOException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IllegalArgumentException
is a RuntimeException
, so doesn't need to be listed.
authz/src/main/java/io/grpc/authz/FileWatcherAuthorizationServerInterceptor.java
Show resolved
Hide resolved
try { | ||
updateInternalInterceptor(); | ||
} catch (Exception e) { | ||
logger.log(Level.WARNING, "Authorization Policy file reload failed: " + e); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
try (FileOutputStream outputStream = new FileOutputStream(policyFile)) { | ||
String policy = "{ \"name\": \"abc\",, }"; | ||
outputStream.write(policy.getBytes(UTF_8)); | ||
outputStream.close(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The try-with-resources will close the output stream, so this line can be deleted.
assertThat(ioe).hasMessageThat().isEqualTo( | ||
"Use JsonReader.setLenient(true) to accept malformed JSON" | ||
+ " at line 1 column 18 path $.name"); | ||
} catch (Exception e) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Delete this catch and let the exception propagate.
public void invalidPolicyFailsAuthzInterceptorCreation() throws Exception { | ||
File policyFile = File.createTempFile("temp", "json"); | ||
policyFile.deleteOnExit(); | ||
try (FileOutputStream outputStream = new FileOutputStream(policyFile)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Feel free to use Guava's Files.write(byte[], File)
and/or create a helper function to help make the test more terse.
fail("exception expected"); | ||
} catch (IOException ioe) { | ||
assertThat(ioe).hasMessageThat().isEqualTo( | ||
"Use JsonReader.setLenient(true) to accept malformed JSON" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do not assert messages that you don't generate. You could maybe check for "malformed," but this full message is far too precise and would trivially break on an upgrade to GSON.
FileWatcherAuthorizationServerInterceptor interceptor = | ||
FileWatcherAuthorizationServerInterceptor.create(policyFile); | ||
assertNotNull(interceptor); | ||
interceptor.scheduleRefreshes(1, TimeUnit.SECONDS); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the point of this line? It is leaking the returned Closeable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewable status: 0 of 5 files reviewed, 13 unresolved discussions (waiting on @ejona86)
a discussion (no related file):
Thank you for the review:) Please review the updated code.
authz/src/main/java/io/grpc/authz/FileWatcherAuthorizationServerInterceptor.java
line 50 at r1 (raw file):
Previously, ejona86 (Eric Anderson) wrote…
Have the user pass this in to
scheduleRefreshes()
. For reference, seeAdvancedTlsX509TrustManager.updateTrustCredentialsFromFile()
.Then, in the tests pass FakeClock. That will then allow you to modify the policy file, forwardTime() (commonly we do this in two phases, forward time too little, check the behavior is still the old behavior, then forward time the small remaining amount), and then check the interceptor behavior changed. You wouldn't need
testCallback
.
Done.
authz/src/main/java/io/grpc/authz/FileWatcherAuthorizationServerInterceptor.java
line 63 at r1 (raw file):
Previously, ejona86 (Eric Anderson) wrote…
IllegalArgumentException
is aRuntimeException
, so doesn't need to be listed.
Done.
authz/src/main/java/io/grpc/authz/FileWatcherAuthorizationServerInterceptor.java
line 99 at r1 (raw file):
Previously, ejona86 (Eric Anderson) wrote…
Intent two more spaces, since it is a line continuation. Ditto for create().
(Or don't wrap the line)
Done.
authz/src/main/java/io/grpc/authz/FileWatcherAuthorizationServerInterceptor.java
line 109 at r1 (raw file):
Previously, ejona86 (Eric Anderson) wrote…
Pass
e
as its own argument.
Done.
authz/src/main/java/io/grpc/authz/FileWatcherAuthorizationServerInterceptor.java
line 111 at r1 (raw file):
Previously, ejona86 (Eric Anderson) wrote…
Unindent.
Done.
authz/src/test/java/io/grpc/authz/AuthorizationEnd2EndTest.java
line 447 at r1 (raw file):
Previously, ejona86 (Eric Anderson) wrote…
This is a strange use of
deleteOnExit()
, because it seems it could just bedelete()
instead. I'd expect anydeleteOnExit()
to be just after the file is created, so that if an exception is thrown later in the test the file would still get deleted.
Moved the logic to delete policy file to tearDown()
authz/src/test/java/io/grpc/authz/FileWatcherAuthorizationServerInterceptorTest.java
line 36 at r1 (raw file):
Previously, ejona86 (Eric Anderson) wrote…
Sometimes it is convenient to use
createTempFile()
+deleteOnExit()
in tests, althoughTemporaryFolder
is generally preferred because it will be cleaned up at the end of the test instead of if/when the JVM exits cleanly.Because this is an easy case, you could also do:
private File policyFile = File.createTempFile("temp", "json"); @After public void cleanUp() { policyFile.delete(); // does not throw if file not found }
Done.
authz/src/test/java/io/grpc/authz/FileWatcherAuthorizationServerInterceptorTest.java
line 38 at r1 (raw file):
Previously, ejona86 (Eric Anderson) wrote…
Feel free to use Guava's
Files.write(byte[], File)
and/or create a helper function to help make the test more terse.
Thank you for the suggestion. Updated the tests to use Guava API.
authz/src/test/java/io/grpc/authz/FileWatcherAuthorizationServerInterceptorTest.java
line 41 at r1 (raw file):
Previously, ejona86 (Eric Anderson) wrote…
The try-with-resources will close the output stream, so this line can be deleted.
Done.
authz/src/test/java/io/grpc/authz/FileWatcherAuthorizationServerInterceptorTest.java
line 48 at r1 (raw file):
Previously, ejona86 (Eric Anderson) wrote…
Do not assert messages that you don't generate. You could maybe check for "malformed," but this full message is far too precise and would trivially break on an upgrade to GSON.
Done.
authz/src/test/java/io/grpc/authz/FileWatcherAuthorizationServerInterceptorTest.java
line 50 at r1 (raw file):
Previously, ejona86 (Eric Anderson) wrote…
Delete this catch and let the exception propagate.
Done.
authz/src/test/java/io/grpc/authz/FileWatcherAuthorizationServerInterceptorTest.java
line 84 at r1 (raw file):
Previously, ejona86 (Eric Anderson) wrote…
What is the point of this line? It is leaking the returned Closeable.
Deleted the line. I agree it does not make sense here.
3bd8770
to
3f4d2c6
Compare
@ejona86 PTAL |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is one stylistic review comment not addressed, which is about not relying on deleteOnExit for a test to cleanup the temporary file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should probably fix the formatting of the one string before merging.
authz/src/main/java/io/grpc/authz/FileWatcherAuthorizationServerInterceptor.java
Outdated
Show resolved
Hide resolved
|
||
private final File policyFile; | ||
private FileTime lastModifiedTime; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI, for testing you can do something like:
Lines 117 to 118 in 1551cc7
Files.setLastModifiedTime( | |
Paths.get(certFile), FileTime.fromMillis(timeProvider.currentTimeMillis())); |
This change is