Skip to content
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

Dimension Field Tagging and Dynamic Dimension Field Serilization #137

Merged
merged 6 commits into from
Jan 20, 2017

Conversation

garyluoex
Copy link
Collaborator

@garyluoex garyluoex commented Jan 14, 2017

  • Added a new module fili-navi for components added to support for Navi
  • Added TaggedDimensionField and related components in fili-navi
  • Changed fili-core dimension endpoint DimensionField serialization strategy from hard coded static attributes to dynamic serialization based on jackson serializer
  • Deprecated DimensionsServlet::getDimensionFieldListSummaryView and DimensionsServlet::getDimensionFieldSummaryView
    since there is no need for it anymore due to the change in serialization of DimensionField

* Constructor, build name using camel cased enum name.
*/
DefaultDimensionFieldTag() {
this.tagName = EnumUtils.camelCase(name());
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CamelCase or just LowerCase? (Does LowerCase feel more like tags?)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A quick survery of online tag systems suggests that they are mostly flat cased and searched case insensitively. I agree that all-lower is the right impulse.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we do make them sortable, I'd make DimensionTag comparable on getName()

Copy link
Contributor

@michael-mclawhorn michael-mclawhorn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I concur with making tags flat cased. I also think that they should be unique on a field (e.g. on any given field, there is not a multiset quality), and I think that having a canonical externally imposed order will make for more consistent behavior.

* Constructor, build name using camel cased enum name.
*/
DefaultDimensionFieldTag() {
this.tagName = EnumUtils.camelCase(name());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A quick survery of online tag systems suggests that they are mostly flat cased and searched case insensitively. I agree that all-lower is the right impulse.

*
* @return a list of tags
*/
List<? extends Tag> getTags();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think tags should probably be a set. Maybe even a sorted set to encourage canonical display.

TEST_PRIMARY_KEY(Collections.singletonList(PRIMARY_KEY)),
TEST_DISPLAY_NAME(Arrays.asList(PRIMARY_KEY, PRIMARY_KEY)),
TEST_DESCRIPTION(Collections.<Tag>emptyList())
;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If these fields exist only to illustrate behavior on single tag, multiple tags and no tags, you might want to just rename the dimensions to reflect that purpose.

Also, would it be clearer to instantiate these tags as singletons in the test class? That would make it easer to see what you're testing by putting it next to the test itself, if the test is the only place these are being consumed.

* Constructor, build name using camel cased enum name.
*/
DefaultDimensionFieldTag() {
this.tagName = EnumUtils.camelCase(name());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we do make them sortable, I'd make DimensionTag comparable on getName()

Copy link
Collaborator

@cdeszaq cdeszaq left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nothing major, just a few small things to tighten up.

@@ -334,6 +334,6 @@ class SerializationResources extends Specification {
}

String getSerializedReponseContext1() {
"""["com.yahoo.bard.webservice.web.responseprocessors.ResponseContext",{"randomHeader":"someHeader","apiMetricColumnNames":["java.util.LinkedHashSet",["metric1, metric2"]],"requestedApiDimensionFields":["java.util.LinkedHashMap",{"ageBracket":["java.util.LinkedHashSet",[["com.yahoo.bard.webservice.data.dimension.BardDimensionField","ID"]]]}]}]"""
"""["com.yahoo.bard.webservice.web.responseprocessors.ResponseContext",{"randomHeader":"someHeader","apiMetricColumnNames":["java.util.LinkedHashSet",["metric1, metric2"]],"requestedApiDimensionFields":["java.util.LinkedHashMap",{"ageBracket":["java.util.LinkedHashSet",[["com.yahoo.bard.webservice.data.dimension.BardDimensionField",{"name":"id","description":"Dimension ID"}]]]}]}]"""
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should make sure that this don't make anything that was serialized in the old way explode. I'm not 100% clear on what was going on with this before (@archolewa may have some sense of it, since i think it's tied to the async work?), but we want to ensure we're not killing existing serialized things.

Copy link
Collaborator Author

@garyluoex garyluoex Jan 18, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like it is a custom serialization done in PreResponseSerializationProxy, which is used by at least Digits by MobstorPreResponseStore bind in DigitsBinderFactory. Still not sure if the format of dimension field stored matters or not, can dig deeper or ask Digits people if necessary.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The piece I'm most concerned about is the deserialization of this thing. That's what usually breaks when serialization / deserialization don't line up. Since this capability is lightly (if ever) used over a duration that spans more than a single request, it's probably OK to set this asside.

import com.fasterxml.jackson.annotation.JsonValue;

/**
* An interface for tag.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't giving us any info that the interface signature doesn't already have. Instead, it would be good if this doc talked about what these tags are for (ie. indicating semantic meaning to dimension fields so the clients can have a better sense of properties of the fields). It would also be good to give some examples, like "primaryKey", "unique", "localId", etc.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking maybe one day we might need tag for other things, so this serves as a general purpose tag with a name interface. Let me know if you think we should indicate that it is for dimension field for now.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is tucked under the dimension package, and we only have 1 use for tags at the moment, I think it's OK to keep it tight. If we need to make it more widely used later, that should be easy enough to do.

import java.util.Set;

/**
* Dimension field with tags.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, a bit deeper on why tags are here and what purpose they have makes this doc more useful.

public interface TaggedDimensionField extends DimensionField {

/**
* Get a list of tags associated to the current field.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to update comment to reflect kind of collection, since it's no longer a list?

import java.util.Locale;

/**
* Default dimension field tag provided in fili-navi to match fili-core concept "key" field.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might drop the explicit mention of key fields at the class level, making this just be "... to match fili-core concepts". You could then move the info about "key field" onto JavaDoc on the PRIMARY_KEY instance.

* Constructor, build name using camel cased enum name.
*/
DefaultDimensionFieldTag() {
this.tagName = name().toLowerCase(Locale.ENGLISH);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that pretty much all other identifiers in the Fili ecosystem are camelCase, I think it might be a bit awkward for this to be small_snake_case. I know there's been some discussion on this already, and I agree that this shouldn't be PascalCase, but I don't think small_snake_case jives with the rest of the feel of Fili.

Sorry to push back and forth on this :)

Copy link
Collaborator Author

@garyluoex garyluoex Jan 18, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well not all, the physical names of things are all* lower cased, the logical names of things are all* camel cased. Let me know if you still want it to be camel case, thanks!

* Well, all that I know of

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, I meant all the external names. Internal names, in general, do use snake_case, but external uses camelCase. (that's one distinction that actually helps identify where an identifier is coming from)

I'd say we should still go with camelCase for consistency

@michael-mclawhorn
Copy link
Contributor

👍

@michael-mclawhorn michael-mclawhorn merged commit 2ae0605 into master Jan 20, 2017
@garyluoex garyluoex deleted the FieldTagging branch April 3, 2017 15:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants