How to implement dynamic attributes in multi tenant app

For example, client A may want entity Foo to have Size and Color Attribute, whereas client tenant B may want entity Foo to have Tax Amount.
Do you have idea how to implement it?

Thanks

Hello Muhammad, sorry for the late reply.

You could use Cuba dynamic attributes for this. However we’ve found a bug in Cuba which would prevent you from implementing everything correctly, but now it is fixed and will be included in the next Cuba minor release (6.3.6).

In order to make dynamic attributes tenant-specific you want to extend Cuba entities Category, CategoryAttribute, CategoryAttributeValue and make them tenant-specific by adding tenant id attribute to them (like you do for your other tenant-specific entities).

This will allow tenants to have their own categories and sets of attributes for existing entities.
You read more about dynamic attributes here.

Then you will have to override the rules of adding dynamic attributes in UI in order to include filtering of attributes by tenant id.
You could extend DynamicAttributesGuiTools bean in GUI module like this:


package com.haulmont.test.gui.dynamicattributes;

import com.haulmont.cuba.core.entity.CategoryAttribute;
import com.haulmont.cuba.core.global.UserSessionSource;
import com.haulmont.cuba.gui.dynamicattributes.DynamicAttributesGuiTools;
import com.haulmont.test.entity.MyCategoryAttribute;

import javax.inject.Inject;
import java.util.Objects;

public class MyDynamicAttributesGuiTools extends DynamicAttributesGuiTools {

    @Inject
    protected UserSessionSource uss;

    @Override
    protected boolean attributeShouldBeShownOnTheScreen(String screen, String component, CategoryAttribute attribute) {
        MyCategoryAttribute myAttribute = (MyCategoryAttribute) attribute;
        String tenantId = uss.getUserSession().getAttribute("tenant_id");
        if (myAttribute.getTenantId() != null && !Objects.equals(tenantId, myAttribute.getTenantId())) {
            return false;
        }
        return super.attributeShouldBeShownOnTheScreen(screen, component, attribute);
    }
}

this will filter attributes by tenant.
Don’t forget to register it in web-spring.xml:


    <bean id="cuba_DynamicAttributesGuiTools" class="com.haulmont.test.gui.dynamicattributes.MyDynamicAttributesGuiTools"/>

I hope it helps.

Hi Igor,

Thanks for your clear explanation which helps a lot!