-
Notifications
You must be signed in to change notification settings - Fork 32
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
feat: Add ODP GraphQL Api Interface #481
Conversation
2. Added error response parsing and it's unit tests
} | ||
*/ | ||
@Override | ||
public String fetchQualifiedSegments(String apiKey, String apiEndpoint, String userKey, String userValue, List<String> segmentsToCheck) { |
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.
Name "fetchQualifiedSegments" is already used in upcoming "ODPSegmentManager" (per Jae's naming). Risk of name conflict. Unless you use different names, but that might be a deviation from naming consistency across SDKs?
import java.util.List; | ||
|
||
public interface ODPApiManager { | ||
String fetchQualifiedSegments(String apiKey, String apiEndpoint, String userKey, String userValue, List<String> segmentsToCheck); |
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.
Name already "reserved" for the method in ODPSegmentManager? This one should be fetchSegments, no? (consistency across SDKs)
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.
Not 100% sure, maybe I'm wrong... you have ODPAPIManager interface that defines fetchQualifiedSegments method, but there is also method fetchSegments in Swift PR that is located in the GraphQL API Manager. Not sure how you are overriding, but it seems smth not quite right...unless it's my weak java knowledge
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.
Design of java is a little different than other sdks. For all the external calls, we need to create an interface and pass it in to the core SDK from the outside. That is why i created ODPAPIManager which is an interface that will contain all the external calls such as graphQL and ODPEvents. Then i am providing a DefaultODPApiManager as a default implementation. user will use this by default but can pass in their own implementation. To me fethQualifiedSegments
makes more sense because thats exactly what this call does. It fetches the qualified segments not all or just any segments.
logbackVerifier.expectMessage(Level.ERROR, "Unexpected response from ODP server, Response code: 500, null"); | ||
assertEquals(null, responseString); | ||
} | ||
} |
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 about the test for network issues, such as internet is down, where status code is not returned. Request is not reaching the server and bounces off?
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.
A refactoring for sharing multiple JSON parsers suggested if it's not too much.
I need to see the next stage to see how you want to implement all. It looks good as is!
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
public enum JsonParserProvider { |
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.
Looks good! Just wondering if there is a smart way to reuse the same code for DefaultConfigParser. It is quite complicated currently supporting multiple parsers and this repeated code will make it worse :)
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 wanted to reuse code from there but it was tightly coupled. I wanted to refactor DefaultConfigParser to use this one but i thought i will add a comment and do that later as a separate ticket. Right now it will become too much work. what do you think?
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 idea is to make DefaultConfigParser and whatever else needs a parser use this code eventually. i am just too afraid to touch DafaultConfigParser in this PR
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 leave it to you.
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.
Cool! I will add a comment in the DefaultConfigParser mentioning the same. I will also add a ticket to refactor this and put it in the tech debt backlog.
logMessage.append(errors.get(i).getAsJsonObject().get("message").getAsString()); | ||
} | ||
logger.error(logMessage.toString()); | ||
return null; |
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.
Collecting error messages looks good. For other SDKs (swift and go), extracting "InvalidIdentifierException" from error "classification" and passing back to clients is important. Not sure how we can pass back this info to callers in Java. We can log in at minimum, but this may be redundant to your error log message already collecting all error messages.
return null; | ||
} | ||
|
||
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { |
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 about more generous error checking like ">= 400"?
*/ | ||
@Override | ||
public String fetchQualifiedSegments(String apiKey, String apiEndpoint, String userKey, String userValue, List<String> segmentsToCheck) { | ||
HttpPost request = new HttpPost(apiEndpoint); |
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.
Not sure about the plan to feed endpoint, but needs "/v3/graphql" appended for graphql to the shred apiEndpoint.
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 see this as the lowest level method that will make the actual call that is why it's getting the full endPoint. Users might provide their own implementation so it made more sense for it to expect the full endPoint. My plan is to build this endpoint using the host and path in the ODPSegmentManager
and pass it to this one. What do you think?
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.
That's what I thought. If we plan to support custom endpoints, this makes sense. Let's move on and review again at the top level.
One thing we also should consider is that if clients want to implement their own segment services (replacing all our default ODPManager), they can determine segments using their own solution and directly feed the "qualifedSegments" into OptimizelyUserContext, instead of injecting own ODPManager into our SDKs.
import java.util.List; | ||
|
||
public interface ODPApiManager { | ||
String fetchQualifiedSegments(String apiKey, String apiEndpoint, String userKey, String userValue, List<String> segmentsToCheck); |
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.
It looks like you plan to open all ODP APIs here to public for customization support. It looks good for now and we can continue discussion the final apis.
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.
Yes, this will contain all the methods that make an external call. ODPEvents calls will also go here
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.
LGTM
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.
lgtm
Summary
Test plan
Issues
OASIS-8384