Fix cached entity was updated during inlineImages
This commit is contained in:
		
							parent
							
								
									ed65586024
								
							
						
					
					
						commit
						ad97199f04
					
				@ -88,7 +88,7 @@ public class AssetProfileController extends BaseController {
 | 
			
		||||
        AssetProfileId assetProfileId = new AssetProfileId(toUUID(strAssetProfileId));
 | 
			
		||||
        var result = checkAssetProfileId(assetProfileId, Operation.READ);
 | 
			
		||||
        if (inlineImages) {
 | 
			
		||||
            imageService.inlineImage(result);
 | 
			
		||||
            result = imageService.inlineImage(result);
 | 
			
		||||
        }
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -96,7 +96,7 @@ public class DeviceProfileController extends BaseController {
 | 
			
		||||
        DeviceProfileId deviceProfileId = new DeviceProfileId(toUUID(strDeviceProfileId));
 | 
			
		||||
        var result = checkDeviceProfileId(deviceProfileId, Operation.READ);
 | 
			
		||||
        if (inlineImages) {
 | 
			
		||||
            imageService.inlineImage(result);
 | 
			
		||||
            result = imageService.inlineImage(result);
 | 
			
		||||
        }
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -90,7 +90,7 @@ public class WidgetsBundleController extends BaseController {
 | 
			
		||||
        WidgetsBundleId widgetsBundleId = new WidgetsBundleId(toUUID(strWidgetsBundleId));
 | 
			
		||||
        var result = checkWidgetsBundleId(widgetsBundleId, Operation.READ);
 | 
			
		||||
        if (inlineImages) {
 | 
			
		||||
            imageService.inlineImage(result);
 | 
			
		||||
            result = imageService.inlineImage(result);
 | 
			
		||||
        }
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -34,7 +34,6 @@ public class AssetProfileExportService extends BaseEntityExportService<AssetProf
 | 
			
		||||
        assetProfile.setDefaultDashboardId(getExternalIdOrElseInternal(ctx, assetProfile.getDefaultDashboardId()));
 | 
			
		||||
        assetProfile.setDefaultRuleChainId(getExternalIdOrElseInternal(ctx, assetProfile.getDefaultRuleChainId()));
 | 
			
		||||
        assetProfile.setDefaultEdgeRuleChainId(getExternalIdOrElseInternal(ctx, assetProfile.getDefaultEdgeRuleChainId()));
 | 
			
		||||
        imageService.inlineImage(assetProfile);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
 | 
			
		||||
@ -32,7 +32,6 @@ import org.thingsboard.server.common.data.sync.ie.AttributeExportData;
 | 
			
		||||
import org.thingsboard.server.common.data.sync.ie.EntityExportData;
 | 
			
		||||
import org.thingsboard.server.dao.attributes.AttributesService;
 | 
			
		||||
import org.thingsboard.server.dao.relation.RelationDao;
 | 
			
		||||
import org.thingsboard.server.dao.resource.ImageService;
 | 
			
		||||
import org.thingsboard.server.queue.util.TbCoreComponent;
 | 
			
		||||
import org.thingsboard.server.service.sync.ie.exporting.EntityExportService;
 | 
			
		||||
import org.thingsboard.server.service.sync.ie.exporting.ExportableEntitiesService;
 | 
			
		||||
@ -60,8 +59,6 @@ public class DefaultEntityExportService<I extends EntityId, E extends Exportable
 | 
			
		||||
    private RelationDao relationDao;
 | 
			
		||||
    @Autowired
 | 
			
		||||
    private AttributesService attributesService;
 | 
			
		||||
    @Autowired
 | 
			
		||||
    protected ImageService imageService;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public final D getExportData(EntitiesExportCtx<?> ctx, I entityId) throws ThingsboardException {
 | 
			
		||||
 | 
			
		||||
@ -34,7 +34,6 @@ public class DeviceProfileExportService extends BaseEntityExportService<DevicePr
 | 
			
		||||
        deviceProfile.setDefaultDashboardId(getExternalIdOrElseInternal(ctx, deviceProfile.getDefaultDashboardId()));
 | 
			
		||||
        deviceProfile.setDefaultRuleChainId(getExternalIdOrElseInternal(ctx, deviceProfile.getDefaultRuleChainId()));
 | 
			
		||||
        deviceProfile.setDefaultEdgeRuleChainId(getExternalIdOrElseInternal(ctx, deviceProfile.getDefaultEdgeRuleChainId()));
 | 
			
		||||
        imageService.inlineImage(deviceProfile);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
 | 
			
		||||
@ -40,7 +40,6 @@ public class WidgetsBundleExportService extends BaseEntityExportService<WidgetsB
 | 
			
		||||
        if (widgetsBundle.getTenantId() == null || widgetsBundle.getTenantId().isNullUid()) {
 | 
			
		||||
            throw new IllegalArgumentException("Export of system Widget Bundles is not allowed");
 | 
			
		||||
        }
 | 
			
		||||
        imageService.inlineImage(widgetsBundle);
 | 
			
		||||
 | 
			
		||||
        List<String> fqns = widgetTypeService.findWidgetFqnsByWidgetsBundleId(ctx.getTenantId(), widgetsBundle.getId());
 | 
			
		||||
        exportData.setFqns(fqns);
 | 
			
		||||
 | 
			
		||||
@ -24,6 +24,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 | 
			
		||||
import org.springframework.http.HttpMethod;
 | 
			
		||||
import org.springframework.test.context.TestPropertySource;
 | 
			
		||||
import org.thingsboard.common.util.JacksonUtil;
 | 
			
		||||
import org.thingsboard.server.common.data.DeviceProfile;
 | 
			
		||||
import org.thingsboard.server.common.data.ImageDescriptor;
 | 
			
		||||
import org.thingsboard.server.common.data.ResourceExportData;
 | 
			
		||||
import org.thingsboard.server.common.data.ResourceSubType;
 | 
			
		||||
@ -321,6 +322,24 @@ public class ImageControllerTest extends AbstractControllerTest {
 | 
			
		||||
        assertThat(systemParams.getMaxResourceSize()).isEqualTo(0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void testInlineImages() throws Exception {
 | 
			
		||||
        TbResourceInfo imageInfo = uploadImage(HttpMethod.POST, "/api/image", "my_png_image.png", "image/png", PNG_IMAGE);
 | 
			
		||||
        DeviceProfile deviceProfile = createDeviceProfile("Test");
 | 
			
		||||
        deviceProfile.setImage("tb-image;" + imageInfo.getLink());
 | 
			
		||||
        deviceProfile = doPost("/api/deviceProfile", deviceProfile, DeviceProfile.class);
 | 
			
		||||
 | 
			
		||||
        DeviceProfile deviceProfileInlined = doGet("/api/deviceProfile/" + deviceProfile.getUuidId() + "?inlineImages=true", DeviceProfile.class);
 | 
			
		||||
        assertThat(deviceProfileInlined.getImage()).isEqualTo("tb-image:" +
 | 
			
		||||
                Base64.getEncoder().encodeToString(imageInfo.getResourceKey().getBytes()) + ":"
 | 
			
		||||
                + Base64.getEncoder().encodeToString(imageInfo.getName().getBytes()) + ":"
 | 
			
		||||
                + Base64.getEncoder().encodeToString(imageInfo.getResourceSubType().name().getBytes()) +
 | 
			
		||||
                ";data:image/png;base64," + Base64.getEncoder().encodeToString(PNG_IMAGE));
 | 
			
		||||
 | 
			
		||||
        deviceProfile = doGet("/api/deviceProfile/" + deviceProfile.getUuidId(), DeviceProfile.class);
 | 
			
		||||
        assertThat(deviceProfile.getImage()).isEqualTo("tb-image;" + imageInfo.getLink());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private TbResourceInfo updateImagePublicStatus(String filename, boolean isPublic) throws Exception {
 | 
			
		||||
        return doPut("/api/images/tenant/" + filename + "/public/" + isPublic, "", TbResourceInfo.class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -64,7 +64,7 @@ public interface ImageService {
 | 
			
		||||
 | 
			
		||||
    boolean updateImagesUsage(WidgetTypeDetails widgetType);
 | 
			
		||||
 | 
			
		||||
    void inlineImage(HasImage entity);
 | 
			
		||||
    <T extends HasImage> T inlineImage(T entity);
 | 
			
		||||
 | 
			
		||||
    Collection<TbResourceInfo> getUsedImages(Dashboard dashboard);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -27,6 +27,7 @@ import org.apache.commons.lang3.tuple.Pair;
 | 
			
		||||
import org.springframework.stereotype.Service;
 | 
			
		||||
import org.springframework.transaction.annotation.Transactional;
 | 
			
		||||
import org.thingsboard.common.util.JacksonUtil;
 | 
			
		||||
import org.thingsboard.server.cache.CaffeineTbTransactionalCache;
 | 
			
		||||
import org.thingsboard.server.common.data.Dashboard;
 | 
			
		||||
import org.thingsboard.server.common.data.DataConstants;
 | 
			
		||||
import org.thingsboard.server.common.data.EntityType;
 | 
			
		||||
@ -526,9 +527,16 @@ public class BaseImageService extends BaseResourceService implements ImageServic
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void inlineImage(HasImage entity) {
 | 
			
		||||
    public <T extends HasImage> T inlineImage(T entity) {
 | 
			
		||||
        log.trace("Executing inlineImage [{}] [{}] [{}]", entity.getTenantId(), entity.getClass().getSimpleName(), entity.getName());
 | 
			
		||||
        if (StringUtils.isEmpty(entity.getImage())) {
 | 
			
		||||
            return entity;
 | 
			
		||||
        }
 | 
			
		||||
        if (cache instanceof CaffeineTbTransactionalCache) {
 | 
			
		||||
            entity = JacksonUtil.clone(entity); // cloning the entity to avoid updating the cached one
 | 
			
		||||
        }
 | 
			
		||||
        entity.setImage(inlineImage(entity.getTenantId(), "image", entity.getImage(), true));
 | 
			
		||||
        return entity;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user