-
Notifications
You must be signed in to change notification settings - Fork 682
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
GEODE-3213: Refactor ProtoBuf handler flow #646
Conversation
operationHandler.process(serializationServiceStub, generateTestRequest(), cacheStub); | ||
|
||
Assert.assertEquals(ClientProtocol.Response.ResponseAPICase.ERRORRESPONSE, | ||
response.getResponseAPICase()); | ||
Assert.assertTrue(result instanceof Failure); |
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 we need to assert at the error message
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.
no. Is it worth asserting part of it?
operationHandler.process(serializationServiceStub, generateTestRequest(), cacheStub); | ||
|
||
Assert.assertEquals(ClientProtocol.Response.ResponseAPICase.ERRORRESPONSE, | ||
response.getResponseAPICase()); | ||
Assert.assertTrue(result instanceof Failure); |
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 need to assert at least the error message. Maybe later on the error code
operationHandler.process(serializationServiceStub, generateTestRequest(), cacheStub); | ||
|
||
Assert.assertEquals(ClientProtocol.Response.ResponseAPICase.PUTRESPONSE, | ||
response.getResponseAPICase()); | ||
Assert.assertNotNull(result); |
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 assert that we got back a Success Object rather than just result != null
|
||
import java.util.function.Function; | ||
|
||
public class OperationContext<OperationReq, OperationResponse> { |
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.
Would it make sense to maybe package restrict this class
ClientProtocol.ErrorResponse error = | ||
ClientProtocol.ErrorResponse.newBuilder().setMessage(errorMessage).build(); | ||
return ClientProtocol.Response.newBuilder().setErrorResponse(error).build(); | ||
public static Failure createFailureResult(String errorMessage) { |
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.
I disagree with this method description or its implementation. Either the method name should state createFailureResultWithErrorResponseForErrorMessage
OR the signature becomes createFailureResult(ErrorResponse errorResponse)
.
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.
@pivotal-amurmann @kohlmu-pivotal Did this get addressed?
return ClientProtocol.Response.newBuilder().setGetResponse(getResponse).build(); | ||
public static Success<RegionAPI.GetResponse> createGetResult( | ||
BasicTypes.EncodedValue resultValue) { | ||
return new Success<>(RegionAPI.GetResponse.newBuilder().setResult(resultValue).build()); |
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.
could we replace these types of calls with inline Success.of(EncodedValue)
bc9de53
to
b36e62c
Compare
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.
Still reviewing, but here's some initial comments.
|
||
import java.util.function.Function; | ||
|
||
public interface Result<SuccessType> { |
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.
This is tightly bound to the ClientProtocol.ErrorResponse, can we give it a less generic name? Maybe ProtocolHandlerResponse?
* or implied. See the License for the specific language governing permissions and limitations under | ||
* the License. | ||
*/ | ||
package org.apache.geode.protocol.operations; |
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.
In terms of package layout, I had thought the intent was to have generic code that could be used for any protocol in this package, while protobuf specific code would be under org.apache.geode.protocol.protobuf.* All of the Result and OperationContext code is now protobuf specific. Should it be moved?
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 wrote a test that enforces that every enum value has a handler. Of course that test won't pass until we have implemented all operations which isn't going to happen any time soon. So we removed it again. By the time all operations are implemented the test would basically enforce that we don't delete any of the operations and hook them up correctly. However, that's already enforced via the individual integration tests. So it's a very low value test.
ClientProtocol.Request.RequestAPICase requestType = request.getRequestAPICase(); | ||
OperationHandler opsHandler = | ||
opsHandlerRegistry.getOperationHandlerForOperationId(requestType.getNumber()); | ||
OperationContext operationContext = operationContextRegistry.getOperationContext(requestType); |
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.
How are we dealing with missing registry entries now that we're no longer throwing OperationNotRegisteredException?
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.
Currently we are getting a NPE for those which is awful and already lead to wasted time debugging the non-obvious error. Let's go back to throwing something specific.
b36e62c
to
102114f
Compare
102114f
to
ff66707
Compare
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.
Partial review so far, a few comments.
I'm wondering how much the OperationHandlerContext
adds here, or whether it would be cleaner to call through. On the other hand, so far it doesn't look worse than what we have so far.
import java.util.function.Function; | ||
|
||
public class OperationContext<OperationReq, OperationResponse> { | ||
private OperationHandler<OperationReq, OperationResponse> operationHandler; |
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.
I think these fields should be final.
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.
These could be public final and the getters removed. getFromRequest
and getToResponse
make it sound like the builder is doing something, when all it's doing is returning an imutable final field.
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.
Or we could even write a fromRequest
(etc. family of) method that calls fromRequest.apply()
on the arguments. Or we could have the context just have a process
method that does things in the right order. I'm wondering what's the best way to write this.
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 could even just make instances of some interface and not have references to these Functions at all.
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.
I don't think there's a clear best way to do this, feel free to ignore this comment chain and carry on if you want.
SerializationService serializationService) { | ||
this.opsHandlerRegistry = opsHandlerRegistry; | ||
public ProtobufOpsProcessor(SerializationService serializationService, | ||
OperationContextRegistry operationsContextRegistry) { |
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.
seems like a nitpick, but why are we using both operation and operations in names here?
private Function<OperationResponse, ClientProtocol.Response.Builder> toResponse; | ||
private Function<ClientProtocol.ErrorResponse, ClientProtocol.Response.Builder> toErrorResponse; | ||
|
||
public OperationContext(Function<ClientProtocol.Request, OperationReq> fromRequest, |
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.
Can we use OperationRequest
and OperationResponse
?
ff66707
to
510a42a
Compare
@@ -50,47 +38,14 @@ | |||
* @param ex - exception which should be logged | |||
* @return An error response containing the first three parameters. | |||
*/ | |||
public static ClientProtocol.Response createAndLogErrorResponse(String errorMessage, | |||
public static ClientProtocol.ErrorResponse createAndLogFailureResponse(String errorMessage, |
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.
why'd the name change to FailureResponse
when the type changed to ErrorResponse
?
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.
I think those were to changes that were made independently. Syncing this up right now
@@ -144,21 +138,22 @@ public void processReturnsErrorWhenUnableToDecodeRequest() | |||
when(serializationServiceStub.decode(BasicTypes.EncodingType.STRING, | |||
TEST_KEY.getBytes(Charset.forName("UTF-8")))).thenThrow(exception); | |||
|
|||
ClientProtocol.Request getRequest = generateTestRequest(false, false, false); | |||
ClientProtocol.Response response = (ClientProtocol.Response) operationHandler |
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.
👍 getting rid of typecasts.
510a42a
to
e0ebe4a
Compare
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.
I like the Result type. It's interesting trying to do functional-style programming in Java. I think this code is better than what we have now and approve of shipping it.
|
||
import java.util.function.Function; | ||
|
||
public class OperationContext<OperationRequest, OperationResponse> { |
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.
I think it makes more sense to have these be implementations of an interface, since they're acting as an immutable collection of functions.
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.
+1
If you are using IntelliJ as your IDE, please remember to update your style file to that located in After having done so, please optimize the imports to the correct order and to eliminate the use of the wildcard imports from the 25 offending files this pull request touches. |
Signed-off-by: Alexander Murmann <amurmann@pivotal.io>
e0ebe4a
to
f2896f3
Compare
Signed-off-by: Alexander Murmann amurmann@pivotal.io
Thank you for submitting a contribution to Apache Geode.
In order to streamline the review of the contribution we ask you
to ensure the following steps have been taken:
For all changes:
Is there a JIRA ticket associated with this PR? Is it referenced in the commit message?
GEODE-3213
Has your PR been rebased against the latest commit within the target branch (typically
develop
)?Is your initial contribution a single, squashed commit?
Does
gradlew build
run cleanly?Have you written or updated unit tests to verify your changes?
If adding new dependencies to the code, are these dependencies licensed in a way that is compatible for inclusion under ASF 2.0?
NA
Note:
Please ensure that once the PR is submitted, you check travis-ci for build issues and
submit an update to your PR as soon as possible. If you need help, please send an
email to dev@geode.apache.org.