1

Update: The question (below; see "Original Question") still stands, but I have additional data. I was able to successfully retrieve an asset by putting the access token into the source code as a string where the services field is instantiated. I.e., this works:

String token = "[mysecrettoken]";
try{
    connector = V1Connector
        .withInstanceUrl(V1_LOC)
        .withUserAgentHeader(APPLICATION_NAME, APPLICATION_VERSION)
        .withAccessToken(token)
        .build();
}

However, when I use a class I created to retrieve the token from an encrypted text file, it fails with the error I specified below.

String token = TokenUtils.getAccessToken();

I've used System.out.println to visually verify that the token is being decrypted perfectly. Why would the decrypted String returned by TokenUtils (which appears to be correct) be any different than the String when it's included directly in the source code?

Original Question:

I'm having a similar problem to Griffin's, but I'm using Java, and I'm unable to ferret out the root cause thus far. It's worth noting that an earlier version of this program was successfully able to connect to VersionOne and retrieve assets, but when I retrieved that commit and tried it again with the current access token (which has changed since it was committed), I get the same error as below.

Here is the relevant method; The services variable is a field of the containing class:

private Asset findTeam(String teamName){

        assert teamName != null;

        Asset result = null;
        IAssetType assetType = services.getMeta().getAssetType("Team");
        Query query = new Query(assetType);
        IAttributeDefinition nameAttr = 
            assetType.getAttributeDefinition("Name");
        query.getSelection().add(nameAttr);

        try{
            QueryResult queryResult = services.retrieve(query);

            for (Asset team: queryResult.getAssets()){
                String str = team.getAttribute(nameAttr).getValue().toString();
                assert str != null;
                if (teamName.equals(str)){
                    result = team;
                    break;
                }
            }           
        }
        catch(Exception e){
            assert false;
            e.printStackTrace();
        }
        return result;

    }

And here is the resulting error:

com.versionone.apiclient.exceptions.ConnectionException: 
HTTP/1.1 400 Bad Request error code: 400 VersionOne could not process the request.
    at com.versionone.apiclient.V1Connector.manageErrors(V1Connector.java:420)
    at com.versionone.apiclient.V1Connector.getData(V1Connector.java:368)
    at com.versionone.apiclient.MetaModel.createDocument(MetaModel.java:252)
    at com.versionone.apiclient.MetaModel.hookupAssetType(MetaModel.java:185)
    at com.versionone.apiclient.MetaModel.findAssetType(MetaModel.java:140)
    at com.versionone.apiclient.MetaModel.getAssetType(MetaModel.java:85)
    at com.billhorvath.v1mods.TeamModder.addToTeam(TeamModder.java:63)
    at com.billhorvath.v1mods.TeamModder.main(TeamModder.java:38)
com.versionone.apiclient.exceptions.MetaException: Error creating Document: Team
    at com.versionone.apiclient.MetaModel.createDocument(MetaModel.java:259)
    at com.versionone.apiclient.MetaModel.hookupAssetType(MetaModel.java:185)
    at com.versionone.apiclient.MetaModel.findAssetType(MetaModel.java:140)
    at com.versionone.apiclient.MetaModel.getAssetType(MetaModel.java:85)
    at com.billhorvath.v1mods.TeamModder.addToTeam(TeamModder.java:63)
    at com.billhorvath.v1mods.TeamModder.main(TeamModder.java:38)
Caused by: com.versionone.apiclient.exceptions.ConnectionException: 
HTTP/1.1 400 Bad Request error code: 400 VersionOne could not process the request.
    at com.versionone.apiclient.V1Connector.manageErrors(V1Connector.java:420)
    at com.versionone.apiclient.V1Connector.getData(V1Connector.java:368)
    at com.versionone.apiclient.MetaModel.createDocument(MetaModel.java:252)
    ... 5 more
Exception in thread "main" com.versionone.apiclient.exceptions.MetaException: Unknown AssetType: Team
    at com.versionone.apiclient.MetaModel.getAssetType(MetaModel.java:88)
    at com.billhorvath.v1mods.TeamModder.addToTeam(TeamModder.java:63)
    at com.billhorvath.v1mods.TeamModder.main(TeamModder.java:38)
Caused by: com.versionone.apiclient.exceptions.MetaException: Error creating Document: Team
    at com.versionone.apiclient.MetaModel.createDocument(MetaModel.java:259)
    at com.versionone.apiclient.MetaModel.hookupAssetType(MetaModel.java:185)
    at com.versionone.apiclient.MetaModel.findAssetType(MetaModel.java:140)
    at com.versionone.apiclient.MetaModel.getAssetType(MetaModel.java:85)
    ... 2 more
Caused by: com.versionone.apiclient.exceptions.ConnectionException: 
HTTP/1.1 400 Bad Request error code: 400 VersionOne could not process the request.
    at com.versionone.apiclient.V1Connector.manageErrors(V1Connector.java:420)
    at com.versionone.apiclient.V1Connector.getData(V1Connector.java:368)
    at com.versionone.apiclient.MetaModel.createDocument(MetaModel.java:252)
    ... 5 more

In addition to the usual searches, I've reviewed the source code of the VersionOne Java API, as well as the RFC for the 400 error code; I haven't found any answers. Anyone have any suggestions?

Community
  • 1
  • 1
Bill Horvath
  • 1,336
  • 9
  • 24
  • 1
    Bill what happens when you do a diff on the string literal VS decrypted string? StringUtils.difference("token", token); Try that or some other method to do a binary diff. It might expose some subtle differences between the raw token string and the var that holds the deserialized token. Not a Java guru but I am thinking since string literal is same as String object (with exception of storage locale) the issue could be with superfluous chars. – Mark Irvin Jul 16 '15 at 19:32
  • I was thinking the same thing, maybe having to do with the character set of the respective strings. I'll poke around and let you know what I find out. – Bill Horvath Jul 16 '15 at 19:55

1 Answers1

1

(Hat tip to Mark Irvin for the binary-comparison suggestion.)

It turns out that the problem had to do with the way the token was encrypted: Since the token is 30 characters long, and the requirements of the cipher algorithm (AES in this case) called for 32 bytes, two blank bytes were appended during the encryption process. I modified the decryption cycle to strip characters whose integer value was 0 off the end of the String, and wallah! It works.

Community
  • 1
  • 1
Bill Horvath
  • 1,336
  • 9
  • 24