1

I want to extend the managed object with some custom fragments. Something like this:

@Alias(value = "Dictionary")
public class Dictionary extends AbstractDynamicProperties {
    private Map<String, String> records = new HashMap<>();

    @JSONProperty(ignoreIfNull = false)
    public Map<String, String> getRecords() { return this.records; }

    (...)
}

When I create a new managed object and save it into the inventory API everything looks great:

ManagedObjectRepresentation dictionary = new ManagedObjectRepresentation();
dictionary.setName(dictionaryName);
dictionary.set(new Dictionary());

Unfortunately, when I fetch this managed object and want to retrieve the Dictionary class I receive a HashMap:

dictionary.get(Dictionary.class).addRecord(key, value);

After some debugging, I founded that when a managed object is saved, ExtensibilityConverter (tryGetAlias() line 98) is iterating over all annotation in the object and if it finds the Alias annotation, it takes the value from there.

On the other hand, when the response from the Cumulocity is being deserialized, Svenson is using AliasMapClassFinder and I can see only initialization in the ExtensibilityConverter. I can't spot any place that this map alias2ClassName is filled and because it's always empty I receive the HashMap instead of the class I expect.

Am I missing something? Or this is a bug in the SDK?

Mariusz Kraj
  • 107
  • 5

1 Answers1

1

I'm not sure what you are trying to do with alias annotations. I assume you simply want to manage custom fragments in your Java application.

The easiest way to create a custom fragment and handle it in a type safe way is by simply creating a class that resembles your fragment.

Say you want to manage the following fragment:

{
    "my_custom_Fragment":{
        "stringProperty": "hello world",
        "numericProperty": 1337
    }
}

Then you create this class to resemble it:

package my.custom;

public class Fragment {
    private String stringProperty;
    private int numericProperty;

    //constructors, getters, setters
}

If you want to support dynamic properties, also extend AbstractDynamicProperties as in your example.

The fully qualified class name where dots are replaced with underscores will become the fragment name (in our example my_custom_Fragment) when you assign it to you managed object.

ManagedObjectRepresentation managedObject = new ManagedObjectRepresentation();
Fragment fragment = new Fragment();
//set fragment properties
managedObject.set(fragment);

You can retrieve the fragment from your managed object in a type safe way as well.

ManagedObjectRepresentation created = inventoryApi.create(managedObject);
Fragment createdFragment = created.get(Fragment.class);
l2p
  • 420
  • 3
  • 9
  • Hi, and this is exactly what I started to do. What I wanted to accomplish with the @alias annotation is to locate a class in module: my.custom.model.Fragment but to use fragment "my_custom_Fragment" and as I said, when I save the mo it's ok. Reading doesn't work, Svenson doesn't find the custom class. – Mariusz Kraj Jul 31 '18 at 11:01