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

Do not serialize DTO fields with empty or null objects and arrays #13515

Merged
merged 11 commits into from
Jun 18, 2019

Conversation

mkuznyetsov
Copy link
Contributor

@mkuznyetsov mkuznyetsov commented Jun 11, 2019

Signed-off-by: Mykhailo Kuznietsov mkuznets@redhat.com

What does this PR do?

currently serialization of devfileDto creates problems, when null or empty fields with collection/map types get serialized, which results in invalid Devfile.
In PR, special adapters for GSON would exclude fields with null or empty collections/maps from serialization.

Also added additional Enviroment Variable that can be used to revert the old behaviour:
CHE_LEGACY__DTO__JSON__SERIALIZATION (if true, empty and null collections and maps will be serialized)

What issues does this PR fix or reference?

Signed-off-by: Mykhailo Kuznietsov <mkuznets@redhat.com>
@todo
Copy link

todo bot commented Jun 11, 2019

Copy link
Member

@sleshchenko sleshchenko left a comment

Choose a reason for hiding this comment

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

In general, I'm OK with these changes. Let's run ci-test to check if it does not break current functionalities

Signed-off-by: Mykhailo Kuznietsov <mkuznets@redhat.com>
@mkuznyetsov
Copy link
Contributor Author

ci-test

@che-bot
Copy link
Contributor

che-bot commented Jun 11, 2019

Results of automated E2E tests of Eclipse Che Multiuser on OCP:
Build details
Test report
docker image: eclipseche/che-server:13515
https://github.com/orgs/eclipse/teams/eclipse-che-qa please check this report.

@mkuznyetsov mkuznyetsov marked this pull request as ready for review June 12, 2019 07:55
@mkuznyetsov mkuznyetsov requested a review from skabashnyuk as a code owner June 12, 2019 07:55
@Override
public JsonElement serialize(List<?> src, Type typeOfSrc, JsonSerializationContext context) {
if (src == null || src.isEmpty()) {
return null;
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure this is correct. Isn't there a semantic difference between null and empty list? While it may solve an issue for stuff within the devfile, I'm not sure it won't cause trouble for other types of entities...

Copy link
Member

Choose a reason for hiding this comment

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

According to our DTOs impl - there is not any semantic difference between null or empty list/map. I mean null and empty collection/map can be used only as initialized collection/map (not null) after parsing.
From Che Server and GWT (client impls) perspective, nothing is changed.
For CLI that we used to use nothing is changed as well since typescript DTO generator initializes null fields.

The things that may be affected:

  • UD: it uses received JSON directly via interface without using DTO impls, and null collections/maps are not initialized. So, code like workspace.devfile.properties["persistVolumes"] = false may cause a failure, but I'm not sure. Thank @ashumilova, who agreed to check this and provide more info how it may affect UD;
  • Any other Che Server API client that relies on current DTO serialization style where all fields are set, even if they were not set initially;

I think we can stop serialization empty collections/maps if does not cause any ingressions.
What are the alternatives?:

  • stop using the same DTO object for all kind of components types and have like different classes for CheEditorComponentDto, ChePluginComponentDto, .... I do not have a clear picture of how it could be implemented;
  • make ComponentDto - a special DTO that has untypical behavior for DTOs (null, empty collections/maps are not serialized). It looks safer against the implemented solution, but it makes our DTOs behavior variational from class to class, which is not a good thing IMHO.
  • Do not use DTOs for devfile at all, and it's not clear what we can use instead, especially if we take into account that Devfile should be returned as part of WorkspaceDto.

I'm not sure it won't cause trouble for other types of entities...

@metlos Can you elaborate more about your thoughts about possible issues? Are you OK with this approach if everything works fine (ci-test result is 97+%, I do not expect issues in master)?

Copy link
Contributor

Choose a reason for hiding this comment

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

Well, the thing that changes for the clients is that where they saw empty collections coming from our API endpoints, they're going to start seeing nulls. So if anyone happens to rely on non-null arrays being present, they will be caught by surprise by this...

Copy link
Contributor

Choose a reason for hiding this comment

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

in case of objects, instead of properties with empty arrays, they won't see the properties at all anymore, so the clients will have to start dealing with undefined values where before they didn't have to. Am I right?

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm OK with making such change because we kinda need it, I just want to point out the consequences for the existing clients (e.g. che-theia and any other custom UI built on top of wsmaster API).

Copy link
Member

Choose a reason for hiding this comment

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

so the clients will have to start dealing with undefined values where before they didn't have to. Am I right?

Right!

Copy link
Member

Choose a reason for hiding this comment

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

@mkuznyetsov and I found some generated typescript DTOs impl which look like initialize collections and maps

home/michael/IdeaProjects/che/dockerfiles/lib/src/api/dto/che-dto.ts

export module org.eclipse.che.api.workspace.shared.dto.devfile {

 export class DevfileDtoImpl implements org.eclipse.che.api.workspace.shared.dto.devfile.DevfileDto {

       components : Array<org.eclipse.che.api.workspace.shared.dto.devfile.ComponentDto>;
       metadata : org.eclipse.che.api.workspace.shared.dto.devfile.MetadataDto;
       projects : Array<org.eclipse.che.api.workspace.shared.dto.devfile.ProjectDto>;
       apiVersion : string;
       name : string;
       attributes : Map<string,string>;
       commands : Array<org.eclipse.che.api.workspace.shared.dto.devfile.DevfileCommandDto>;

   __jsonObject : any;

   constructor(__jsonObject?: any) {
     this.__jsonObject = __jsonObject;
           this.components = new Array<org.eclipse.che.api.workspace.shared.dto.devfile.ComponentDto>();
           if (__jsonObject) {
             if (__jsonObject.components) {
                 __jsonObject.components.forEach((item) => {
                 this.components.push(new org.eclipse.che.api.workspace.shared.dto.devfile.ComponentDtoImpl(item));
                 });
             }
           }

@mmorhun helps us to find that Theia works with DTOs without impls but via generated interfaces, but undefined/null should not happen here since all fields are marked as optional (?) and strictNull option is set on compiler, everyplace should contain the corresponding check before invocation of it. Terminology may be not right, but that's what I understand from converstation with @evidolob and @mmorhun

And Dashboard uses manually written interfaces and not all fields are marked as optional
https://github.com/eclipse/che/blob/master/dashboard/src/components/typings/che.d.ts#L340
Also, I do not know what is settings of compiler, if before invocation client should check field existence. @ashumilova @benoitf Can you take a look? For Dashboard it works in the same way as for Theia? If not, can we so them work in the same way?

Copy link
Contributor

Choose a reason for hiding this comment

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

in dashboard it fails at runtime if try to access workspace.attributes.plugins, when attributes is null.

Copy link
Contributor

Choose a reason for hiding this comment

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

For typescript, consumers of the DTO should never see null values on collections/map

if field is mandatory then it needs to be empty value, if the field is optional then it can be undefined

if it's not the case, then the TypeScript DTO needs to be enhanced.

in Ann's case, if attributes is optional field then all consumers have to check if it's defined or not but if attributes is mandatory then it should always return an empty value

@mkuznyetsov
Copy link
Contributor Author

ci-test

@che-bot
Copy link
Contributor

che-bot commented Jun 12, 2019

Results of automated E2E tests of Eclipse Che Multiuser on OCP:
Build details
Test report
docker image: eclipseche/che-server:13515
https://github.com/orgs/eclipse/teams/eclipse-che-qa please check this report.

Signed-off-by: Anna Shumilova <ashumilo@redhat.com>
@mkuznyetsov mkuznyetsov requested a review from benoitf as a code owner June 12, 2019 20:35
@ashumilova
Copy link
Contributor

ci-test

@che-bot
Copy link
Contributor

che-bot commented Jun 13, 2019

Results of automated E2E tests of Eclipse Che Multiuser on OCP:
Build details
Test report
docker image: eclipseche/che-server:13515
https://github.com/orgs/eclipse/teams/eclipse-che-qa please check this report.

@SkorikSergey
Copy link
Contributor

ci-test

Signed-off-by: Mykhailo Kuznietsov <mkuznets@redhat.com>
@mkuznyetsov mkuznyetsov requested a review from vparfonov as a code owner June 13, 2019 13:40
Signed-off-by: Mykhailo Kuznietsov <mkuznets@redhat.com>
@che-bot
Copy link
Contributor

che-bot commented Jun 13, 2019

Results of automated E2E tests of Eclipse Che Multiuser on OCP:
Build details
Test report
docker image: eclipseche/che-server:13515
https://github.com/orgs/eclipse/teams/eclipse-che-qa please check this report.

@mkuznyetsov
Copy link
Contributor Author

ci-test

Copy link
Member

@sleshchenko sleshchenko left a comment

Choose a reason for hiding this comment

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

Platform team agreed that there is no necessity to serialize empty collections/fields.
The only bad side of not doing it: clients must check fields existence before using it.

And as Florent said

if field is mandatory then it needs to be empty value, if the field is optional then it can be undefined

In case of Che, we have some required collections/maps in our model which are used on REST API(machines in workspace config), but required collection or map means that at least one value MUST be present and empty collection/map is not valid.

If anybody has strong concerns against this PR then this solution can be rethinking again even after a merging.
But now it looks as the simplest solution for devfile issue and drawbacks looks not critical.

@che-bot
Copy link
Contributor

che-bot commented Jun 13, 2019

Results of automated E2E tests of Eclipse Che Multiuser on OCP:
Build details
Test report
docker image: eclipseche/che-server:13515
https://github.com/orgs/eclipse/teams/eclipse-che-qa please check this report.

@SkorikSergey
Copy link
Contributor

Selenium tests execution on Eclipse Che Multiuser on OCP (https://ci.codenvycorp.com/job/che-pullrequests-test-ocp/1861//Selenium_20tests_20report/) doesn't show any regression against this Pull Request.

Signed-off-by: Mykhailo Kuznietsov <mkuznets@redhat.com>
Signed-off-by: Mykhailo Kuznietsov <mkuznets@redhat.com>
@mkuznyetsov
Copy link
Contributor Author

ci-test

@che-bot
Copy link
Contributor

che-bot commented Jun 14, 2019

Results of automated E2E tests of Eclipse Che Multiuser on OCP:
Build details
Test report
docker image: eclipseche/che-server:13515
https://github.com/orgs/eclipse/teams/eclipse-che-qa please check this report.

@skabashnyuk
Copy link
Contributor

ci-test

@che-bot
Copy link
Contributor

che-bot commented Jun 15, 2019

Results of automated E2E tests of Eclipse Che Multiuser on OCP:
Build details
Test report
docker image: eclipseche/che-server:13515
https://github.com/orgs/eclipse/teams/eclipse-che-qa please check this report.

@mkuznyetsov
Copy link
Contributor Author

ci-test

@@ -588,8 +588,8 @@ export class WorkspaceDetailsController {
* Checks whether "plugins" are enabled in workspace config.
*/
isPluginsEnabled(): boolean {
let editor = this.workspaceDetails.config.attributes.editor || '';
let plugins = this.workspaceDetails.config.attributes.plugins || '';
let editor = this.workspaceDetails.config.attributes ? this.workspaceDetails.config.attributes.editor : '';
Copy link
Contributor

Choose a reason for hiding this comment

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

shouldn't it be an empty array instead of '' ? (same for the next line)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

that whole method may as well be removed since it's not used

Copy link
Contributor

Choose a reason for hiding this comment

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

removed the method

@che-bot
Copy link
Contributor

che-bot commented Jun 17, 2019

Results of automated E2E tests of Eclipse Che Multiuser on OCP:
Build details
Test report
docker image: eclipseche/che-server:13515
https://github.com/orgs/eclipse/teams/eclipse-che-qa please check this report.

@mkuznyetsov mkuznyetsov merged commit 84df6f9 into master Jun 18, 2019
@mkuznyetsov mkuznyetsov deleted the dto-fix branch June 18, 2019 10:10
@che-bot che-bot added this to the 7.0.0 milestone Jun 27, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants