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

Fixed the object mask to work with result limit. #54

Closed

Conversation

FernandoOjeda
Copy link
Contributor

#52

Copy link
Member

@allmightyspiff allmightyspiff left a comment

Choose a reason for hiding this comment

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

Thanks for the pull request. If you can provide some examples of Masks so I can better understand whats going on that would help me out a lot.

@@ -44,7 +45,26 @@ protected String getMask() {

@Override
public String toString() {
return toString(new StringBuilder()).toString();
String objectMask = new String();
String builtedMask = toString(new StringBuilder()).toString();
Copy link
Member

Choose a reason for hiding this comment

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

should be "builtMask"

return toString(new StringBuilder()).toString();
String objectMask = new String();
String builtedMask = toString(new StringBuilder()).toString();
if(builtedMask.contains("[")){
Copy link
Member

Choose a reason for hiding this comment

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

I don't really understand what this code is trying to do, can you provide an example Mask that would trigger the if(builtedMask.contains("[")){ branch and the else branch?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I´m using this example code:

Account.Service accountService = Account.service(client);

accountService.withMask().blockDeviceTemplateGroups().id();
accountService.withMask().blockDeviceTemplateGroups().blockDevices().diskImage().type();
accountService.withMask().blockDeviceTemplateGroups().status().keyName();

List result = accountService.getBlockDeviceTemplateGroups();

For the conditional if(builtedMask.contains("["))is when I use more than one mask like above objectMask example.

The method toString() of the class Mask return the value like this:

blockDeviceTemplateGroups[id, blockDevices.diskImage.type, status.keyName]

with this data the objectMask will be building to send the request, when the request is sending like this without to put the getObject option between the accountService and getBlockDeviceTemplateGroups() method the response will be that the blockDeviceTemplateGroups is not recognized as a value for the objectMask and the service. It is for that I implemented this code to remove the value blockDeviceTemplateGroups to send the correct objectMask without using getObject for the method getBlockDeviceTemplateGroups().

The result for the conditional if() will be:

id, blockDevices.diskImage.type, status.keyName

For the else branch is for one mask, like this example:

accountService.withMask().blockDeviceTemplateGroups().status().keyName();

The method toString() will return like this:

blockDeviceTemplateGroups.status.keyName

And with this branch else the result will be:

status.keyName

Copy link
Member

Choose a reason for hiding this comment

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

Thanks, that helps me understand what is going on a lot better.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm glad to hear that, now we can do the request using objectMask and resultLimit at the same time.

@allmightyspiff
Copy link
Member

allmightyspiff commented Jun 13, 2018

The build has an error from the unit tests.
https://travis-ci.org/softlayer/softlayer-java/jobs/390882491#L1856

testMaskRemoval(com.softlayer.api.RestApiClientTest)  Time elapsed: 0.008 sec  <<< ERROR!
java.lang.StringIndexOutOfBoundsException: String index out of range: -1
	at java.lang.String.substring(String.java:1967)
	at com.softlayer.api.Mask.toString(Mask.java:66)
	at com.softlayer.api.RestApiClientTest.testMaskRemoval(RestApiClientTest.java:476)

If you could also add unit tests to cover the changes your are making that would be helpful. Since objectMasks are a bit part of the SL API, any changes to how they are handled need to be tested very extensively.

if(builtedMask.contains("[")){
String [] mask = builtedMask.split(Pattern.quote("["));
for (int count = 0; count < mask.length; count ++ ) {
if (count != 0){
Copy link
Member

Choose a reason for hiding this comment

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

You could change the for loop to just start at 1 instead of 0, and remove this if statement

}
}
else {
String [] mask = builtedMask.split(Pattern.quote("."));
Copy link
Member

Choose a reason for hiding this comment

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

Looks like this doesn't quite work when there is only 1 item in the mask, as seen in the failed unit test.

@allmightyspiff
Copy link
Member

After digging into the code a bit, I don't think fixing this problem in toString() is going to be the right approach.

        accountService.withMask().abuseEmail();
        accountService.withMask().virtualGuests();
	    accountService.withMask().blockDeviceTemplateGroups().id();
	    accountService.withMask().blockDeviceTemplateGroups().name();
        System.out.print("mask[" + accountService.withMask().toString() + "]\n");
	    for (Group bd : accountService.getObject().getBlockDeviceTemplateGroups()) {
            System.out.println("BD: " + bd.getId() + " - " + bd.getName());
        }

Will return a mask like this: mask[name,id], which isn't going to work for getObject calls.

Basically, we should check to see if the objectMask starts with the call method name, and if so, drop the first bits of the objectMask, which I think can be done in https://github.com/softlayer/softlayer-java/blob/master/src/main/java/com/softlayer/api/RestApiClient.java#L455

basically if your doing mask[blockDeviceTemplateGroups.id] and Account::getBlockDeviceTemplateGroups(), mask should be changed to mask[id], but if you are using Account::getObject() mask should be unchanged.

@FernandoOjeda
Copy link
Contributor Author

The changes in the code were not to use getObject next to the required method to be able to use objectMask and resultLimit at the same time.

`List = accountService.getBlockDeviceTemplateGroups ()

resultLimit does not work using getObject () between accountService and getBlockDeviceTemplateGroups () like below, it does not recognize it.

`List = accountService.getObject.getBlockDeviceTemplateGroups ()

`I try the mask example below and it works fine without using getObject.

Account.Service accountService = Account.service (client);

        accountService.withMask (). abuseEmail ();
        accountService.withMask (). virtualGuests ();
        accountService.withMask (). blockDeviceTemplateGroups (). id ();
        accountService.withMask (). blockDeviceTemplateGroups (). name ();

        System.out.print ("mask [" + accountService.withMask (). ToString () + "] \ n");
        for (Group bd: accountService.getBlockDeviceTemplateGroups ()) {
            System.out.println ("BD:" + bd.getId () + "-" + bd.getName ());
        }

If we want to use Account :: getObject, the code that I implemented does not removes any value and returns the value that is being sent and the mask is correctly constructed and works.

I use the following code example and it works well:

Account.Service accountService = Account.service (client);

        accountService.withMask (). abuseEmail ();
        accountService.withMask (). virtualGuests ();
        accountService.withMask (). networkStorage ();

        try {
            Account result = accountService.getObject ();
            // Print response in JSON format
            Gson gson = new GsonBuilder (). SetPrettyPrinting (). Create ();
            System.out.println (gson.toJson (result));
        } catch (Exception e) {
            System.out.println ("Error:" + e);
        }

@allmightyspiff
Copy link
Member

Having logic in the toString() method is going to cause a lot of headaches.

Ideally the withMask() feature should be able to build a mask based on the mask supported by the call itself, but that is going to take quite a lot of work to make happen. @camporter says he has some work in progress on this issue, so I'll likely get what hes started and try to finish it.

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.

2 participants