mirror of
				https://github.com/Alfresco/alfresco-community-repo.git
				synced 2025-10-29 15:21:53 +00:00 
			
		
		
		
	Compare commits
	
		
			288 Commits
		
	
	
		
			23.6.0.3
			...
			feature/MN
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					5e0d3cce6e | ||
| 
						 | 
					c6de5c7577 | ||
| 
						 | 
					18bcfc9d3a | ||
| 
						 | 
					36a164965d | ||
| 
						 | 
					c7ef0046a8 | ||
| 
						 | 
					1f25b1370b | ||
| 
						 | 
					8ba10aa019 | ||
| 
						 | 
					154d0441b5 | ||
| 
						 | 
					7a3a05f5ed | ||
| 
						 | 
					63814e0775 | ||
| 
						 | 
					d4294cfa00 | ||
| 
						 | 
					4bf216aa49 | ||
| 
						 | 
					25a3611779 | ||
| 
						 | 
					1295f70435 | ||
| 
						 | 
					9d0de45ddb | ||
| 
						 | 
					b271bf5de5 | ||
| 
						 | 
					99f0040816 | ||
| 
						 | 
					3e6be4555d | ||
| 
						 | 
					1745693725 | ||
| 
						 | 
					ed42c00036 | ||
| 
						 | 
					4af5eabf3b | ||
| 
						 | 
					f8fd9b44b3 | ||
| 
						 | 
					e65e0d54c7 | ||
| 
						 | 
					bfa3f0407f | ||
| 
						 | 
					e9d8b1e388 | ||
| 
						 | 
					fae21b6c0a | ||
| 
						 | 
					8388a1d5bc | ||
| 
						 | 
					7a74f7947a | ||
| 
						 | 
					05e2bcdcdd | ||
| 
						 | 
					29e76f3074 | ||
| 
						 | 
					f39913562b | ||
| 
						 | 
					28e5f76eb7 | ||
| 
						 | 
					3922c07a24 | ||
| 
						 | 
					6d6fbbe3c7 | ||
| 
						 | 
					7f95d62593 | ||
| 
						 | 
					d49d4c2c1d | ||
| 
						 | 
					9692257487 | ||
| 
						 | 
					74cc4c0b4c | ||
| 
						 | 
					855ab535b6 | ||
| 
						 | 
					16e57ae154 | ||
| 
						 | 
					29d25eaf6b | ||
| 
						 | 
					76f537527d | ||
| 
						 | 
					c320d770e8 | ||
| 
						 | 
					610bb4cc6f | ||
| 
						 | 
					b8d08f0866 | ||
| 
						 | 
					7187b5bc47 | ||
| 
						 | 
					ebce052927 | ||
| 
						 | 
					b7a3a5ac0c | ||
| 
						 | 
					e33feb2889 | ||
| 
						 | 
					ba393a5652 | ||
| 
						 | 
					26035477e4 | ||
| 
						 | 
					26c79b4621 | ||
| 
						 | 
					013cfb1403 | ||
| 
						 | 
					d386924ac9 | ||
| 
						 | 
					1027bc14cd | ||
| 
						 | 
					18901c779d | ||
| 
						 | 
					79e2cb6342 | ||
| 
						 | 
					c07109943e | ||
| 
						 | 
					aecb029860 | ||
| 
						 | 
					38e5f56512 | ||
| 
						 | 
					9684cbfa2f | ||
| 
						 | 
					40efd934ac | ||
| 
						 | 
					697f8d865b | ||
| 
						 | 
					5b14722931 | ||
| 
						 | 
					e0bc0e6ad6 | ||
| 
						 | 
					681b0efbcb | ||
| 
						 | 
					1048c431c0 | ||
| 
						 | 
					674bcb6c36 | ||
| 
						 | 
					cc612bfb57 | ||
| 
						 | 
					4fa084b25b | ||
| 
						 | 
					269a621bfe | ||
| 
						 | 
					76239a92ca | ||
| 
						 | 
					6aaffe4efc | ||
| 
						 | 
					3450f9b2ee | ||
| 
						 | 
					3b7601ff10 | ||
| 
						 | 
					8fa7f9c16a | ||
| 
						 | 
					5cd8ea2bac | ||
| 
						 | 
					0b8612de01 | ||
| 
						 | 
					e1949ee572 | ||
| 
						 | 
					1516ab9035 | ||
| 
						 | 
					289011b665 | ||
| 
						 | 
					4c6633b783 | ||
| 
						 | 
					47799cdbdd | ||
| 
						 | 
					1e42e13f7f | ||
| 
						 | 
					6f1138fe4a | ||
| 
						 | 
					ed20ea1605 | ||
| 
						 | 
					817548aba7 | ||
| 
						 | 
					3b49f50681 | ||
| 
						 | 
					e40afc1d8d | ||
| 
						 | 
					aa8bff499b | ||
| 
						 | 
					c603a77082 | ||
| 
						 | 
					280bbf6bb7 | ||
| 
						 | 
					d1c3ca5a70 | ||
| 
						 | 
					98a3469d60 | ||
| 
						 | 
					0959f820e4 | ||
| 
						 | 
					a620e9114f | ||
| 
						 | 
					9782555d06 | ||
| 
						 | 
					2da3ce6c15 | ||
| 
						 | 
					a747e7b104 | ||
| 
						 | 
					a31adb16a9 | ||
| 
						 | 
					a9bae635fa | ||
| 
						 | 
					a9901ef9e7 | ||
| 
						 | 
					fed54a3252 | ||
| 
						 | 
					7af7c29e0e | ||
| 
						 | 
					21b8354a4b | ||
| 
						 | 
					d92f599d16 | ||
| 
						 | 
					f86142ce18 | ||
| 
						 | 
					6a8d9e076a | ||
| 
						 | 
					2469ff3a1b | ||
| 
						 | 
					385254bcbd | ||
| 
						 | 
					00bfbff922 | ||
| 
						 | 
					d3b9ef1ef8 | ||
| 
						 | 
					7eff12818e | ||
| 
						 | 
					142529d870 | ||
| 
						 | 
					5e711c1a75 | ||
| 
						 | 
					d690797355 | ||
| 
						 | 
					51176042c0 | ||
| 
						 | 
					29d17ece20 | ||
| 
						 | 
					16f93add09 | ||
| 
						 | 
					f4c36ad4e1 | ||
| 
						 | 
					3f86162ab0 | ||
| 
						 | 
					cfbae046dd | ||
| 
						 | 
					61910036b3 | ||
| 
						 | 
					5a1ea3398a | ||
| 
						 | 
					9606d8e2de | ||
| 
						 | 
					46240eb257 | ||
| 
						 | 
					2642067af9 | ||
| 
						 | 
					c9e6ab2144 | ||
| 
						 | 
					c3a0ebc448 | ||
| 
						 | 
					83d798641a | ||
| 
						 | 
					a8c87f7273 | ||
| 
						 | 
					6153c12135 | ||
| 
						 | 
					2fb2f31668 | ||
| 
						 | 
					c854cd7f1b | ||
| 
						 | 
					4a0ca9a133 | ||
| 
						 | 
					f0549d1862 | ||
| 
						 | 
					dca8b792a1 | ||
| 
						 | 
					5279b9925e | ||
| 
						 | 
					a9878d9514 | ||
| 
						 | 
					9f28594ba5 | ||
| 
						 | 
					b43107731f | ||
| 
						 | 
					ed3c189b10 | ||
| 
						 | 
					f3f099df6d | ||
| 
						 | 
					0721099517 | ||
| 
						 | 
					a225f66198 | ||
| 
						 | 
					569d9e85d1 | ||
| 
						 | 
					c01445b916 | ||
| 
						 | 
					8927470328 | ||
| 
						 | 
					cb9c051383 | ||
| 
						 | 
					933a0e67df | ||
| 
						 | 
					1287ab4354 | ||
| 
						 | 
					7300e5b3a3 | ||
| 
						 | 
					d0f133d4b3 | ||
| 
						 | 
					76fdba7720 | ||
| 
						 | 
					94006dcab2 | ||
| 
						 | 
					671190436e | ||
| 
						 | 
					1e0d40a8b8 | ||
| 
						 | 
					33626b4627 | ||
| 
						 | 
					be674a2b17 | ||
| 
						 | 
					0a38c0c991 | ||
| 
						 | 
					0e34ea7f04 | ||
| 
						 | 
					fcc393e0fa | ||
| 
						 | 
					8f8045e302 | ||
| 
						 | 
					a61c1e98e1 | ||
| 
						 | 
					bd6d21f6f3 | ||
| 
						 | 
					90e6bb89b9 | ||
| 
						 | 
					25ba6efdde | ||
| 
						 | 
					17ddfdb6df | ||
| 
						 | 
					420100ec91 | ||
| 
						 | 
					50cd40a1ba | ||
| 
						 | 
					b9f0b8da23 | ||
| 
						 | 
					7f2aaeb672 | ||
| 
						 | 
					6af94b0ca5 | ||
| 
						 | 
					e5dfe0ea94 | ||
| 
						 | 
					0c5cc98de9 | ||
| 
						 | 
					873dfe2224 | ||
| 
						 | 
					44f42992dd | ||
| 
						 | 
					1073677dc7 | ||
| 
						 | 
					aa2acb18b2 | ||
| 
						 | 
					fbfcdfec3e | ||
| 
						 | 
					58cd9db730 | ||
| 
						 | 
					7a16e30f30 | ||
| 
						 | 
					51f8142fd1 | ||
| 
						 | 
					586990db88 | ||
| 
						 | 
					2c879c7b16 | ||
| 
						 | 
					5e9a99dc02 | ||
| 
						 | 
					4faa421a55 | ||
| 
						 | 
					b88af161c8 | ||
| 
						 | 
					044b05481f | ||
| 
						 | 
					0ce174586d | ||
| 
						 | 
					76611fd1ac | ||
| 
						 | 
					3581f54bea | ||
| 
						 | 
					af7ebb06ca | ||
| 
						 | 
					4fbca55d86 | ||
| 
						 | 
					9f109e9672 | ||
| 
						 | 
					32879377d1 | ||
| 
						 | 
					0f6bb34c72 | ||
| 
						 | 
					742ab3669a | ||
| 
						 | 
					4a43eaabb0 | ||
| 
						 | 
					244d10f95f | ||
| 
						 | 
					b3b8b9186c | ||
| 
						 | 
					6206be9c77 | ||
| 
						 | 
					43ca02592c | ||
| 
						 | 
					2f3596266b | ||
| 
						 | 
					4edc87cb52 | ||
| 
						 | 
					ec2280531f | ||
| 
						 | 
					2a1ee7d312 | ||
| 
						 | 
					464fc207fc | ||
| 
						 | 
					6798785893 | ||
| 
						 | 
					1c8c6ff841 | ||
| 
						 | 
					3c7f5b5ad1 | ||
| 
						 | 
					10b436d3c4 | ||
| 
						 | 
					4e86bb70ee | ||
| 
						 | 
					9578891af4 | ||
| 
						 | 
					88d10f2f4f | ||
| 
						 | 
					b47e0551cb | ||
| 
						 | 
					225c521f09 | ||
| 
						 | 
					f9f199deb5 | ||
| 
						 | 
					2022c38913 | ||
| 
						 | 
					5f7b97b6a2 | ||
| 
						 | 
					87ea4444d4 | ||
| 
						 | 
					d0e3c69b55 | ||
| 
						 | 
					bf7f6da4c5 | ||
| 
						 | 
					a2e48a4512 | ||
| 
						 | 
					1f1d80d93d | ||
| 
						 | 
					98a9d6467c | ||
| 
						 | 
					6040b138ef | ||
| 
						 | 
					3f8be2bcd3 | ||
| 
						 | 
					2b2a754a1f | ||
| 
						 | 
					ef4d1d8437 | ||
| 
						 | 
					5ec06091ea | ||
| 
						 | 
					dfcfa87680 | ||
| 
						 | 
					d4ef724648 | ||
| 
						 | 
					8424c1b90a | ||
| 
						 | 
					9180053a29 | ||
| 
						 | 
					6aaa24d9d6 | ||
| 
						 | 
					5e024c95c2 | ||
| 
						 | 
					9d313bd6b3 | ||
| 
						 | 
					63d6de76c4 | ||
| 
						 | 
					ea9231c957 | ||
| 
						 | 
					5deb2b470f | ||
| 
						 | 
					44ecf9fc4c | ||
| 
						 | 
					c2a5948a02 | ||
| 
						 | 
					2deb4f428f | ||
| 
						 | 
					c3e03ca837 | ||
| 
						 | 
					9d9d5ee599 | ||
| 
						 | 
					a16ac952b3 | ||
| 
						 | 
					95e256bfe5 | ||
| 
						 | 
					b1ad2780b9 | ||
| 
						 | 
					9b0337cb8a | ||
| 
						 | 
					e5617d8440 | ||
| 
						 | 
					e1d3469bc5 | ||
| 
						 | 
					2bf9dac653 | ||
| 
						 | 
					7daf9c0d61 | ||
| 
						 | 
					80cb5b6caa | ||
| 
						 | 
					3cd67921d7 | ||
| 
						 | 
					6c5058246f | ||
| 
						 | 
					3d2b1d0ee8 | ||
| 
						 | 
					1b36b51031 | ||
| 
						 | 
					cfe265f1ce | ||
| 
						 | 
					824bca52db | ||
| 
						 | 
					cf45659627 | ||
| 
						 | 
					e119821ce2 | ||
| 
						 | 
					24334d1b29 | ||
| 
						 | 
					e749366a77 | ||
| 
						 | 
					ead9aa9fd3 | ||
| 
						 | 
					bb4d3eb276 | ||
| 
						 | 
					87e64a617d | ||
| 
						 | 
					afb506e4ae | ||
| 
						 | 
					25a95383be | ||
| 
						 | 
					08616cb33d | ||
| 
						 | 
					798549f0f8 | ||
| 
						 | 
					0a7f27c27e | ||
| 
						 | 
					d628fc6799 | ||
| 
						 | 
					4c6052b92d | ||
| 
						 | 
					d06c7b6fd3 | ||
| 
						 | 
					44e14d9fbd | ||
| 
						 | 
					087fbba598 | ||
| 
						 | 
					cf97c3a3ef | ||
| 
						 | 
					368cebde9e | ||
| 
						 | 
					76da68d205 | ||
| 
						 | 
					7c298e6f35 | ||
| 
						 | 
					e6f13528d9 | ||
| 
						 | 
					202c99a99b | ||
| 
						 | 
					490ec6ec08 | ||
| 
						 | 
					53cc9c4eee | ||
| 
						 | 
					b69487c9bb | ||
| 
						 | 
					37ae98e253 | 
							
								
								
									
										3
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							@@ -984,6 +984,9 @@ jobs:
 | 
			
		||||
      - name: "Build TAS integration tests"
 | 
			
		||||
        if: ${{ matrix.test-name }} == 'Integration TAS tests'
 | 
			
		||||
        run: mvn install -pl :alfresco-community-repo-integration-test -am -DskipTests -Pall-tas-tests
 | 
			
		||||
      - name: Setup tmate session
 | 
			
		||||
        if: ${{ matrix.test-name }} == 'REST API TAS tests part3'
 | 
			
		||||
        uses: mxschmitt/action-tmate@v3
 | 
			
		||||
      - name: "Prepare Report Portal"
 | 
			
		||||
        if: github.ref_name == 'master'
 | 
			
		||||
        uses: Alfresco/alfresco-build-tools/.github/actions/reportportal-prepare@v7.1.0
 | 
			
		||||
 
 | 
			
		||||
@@ -731,7 +731,7 @@
 | 
			
		||||
        "filename": "remote-api/src/test/java/org/alfresco/rest/api/tests/AbstractBaseApiTest.java",
 | 
			
		||||
        "hashed_secret": "d033e22ae348aeb5660fc2140aec35850c4da997",
 | 
			
		||||
        "is_verified": false,
 | 
			
		||||
        "line_number": 120,
 | 
			
		||||
        "line_number": 111,
 | 
			
		||||
        "is_secret": false
 | 
			
		||||
      }
 | 
			
		||||
    ],
 | 
			
		||||
@@ -1888,5 +1888,5 @@
 | 
			
		||||
      }
 | 
			
		||||
    ]
 | 
			
		||||
  },
 | 
			
		||||
  "generated_at": "2024-10-02T10:18:47Z"
 | 
			
		||||
}
 | 
			
		||||
  "generated_at": "2024-10-09T09:32:52Z"
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,141 @@
 | 
			
		||||
/*-
 | 
			
		||||
 * #%L
 | 
			
		||||
 * alfresco-tas-restapi
 | 
			
		||||
 * %%
 | 
			
		||||
 * Copyright (C) 2005 - 2024 Alfresco Software Limited
 | 
			
		||||
 * %%
 | 
			
		||||
 * This file is part of the Alfresco software.
 | 
			
		||||
 * If the software was purchased under a paid Alfresco license, the terms of
 | 
			
		||||
 * the paid license agreement will prevail.  Otherwise, the software is
 | 
			
		||||
 * provided under the following open source license terms:
 | 
			
		||||
 *
 | 
			
		||||
 * Alfresco is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU Lesser General Public License as published by
 | 
			
		||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * Alfresco is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 * #L%
 | 
			
		||||
 */
 | 
			
		||||
package org.alfresco.rest.model;
 | 
			
		||||
 | 
			
		||||
import java.util.Date;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
 | 
			
		||||
import com.fasterxml.jackson.annotation.JsonProperty;
 | 
			
		||||
 | 
			
		||||
import org.alfresco.rest.core.IRestModel;
 | 
			
		||||
import org.alfresco.utility.model.TestModel;
 | 
			
		||||
 | 
			
		||||
public class RestSizeDetailsModel extends TestModel implements IRestModel<RestSizeDetailsModel>
 | 
			
		||||
{
 | 
			
		||||
    @JsonProperty(value = "entry")
 | 
			
		||||
    RestSizeDetailsModel model;
 | 
			
		||||
 | 
			
		||||
    private String id;
 | 
			
		||||
    private Long sizeInBytes;
 | 
			
		||||
    private Date calculatedAt;
 | 
			
		||||
    private Integer numberOfFiles;
 | 
			
		||||
    private String jobId;
 | 
			
		||||
    private STATUS status;
 | 
			
		||||
 | 
			
		||||
    public enum STATUS
 | 
			
		||||
    {
 | 
			
		||||
        NOT_INITIATED, PENDING, IN_PROGRESS, COMPLETED, FAILED
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getId()
 | 
			
		||||
    {
 | 
			
		||||
        return id;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setId(String id)
 | 
			
		||||
    {
 | 
			
		||||
        this.id = id;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Long getSizeInBytes()
 | 
			
		||||
    {
 | 
			
		||||
        return sizeInBytes;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setSizeInBytes(Long sizeInBytes)
 | 
			
		||||
    {
 | 
			
		||||
        this.sizeInBytes = sizeInBytes;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Date getCalculatedAt()
 | 
			
		||||
    {
 | 
			
		||||
        return calculatedAt;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setCalculatedAt(Date calculatedAt)
 | 
			
		||||
    {
 | 
			
		||||
        this.calculatedAt = calculatedAt;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Integer getNumberOfFiles()
 | 
			
		||||
    {
 | 
			
		||||
        return numberOfFiles;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setNumberOfFiles(Integer numberOfFiles)
 | 
			
		||||
    {
 | 
			
		||||
        this.numberOfFiles = numberOfFiles;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getJobId()
 | 
			
		||||
    {
 | 
			
		||||
        return jobId;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setJobId(String jobId)
 | 
			
		||||
    {
 | 
			
		||||
        this.jobId = jobId;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public STATUS getStatus()
 | 
			
		||||
    {
 | 
			
		||||
        return status;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setStatus(STATUS status)
 | 
			
		||||
    {
 | 
			
		||||
        this.status = status;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public RestSizeDetailsModel onModel()
 | 
			
		||||
    {
 | 
			
		||||
        return model;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean equals(Object o)
 | 
			
		||||
    {
 | 
			
		||||
        if (this == o)
 | 
			
		||||
        {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        if (o == null || getClass() != o.getClass())
 | 
			
		||||
        {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        RestSizeDetailsModel that = (RestSizeDetailsModel) o;
 | 
			
		||||
        return Objects.equals(id, that.id) && Objects.equals(sizeInBytes, that.sizeInBytes) && Objects.equals(
 | 
			
		||||
                calculatedAt, that.calculatedAt) && Objects.equals(numberOfFiles, that.numberOfFiles)
 | 
			
		||||
                && Objects.equals(jobId, that.jobId) && status == that.status;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int hashCode()
 | 
			
		||||
    {
 | 
			
		||||
        return Objects.hash(id, sizeInBytes, calculatedAt, numberOfFiles, jobId, status);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
 * #%L
 | 
			
		||||
 * alfresco-tas-restapi
 | 
			
		||||
 * %%
 | 
			
		||||
 * Copyright (C) 2005 - 2023 Alfresco Software Limited
 | 
			
		||||
 * Copyright (C) 2005 - 2024 Alfresco Software Limited
 | 
			
		||||
 * %%
 | 
			
		||||
 * This file is part of the Alfresco software. 
 | 
			
		||||
 * If the software was purchased under a paid Alfresco license, the terms of 
 | 
			
		||||
@@ -26,59 +26,34 @@
 | 
			
		||||
 | 
			
		||||
package org.alfresco.rest.requests;
 | 
			
		||||
 | 
			
		||||
import static org.alfresco.rest.core.JsonBodyGenerator.arrayToJson;
 | 
			
		||||
import static org.alfresco.rest.requests.RuleSettings.IS_INHERITANCE_ENABLED;
 | 
			
		||||
import static org.springframework.http.HttpMethod.PUT;
 | 
			
		||||
 | 
			
		||||
import jakarta.json.JsonArrayBuilder;
 | 
			
		||||
import static org.alfresco.rest.core.JsonBodyGenerator.arrayToJson;
 | 
			
		||||
import static org.alfresco.rest.requests.RuleSettings.IS_INHERITANCE_ENABLED;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.FileInputStream;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.stream.Stream;
 | 
			
		||||
import jakarta.json.JsonArrayBuilder;
 | 
			
		||||
 | 
			
		||||
import io.restassured.http.ContentType;
 | 
			
		||||
import org.apache.commons.lang3.StringUtils;
 | 
			
		||||
import org.springframework.http.HttpMethod;
 | 
			
		||||
import org.springframework.http.HttpStatus;
 | 
			
		||||
import org.testng.reporters.Files;
 | 
			
		||||
 | 
			
		||||
import org.alfresco.rest.core.JsonBodyGenerator;
 | 
			
		||||
import org.alfresco.rest.core.RestRequest;
 | 
			
		||||
import org.alfresco.rest.core.RestResponse;
 | 
			
		||||
import org.alfresco.rest.core.RestWrapper;
 | 
			
		||||
import org.alfresco.rest.exception.JsonToModelConversionException;
 | 
			
		||||
import org.alfresco.rest.model.RestActionDefinitionModelsCollection;
 | 
			
		||||
import org.alfresco.rest.model.RestCategoryLinkBodyModel;
 | 
			
		||||
import org.alfresco.rest.model.RestCategoryModel;
 | 
			
		||||
import org.alfresco.rest.model.RestCategoryModelsCollection;
 | 
			
		||||
import org.alfresco.rest.model.RestCommentModel;
 | 
			
		||||
import org.alfresco.rest.model.RestCommentModelsCollection;
 | 
			
		||||
import org.alfresco.rest.model.RestNodeAssocTargetModel;
 | 
			
		||||
import org.alfresco.rest.model.RestNodeAssociationModel;
 | 
			
		||||
import org.alfresco.rest.model.RestNodeAssociationModelCollection;
 | 
			
		||||
import org.alfresco.rest.model.RestNodeAssociationTypeModel;
 | 
			
		||||
import org.alfresco.rest.model.RestNodeBodyModel;
 | 
			
		||||
import org.alfresco.rest.model.RestNodeBodyMoveCopyModel;
 | 
			
		||||
import org.alfresco.rest.model.RestNodeChildAssocModelCollection;
 | 
			
		||||
import org.alfresco.rest.model.RestNodeChildAssociationModel;
 | 
			
		||||
import org.alfresco.rest.model.RestNodeModel;
 | 
			
		||||
import org.alfresco.rest.model.RestNodeModelsCollection;
 | 
			
		||||
import org.alfresco.rest.model.RestRatingModel;
 | 
			
		||||
import org.alfresco.rest.model.RestRatingModelsCollection;
 | 
			
		||||
import org.alfresco.rest.model.RestRenditionInfoModel;
 | 
			
		||||
import org.alfresco.rest.model.RestRenditionInfoModelCollection;
 | 
			
		||||
import org.alfresco.rest.model.RestRuleExecutionModel;
 | 
			
		||||
import org.alfresco.rest.model.RestRuleSetLinkModel;
 | 
			
		||||
import org.alfresco.rest.model.RestRuleSetModel;
 | 
			
		||||
import org.alfresco.rest.model.RestRuleSetModelsCollection;
 | 
			
		||||
import org.alfresco.rest.model.RestTagModel;
 | 
			
		||||
import org.alfresco.rest.model.RestTagModelsCollection;
 | 
			
		||||
import org.alfresco.rest.model.RestVersionModel;
 | 
			
		||||
import org.alfresco.rest.model.RestVersionModelsCollection;
 | 
			
		||||
import org.alfresco.rest.model.*;
 | 
			
		||||
import org.alfresco.rest.model.body.RestNodeLockBodyModel;
 | 
			
		||||
import org.alfresco.rest.model.builder.NodesBuilder;
 | 
			
		||||
import org.alfresco.utility.Utility;
 | 
			
		||||
import org.alfresco.utility.model.RepoTestModel;
 | 
			
		||||
import org.apache.commons.lang3.StringUtils;
 | 
			
		||||
import org.springframework.http.HttpMethod;
 | 
			
		||||
import org.springframework.http.HttpStatus;
 | 
			
		||||
import org.testng.reporters.Files;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Declares all Rest API under the /nodes path
 | 
			
		||||
@@ -294,6 +269,7 @@ public class Node extends ModelRequest<Node>
 | 
			
		||||
    /**
 | 
			
		||||
     * 
 | 
			
		||||
     * Get fivestar rating of a document using GET call on "nodes/{nodeId}/ratings/{ratingId}"
 | 
			
		||||
     * 
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    public RestRatingModel getFiveStarRating()
 | 
			
		||||
@@ -336,7 +312,6 @@ public class Node extends ModelRequest<Node>
 | 
			
		||||
        return restWrapper.processModels(RestTagModelsCollection.class, request);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Deletes a tag for a specific content node using DELETE call on nodes/{nodeId}/tags/{tagId}
 | 
			
		||||
     *
 | 
			
		||||
@@ -381,6 +356,7 @@ public class Node extends ModelRequest<Node>
 | 
			
		||||
     * You need to specify first the multipart call {@link RestWrapper#usingMultipartFile(java.io.File)}
 | 
			
		||||
     *
 | 
			
		||||
     * <code>usingMultipartFile(new File("your-local-file.txt")).withCoreAPI().usingNode(ContentModel.my()).createNode();</code>
 | 
			
		||||
     * 
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    public RestNodeModel createNode()
 | 
			
		||||
@@ -415,7 +391,8 @@ public class Node extends ModelRequest<Node>
 | 
			
		||||
    /**
 | 
			
		||||
     * Create node rendition using POST call on '/nodes/{nodeId}/renditions'
 | 
			
		||||
     *
 | 
			
		||||
     * @param renditionId id of rendition to be created
 | 
			
		||||
     * @param renditionId
 | 
			
		||||
     *            id of rendition to be created
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    public void createNodeRendition(String renditionId)
 | 
			
		||||
@@ -428,8 +405,10 @@ public class Node extends ModelRequest<Node>
 | 
			
		||||
    /**
 | 
			
		||||
     * Create node version rendition using POST call on '/nodes/{nodeId}/versions/{versionId}/renditions'
 | 
			
		||||
     *
 | 
			
		||||
     * @param renditionId id of rendition to be created
 | 
			
		||||
     * @param versionId version id of node
 | 
			
		||||
     * @param renditionId
 | 
			
		||||
     *            id of rendition to be created
 | 
			
		||||
     * @param versionId
 | 
			
		||||
     *            version id of node
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    public void createNodeVersionRendition(String renditionId, String versionId)
 | 
			
		||||
@@ -442,10 +421,10 @@ public class Node extends ModelRequest<Node>
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check if specified rendition exists and if not
 | 
			
		||||
     * create node rendition using POST call on '/nodes/{nodeId}/renditions'
 | 
			
		||||
     * Check if specified rendition exists and if not create node rendition using POST call on '/nodes/{nodeId}/renditions'
 | 
			
		||||
     *
 | 
			
		||||
     * @param renditionId id of rendition to be created
 | 
			
		||||
     * @param renditionId
 | 
			
		||||
     *            id of rendition to be created
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    public void createNodeRenditionIfNotExists(String renditionId)
 | 
			
		||||
@@ -460,9 +439,10 @@ public class Node extends ModelRequest<Node>
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get  node rendition using GET call on '/nodes/{nodeId}/renditions/{renditionId}
 | 
			
		||||
     * Get node rendition using GET call on '/nodes/{nodeId}/renditions/{renditionId}
 | 
			
		||||
     *
 | 
			
		||||
     * @param renditionId id of rendition to be retrieved
 | 
			
		||||
     * @param renditionId
 | 
			
		||||
     *            id of rendition to be retrieved
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    public RestRenditionInfoModel getNodeRendition(String renditionId)
 | 
			
		||||
@@ -474,8 +454,10 @@ public class Node extends ModelRequest<Node>
 | 
			
		||||
    /**
 | 
			
		||||
     * Get node version rendition using GET call on '/nodes/{nodeId}/versions/{versionId}renditions/{renditionId}
 | 
			
		||||
     *
 | 
			
		||||
     * @param renditionId id of rendition to be retrieved
 | 
			
		||||
     * @param versionId versionId of the node
 | 
			
		||||
     * @param renditionId
 | 
			
		||||
     *            id of rendition to be retrieved
 | 
			
		||||
     * @param versionId
 | 
			
		||||
     *            versionId of the node
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    public RestRenditionInfoModel getNodeVersionRendition(String renditionId, String versionId)
 | 
			
		||||
@@ -487,8 +469,7 @@ public class Node extends ModelRequest<Node>
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get node rendition using GET call on 'nodes/{nodeId}/renditions/{renditionId} Please note that it retries to get
 | 
			
		||||
     * the renditions response several times because on the alfresco server the rendition can take a while to be created.
 | 
			
		||||
     * Get node rendition using GET call on 'nodes/{nodeId}/renditions/{renditionId} Please note that it retries to get the renditions response several times because on the alfresco server the rendition can take a while to be created.
 | 
			
		||||
     *
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
@@ -510,8 +491,7 @@ public class Node extends ModelRequest<Node>
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get node version rendition using GET call on 'nodes/{nodeId}/versions/{versionId}/renditions/{renditionId} Please note that it retries to get
 | 
			
		||||
     * the renditions response several times because on the alfresco server the rendition can take a while to be created.
 | 
			
		||||
     * Get node version rendition using GET call on 'nodes/{nodeId}/versions/{versionId}/renditions/{renditionId} Please note that it retries to get the renditions response several times because on the alfresco server the rendition can take a while to be created.
 | 
			
		||||
     *
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
@@ -533,10 +513,7 @@ public class Node extends ModelRequest<Node>
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get node rendition content using GET call on
 | 
			
		||||
     * 'nodes/{nodeId}/renditions/{renditionId}/content Please note that it
 | 
			
		||||
     * retries to get the renditions response several times because on the
 | 
			
		||||
     * alfresco server the rendition can take a while to be created.
 | 
			
		||||
     * Get node rendition content using GET call on 'nodes/{nodeId}/renditions/{renditionId}/content Please note that it retries to get the renditions response several times because on the alfresco server the rendition can take a while to be created.
 | 
			
		||||
     *
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
@@ -546,7 +523,7 @@ public class Node extends ModelRequest<Node>
 | 
			
		||||
                renditionId);
 | 
			
		||||
        RestResponse response = restWrapper.process(request);
 | 
			
		||||
        int retry = 0;
 | 
			
		||||
        //Multiplied by '8' because AI rendition test cases need more time (~30 seconds) - see ACS-2158
 | 
			
		||||
        // Multiplied by '8' because AI rendition test cases need more time (~30 seconds) - see ACS-2158
 | 
			
		||||
        while (!Integer.valueOf(response.getStatusCode()).equals(HttpStatus.OK.value()) && retry < (8 * Utility.retryCountSeconds))
 | 
			
		||||
        {
 | 
			
		||||
            Utility.waitToLoopTime(1);
 | 
			
		||||
@@ -558,10 +535,7 @@ public class Node extends ModelRequest<Node>
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get node version rendition content using GET call on
 | 
			
		||||
     * 'nodes/{nodeId}/versions/{versionId}/renditions/{renditionId}/content Please note that it
 | 
			
		||||
     * retries to get the renditions response several times because on the
 | 
			
		||||
     * alfresco server the rendition can take a while to be created.
 | 
			
		||||
     * Get node version rendition content using GET call on 'nodes/{nodeId}/versions/{versionId}/renditions/{renditionId}/content Please note that it retries to get the renditions response several times because on the alfresco server the rendition can take a while to be created.
 | 
			
		||||
     *
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
@@ -582,8 +556,7 @@ public class Node extends ModelRequest<Node>
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get node rendition content using GET call on
 | 
			
		||||
     * 'nodes/{nodeId}/renditions/{renditionId}/content
 | 
			
		||||
     * Get node rendition content using GET call on 'nodes/{nodeId}/renditions/{renditionId}/content
 | 
			
		||||
     *
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
@@ -595,8 +568,7 @@ public class Node extends ModelRequest<Node>
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get node version rendition content using GET call on
 | 
			
		||||
     * 'nodes/{nodeId}/versions/{versionId}/renditions/{renditionId}/content
 | 
			
		||||
     * Get node version rendition content using GET call on 'nodes/{nodeId}/versions/{versionId}/renditions/{renditionId}/content
 | 
			
		||||
     *
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
@@ -608,8 +580,8 @@ public class Node extends ModelRequest<Node>
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get rendition information for available renditions for the node using GET call on
 | 
			
		||||
     * 'nodes/{nodeId}/renditions'
 | 
			
		||||
     * Get rendition information for available renditions for the node using GET call on 'nodes/{nodeId}/renditions'
 | 
			
		||||
     * 
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    public RestRenditionInfoModelCollection getNodeRenditionsInfo()
 | 
			
		||||
@@ -620,8 +592,8 @@ public class Node extends ModelRequest<Node>
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get rendition information for available renditions for the node version using GET call on
 | 
			
		||||
     * 'nodes/{nodeId}/versions/{versionId}/renditions'
 | 
			
		||||
     * Get rendition information for available renditions for the node version using GET call on 'nodes/{nodeId}/versions/{versionId}/renditions'
 | 
			
		||||
     * 
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    public RestRenditionInfoModelCollection getNodeVersionRenditionsInfo(String versionId)
 | 
			
		||||
@@ -631,11 +603,11 @@ public class Node extends ModelRequest<Node>
 | 
			
		||||
        return restWrapper.processModels(RestRenditionInfoModelCollection.class, request);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Delete the rendition identified by renditionId using DELETE call on "/nodes/{nodeId}/renditions/{renditionId}"
 | 
			
		||||
     *
 | 
			
		||||
     * @param renditionId id of rendition to delete
 | 
			
		||||
     * @param renditionId
 | 
			
		||||
     *            id of rendition to delete
 | 
			
		||||
     */
 | 
			
		||||
    public void deleteNodeRendition(String renditionId)
 | 
			
		||||
    {
 | 
			
		||||
@@ -657,7 +629,8 @@ public class Node extends ModelRequest<Node>
 | 
			
		||||
    /**
 | 
			
		||||
     * Move a node to a target folder
 | 
			
		||||
     *
 | 
			
		||||
     * @param moveBody a {@link RestNodeBodyMoveCopyModel} containing at least the target parent id
 | 
			
		||||
     * @param moveBody
 | 
			
		||||
     *            a {@link RestNodeBodyMoveCopyModel} containing at least the target parent id
 | 
			
		||||
     * @return the moved node's new information
 | 
			
		||||
     */
 | 
			
		||||
    public RestNodeModel move(RestNodeBodyMoveCopyModel moveBody)
 | 
			
		||||
@@ -669,7 +642,8 @@ public class Node extends ModelRequest<Node>
 | 
			
		||||
    /**
 | 
			
		||||
     * Copy a node to a target folder
 | 
			
		||||
     *
 | 
			
		||||
     * @param copyBody a {@link RestNodeBodyMoveCopyModel} containing at least the target parent id
 | 
			
		||||
     * @param copyBody
 | 
			
		||||
     *            a {@link RestNodeBodyMoveCopyModel} containing at least the target parent id
 | 
			
		||||
     * @return the moved node's new information
 | 
			
		||||
     */
 | 
			
		||||
    public RestNodeModel copy(RestNodeBodyMoveCopyModel copyBody)
 | 
			
		||||
@@ -679,7 +653,6 @@ public class Node extends ModelRequest<Node>
 | 
			
		||||
        return restWrapper.processModel(RestNodeModel.class, request);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Lock a specific node using POST call on "nodes/{nodeId}/lock"
 | 
			
		||||
     *
 | 
			
		||||
@@ -747,8 +720,7 @@ public class Node extends ModelRequest<Node>
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Delete a target for a specific node using DELETE call on
 | 
			
		||||
     * nodes/{nodeId}/targets/{targetId}
 | 
			
		||||
     * Delete a target for a specific node using DELETE call on nodes/{nodeId}/targets/{targetId}
 | 
			
		||||
     *
 | 
			
		||||
     * @param target
 | 
			
		||||
     */
 | 
			
		||||
@@ -830,7 +802,8 @@ public class Node extends ModelRequest<Node>
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a secondary child association using POST call to: 'nodes/{nodeId}/secondary-children'.
 | 
			
		||||
     *
 | 
			
		||||
     * @param secondaryChild - node, which should become a secondary child
 | 
			
		||||
     * @param secondaryChild
 | 
			
		||||
     *            - node, which should become a secondary child
 | 
			
		||||
     * @return a node's parent-child association
 | 
			
		||||
     */
 | 
			
		||||
    public RestNodeChildAssociationModel addSecondaryChild(RepoTestModel secondaryChild)
 | 
			
		||||
@@ -841,8 +814,10 @@ public class Node extends ModelRequest<Node>
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a secondary child association using POST call to: 'nodes/{nodeId}/secondary-children'.
 | 
			
		||||
     *
 | 
			
		||||
     * @param associationType - type of secondary parent-child relationship association
 | 
			
		||||
     * @param secondaryChild - node, which should become a secondary child
 | 
			
		||||
     * @param associationType
 | 
			
		||||
     *            - type of secondary parent-child relationship association
 | 
			
		||||
     * @param secondaryChild
 | 
			
		||||
     *            - node, which should become a secondary child
 | 
			
		||||
     * @return a node's parent-child association
 | 
			
		||||
     */
 | 
			
		||||
    public RestNodeChildAssociationModel addSecondaryChild(String associationType, RepoTestModel secondaryChild)
 | 
			
		||||
@@ -853,7 +828,8 @@ public class Node extends ModelRequest<Node>
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a secondary child association using POST call to: 'nodes/{nodeId}/secondary-children'.
 | 
			
		||||
     *
 | 
			
		||||
     * @param secondaryChildAssociation - node's secondary parent-child association model
 | 
			
		||||
     * @param secondaryChildAssociation
 | 
			
		||||
     *            - node's secondary parent-child association model
 | 
			
		||||
     * @return a node's parent-child association
 | 
			
		||||
     */
 | 
			
		||||
    public RestNodeChildAssociationModel addSecondaryChild(RestNodeChildAssociationModel secondaryChildAssociation)
 | 
			
		||||
@@ -865,7 +841,8 @@ public class Node extends ModelRequest<Node>
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a secondary children association using POST call to: 'nodes/{nodeId}/secondary-children'.
 | 
			
		||||
     *
 | 
			
		||||
     * @param secondaryChildren - nodes, which should become secondary children
 | 
			
		||||
     * @param secondaryChildren
 | 
			
		||||
     *            - nodes, which should become secondary children
 | 
			
		||||
     * @return a collection of node's parent-child associations
 | 
			
		||||
     */
 | 
			
		||||
    public RestNodeChildAssocModelCollection addSecondaryChildren(RepoTestModel... secondaryChildren)
 | 
			
		||||
@@ -876,21 +853,24 @@ public class Node extends ModelRequest<Node>
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a secondary children association using POST call to: 'nodes/{nodeId}/secondary-children'.
 | 
			
		||||
     *
 | 
			
		||||
     * @param associationType - type of secondary parent-child relationship association
 | 
			
		||||
     * @param secondaryChildren - nodes, which should become secondary children
 | 
			
		||||
     * @param associationType
 | 
			
		||||
     *            - type of secondary parent-child relationship association
 | 
			
		||||
     * @param secondaryChildren
 | 
			
		||||
     *            - nodes, which should become secondary children
 | 
			
		||||
     * @return a collection of node's parent-child associations
 | 
			
		||||
     */
 | 
			
		||||
    public RestNodeChildAssocModelCollection addSecondaryChildren(String associationType, RepoTestModel... secondaryChildren)
 | 
			
		||||
    {
 | 
			
		||||
        return addSecondaryChildren(Stream.of(secondaryChildren)
 | 
			
		||||
            .map(child -> new RestNodeChildAssociationModel(child.getNodeRef(), associationType))
 | 
			
		||||
            .toArray(RestNodeChildAssociationModel[]::new));
 | 
			
		||||
                .map(child -> new RestNodeChildAssociationModel(child.getNodeRef(), associationType))
 | 
			
		||||
                .toArray(RestNodeChildAssociationModel[]::new));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a secondary children association using POST call to: 'nodes/{nodeId}/secondary-children'.
 | 
			
		||||
     *
 | 
			
		||||
     * @param secondaryChildrenAssociations - node's secondary parent-child association models
 | 
			
		||||
     * @param secondaryChildrenAssociations
 | 
			
		||||
     *            - node's secondary parent-child association models
 | 
			
		||||
     * @return a collection of node's parent-child associations
 | 
			
		||||
     */
 | 
			
		||||
    public RestNodeChildAssocModelCollection addSecondaryChildren(RestNodeChildAssociationModel... secondaryChildrenAssociations)
 | 
			
		||||
@@ -903,7 +883,8 @@ public class Node extends ModelRequest<Node>
 | 
			
		||||
    /**
 | 
			
		||||
     * Removes secondary child association using DELETE call 'nodes/{nodeId}/secondary-children/{childId}'.
 | 
			
		||||
     *
 | 
			
		||||
     * @param secondaryChild - node, which should NOT be a secondary child anymore
 | 
			
		||||
     * @param secondaryChild
 | 
			
		||||
     *            - node, which should NOT be a secondary child anymore
 | 
			
		||||
     */
 | 
			
		||||
    public void removeSecondaryChild(RepoTestModel secondaryChild)
 | 
			
		||||
    {
 | 
			
		||||
@@ -913,8 +894,10 @@ public class Node extends ModelRequest<Node>
 | 
			
		||||
    /**
 | 
			
		||||
     * Removes secondary child association using DELETE call 'nodes/{nodeId}/secondary-children/{childId}'.
 | 
			
		||||
     *
 | 
			
		||||
     * @param associationType - type of secondary parent-child relationship association
 | 
			
		||||
     * @param secondaryChild - node, which should NOT be a secondary child anymore
 | 
			
		||||
     * @param associationType
 | 
			
		||||
     *            - type of secondary parent-child relationship association
 | 
			
		||||
     * @param secondaryChild
 | 
			
		||||
     *            - node, which should NOT be a secondary child anymore
 | 
			
		||||
     */
 | 
			
		||||
    public void removeSecondaryChild(String associationType, RepoTestModel secondaryChild)
 | 
			
		||||
    {
 | 
			
		||||
@@ -932,13 +915,12 @@ public class Node extends ModelRequest<Node>
 | 
			
		||||
    /**
 | 
			
		||||
     * Removes secondary child association using DELETE call 'nodes/{nodeId}/secondary-children/{childId}'.
 | 
			
		||||
     *
 | 
			
		||||
     * @param secondaryChildAssociation - node's secondary parent-child association to remove
 | 
			
		||||
     * @param secondaryChildAssociation
 | 
			
		||||
     *            - node's secondary parent-child association to remove
 | 
			
		||||
     */
 | 
			
		||||
    public void removeSecondaryChild(RestNodeAssociationModel secondaryChildAssociation)
 | 
			
		||||
    {
 | 
			
		||||
        String parameters = StringUtils.isNotEmpty(secondaryChildAssociation.getAssociation().getAssocType()) ?
 | 
			
		||||
            "assocType=" + secondaryChildAssociation.getAssociation().getAssocType() + "&" + restWrapper.getParameters() :
 | 
			
		||||
            restWrapper.getParameters();
 | 
			
		||||
        String parameters = StringUtils.isNotEmpty(secondaryChildAssociation.getAssociation().getAssocType()) ? "assocType=" + secondaryChildAssociation.getAssociation().getAssocType() + "&" + restWrapper.getParameters() : restWrapper.getParameters();
 | 
			
		||||
        RestRequest request = RestRequest.simpleRequest(HttpMethod.DELETE, "nodes/{nodeId}/secondary-children/{childId}?{parameters}", repoModel.getNodeRef(), secondaryChildAssociation.getId(), parameters);
 | 
			
		||||
        restWrapper.processEmptyModel(request);
 | 
			
		||||
    }
 | 
			
		||||
@@ -1013,7 +995,6 @@ public class Node extends ModelRequest<Node>
 | 
			
		||||
        deleteNode(nodeModel.getId());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Delete a specific node using DELETE call on nodes/{nodeId}
 | 
			
		||||
     *
 | 
			
		||||
@@ -1035,6 +1016,7 @@ public class Node extends ModelRequest<Node>
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get Direct Access URL for a node
 | 
			
		||||
     * 
 | 
			
		||||
     * @param postBody
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
@@ -1055,6 +1037,7 @@ public class Node extends ModelRequest<Node>
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get Direct Access URL for a specific node rendition E.g "pdf"
 | 
			
		||||
     * 
 | 
			
		||||
     * @param renditionId
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
@@ -1067,6 +1050,7 @@ public class Node extends ModelRequest<Node>
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get Direct Access URL for a specific node version. E.g "1.1"
 | 
			
		||||
     * 
 | 
			
		||||
     * @param versionId
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
@@ -1079,6 +1063,7 @@ public class Node extends ModelRequest<Node>
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get Direct Access URL for a specific node version rendition. E.g ("1.1", "pdf")
 | 
			
		||||
     * 
 | 
			
		||||
     * @param versionId
 | 
			
		||||
     * @param renditionId
 | 
			
		||||
     * @return
 | 
			
		||||
@@ -1132,7 +1117,8 @@ public class Node extends ModelRequest<Node>
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the specified rule set from a folder.
 | 
			
		||||
     *
 | 
			
		||||
     * @param ruleSetId The id of the rule set.
 | 
			
		||||
     * @param ruleSetId
 | 
			
		||||
     *            The id of the rule set.
 | 
			
		||||
     * @return The specified rule set.
 | 
			
		||||
     */
 | 
			
		||||
    public RestRuleSetModel getRuleSet(String ruleSetId)
 | 
			
		||||
@@ -1145,7 +1131,8 @@ public class Node extends ModelRequest<Node>
 | 
			
		||||
    /**
 | 
			
		||||
     * Update a rule set on this folder - for example to reorder the rules.
 | 
			
		||||
     *
 | 
			
		||||
     * @param ruleSet The updated rule set.
 | 
			
		||||
     * @param ruleSet
 | 
			
		||||
     *            The updated rule set.
 | 
			
		||||
     * @return The updated rule set returned by the server.
 | 
			
		||||
     */
 | 
			
		||||
    public RestRuleSetModel updateRuleSet(RestRuleSetModel ruleSet)
 | 
			
		||||
@@ -1188,7 +1175,8 @@ public class Node extends ModelRequest<Node>
 | 
			
		||||
    /**
 | 
			
		||||
     * Try to delete a ruleset link performing a DELETE call on "/nodes/{folderNodeId}/rule-set-links/{rulesetId}"
 | 
			
		||||
     *
 | 
			
		||||
     * @param ruleSetId the id of the ruleset to be unlinked from the folder
 | 
			
		||||
     * @param ruleSetId
 | 
			
		||||
     *            the id of the ruleset to be unlinked from the folder
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    public void unlinkRuleSet(String ruleSetId)
 | 
			
		||||
@@ -1200,7 +1188,8 @@ public class Node extends ModelRequest<Node>
 | 
			
		||||
    /**
 | 
			
		||||
     * Trigger rules on a folder performing POST call on "/nodes/{folderNodeId}/rule-executions"
 | 
			
		||||
     *
 | 
			
		||||
     * @param body - rules execution request
 | 
			
		||||
     * @param body
 | 
			
		||||
     *            - rules execution request
 | 
			
		||||
     * @return execution result
 | 
			
		||||
     */
 | 
			
		||||
    public RestRuleExecutionModel executeRules(RestRuleExecutionModel body)
 | 
			
		||||
@@ -1223,7 +1212,8 @@ public class Node extends ModelRequest<Node>
 | 
			
		||||
    /**
 | 
			
		||||
     * Link content to category performing POST call on "/nodes/{nodeId}/category-links"
 | 
			
		||||
     *
 | 
			
		||||
     * @param categoryLink - contains category ID
 | 
			
		||||
     * @param categoryLink
 | 
			
		||||
     *            - contains category ID
 | 
			
		||||
     * @return linked to category
 | 
			
		||||
     */
 | 
			
		||||
    public RestCategoryModel linkToCategory(RestCategoryLinkBodyModel categoryLink)
 | 
			
		||||
@@ -1235,7 +1225,8 @@ public class Node extends ModelRequest<Node>
 | 
			
		||||
    /**
 | 
			
		||||
     * Link content to many categories performing POST call on "/nodes/{nodeId}/category-links"
 | 
			
		||||
     *
 | 
			
		||||
     * @param categoryLinks - contains categories IDs
 | 
			
		||||
     * @param categoryLinks
 | 
			
		||||
     *            - contains categories IDs
 | 
			
		||||
     * @return linked to categories
 | 
			
		||||
     */
 | 
			
		||||
    public RestCategoryModelsCollection linkToCategories(List<RestCategoryLinkBodyModel> categoryLinks)
 | 
			
		||||
@@ -1247,11 +1238,34 @@ public class Node extends ModelRequest<Node>
 | 
			
		||||
    /**
 | 
			
		||||
     * Unlink content from a category performing a DELETE call on "nodes/{nodeId}/category-links/{categoryId}"
 | 
			
		||||
     *
 | 
			
		||||
     * @param categoryId the id of the category to be unlinked from content
 | 
			
		||||
     * @param categoryId
 | 
			
		||||
     *            the id of the category to be unlinked from content
 | 
			
		||||
     */
 | 
			
		||||
    public void unlinkFromCategory(String categoryId)
 | 
			
		||||
    {
 | 
			
		||||
        RestRequest request = RestRequest.simpleRequest(HttpMethod.DELETE, "nodes/{nodeId}/category-links/{categoryId}", repoModel.getNodeRef(), categoryId);
 | 
			
		||||
        restWrapper.processEmptyModel(request);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * In order to retrieve folder size details using POST call on "nodes/{nodeId}/size-details"
 | 
			
		||||
     *
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    public RestSizeDetailsModel executeSizeDetails()
 | 
			
		||||
    {
 | 
			
		||||
        RestRequest request = RestRequest.simpleRequest(HttpMethod.POST, "nodes/{nodeId}/size-details", repoModel.getNodeRef());
 | 
			
		||||
        return restWrapper.processModel(RestSizeDetailsModel.class, request);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Getting Folder size details using GET call on "nodes/{nodeId}/size-details/{jobId}"
 | 
			
		||||
     *
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    public RestSizeDetailsModel getSizeDetails(String jobId)
 | 
			
		||||
    {
 | 
			
		||||
        RestRequest request = RestRequest.simpleRequest(HttpMethod.GET, "nodes/{nodeId}/size-details/{jobId}", repoModel.getNodeRef(), jobId);
 | 
			
		||||
        return restWrapper.processModel(RestSizeDetailsModel.class, request);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,176 @@
 | 
			
		||||
package org.alfresco.rest.nodes;
 | 
			
		||||
 | 
			
		||||
import static org.alfresco.utility.report.log.Step.STEP;
 | 
			
		||||
 | 
			
		||||
import java.util.stream.IntStream;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.lang3.RandomStringUtils;
 | 
			
		||||
import org.springframework.http.HttpStatus;
 | 
			
		||||
import org.testng.Assert;
 | 
			
		||||
import org.testng.annotations.BeforeClass;
 | 
			
		||||
import org.testng.annotations.Test;
 | 
			
		||||
 | 
			
		||||
import org.alfresco.dataprep.CMISUtil.DocumentType;
 | 
			
		||||
import org.alfresco.rest.RestTest;
 | 
			
		||||
import org.alfresco.rest.model.RestNodeModel;
 | 
			
		||||
import org.alfresco.rest.model.RestSizeDetailsModel;
 | 
			
		||||
import org.alfresco.utility.Utility;
 | 
			
		||||
import org.alfresco.utility.model.FileModel;
 | 
			
		||||
import org.alfresco.utility.model.FileType;
 | 
			
		||||
import org.alfresco.utility.model.FolderModel;
 | 
			
		||||
import org.alfresco.utility.model.SiteModel;
 | 
			
		||||
import org.alfresco.utility.model.TestGroup;
 | 
			
		||||
import org.alfresco.utility.model.UserModel;
 | 
			
		||||
import org.alfresco.utility.testrail.ExecutionType;
 | 
			
		||||
import org.alfresco.utility.testrail.annotation.TestRail;
 | 
			
		||||
 | 
			
		||||
public class NodeSizeDetailsTests extends RestTest
 | 
			
		||||
{
 | 
			
		||||
    private UserModel user1;
 | 
			
		||||
    private SiteModel siteModel;
 | 
			
		||||
    private FolderModel folder;
 | 
			
		||||
 | 
			
		||||
    @BeforeClass(alwaysRun = true)
 | 
			
		||||
    public void dataPreparation()
 | 
			
		||||
    {
 | 
			
		||||
        user1 = dataUser.createRandomTestUser("User-1");
 | 
			
		||||
        siteModel = dataSite.usingUser(user1).createPublicRandomSite();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sanity check for the following api endpoint POST /nodes/{nodeId}/size-details GET /nodes/{nodeId}/size-details/{jobId}
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    @TestRail(section = {TestGroup.REST_API, TestGroup.NODES}, executionType = ExecutionType.SANITY)
 | 
			
		||||
    @Test(groups = {TestGroup.REST_API, TestGroup.NODES, TestGroup.SANITY})
 | 
			
		||||
    public void createSizeDetails() throws Exception
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
        STEP("Create a folder in the test site.");
 | 
			
		||||
        folder = dataContent.usingUser(user1).usingSite(siteModel).createFolder(FolderModel.getRandomFolderModel());
 | 
			
		||||
 | 
			
		||||
        STEP("Upload a text document to the folder.");
 | 
			
		||||
        restClient.authenticateUser(user1).configureRequestSpec().addMultiPart("filedata", Utility.getResourceTestDataFile("sampleLargeContent.txt"));
 | 
			
		||||
        RestNodeModel fileNode = restClient.withCoreAPI().usingNode(folder).createNode();
 | 
			
		||||
        restClient.assertStatusCodeIs(HttpStatus.CREATED);
 | 
			
		||||
        fileNode.assertThat().field("id").isNotNull()
 | 
			
		||||
                .and().field("name").is("sampleLargeContent.txt")
 | 
			
		||||
                .and().field("content.mimeType").is(FileType.TEXT_PLAIN.mimeType);
 | 
			
		||||
 | 
			
		||||
        RestSizeDetailsModel restSizeDetailsModel = restClient.authenticateUser(user1).withCoreAPI().usingNode(folder).executeSizeDetails();
 | 
			
		||||
        restClient.assertStatusCodeIs(HttpStatus.ACCEPTED);
 | 
			
		||||
        restSizeDetailsModel.assertThat().field("jobId").isNotEmpty();
 | 
			
		||||
 | 
			
		||||
        String jobId = restSizeDetailsModel.getJobId();
 | 
			
		||||
        restSizeDetailsModel = restClient.authenticateUser(user1).withCoreAPI().usingNode(folder).getSizeDetails(jobId);
 | 
			
		||||
        restClient.assertStatusCodeIs(HttpStatus.OK);
 | 
			
		||||
        restSizeDetailsModel.assertThat().field("sizeInBytes").isNotEmpty();
 | 
			
		||||
        Assert.assertTrue((restSizeDetailsModel.getSizeInBytes() > 8200), "Value of sizeInBytes " + restSizeDetailsModel.getSizeInBytes() + " is less than expected 8200");
 | 
			
		||||
        Assert.assertTrue((restSizeDetailsModel.getSizeInBytes() < 8500), "Value of sizeInBytes " + restSizeDetailsModel.getSizeInBytes() + " is greater than expected 8500");
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     *
 | 
			
		||||
     * Unauthenticated user not able to execute POST /nodes/{nodeId}/size-details: 401 STATUS CODE
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    @TestRail(section = {TestGroup.REST_API, TestGroup.NODES}, executionType = ExecutionType.SANITY)
 | 
			
		||||
    @Test(groups = {TestGroup.REST_API, TestGroup.NODES, TestGroup.SANITY})
 | 
			
		||||
    public void unauthenticatedUserIsNotAbleGetSizeDetails()
 | 
			
		||||
    {
 | 
			
		||||
        restClient.authenticateUser(new UserModel("random user", "random password"));
 | 
			
		||||
        restClient.withCoreAPI().usingNode(folder).executeSizeDetails();
 | 
			
		||||
        restClient.assertStatusCodeIs(HttpStatus.UNAUTHORIZED);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Node Id Not Exist: 404 STATUS CODE
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    @TestRail(section = {TestGroup.REST_API, TestGroup.NODES}, executionType = ExecutionType.SANITY)
 | 
			
		||||
    @Test(groups = {TestGroup.REST_API, TestGroup.NODES, TestGroup.SANITY})
 | 
			
		||||
    public void nodeIdNotExist()
 | 
			
		||||
    {
 | 
			
		||||
        folder.setNodeRef(RandomStringUtils.randomAlphanumeric(20));
 | 
			
		||||
        restClient.authenticateUser(user1).withCoreAPI().usingNode(folder).executeSizeDetails();
 | 
			
		||||
        restClient.assertStatusCodeIs(HttpStatus.NOT_FOUND);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     *
 | 
			
		||||
     * Value of nodeId is invalid: 422 STATUS CODE
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    @TestRail(section = {TestGroup.REST_API, TestGroup.NODES}, executionType = ExecutionType.SANITY)
 | 
			
		||||
    @Test(groups = {TestGroup.REST_API, TestGroup.NODES, TestGroup.SANITY})
 | 
			
		||||
    public void nodeIdNotValid()
 | 
			
		||||
    {
 | 
			
		||||
        FileModel document = dataContent.usingSite(siteModel).usingUser(user1).createContent(DocumentType.TEXT_PLAIN);
 | 
			
		||||
        restClient.authenticateUser(user1).withCoreAPI().usingNode(document).executeSizeDetails();
 | 
			
		||||
        restClient.assertStatusCodeIs(HttpStatus.UNPROCESSABLE_ENTITY);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     *
 | 
			
		||||
     * Performance testCase
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    @TestRail(section = {TestGroup.REST_API, TestGroup.NODES}, executionType = ExecutionType.SANITY)
 | 
			
		||||
    @Test(groups = {TestGroup.REST_API, TestGroup.NODES, TestGroup.SANITY})
 | 
			
		||||
    public void performanceTestCase() throws InterruptedException
 | 
			
		||||
    {
 | 
			
		||||
        STEP("1. Create a parent folder in the test site.");
 | 
			
		||||
        FolderModel folder = dataContent.usingUser(user1).usingSite(siteModel).createFolder(FolderModel.getRandomFolderModel());
 | 
			
		||||
 | 
			
		||||
        STEP("2. Creating a 51 nested folders in the folder-1");
 | 
			
		||||
 | 
			
		||||
        IntStream.rangeClosed(1, 51).forEach(i -> {
 | 
			
		||||
            String folder0Name = "childFolder" + i + RandomStringUtils.randomAlphanumeric(2);
 | 
			
		||||
            FolderModel folderModel = new FolderModel();
 | 
			
		||||
            folderModel.setName(folder0Name);
 | 
			
		||||
 | 
			
		||||
            FolderModel childFolder = dataContent.usingUser(user1)
 | 
			
		||||
                    .usingSite(siteModel)
 | 
			
		||||
                    .usingResource(folder)
 | 
			
		||||
                    .createFolder(folderModel);
 | 
			
		||||
 | 
			
		||||
            STEP("Upload a text document to the childFolders.");
 | 
			
		||||
            restClient.authenticateUser(user1)
 | 
			
		||||
                    .configureRequestSpec()
 | 
			
		||||
                    .addMultiPart("filedata", Utility.getResourceTestDataFile("sampleLargeContent.txt"));
 | 
			
		||||
 | 
			
		||||
            RestNodeModel newNode = restClient.authenticateUser(user1)
 | 
			
		||||
                    .withCoreAPI()
 | 
			
		||||
                    .usingNode(childFolder)
 | 
			
		||||
                    .createNode();
 | 
			
		||||
 | 
			
		||||
            restClient.assertStatusCodeIs(HttpStatus.CREATED);
 | 
			
		||||
 | 
			
		||||
            newNode.assertThat()
 | 
			
		||||
                    .field("id")
 | 
			
		||||
                    .isNotNull()
 | 
			
		||||
                    .and()
 | 
			
		||||
                    .field("name")
 | 
			
		||||
                    .is("sampleLargeContent.txt")
 | 
			
		||||
                    .and()
 | 
			
		||||
                    .field("content.mimeType")
 | 
			
		||||
                    .is(FileType.TEXT_PLAIN.mimeType);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        RestSizeDetailsModel restSizeDetailsModel = restClient.authenticateUser(user1).withCoreAPI().usingNode(folder).executeSizeDetails();
 | 
			
		||||
        restClient.assertStatusCodeIs(HttpStatus.ACCEPTED);
 | 
			
		||||
        restSizeDetailsModel.assertThat().field("jobId").isNotEmpty();
 | 
			
		||||
        String jobId = restSizeDetailsModel.getJobId();
 | 
			
		||||
 | 
			
		||||
        Utility.sleep(4000, 60000, () -> {
 | 
			
		||||
            RestSizeDetailsModel sizeDetailsModel = restClient.authenticateUser(user1).withCoreAPI().usingNode(folder).getSizeDetails(jobId);
 | 
			
		||||
            restClient.assertStatusCodeIs(HttpStatus.OK);
 | 
			
		||||
            sizeDetailsModel.assertThat().field("sizeInBytes").isNotEmpty();
 | 
			
		||||
            Assert.assertTrue(sizeDetailsModel.getSizeInBytes() > 410000, "Value of sizeInBytes " + sizeDetailsModel.getSizeInBytes() + " is less than expected " + 410000);
 | 
			
		||||
            Assert.assertTrue(sizeDetailsModel.getSizeInBytes() < 420000, "Value of sizeInBytes " + sizeDetailsModel.getSizeInBytes() + " is less than expected " + 420000);
 | 
			
		||||
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										600
									
								
								packaging/tests/tas-restapi/src/test/resources/shared-resources/testdata/sampleLargeContent.txt
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										600
									
								
								packaging/tests/tas-restapi/src/test/resources/shared-resources/testdata/sampleLargeContent.txt
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,600 @@
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
Sample text.
 | 
			
		||||
@@ -0,0 +1,36 @@
 | 
			
		||||
/*
 | 
			
		||||
 * #%L
 | 
			
		||||
 * Alfresco Remote API
 | 
			
		||||
 * %%
 | 
			
		||||
 * Copyright (C) 2005 - 2024 Alfresco Software Limited
 | 
			
		||||
 * %%
 | 
			
		||||
 * This file is part of the Alfresco software.
 | 
			
		||||
 * If the software was purchased under a paid Alfresco license, the terms of
 | 
			
		||||
 * the paid license agreement will prevail.  Otherwise, the software is
 | 
			
		||||
 * provided under the following open source license terms:
 | 
			
		||||
 *
 | 
			
		||||
 * Alfresco is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU Lesser General Public License as published by
 | 
			
		||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * Alfresco is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 * #L%
 | 
			
		||||
 */
 | 
			
		||||
package org.alfresco.rest.api;
 | 
			
		||||
 | 
			
		||||
import org.alfresco.repo.node.sizedetails.NodeSizeDetailsServiceImpl.NodeSizeDetails;
 | 
			
		||||
 | 
			
		||||
public interface SizeDetails
 | 
			
		||||
{
 | 
			
		||||
    NodeSizeDetails generateNodeSizeDetailsRequest(String nodeId);
 | 
			
		||||
 | 
			
		||||
    NodeSizeDetails getNodeSizeDetails(String nodeId, String jobId);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,119 @@
 | 
			
		||||
/*
 | 
			
		||||
 * #%L
 | 
			
		||||
 * Alfresco Remote API
 | 
			
		||||
 * %%
 | 
			
		||||
 * Copyright (C) 2005 - 2024 Alfresco Software Limited
 | 
			
		||||
 * %%
 | 
			
		||||
 * This file is part of the Alfresco software.
 | 
			
		||||
 * If the software was purchased under a paid Alfresco license, the terms of
 | 
			
		||||
 * the paid license agreement will prevail.  Otherwise, the software is
 | 
			
		||||
 * provided under the following open source license terms:
 | 
			
		||||
 *
 | 
			
		||||
 * Alfresco is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU Lesser General Public License as published by
 | 
			
		||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * Alfresco is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 * #L%
 | 
			
		||||
 */
 | 
			
		||||
package org.alfresco.rest.api.impl;
 | 
			
		||||
 | 
			
		||||
import java.util.Optional;
 | 
			
		||||
 | 
			
		||||
import org.springframework.beans.factory.InitializingBean;
 | 
			
		||||
 | 
			
		||||
import org.alfresco.model.ContentModel;
 | 
			
		||||
import org.alfresco.repo.node.sizedetails.NodeSizeDetailsService;
 | 
			
		||||
import org.alfresco.repo.node.sizedetails.NodeSizeDetailsServiceImpl.NodeSizeDetails;
 | 
			
		||||
import org.alfresco.repo.node.sizedetails.NodeSizeDetailsServiceImpl.NodeSizeDetails.STATUS;
 | 
			
		||||
import org.alfresco.rest.api.Nodes;
 | 
			
		||||
import org.alfresco.rest.api.SizeDetails;
 | 
			
		||||
import org.alfresco.rest.framework.core.exceptions.InvalidNodeTypeException;
 | 
			
		||||
import org.alfresco.rest.framework.core.exceptions.NotFoundException;
 | 
			
		||||
import org.alfresco.service.cmr.repository.NodeRef;
 | 
			
		||||
import org.alfresco.util.GUID;
 | 
			
		||||
import org.alfresco.util.ParameterCheck;
 | 
			
		||||
 | 
			
		||||
public class SizeDetailsImpl implements SizeDetails, InitializingBean
 | 
			
		||||
{
 | 
			
		||||
    private final Nodes nodes;
 | 
			
		||||
    private final NodeSizeDetailsService nodeSizeDetailsService;
 | 
			
		||||
 | 
			
		||||
    public SizeDetailsImpl(Nodes nodes, NodeSizeDetailsService nodeSizeDetailsService)
 | 
			
		||||
    {
 | 
			
		||||
        this.nodes = nodes;
 | 
			
		||||
        this.nodeSizeDetailsService = nodeSizeDetailsService;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * generateNodeSizeDetailsRequest : providing HTTP STATUS 202 with jobId.
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public NodeSizeDetails generateNodeSizeDetailsRequest(String nodeId)
 | 
			
		||||
    {
 | 
			
		||||
        NodeRef nodeRef = nodes.validateOrLookupNode(nodeId);
 | 
			
		||||
        validateType(nodeRef);
 | 
			
		||||
 | 
			
		||||
        Optional<NodeSizeDetails> nodeSizeDetails = nodeSizeDetailsService.getSizeDetails(nodeId);
 | 
			
		||||
        String actionId = nodeSizeDetails.map(NodeSizeDetails::getJobId)
 | 
			
		||||
                .orElseGet(() -> executeSizeDetails(nodeRef));
 | 
			
		||||
 | 
			
		||||
        return new NodeSizeDetails(actionId);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * getNodeSizeDetails : providing HTTP STATUS 200 with NodeSizeDetails data from cache.
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public NodeSizeDetails getNodeSizeDetails(final String nodeId, final String jobId)
 | 
			
		||||
    {
 | 
			
		||||
        NodeRef nodeRef = nodes.validateOrLookupNode(nodeId);
 | 
			
		||||
        validateType(nodeRef);
 | 
			
		||||
 | 
			
		||||
        Optional<NodeSizeDetails> optionalDetails = nodeSizeDetailsService.getSizeDetails(nodeId);
 | 
			
		||||
        return optionalDetails.map(details -> {
 | 
			
		||||
            String cachedJobId = details.getJobId();
 | 
			
		||||
            if (cachedJobId != null && !jobId.equalsIgnoreCase(cachedJobId))
 | 
			
		||||
            {
 | 
			
		||||
                throw new NotFoundException("jobId does not exist");
 | 
			
		||||
            }
 | 
			
		||||
            return details;
 | 
			
		||||
        })
 | 
			
		||||
                .orElseGet(() -> new NodeSizeDetails(nodeId, STATUS.NOT_INITIATED));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Executing Asynchronously.
 | 
			
		||||
     */
 | 
			
		||||
    private String executeSizeDetails(NodeRef nodeRef)
 | 
			
		||||
    {
 | 
			
		||||
        String jobId = GUID.generate();
 | 
			
		||||
        NodeSizeDetails nodeSizeDetails = new NodeSizeDetails(nodeRef.getId(), jobId, STATUS.PENDING);
 | 
			
		||||
        nodeSizeDetailsService.putSizeDetails(nodeRef.getId(), nodeSizeDetails);
 | 
			
		||||
        nodeSizeDetailsService.invokeSizeDetailsExecutor(nodeRef, jobId);
 | 
			
		||||
        return jobId;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void validateType(NodeRef nodeRef) throws InvalidNodeTypeException
 | 
			
		||||
    {
 | 
			
		||||
        if (!nodes.isSubClass(nodeRef, ContentModel.TYPE_FOLDER, false))
 | 
			
		||||
        {
 | 
			
		||||
            throw new InvalidNodeTypeException("Node id " + nodeRef.getId() + " does not represent a folder.");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void afterPropertiesSet() throws Exception
 | 
			
		||||
    {
 | 
			
		||||
        ParameterCheck.mandatory("nodes", this.nodes);
 | 
			
		||||
        ParameterCheck.mandatory("nodeSizeDetailsServiceImpl", this.nodeSizeDetailsService);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,84 @@
 | 
			
		||||
/*
 | 
			
		||||
 * #%L
 | 
			
		||||
 * Alfresco Remote API
 | 
			
		||||
 * %%
 | 
			
		||||
 * Copyright (C) 2005 - 2024 Alfresco Software Limited
 | 
			
		||||
 * %%
 | 
			
		||||
 * This file is part of the Alfresco software.
 | 
			
		||||
 * If the software was purchased under a paid Alfresco license, the terms of
 | 
			
		||||
 * the paid license agreement will prevail.  Otherwise, the software is
 | 
			
		||||
 * provided under the following open source license terms:
 | 
			
		||||
 *
 | 
			
		||||
 * Alfresco is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU Lesser General Public License as published by
 | 
			
		||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * Alfresco is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 * #L%
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.alfresco.rest.api.nodes;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import org.springframework.beans.factory.InitializingBean;
 | 
			
		||||
import org.springframework.extensions.webscripts.Status;
 | 
			
		||||
 | 
			
		||||
import org.alfresco.repo.node.sizedetails.NodeSizeDetailsServiceImpl.NodeSizeDetails;
 | 
			
		||||
import org.alfresco.rest.api.SizeDetails;
 | 
			
		||||
import org.alfresco.rest.framework.WebApiDescription;
 | 
			
		||||
import org.alfresco.rest.framework.WebApiParam;
 | 
			
		||||
import org.alfresco.rest.framework.WebApiParameters;
 | 
			
		||||
import org.alfresco.rest.framework.core.ResourceParameter;
 | 
			
		||||
import org.alfresco.rest.framework.core.exceptions.RelationshipResourceNotFoundException;
 | 
			
		||||
import org.alfresco.rest.framework.resource.RelationshipResource;
 | 
			
		||||
import org.alfresco.rest.framework.resource.actions.interfaces.RelationshipResourceAction;
 | 
			
		||||
import org.alfresco.rest.framework.resource.parameters.Parameters;
 | 
			
		||||
import org.alfresco.util.ParameterCheck;
 | 
			
		||||
 | 
			
		||||
@RelationshipResource(name = "size-details", entityResource = NodesEntityResource.class, title = "Node Size Details")
 | 
			
		||||
public class NodeSizeDetailsRelation implements RelationshipResourceAction.ReadById<NodeSizeDetails>,
 | 
			
		||||
        RelationshipResourceAction.Create<NodeSizeDetails>, InitializingBean
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    private SizeDetails sizeDetails;
 | 
			
		||||
 | 
			
		||||
    public void setSizeDetails(SizeDetails sizeDetails)
 | 
			
		||||
    {
 | 
			
		||||
        this.sizeDetails = sizeDetails;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void afterPropertiesSet()
 | 
			
		||||
    {
 | 
			
		||||
        ParameterCheck.mandatory("sizeDetails", this.sizeDetails);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @WebApiDescription(title = "Create node-size details request", successStatus = Status.STATUS_ACCEPTED)
 | 
			
		||||
    @WebApiParam(name = "nodeSizeEntity", title = "Node Size Details Request",
 | 
			
		||||
            description = "Request for processing Node Size.", kind = ResourceParameter.KIND.HTTP_BODY_OBJECT,
 | 
			
		||||
            allowMultiple = false)
 | 
			
		||||
    @Override
 | 
			
		||||
    public List<NodeSizeDetails> create(String nodeId, List<NodeSizeDetails> nodeSizeEntity, Parameters parameters)
 | 
			
		||||
    {
 | 
			
		||||
        return List.of(sizeDetails.generateNodeSizeDetailsRequest(nodeId));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @WebApiDescription(title = "Get Node Size Details", description = "Get the Node Size Details")
 | 
			
		||||
    @WebApiParameters({@WebApiParam(name = "nodeId", title = "The unique id of the Node being addressed",
 | 
			
		||||
            description = "A single Node id"),
 | 
			
		||||
            @WebApiParam(name = "jobId", title = "Job Id to get the NodeSizeDetails", description = "JobId")})
 | 
			
		||||
    @Override
 | 
			
		||||
    public NodeSizeDetails readById(String nodeId, String jobId, Parameters parameters)
 | 
			
		||||
            throws RelationshipResourceNotFoundException
 | 
			
		||||
    {
 | 
			
		||||
        return sizeDetails.getNodeSizeDetails(nodeId, jobId);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -996,6 +996,25 @@
 | 
			
		||||
        </property>
 | 
			
		||||
    </bean>
 | 
			
		||||
 | 
			
		||||
    <bean id="sizeDetailsImpl" class="org.alfresco.rest.api.impl.SizeDetailsImpl">
 | 
			
		||||
        <constructor-arg name="nodes" ref="nodes" />
 | 
			
		||||
        <constructor-arg name="nodeSizeDetailsService" ref="NodeSizeDetailsService" />
 | 
			
		||||
    </bean>
 | 
			
		||||
 | 
			
		||||
    <bean id="sizeDetails" class="org.springframework.aop.framework.ProxyFactoryBean">
 | 
			
		||||
        <property name="proxyInterfaces">
 | 
			
		||||
            <value>org.alfresco.rest.api.SizeDetails</value>
 | 
			
		||||
        </property>
 | 
			
		||||
        <property name="target">
 | 
			
		||||
            <ref bean="sizeDetailsImpl" />
 | 
			
		||||
        </property>
 | 
			
		||||
        <property name="interceptorNames">
 | 
			
		||||
            <list>
 | 
			
		||||
                <idref bean="legacyExceptionInterceptor" />
 | 
			
		||||
            </list>
 | 
			
		||||
        </property>
 | 
			
		||||
    </bean>
 | 
			
		||||
 | 
			
		||||
    <bean class="org.alfresco.rest.api.rules.NodeRuleSettingsRelation">
 | 
			
		||||
        <property name="ruleSettings" ref="RuleSettings" />
 | 
			
		||||
    </bean>
 | 
			
		||||
@@ -1770,4 +1789,8 @@
 | 
			
		||||
            </list>
 | 
			
		||||
        </property>
 | 
			
		||||
    </bean>
 | 
			
		||||
 | 
			
		||||
    <bean class="org.alfresco.rest.api.nodes.NodeSizeDetailsRelation">
 | 
			
		||||
        <property name="sizeDetails" ref="sizeDetails" />
 | 
			
		||||
    </bean>
 | 
			
		||||
</beans>
 | 
			
		||||
 
 | 
			
		||||
@@ -4,21 +4,21 @@
 | 
			
		||||
 * %%
 | 
			
		||||
 * Copyright (C) 2005 - 2021 Alfresco Software Limited
 | 
			
		||||
 * %%
 | 
			
		||||
 * This file is part of the Alfresco software. 
 | 
			
		||||
 * If the software was purchased under a paid Alfresco license, the terms of 
 | 
			
		||||
 * the paid license agreement will prevail.  Otherwise, the software is 
 | 
			
		||||
 * This file is part of the Alfresco software.
 | 
			
		||||
 * If the software was purchased under a paid Alfresco license, the terms of
 | 
			
		||||
 * the paid license agreement will prevail.  Otherwise, the software is
 | 
			
		||||
 * provided under the following open source license terms:
 | 
			
		||||
 * 
 | 
			
		||||
 *
 | 
			
		||||
 * Alfresco is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU Lesser General Public License as published by
 | 
			
		||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * 
 | 
			
		||||
 *
 | 
			
		||||
 * Alfresco is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU Lesser General Public License for more details.
 | 
			
		||||
 * 
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 * #L%
 | 
			
		||||
@@ -71,7 +71,7 @@ import org.junit.runners.Suite;
 | 
			
		||||
    org.alfresco.rest.api.tests.TestPublicApiCaching.class,
 | 
			
		||||
    org.alfresco.rest.api.tests.TestUserPreferences.class,
 | 
			
		||||
    org.alfresco.rest.api.tests.WherePredicateApiTest.class,
 | 
			
		||||
    org.alfresco.rest.api.tests.TestRemovePermissions.class, 
 | 
			
		||||
    org.alfresco.rest.api.tests.TestRemovePermissions.class,
 | 
			
		||||
    org.alfresco.rest.api.tests.TempOutputStreamTest.class,
 | 
			
		||||
    org.alfresco.rest.api.tests.BufferedResponseTest.class,
 | 
			
		||||
    org.alfresco.rest.workflow.api.tests.DeploymentWorkflowApiTest.class,
 | 
			
		||||
 
 | 
			
		||||
@@ -2,23 +2,23 @@
 | 
			
		||||
 * #%L
 | 
			
		||||
 * Alfresco Repository
 | 
			
		||||
 * %%
 | 
			
		||||
 * Copyright (C) 2005 - 2021 Alfresco Software Limited
 | 
			
		||||
 * Copyright (C) 2005 - 2024 Alfresco Software Limited
 | 
			
		||||
 * %%
 | 
			
		||||
 * This file is part of the Alfresco software. 
 | 
			
		||||
 * If the software was purchased under a paid Alfresco license, the terms of 
 | 
			
		||||
 * the paid license agreement will prevail.  Otherwise, the software is 
 | 
			
		||||
 * This file is part of the Alfresco software.
 | 
			
		||||
 * If the software was purchased under a paid Alfresco license, the terms of
 | 
			
		||||
 * the paid license agreement will prevail.  Otherwise, the software is
 | 
			
		||||
 * provided under the following open source license terms:
 | 
			
		||||
 * 
 | 
			
		||||
 *
 | 
			
		||||
 * Alfresco is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU Lesser General Public License as published by
 | 
			
		||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * 
 | 
			
		||||
 *
 | 
			
		||||
 * Alfresco is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU Lesser General Public License for more details.
 | 
			
		||||
 * 
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 * #L%
 | 
			
		||||
@@ -36,6 +36,8 @@ import org.alfresco.util.testing.category.NonBuildTests;
 | 
			
		||||
@RunWith(Categories.class)
 | 
			
		||||
@Categories.ExcludeCategory({DBTests.class, NonBuildTests.class})
 | 
			
		||||
@Suite.SuiteClasses({
 | 
			
		||||
        // [classpath:alfresco/application-context.xml, classpath:alfresco/web-scripts-application-context-test.xml,
 | 
			
		||||
        // classpath:alfresco/web-scripts-application-context.xml]
 | 
			
		||||
        org.alfresco.repo.web.scripts.quickshare.QuickShareRestApiTest.class,
 | 
			
		||||
        org.alfresco.repo.web.scripts.admin.AdminWebScriptTest.class,
 | 
			
		||||
        org.alfresco.repo.web.scripts.audit.AuditWebScriptTest.class,
 | 
			
		||||
@@ -47,8 +49,7 @@ import org.alfresco.util.testing.category.NonBuildTests;
 | 
			
		||||
        org.alfresco.repo.web.scripts.forms.FormRestApiJsonPost_Test.class,
 | 
			
		||||
        org.alfresco.repo.web.scripts.groups.GroupsTest.class,
 | 
			
		||||
        org.alfresco.repo.web.scripts.invitation.InvitationWebScriptTest.class,
 | 
			
		||||
        org.alfresco.repo.web.scripts.invite.InviteServiceTest.class,
 | 
			
		||||
        org.alfresco.repo.web.scripts.LoginTest.class,
 | 
			
		||||
        org.alfresco.repo.web.scripts.invite.InviteServiceTest.class, org.alfresco.repo.web.scripts.LoginTest.class,
 | 
			
		||||
        org.alfresco.repo.web.scripts.search.PersonSearchTest.class,
 | 
			
		||||
        org.alfresco.repo.web.scripts.person.PersonServiceTest.class,
 | 
			
		||||
        org.alfresco.repo.web.scripts.preference.PreferenceServiceTest.class,
 | 
			
		||||
@@ -76,9 +77,8 @@ import org.alfresco.util.testing.category.NonBuildTests;
 | 
			
		||||
        org.alfresco.repo.web.scripts.node.NodeWebScripTest.class,
 | 
			
		||||
        org.alfresco.rest.api.impl.CommentsImplUnitTest.class,
 | 
			
		||||
        org.alfresco.rest.api.impl.DownloadsImplCheckArchiveStatusUnitTest.class,
 | 
			
		||||
        org.alfresco.rest.api.impl.FavouritesImplUnitTest.class,
 | 
			
		||||
        org.alfresco.rest.api.impl.RestApiDirectUrlConfigUnitTest.class
 | 
			
		||||
})
 | 
			
		||||
        org.alfresco.rest.api.impl.RestApiDirectUrlConfigUnitTest.class,
 | 
			
		||||
        org.alfresco.rest.api.impl.SizeDetailsImplTest.class})
 | 
			
		||||
public class AppContext04TestSuite
 | 
			
		||||
{
 | 
			
		||||
    public AppContext04TestSuite()
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,107 @@
 | 
			
		||||
/*
 | 
			
		||||
 * #%L
 | 
			
		||||
 * Alfresco Remote API
 | 
			
		||||
 * %%
 | 
			
		||||
 * Copyright (C) 2005 - 2024 Alfresco Software Limited
 | 
			
		||||
 * %%
 | 
			
		||||
 * This file is part of the Alfresco software.
 | 
			
		||||
 * If the software was purchased under a paid Alfresco license, the terms of
 | 
			
		||||
 * the paid license agreement will prevail.  Otherwise, the software is
 | 
			
		||||
 * provided under the following open source license terms:
 | 
			
		||||
 *
 | 
			
		||||
 * Alfresco is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU Lesser General Public License as published by
 | 
			
		||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * Alfresco is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 * #L%
 | 
			
		||||
 */
 | 
			
		||||
package org.alfresco.rest.api.impl;
 | 
			
		||||
 | 
			
		||||
import static org.junit.Assert.assertNotNull;
 | 
			
		||||
import static org.mockito.Mockito.mock;
 | 
			
		||||
import static org.mockito.Mockito.verify;
 | 
			
		||||
import static org.mockito.Mockito.when;
 | 
			
		||||
 | 
			
		||||
import java.io.Serializable;
 | 
			
		||||
import java.util.Optional;
 | 
			
		||||
import java.util.concurrent.ThreadPoolExecutor;
 | 
			
		||||
 | 
			
		||||
import org.junit.Before;
 | 
			
		||||
import org.junit.Test;
 | 
			
		||||
 | 
			
		||||
import org.alfresco.model.ContentModel;
 | 
			
		||||
import org.alfresco.repo.cache.SimpleCache;
 | 
			
		||||
import org.alfresco.repo.node.sizedetails.NodeSizeDetailsServiceImpl;
 | 
			
		||||
import org.alfresco.repo.node.sizedetails.NodeSizeDetailsServiceImpl.NodeSizeDetails;
 | 
			
		||||
import org.alfresco.rest.api.Nodes;
 | 
			
		||||
import org.alfresco.rest.api.model.Node;
 | 
			
		||||
import org.alfresco.service.cmr.repository.NodeRef;
 | 
			
		||||
import org.alfresco.service.cmr.search.SearchService;
 | 
			
		||||
import org.alfresco.service.namespace.QName;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Unit tests for {@link SizeDetailsImpl} class.
 | 
			
		||||
 */
 | 
			
		||||
public class SizeDetailsImplTest
 | 
			
		||||
{
 | 
			
		||||
    private static final String NAMESPACE = "http://www.alfresco.org/test/NodeSizeDetailsTest";
 | 
			
		||||
    private static final QName TYPE_FOLDER = QName.createQName(NAMESPACE, "folder");
 | 
			
		||||
    private SizeDetailsImpl sizeDetailsImpl;
 | 
			
		||||
    private Nodes nodes;
 | 
			
		||||
    private NodeSizeDetailsServiceImpl nodeSizeDetailsServiceImpl;
 | 
			
		||||
    private NodeSizeDetails nodeSizeDetails;
 | 
			
		||||
 | 
			
		||||
    @Before
 | 
			
		||||
    public void setUp() throws Exception
 | 
			
		||||
    {
 | 
			
		||||
        nodes = mock(Nodes.class);
 | 
			
		||||
        SearchService searchService = mock(SearchService.class);
 | 
			
		||||
        nodeSizeDetailsServiceImpl = mock(NodeSizeDetailsServiceImpl.class);
 | 
			
		||||
        ThreadPoolExecutor threadPoolExecutor = mock(ThreadPoolExecutor.class);
 | 
			
		||||
        SimpleCache<Serializable, NodeSizeDetails> simpleCache = mock(SimpleCache.class);
 | 
			
		||||
        nodeSizeDetails = mock(NodeSizeDetails.class);
 | 
			
		||||
 | 
			
		||||
        nodeSizeDetailsServiceImpl.setSearchService(searchService);
 | 
			
		||||
        nodeSizeDetailsServiceImpl.setDefaultItems(1000);
 | 
			
		||||
        nodeSizeDetailsServiceImpl.setSimpleCache(simpleCache);
 | 
			
		||||
        verify(nodeSizeDetailsServiceImpl).setSimpleCache(simpleCache);
 | 
			
		||||
        nodeSizeDetailsServiceImpl.setThreadPoolExecutor(threadPoolExecutor);
 | 
			
		||||
        sizeDetailsImpl = new SizeDetailsImpl(nodes, nodeSizeDetailsServiceImpl);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void calculateNodeSizeDetails()
 | 
			
		||||
    {
 | 
			
		||||
        String nodeName = "folderNode";
 | 
			
		||||
        String nodeId = "node-id";
 | 
			
		||||
        String jobId = "job-id";
 | 
			
		||||
        NodeRef nodeRef = new NodeRef("protocol", "identifier", nodeId);
 | 
			
		||||
 | 
			
		||||
        Node node = new Node();
 | 
			
		||||
        node.setIsFolder(true);
 | 
			
		||||
        node.setNodeRef(nodeRef);
 | 
			
		||||
        node.setName(nodeName);
 | 
			
		||||
        node.setNodeType(TYPE_FOLDER.getLocalName());
 | 
			
		||||
        node.setNodeId(nodeRef.getId());
 | 
			
		||||
 | 
			
		||||
        when(nodes.validateOrLookupNode(nodeId)).thenReturn(nodeRef);
 | 
			
		||||
        when(nodes.isSubClass(nodeRef, ContentModel.TYPE_FOLDER, false)).thenReturn(true);
 | 
			
		||||
        when(nodeSizeDetailsServiceImpl.getSizeDetails(nodeId)).thenReturn(Optional.ofNullable(nodeSizeDetails));
 | 
			
		||||
 | 
			
		||||
        NodeSizeDetails requestSizeDetails = sizeDetailsImpl.generateNodeSizeDetailsRequest(nodeId);
 | 
			
		||||
        assertNotNull("After executing POST/size-details, it will provide with 202 status code", requestSizeDetails);
 | 
			
		||||
 | 
			
		||||
        NodeSizeDetails nodeSizeDetails = sizeDetailsImpl.getNodeSizeDetails(nodeId, jobId);
 | 
			
		||||
        assertNotNull("After executing GET/size-details, it will provide with 200 status code", nodeSizeDetails);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -2,50 +2,68 @@
 | 
			
		||||
 * #%L
 | 
			
		||||
 * Alfresco Remote API
 | 
			
		||||
 * %%
 | 
			
		||||
 * Copyright (C) 2005 - 2023 Alfresco Software Limited
 | 
			
		||||
 * Copyright (C) 2005 - 2024 Alfresco Software Limited
 | 
			
		||||
 * %%
 | 
			
		||||
 * This file is part of the Alfresco software. 
 | 
			
		||||
 * If the software was purchased under a paid Alfresco license, the terms of 
 | 
			
		||||
 * the paid license agreement will prevail.  Otherwise, the software is 
 | 
			
		||||
 * This file is part of the Alfresco software.
 | 
			
		||||
 * If the software was purchased under a paid Alfresco license, the terms of
 | 
			
		||||
 * the paid license agreement will prevail.  Otherwise, the software is
 | 
			
		||||
 * provided under the following open source license terms:
 | 
			
		||||
 * 
 | 
			
		||||
 *
 | 
			
		||||
 * Alfresco is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU Lesser General Public License as published by
 | 
			
		||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * 
 | 
			
		||||
 *
 | 
			
		||||
 * Alfresco is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU Lesser General Public License for more details.
 | 
			
		||||
 * 
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 * #L%
 | 
			
		||||
 */
 | 
			
		||||
package org.alfresco.rest.api.tests;
 | 
			
		||||
 | 
			
		||||
import org.alfresco.repo.content.directurl.SystemWideDirectUrlConfig;
 | 
			
		||||
import org.alfresco.rest.api.impl.directurl.RestApiDirectUrlConfig;
 | 
			
		||||
import org.alfresco.rest.api.tests.client.PublicApiHttpClient;
 | 
			
		||||
import static org.alfresco.rest.api.tests.util.RestApiUtil.toJsonAsString;
 | 
			
		||||
import static org.alfresco.rest.api.tests.util.RestApiUtil.toJsonAsStringNonNull;
 | 
			
		||||
import static org.junit.Assert.assertEquals;
 | 
			
		||||
import static org.junit.Assert.assertNotNull;
 | 
			
		||||
import static org.junit.Assert.assertNull;
 | 
			
		||||
import static org.junit.Assert.fail;
 | 
			
		||||
import static org.junit.Assert.assertTrue;
 | 
			
		||||
import static org.junit.Assert.fail;
 | 
			
		||||
 | 
			
		||||
import static org.alfresco.rest.api.tests.util.RestApiUtil.toJsonAsString;
 | 
			
		||||
import static org.alfresco.rest.api.tests.util.RestApiUtil.toJsonAsStringNonNull;
 | 
			
		||||
 | 
			
		||||
import java.io.ByteArrayInputStream;
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.FileNotFoundException;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.net.URL;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
import org.json.simple.JSONObject;
 | 
			
		||||
import org.junit.After;
 | 
			
		||||
import org.junit.Before;
 | 
			
		||||
import org.junit.experimental.categories.Category;
 | 
			
		||||
import org.springframework.util.ResourceUtils;
 | 
			
		||||
 | 
			
		||||
import org.alfresco.repo.content.directurl.SystemWideDirectUrlConfig;
 | 
			
		||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
 | 
			
		||||
import org.alfresco.repo.tenant.TenantService;
 | 
			
		||||
import org.alfresco.repo.tenant.TenantUtil;
 | 
			
		||||
import org.alfresco.repo.transaction.RetryingTransactionHelper;
 | 
			
		||||
import org.alfresco.rest.api.Nodes;
 | 
			
		||||
import org.alfresco.rest.api.impl.directurl.RestApiDirectUrlConfig;
 | 
			
		||||
import org.alfresco.rest.api.model.Site;
 | 
			
		||||
import org.alfresco.rest.api.nodes.NodesEntityResource;
 | 
			
		||||
import org.alfresco.rest.api.tests.RepoService.TestNetwork;
 | 
			
		||||
import org.alfresco.rest.api.tests.client.HttpResponse;
 | 
			
		||||
import org.alfresco.rest.api.tests.client.PublicApiClient;
 | 
			
		||||
import org.alfresco.rest.api.tests.client.PublicApiHttpClient;
 | 
			
		||||
import org.alfresco.rest.api.tests.client.PublicApiHttpClient.BinaryPayload;
 | 
			
		||||
import org.alfresco.rest.api.tests.client.PublicApiHttpClient.RequestBuilder;
 | 
			
		||||
import org.alfresco.rest.api.tests.client.RequestContext;
 | 
			
		||||
@@ -65,26 +83,10 @@ import org.alfresco.service.cmr.security.PersonService;
 | 
			
		||||
import org.alfresco.service.cmr.site.SiteVisibility;
 | 
			
		||||
import org.alfresco.util.TempFileProvider;
 | 
			
		||||
import org.alfresco.util.testing.category.LuceneTests;
 | 
			
		||||
import org.json.simple.JSONObject;
 | 
			
		||||
import org.junit.After;
 | 
			
		||||
import org.junit.Before;
 | 
			
		||||
import org.junit.experimental.categories.Category;
 | 
			
		||||
import org.springframework.util.ResourceUtils;
 | 
			
		||||
 | 
			
		||||
import java.io.ByteArrayInputStream;
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.FileNotFoundException;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.net.URL;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Generic methods for calling the Api (originally taken and adapted from BaseCustomModelApiTest)
 | 
			
		||||
 * 
 | 
			
		||||
 *
 | 
			
		||||
 * @author Jamal Kaabi-Mofrad
 | 
			
		||||
 * @author janv
 | 
			
		||||
 * @author gethin
 | 
			
		||||
@@ -94,54 +96,40 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
 | 
			
		||||
{
 | 
			
		||||
    public static final String LAST_MODIFIED_HEADER = "Last-Modified";
 | 
			
		||||
    public static final String IF_MODIFIED_SINCE_HEADER = "If-Modified-Since";
 | 
			
		||||
 | 
			
		||||
    private static final String RESOURCE_PREFIX = "publicapi/upload/";
 | 
			
		||||
 | 
			
		||||
    protected static final String URL_NODES = "nodes";
 | 
			
		||||
    protected static final String URL_DELETED_NODES = "deleted-nodes";
 | 
			
		||||
 | 
			
		||||
    protected static final String URL_RENDITIONS = "renditions";
 | 
			
		||||
    protected static final String URL_VERSIONS = "versions";
 | 
			
		||||
 | 
			
		||||
    private static final String URL_CHILDREN = "children";
 | 
			
		||||
    private static final String URL_CONTENT = "content";
 | 
			
		||||
 | 
			
		||||
    protected static final String TYPE_CM_FOLDER = "cm:folder";
 | 
			
		||||
    protected static final String TYPE_CM_CONTENT = "cm:content";
 | 
			
		||||
    protected static final String TYPE_CM_OBJECT = "cm:cmobject";
 | 
			
		||||
 | 
			
		||||
    protected static final String ASPECT_CM_PREFERENCES = "cm:preferences";
 | 
			
		||||
    protected static final String ASSOC_TYPE_CM_PREFERENCE_IMAGE = "cm:preferenceImage";
 | 
			
		||||
 | 
			
		||||
    protected static final String ASSOC_TYPE_CM_CONTAINS = "cm:contains";
 | 
			
		||||
    
 | 
			
		||||
    // TODO improve admin-related tests, including ability to override default admin un/pw
 | 
			
		||||
    protected static final String DEFAULT_ADMIN = "admin";
 | 
			
		||||
    protected static final String DEFAULT_ADMIN_PWD = "admin";
 | 
			
		||||
 | 
			
		||||
    protected static final long PAUSE_TIME = 5000; // millisecond
 | 
			
		||||
    protected static final int MAX_RETRY = 20;
 | 
			
		||||
    private static final String RESOURCE_PREFIX = "publicapi/upload/";
 | 
			
		||||
    private static final String URL_CHILDREN = "children";
 | 
			
		||||
    private static final String URL_CONTENT = "content";
 | 
			
		||||
    private static final String URL_CALCULATEFOLDERSIZE = "size-details";
 | 
			
		||||
    private static final String REQUEST_DIRECT_ACCESS_URL = "request-direct-access-url";
 | 
			
		||||
    // network1 with user1, user2 and a testsite1
 | 
			
		||||
    protected static TestNetwork networkOne;
 | 
			
		||||
    
 | 
			
		||||
    protected static String user1; // user1 from network1
 | 
			
		||||
    protected static String user2; // user2 from network1
 | 
			
		||||
 | 
			
		||||
    // network admin (or default super admin, if not running within a tenant/network)
 | 
			
		||||
    protected static String networkAdmin = DEFAULT_ADMIN;
 | 
			
		||||
 | 
			
		||||
    protected static String tSiteId;
 | 
			
		||||
    protected static String tDocLibNodeId;
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
    protected static List<String> users = new ArrayList<>();
 | 
			
		||||
 | 
			
		||||
    protected static JacksonUtil jacksonUtil;
 | 
			
		||||
    protected static MutableAuthenticationService authenticationService;
 | 
			
		||||
    protected static PersonService personService;
 | 
			
		||||
    protected final String RUNID = System.currentTimeMillis() + "";
 | 
			
		||||
 | 
			
		||||
    protected final String RUNID = System.currentTimeMillis()+"";
 | 
			
		||||
 | 
			
		||||
    private static final String REQUEST_DIRECT_ACCESS_URL = "request-direct-access-url";
 | 
			
		||||
    
 | 
			
		||||
    @Override
 | 
			
		||||
    @Before
 | 
			
		||||
    public void setup() throws Exception
 | 
			
		||||
@@ -153,22 +141,22 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
 | 
			
		||||
            // note: populateTestData/createTestData will be called (which currently creates 2 tenants, 9 users per tenant, 10 sites per tenant, ...)
 | 
			
		||||
            networkOne = getTestFixture().getRandomNetwork();
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        //userOneN1 = networkN1.createUser();
 | 
			
		||||
        //userTwoN1 = networkN1.createUser();
 | 
			
		||||
 | 
			
		||||
        // userOneN1 = networkN1.createUser();
 | 
			
		||||
        // userTwoN1 = networkN1.createUser();
 | 
			
		||||
 | 
			
		||||
        String tenantDomain = networkOne.getId();
 | 
			
		||||
        
 | 
			
		||||
        if (! TenantService.DEFAULT_DOMAIN.equals(tenantDomain))
 | 
			
		||||
 | 
			
		||||
        if (!TenantService.DEFAULT_DOMAIN.equals(tenantDomain))
 | 
			
		||||
        {
 | 
			
		||||
            networkAdmin = DEFAULT_ADMIN+"@"+tenantDomain;
 | 
			
		||||
            networkAdmin = DEFAULT_ADMIN + "@" + tenantDomain;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // to enable admin access via test calls - eg. via PublicApiClient -> AbstractTestApi -> findUserByUserName
 | 
			
		||||
        getOrCreateUser(networkAdmin, "admin", networkOne);
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        setRequestContext(networkOne.getId(), networkAdmin, DEFAULT_ADMIN_PWD);
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        // note: createUser currently relies on repoService
 | 
			
		||||
        user1 = createUser("user1-" + RUNID, "user1Password", networkOne);
 | 
			
		||||
        user2 = createUser("user2-" + RUNID, "user2Password", networkOne);
 | 
			
		||||
@@ -180,7 +168,7 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
 | 
			
		||||
        users.add(user2);
 | 
			
		||||
 | 
			
		||||
        setRequestContext(networkOne.getId(), user1, null);
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        tSiteId = createSite("TestSite A - " + RUNID, SiteVisibility.PRIVATE).getId();
 | 
			
		||||
        tDocLibNodeId = getSiteContainerNodeId(tSiteId, "documentLibrary");
 | 
			
		||||
 | 
			
		||||
@@ -197,11 +185,10 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        setRequestContext(networkAdmin);
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        for (final String username : users)
 | 
			
		||||
        {
 | 
			
		||||
            transactionHelper.doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Void>()
 | 
			
		||||
            {
 | 
			
		||||
            transactionHelper.doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Void>() {
 | 
			
		||||
                @Override
 | 
			
		||||
                public Void execute() throws Throwable
 | 
			
		||||
                {
 | 
			
		||||
@@ -210,7 +197,7 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        users.clear();
 | 
			
		||||
        AuthenticationUtil.clearCurrentSecurityContext();
 | 
			
		||||
        setRequestContext(null);
 | 
			
		||||
@@ -233,7 +220,8 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
 | 
			
		||||
 | 
			
		||||
    protected String getRequestArchivedRenditonContentDirectUrl(String nodeId, String renditionID)
 | 
			
		||||
    {
 | 
			
		||||
        return URL_DELETED_NODES + "/" + nodeId + "/" + URL_RENDITIONS + "/" + renditionID + "/" + REQUEST_DIRECT_ACCESS_URL;
 | 
			
		||||
        return URL_DELETED_NODES + "/" + nodeId + "/" + URL_RENDITIONS + "/" + renditionID + "/"
 | 
			
		||||
                + REQUEST_DIRECT_ACCESS_URL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected String getRequestRenditionDirectAccessUrl(String nodeId, String renditionID)
 | 
			
		||||
@@ -246,7 +234,6 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
 | 
			
		||||
        return URL_NODES + "/" + nodeId + "/" + URL_VERSIONS + "/" + versionId + "/" + REQUEST_DIRECT_ACCESS_URL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The api scope. either public or private
 | 
			
		||||
     *
 | 
			
		||||
@@ -262,10 +249,10 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
 | 
			
		||||
        return response;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected HttpResponse post(String url, byte[] body, Map<String, String> params, Map<String, String> headers, String apiName, String contentType, int expectedStatus) throws Exception
 | 
			
		||||
    protected HttpResponse post(String url, byte[] body, Map<String, String> params, Map<String, String> headers,
 | 
			
		||||
            String apiName, String contentType, int expectedStatus) throws Exception
 | 
			
		||||
    {
 | 
			
		||||
        RequestBuilder requestBuilder = httpClient.new PostRequestBuilder()
 | 
			
		||||
                .setBodyAsByteArray(body)
 | 
			
		||||
        RequestBuilder requestBuilder = httpClient.new PostRequestBuilder().setBodyAsByteArray(body)
 | 
			
		||||
                .setContentType(contentType)
 | 
			
		||||
                .setRequestContext(publicApiClient.getRequestContext())
 | 
			
		||||
                .setScope(getScope())
 | 
			
		||||
@@ -279,10 +266,10 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
 | 
			
		||||
        return response;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected HttpResponse post(String url, String body, Map<String, String> params, Map<String, String> headers, String apiName, int expectedStatus) throws Exception
 | 
			
		||||
    protected HttpResponse post(String url, String body, Map<String, String> params, Map<String, String> headers,
 | 
			
		||||
            String apiName, int expectedStatus) throws Exception
 | 
			
		||||
    {
 | 
			
		||||
        RequestBuilder requestBuilder = httpClient.new PostRequestBuilder()
 | 
			
		||||
                .setBodyAsString(body)
 | 
			
		||||
        RequestBuilder requestBuilder = httpClient.new PostRequestBuilder().setBodyAsString(body)
 | 
			
		||||
                .setRequestContext(publicApiClient.getRequestContext())
 | 
			
		||||
                .setScope(getScope())
 | 
			
		||||
                .setApiName(apiName)
 | 
			
		||||
@@ -307,7 +294,8 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
 | 
			
		||||
        return response;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected HttpResponse post(String url, String body, String queryString, String contentType, int expectedStatus) throws Exception
 | 
			
		||||
    protected HttpResponse post(String url, String body, String queryString, String contentType, int expectedStatus)
 | 
			
		||||
            throws Exception
 | 
			
		||||
    {
 | 
			
		||||
        if (queryString != null)
 | 
			
		||||
        {
 | 
			
		||||
@@ -319,7 +307,8 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
 | 
			
		||||
        return response;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected HttpResponse post(String url, byte[] body, String queryString, String contentType, int expectedStatus) throws Exception
 | 
			
		||||
    protected HttpResponse post(String url, byte[] body, String queryString, String contentType, int expectedStatus)
 | 
			
		||||
            throws Exception
 | 
			
		||||
    {
 | 
			
		||||
        if (queryString != null)
 | 
			
		||||
        {
 | 
			
		||||
@@ -332,9 +321,12 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // TODO unused queryString - fix-up usages and then remove
 | 
			
		||||
    protected HttpResponse post(String entityCollectionName, String entityId, String relationCollectionName, byte[] body, String queryString, String contentType, int expectedStatus) throws Exception
 | 
			
		||||
    protected HttpResponse post(String entityCollectionName, String entityId, String relationCollectionName,
 | 
			
		||||
            byte[] body, String queryString, String contentType, int expectedStatus)
 | 
			
		||||
            throws Exception
 | 
			
		||||
    {
 | 
			
		||||
        HttpResponse response = publicApiClient.post(getScope(), entityCollectionName, entityId, relationCollectionName, null, body, contentType);
 | 
			
		||||
        HttpResponse response = publicApiClient.post(getScope(), entityCollectionName, entityId, relationCollectionName, null, body,
 | 
			
		||||
                contentType);
 | 
			
		||||
        checkStatus(expectedStatus, response.getStatusCode());
 | 
			
		||||
 | 
			
		||||
        return response;
 | 
			
		||||
@@ -345,7 +337,8 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
 | 
			
		||||
        return getAll(url, paging, null, expectedStatus);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected HttpResponse getAll(String url, PublicApiClient.Paging paging, Map<String, String> otherParams, int expectedStatus) throws Exception
 | 
			
		||||
    protected HttpResponse getAll(String url, PublicApiClient.Paging paging, Map<String, String> otherParams,
 | 
			
		||||
            int expectedStatus) throws Exception
 | 
			
		||||
    {
 | 
			
		||||
        Map<String, String> params = createParams(paging, otherParams);
 | 
			
		||||
 | 
			
		||||
@@ -355,7 +348,8 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
 | 
			
		||||
        return response;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected HttpResponse getAll(Class<?> entityResource, PublicApiClient.Paging paging, Map<String, String> otherParams, int expectedStatus) throws Exception
 | 
			
		||||
    protected HttpResponse getAll(Class<?> entityResource, PublicApiClient.Paging paging,
 | 
			
		||||
            Map<String, String> otherParams, int expectedStatus) throws Exception
 | 
			
		||||
    {
 | 
			
		||||
        HttpResponse response = publicApiClient.get(entityResource, null, null, otherParams);
 | 
			
		||||
        checkStatus(expectedStatus, response.getStatusCode());
 | 
			
		||||
@@ -363,16 +357,17 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
 | 
			
		||||
        return response;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected HttpResponse getAll(String url, PublicApiClient.Paging paging, Map<String, String> otherParams, Map<String, String> headers, int expectedStatus) throws Exception
 | 
			
		||||
    protected HttpResponse getAll(String url, PublicApiClient.Paging paging, Map<String, String> otherParams,
 | 
			
		||||
            Map<String, String> headers, int expectedStatus) throws Exception
 | 
			
		||||
    {
 | 
			
		||||
        return getAll(url, paging, otherParams, headers, null, expectedStatus);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected HttpResponse getAll(String url, PublicApiClient.Paging paging, Map<String, String> otherParams, Map<String, String> headers, String apiName, int expectedStatus) throws Exception
 | 
			
		||||
    protected HttpResponse getAll(String url, PublicApiClient.Paging paging, Map<String, String> otherParams,
 | 
			
		||||
            Map<String, String> headers, String apiName, int expectedStatus) throws Exception
 | 
			
		||||
    {
 | 
			
		||||
        Map<String, String> params = createParams(paging, otherParams);
 | 
			
		||||
        RequestBuilder requestBuilder = httpClient.new GetRequestBuilder()
 | 
			
		||||
                .setRequestContext(publicApiClient.getRequestContext())
 | 
			
		||||
        RequestBuilder requestBuilder = httpClient.new GetRequestBuilder().setRequestContext(publicApiClient.getRequestContext())
 | 
			
		||||
                .setScope(getScope())
 | 
			
		||||
                .setApiName(apiName)
 | 
			
		||||
                .setEntityCollectionName(url)
 | 
			
		||||
@@ -384,7 +379,7 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
 | 
			
		||||
 | 
			
		||||
        return response;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    protected HttpResponse getSingle(String url, String entityId, int expectedStatus) throws Exception
 | 
			
		||||
    {
 | 
			
		||||
        return getSingle(url, entityId, null, expectedStatus);
 | 
			
		||||
@@ -398,7 +393,8 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
 | 
			
		||||
        return response;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected HttpResponse getSingle(String url, String entityId, Map<String, String> params, int expectedStatus) throws Exception
 | 
			
		||||
    protected HttpResponse getSingle(String url, String entityId, Map<String, String> params, int expectedStatus)
 | 
			
		||||
            throws Exception
 | 
			
		||||
    {
 | 
			
		||||
        HttpResponse response = publicApiClient.get(getScope(), url, entityId, null, null, params);
 | 
			
		||||
        checkStatus(expectedStatus, response.getStatusCode());
 | 
			
		||||
@@ -406,7 +402,8 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
 | 
			
		||||
        return response;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected HttpResponse getSingle(Class<?> entityResource, String entityId, Map<String, String> params, int expectedStatus) throws Exception
 | 
			
		||||
    protected HttpResponse getSingle(Class<?> entityResource, String entityId, Map<String, String> params,
 | 
			
		||||
            int expectedStatus) throws Exception
 | 
			
		||||
    {
 | 
			
		||||
        HttpResponse response = publicApiClient.get(entityResource, entityId, null, params);
 | 
			
		||||
        checkStatus(expectedStatus, response.getStatusCode());
 | 
			
		||||
@@ -414,15 +411,16 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
 | 
			
		||||
        return response;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected HttpResponse getSingle(String url, String entityId, Map<String, String> params, Map<String, String> headers, int expectedStatus) throws Exception
 | 
			
		||||
    protected HttpResponse getSingle(String url, String entityId, Map<String, String> params,
 | 
			
		||||
            Map<String, String> headers, int expectedStatus) throws Exception
 | 
			
		||||
    {
 | 
			
		||||
        return getSingle(url, entityId, params, headers, null, expectedStatus);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected HttpResponse getSingle(String url, String entityId, Map<String, String> params, Map<String, String> headers, String apiName, int expectedStatus) throws Exception
 | 
			
		||||
    protected HttpResponse getSingle(String url, String entityId, Map<String, String> params,
 | 
			
		||||
            Map<String, String> headers, String apiName, int expectedStatus) throws Exception
 | 
			
		||||
    {
 | 
			
		||||
        RequestBuilder requestBuilder = httpClient.new GetRequestBuilder()
 | 
			
		||||
                .setRequestContext(publicApiClient.getRequestContext())
 | 
			
		||||
        RequestBuilder requestBuilder = httpClient.new GetRequestBuilder().setRequestContext(publicApiClient.getRequestContext())
 | 
			
		||||
                .setScope(getScope())
 | 
			
		||||
                .setApiName(apiName)
 | 
			
		||||
                .setEntityCollectionName(url)
 | 
			
		||||
@@ -437,7 +435,8 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected HttpResponse getSingleWithDelayRetry(String url, String entityId, Map<String, String> params,
 | 
			
		||||
                                                   Map<String, String> headers, int repeat, long pauseInMillisecond, int expectedStatus) throws Exception
 | 
			
		||||
            Map<String, String> headers, int repeat, long pauseInMillisecond,
 | 
			
		||||
            int expectedStatus) throws Exception
 | 
			
		||||
    {
 | 
			
		||||
        int retryCount = 0;
 | 
			
		||||
        while (retryCount < repeat)
 | 
			
		||||
@@ -445,7 +444,7 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                return getSingle(url, entityId, params, headers, expectedStatus);
 | 
			
		||||
            } 
 | 
			
		||||
            }
 | 
			
		||||
            catch (AssertionError ex)
 | 
			
		||||
            {
 | 
			
		||||
                retryCount++;
 | 
			
		||||
@@ -455,7 +454,8 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected HttpResponse put(String url, String entityId, String body, String queryString, int expectedStatus) throws Exception
 | 
			
		||||
    protected HttpResponse put(String url, String entityId, String body, String queryString, int expectedStatus)
 | 
			
		||||
            throws Exception
 | 
			
		||||
    {
 | 
			
		||||
        if (queryString != null)
 | 
			
		||||
        {
 | 
			
		||||
@@ -467,8 +467,8 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
 | 
			
		||||
        return response;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected HttpResponse putBinary(String url, int version, BinaryPayload payload, String queryString, Map<String, String> params,
 | 
			
		||||
                                     int expectedStatus) throws Exception
 | 
			
		||||
    protected HttpResponse putBinary(String url, int version, BinaryPayload payload, String queryString,
 | 
			
		||||
            Map<String, String> params, int expectedStatus) throws Exception
 | 
			
		||||
    {
 | 
			
		||||
        if (queryString != null)
 | 
			
		||||
        {
 | 
			
		||||
@@ -482,7 +482,7 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected HttpResponse putBinary(String url, BinaryPayload payload, String queryString, Map<String, String> params,
 | 
			
		||||
                                     int expectedStatus) throws Exception
 | 
			
		||||
            int expectedStatus) throws Exception
 | 
			
		||||
    {
 | 
			
		||||
        return putBinary(url, 1, payload, queryString, params, expectedStatus);
 | 
			
		||||
    }
 | 
			
		||||
@@ -492,18 +492,19 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
 | 
			
		||||
        return delete(url, entityId, null, expectedStatus);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected HttpResponse delete(String url, String entityId, Map<String, String> params, int expectedStatus) throws Exception
 | 
			
		||||
    protected HttpResponse delete(String url, String entityId, Map<String, String> params, int expectedStatus)
 | 
			
		||||
            throws Exception
 | 
			
		||||
    {
 | 
			
		||||
        HttpResponse response = publicApiClient.delete(getScope(), 1, url, entityId, null, null, params);
 | 
			
		||||
        checkStatus(expectedStatus, response.getStatusCode());
 | 
			
		||||
 | 
			
		||||
        return response;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    protected HttpResponse delete(String url, String entityId, Map<String, String> params, Map<String, String> headers, String apiName, int expectedStatus) throws Exception
 | 
			
		||||
 | 
			
		||||
    protected HttpResponse delete(String url, String entityId, Map<String, String> params, Map<String, String> headers,
 | 
			
		||||
            String apiName, int expectedStatus) throws Exception
 | 
			
		||||
    {
 | 
			
		||||
        RequestBuilder requestBuilder = httpClient.new DeleteRequestBuilder()
 | 
			
		||||
                .setRequestContext(publicApiClient.getRequestContext())
 | 
			
		||||
        RequestBuilder requestBuilder = httpClient.new DeleteRequestBuilder().setRequestContext(publicApiClient.getRequestContext())
 | 
			
		||||
                .setScope(getScope())
 | 
			
		||||
                .setApiName(apiName)
 | 
			
		||||
                .setEntityCollectionName(url)
 | 
			
		||||
@@ -524,7 +525,10 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
 | 
			
		||||
 | 
			
		||||
    protected String createUser(String usernameIn, String password, TestNetwork network)
 | 
			
		||||
    {
 | 
			
		||||
        return createUser(new PersonInfo(usernameIn, usernameIn, usernameIn, password, null, null, null, null, null, null, null), network);
 | 
			
		||||
        return createUser(
 | 
			
		||||
                new PersonInfo(usernameIn, usernameIn, usernameIn, password, null, null, null, null, null, null,
 | 
			
		||||
                        null),
 | 
			
		||||
                network);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -533,17 +537,16 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
 | 
			
		||||
    protected String createUser(final PersonInfo personInfo, final TestNetwork network)
 | 
			
		||||
    {
 | 
			
		||||
        final String tenantDomain = (network != null ? network.getId() : TenantService.DEFAULT_DOMAIN);
 | 
			
		||||
        
 | 
			
		||||
        return AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<String>()
 | 
			
		||||
        {
 | 
			
		||||
 | 
			
		||||
        return AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<String>() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public String doWork() throws Exception
 | 
			
		||||
            {
 | 
			
		||||
                return TenantUtil.runAsTenant(new TenantUtil.TenantRunAsWork<String>()
 | 
			
		||||
                {
 | 
			
		||||
                return TenantUtil.runAsTenant(new TenantUtil.TenantRunAsWork<String>() {
 | 
			
		||||
                    public String doWork() throws Exception
 | 
			
		||||
                    {
 | 
			
		||||
                        String username = repoService.getPublicApiContext().createUserName(personInfo.getUsername(), tenantDomain);
 | 
			
		||||
                        String username = repoService.getPublicApiContext()
 | 
			
		||||
                                .createUserName(personInfo.getUsername(), tenantDomain);
 | 
			
		||||
                        personInfo.setUsername(username);
 | 
			
		||||
                        RepoService.TestPerson person = repoService.createUser(personInfo, username, network);
 | 
			
		||||
                        return person.getId();
 | 
			
		||||
@@ -561,17 +564,17 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
 | 
			
		||||
    {
 | 
			
		||||
        final String tenantDomain = (network != null ? network.getId() : TenantService.DEFAULT_DOMAIN);
 | 
			
		||||
 | 
			
		||||
        return AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<String>()
 | 
			
		||||
        {
 | 
			
		||||
        return AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<String>() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public String doWork() throws Exception
 | 
			
		||||
            {
 | 
			
		||||
                return TenantUtil.runAsTenant(new TenantUtil.TenantRunAsWork<String>()
 | 
			
		||||
                {
 | 
			
		||||
                return TenantUtil.runAsTenant(new TenantUtil.TenantRunAsWork<String>() {
 | 
			
		||||
                    public String doWork() throws Exception
 | 
			
		||||
                    {
 | 
			
		||||
                        String username = repoService.getPublicApiContext().createUserName(usernameIn, tenantDomain);
 | 
			
		||||
                        PersonInfo personInfo = new PersonInfo(username, username, username, password, null, null, null, null, null, null, null);
 | 
			
		||||
                        String username = repoService.getPublicApiContext()
 | 
			
		||||
                                .createUserName(usernameIn, tenantDomain);
 | 
			
		||||
                        PersonInfo personInfo = new PersonInfo(username, username, username, password, null, null, null, null, null,
 | 
			
		||||
                                null, null);
 | 
			
		||||
                        RepoService.TestPerson person = repoService.getOrCreateUser(personInfo, username, network);
 | 
			
		||||
                        return person.getId();
 | 
			
		||||
                    }
 | 
			
		||||
@@ -587,13 +590,11 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
 | 
			
		||||
    {
 | 
			
		||||
        final String tenantDomain = (network != null ? network.getId() : TenantService.DEFAULT_DOMAIN);
 | 
			
		||||
 | 
			
		||||
        return AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<String>()
 | 
			
		||||
        {
 | 
			
		||||
        return AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<String>() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public String doWork() throws Exception
 | 
			
		||||
            {
 | 
			
		||||
                return TenantUtil.runAsTenant(new TenantUtil.TenantRunAsWork<String>()
 | 
			
		||||
                {
 | 
			
		||||
                return TenantUtil.runAsTenant(new TenantUtil.TenantRunAsWork<String>() {
 | 
			
		||||
                    public String doWork() throws Exception
 | 
			
		||||
                    {
 | 
			
		||||
                        repoService.deleteUser(username, network);
 | 
			
		||||
@@ -603,13 +604,15 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
 | 
			
		||||
            }
 | 
			
		||||
        }, networkAdmin);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    protected SiteMember addSiteMember(String siteId, String userId, final SiteRole siteRole) throws Exception
 | 
			
		||||
    {
 | 
			
		||||
        SiteMember siteMember = new SiteMember(userId, siteRole.name());
 | 
			
		||||
        HttpResponse response = publicApiClient.post(getScope(), "sites", siteId, "members", null, siteMember.toJSON().toString());
 | 
			
		||||
        HttpResponse response = publicApiClient.post(getScope(), "sites", siteId, "members", null, siteMember.toJSON()
 | 
			
		||||
                .toString());
 | 
			
		||||
        checkStatus(201, response.getStatusCode());
 | 
			
		||||
        return SiteMember.parseSiteMember(siteMember.getSiteId(), (JSONObject)response.getJsonResponse().get("entry"));
 | 
			
		||||
        return SiteMember.parseSiteMember(siteMember.getSiteId(), (JSONObject) response.getJsonResponse()
 | 
			
		||||
                .get("entry"));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected Site createSite(String siteTitle, SiteVisibility siteVisibility) throws Exception
 | 
			
		||||
@@ -617,7 +620,8 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
 | 
			
		||||
        return createSite(null, siteTitle, null, siteVisibility, 201);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected Site createSite(String siteId, String siteTitle, String siteDescription, SiteVisibility siteVisibility, int expectedStatus) throws Exception
 | 
			
		||||
    protected Site createSite(String siteId, String siteTitle, String siteDescription, SiteVisibility siteVisibility,
 | 
			
		||||
            int expectedStatus) throws Exception
 | 
			
		||||
    {
 | 
			
		||||
        Site site = new Site();
 | 
			
		||||
        site.setId(siteId);
 | 
			
		||||
@@ -633,7 +637,7 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
 | 
			
		||||
    protected HttpResponse deleteSite(String siteId, boolean permanent, int expectedStatus) throws Exception
 | 
			
		||||
    {
 | 
			
		||||
        Map params = null;
 | 
			
		||||
        if (permanent == true)
 | 
			
		||||
        if (permanent)
 | 
			
		||||
        {
 | 
			
		||||
            params = Collections.singletonMap("permanent", "true");
 | 
			
		||||
        }
 | 
			
		||||
@@ -655,14 +659,14 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
 | 
			
		||||
    protected String getSiteContainerNodeId(String siteId, String containerNameId) throws Exception
 | 
			
		||||
    {
 | 
			
		||||
        Map<String, String> params = Collections.singletonMap(Nodes.PARAM_RELATIVE_PATH, "/Sites/" + siteId + "/" + containerNameId);
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        HttpResponse response = publicApiClient.get(NodesEntityResource.class, Nodes.PATH_ROOT, null, params);
 | 
			
		||||
        checkStatus(200, response.getStatusCode());
 | 
			
		||||
 | 
			
		||||
        Node node = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Node.class);
 | 
			
		||||
        return node.getId();
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    protected void checkStatus(int expectedStatus, int actualStatus)
 | 
			
		||||
    {
 | 
			
		||||
        if (expectedStatus > 0 && expectedStatus != actualStatus)
 | 
			
		||||
@@ -672,9 +676,8 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @deprecated
 | 
			
		||||
     * 
 | 
			
		||||
     * @param runAsUser
 | 
			
		||||
     * @deprecated
 | 
			
		||||
     */
 | 
			
		||||
    protected void setRequestContext(String runAsUser)
 | 
			
		||||
    {
 | 
			
		||||
@@ -702,9 +705,9 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
 | 
			
		||||
        }
 | 
			
		||||
        else if ((runAsUser != null) && runAsUser.equals(DEFAULT_ADMIN))
 | 
			
		||||
        {
 | 
			
		||||
            runAsUser = runAsUser+"@"+runAsNetwork;
 | 
			
		||||
            runAsUser = runAsUser + "@" + runAsNetwork;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        publicApiClient.setRequestContext(new RequestContext(runAsNetwork, runAsUser, password));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -736,7 +739,7 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
 | 
			
		||||
    {
 | 
			
		||||
        return createFolder(parentId, folderName, null);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    protected Folder createFolder(String parentId, String folderName, Map<String, Object> props) throws Exception
 | 
			
		||||
    {
 | 
			
		||||
        return createNode(parentId, folderName, TYPE_CM_FOLDER, props, Folder.class);
 | 
			
		||||
@@ -750,17 +753,18 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
 | 
			
		||||
    protected String createUniqueContent(String folderId) throws Exception
 | 
			
		||||
    {
 | 
			
		||||
        Document documentResp = createTextFile(folderId, "file-" + System.currentTimeMillis(),
 | 
			
		||||
        "some text-" + System.currentTimeMillis(), "UTF-8", null);
 | 
			
		||||
                "some text-" + System.currentTimeMillis(), "UTF-8", null);
 | 
			
		||||
        return documentResp.getId();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected Node createNode(String parentId, String nodeName, String nodeType, Map<String, Object> props) throws Exception
 | 
			
		||||
    protected Node createNode(String parentId, String nodeName, String nodeType, Map<String, Object> props)
 | 
			
		||||
            throws Exception
 | 
			
		||||
    {
 | 
			
		||||
        return createNode(parentId, nodeName, nodeType, props, Node.class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected <T> T createNode(String parentId, String nodeName, String nodeType, Map<String, Object> props, Class<T> returnType)
 | 
			
		||||
                throws Exception
 | 
			
		||||
    protected <T> T createNode(String parentId, String nodeName, String nodeType, Map<String, Object> props,
 | 
			
		||||
            Class<T> returnType) throws Exception
 | 
			
		||||
    {
 | 
			
		||||
        Node n = new Node();
 | 
			
		||||
        n.setName(nodeName);
 | 
			
		||||
@@ -772,7 +776,7 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
 | 
			
		||||
 | 
			
		||||
        return RestApiUtil.parseRestApiEntry(response.getJsonResponse(), returnType);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    protected void deleteNode(String nodeId) throws Exception
 | 
			
		||||
    {
 | 
			
		||||
        deleteNode(nodeId, 204);
 | 
			
		||||
@@ -786,25 +790,27 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
 | 
			
		||||
    protected void deleteNode(String nodeId, boolean permanent, int expectedStatus) throws Exception
 | 
			
		||||
    {
 | 
			
		||||
        Map params = null;
 | 
			
		||||
        if (permanent == true)
 | 
			
		||||
        if (permanent)
 | 
			
		||||
        {
 | 
			
		||||
            params = Collections.singletonMap("permanent", "true");
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        delete(URL_NODES, nodeId, params, expectedStatus);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected Document createTextFile(String parentId, String fileName, String textContent) throws IOException, Exception
 | 
			
		||||
    protected Document createTextFile(String parentId, String fileName, String textContent) throws Exception
 | 
			
		||||
    {
 | 
			
		||||
        return createTextFile(parentId, fileName, textContent, "UTF-8", null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected Document createTextFile(String parentId, String fileName, String textContent, String encoding, Map<String, String> props) throws IOException, Exception
 | 
			
		||||
    protected Document createTextFile(String parentId, String fileName, String textContent, String encoding,
 | 
			
		||||
            Map<String, String> props) throws Exception
 | 
			
		||||
    {
 | 
			
		||||
        return createTextFile(parentId, fileName, textContent, encoding, props, 201);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected Document createTextFile(String parentId, String fileName, String textContent, String encoding, Map<String, String> props, int expectedStatus) throws IOException, Exception
 | 
			
		||||
    protected Document createTextFile(String parentId, String fileName, String textContent, String encoding,
 | 
			
		||||
            Map<String, String> props, int expectedStatus) throws Exception
 | 
			
		||||
    {
 | 
			
		||||
        if (props == null)
 | 
			
		||||
        {
 | 
			
		||||
@@ -820,9 +826,11 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
 | 
			
		||||
                .setProperties(props)
 | 
			
		||||
                .build();
 | 
			
		||||
 | 
			
		||||
        HttpResponse response = post(getNodeChildrenUrl(parentId), reqBody.getBody(), null, reqBody.getContentType(), expectedStatus);
 | 
			
		||||
        HttpResponse response = post(getNodeChildrenUrl(parentId), reqBody.getBody(), null, reqBody.getContentType(),
 | 
			
		||||
                expectedStatus);
 | 
			
		||||
 | 
			
		||||
        if (response.getJsonResponse().get("error") != null)
 | 
			
		||||
        if (response.getJsonResponse()
 | 
			
		||||
                .get("error") != null)
 | 
			
		||||
        {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
@@ -834,8 +842,9 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
 | 
			
		||||
    {
 | 
			
		||||
        return createEmptyTextFile(parentFolderId, docName, null, 201);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    protected Document createEmptyTextFile(String parentFolderId, String docName, Map<String, String> params, int expectedStatus) throws Exception
 | 
			
		||||
 | 
			
		||||
    protected Document createEmptyTextFile(String parentFolderId, String docName, Map<String, String> params,
 | 
			
		||||
            int expectedStatus) throws Exception
 | 
			
		||||
    {
 | 
			
		||||
        Document d1 = new Document();
 | 
			
		||||
        d1.setName(docName);
 | 
			
		||||
@@ -845,7 +854,8 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
 | 
			
		||||
        d1.setContent(ci);
 | 
			
		||||
 | 
			
		||||
        // create empty file
 | 
			
		||||
        HttpResponse response = post(getNodeChildrenUrl(parentFolderId), toJsonAsStringNonNull(d1), params, null, "alfresco", expectedStatus);
 | 
			
		||||
        HttpResponse response = post(getNodeChildrenUrl(parentFolderId), toJsonAsStringNonNull(d1), params, null, "alfresco",
 | 
			
		||||
                expectedStatus);
 | 
			
		||||
        if (expectedStatus != 201)
 | 
			
		||||
        {
 | 
			
		||||
            return null;
 | 
			
		||||
@@ -858,7 +868,8 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
 | 
			
		||||
        return updateTextFile(contentId, textContent, params, 200);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected Document updateTextFile(String contentId, String textContent, Map<String, String> params, int expectedStatus) throws Exception
 | 
			
		||||
    protected Document updateTextFile(String contentId, String textContent, Map<String, String> params,
 | 
			
		||||
            int expectedStatus) throws Exception
 | 
			
		||||
    {
 | 
			
		||||
        ByteArrayInputStream inputStream = new ByteArrayInputStream(textContent.getBytes());
 | 
			
		||||
        File txtFile = TempFileProvider.createTempFile(inputStream, getClass().getSimpleName(), ".txt");
 | 
			
		||||
@@ -874,7 +885,8 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
 | 
			
		||||
 | 
			
		||||
    protected File getResourceFile(String fileName) throws FileNotFoundException
 | 
			
		||||
    {
 | 
			
		||||
        URL url = NodeApiTest.class.getClassLoader().getResource(RESOURCE_PREFIX + fileName);
 | 
			
		||||
        URL url = NodeApiTest.class.getClassLoader()
 | 
			
		||||
                .getResource(RESOURCE_PREFIX + fileName);
 | 
			
		||||
        if (url == null)
 | 
			
		||||
        {
 | 
			
		||||
            fail("Cannot get the resource: " + fileName);
 | 
			
		||||
@@ -907,14 +919,15 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
 | 
			
		||||
     * @return
 | 
			
		||||
     * @throws Exception
 | 
			
		||||
     */
 | 
			
		||||
    protected String updateFileVersions(String userId, String contentNodeId, int cnt,
 | 
			
		||||
                                      String textContentPrefix, int verCnt,
 | 
			
		||||
                                      Boolean majorVersion, String currentVersionLabel) throws Exception
 | 
			
		||||
    protected String updateFileVersions(String userId, String contentNodeId, int cnt, String textContentPrefix,
 | 
			
		||||
            int verCnt, Boolean majorVersion, String currentVersionLabel) throws Exception
 | 
			
		||||
    {
 | 
			
		||||
        String[] parts = currentVersionLabel.split("\\.");
 | 
			
		||||
 | 
			
		||||
        int majorVer = Integer.valueOf(parts[0]).intValue();
 | 
			
		||||
        int minorVer = Integer.valueOf(parts[1]).intValue();
 | 
			
		||||
        int majorVer = Integer.valueOf(parts[0])
 | 
			
		||||
                .intValue();
 | 
			
		||||
        int minorVer = Integer.valueOf(parts[1])
 | 
			
		||||
                .intValue();
 | 
			
		||||
 | 
			
		||||
        Map<String, String> params = new HashMap<>();
 | 
			
		||||
        params.put(Nodes.PARAM_OVERWRITE, "true");
 | 
			
		||||
@@ -928,7 +941,6 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
 | 
			
		||||
            majorVersion = false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        if (majorVersion)
 | 
			
		||||
        {
 | 
			
		||||
            minorVer = 0;
 | 
			
		||||
@@ -961,30 +973,33 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
 | 
			
		||||
            HttpResponse response = putBinary(getNodeContentUrl(contentNodeId), payload, null, params, 200);
 | 
			
		||||
            Node nodeResp = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Node.class);
 | 
			
		||||
 | 
			
		||||
            assertTrue(nodeResp.getAspectNames().contains("cm:versionable"));
 | 
			
		||||
            assertTrue(nodeResp.getAspectNames()
 | 
			
		||||
                    .contains("cm:versionable"));
 | 
			
		||||
            assertNotNull(nodeResp.getProperties());
 | 
			
		||||
            assertEquals(currentVersionLabel, nodeResp.getProperties().get("cm:versionLabel"));
 | 
			
		||||
            assertEquals((majorVersion ? "MAJOR" : "MINOR"), nodeResp.getProperties().get("cm:versionType"));
 | 
			
		||||
            assertEquals(currentVersionLabel, nodeResp.getProperties()
 | 
			
		||||
                    .get("cm:versionLabel"));
 | 
			
		||||
            assertEquals((majorVersion ? "MAJOR" : "MINOR"), nodeResp.getProperties()
 | 
			
		||||
                    .get("cm:versionType"));
 | 
			
		||||
 | 
			
		||||
            // double-check - get version node info
 | 
			
		||||
            response = getSingle(getNodeVersionsUrl(contentNodeId), currentVersionLabel, null, 200);
 | 
			
		||||
            nodeResp = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Node.class);
 | 
			
		||||
            assertEquals(currentVersionLabel, nodeResp.getProperties().get("cm:versionLabel"));
 | 
			
		||||
            assertEquals((majorVersion ? "MAJOR" : "MINOR"), nodeResp.getProperties().get("cm:versionType"));
 | 
			
		||||
            assertEquals(currentVersionLabel, nodeResp.getProperties()
 | 
			
		||||
                    .get("cm:versionLabel"));
 | 
			
		||||
            assertEquals((majorVersion ? "MAJOR" : "MINOR"), nodeResp.getProperties()
 | 
			
		||||
                    .get("cm:versionType"));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return currentVersionLabel;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected static final long PAUSE_TIME = 5000; //millisecond
 | 
			
		||||
    protected static final int MAX_RETRY = 20;
 | 
			
		||||
 | 
			
		||||
    protected Rendition waitAndGetRendition(String sourceNodeId, String versionId, String renditionId) throws Exception
 | 
			
		||||
    {
 | 
			
		||||
        return waitAndGetRendition(sourceNodeId, versionId, renditionId, MAX_RETRY, PAUSE_TIME);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected Rendition waitAndGetRendition(String sourceNodeId, String versionId, String renditionId, int maxRetry, long pauseTime) throws Exception
 | 
			
		||||
    protected Rendition waitAndGetRendition(String sourceNodeId, String versionId, String renditionId, int maxRetry,
 | 
			
		||||
            long pauseTime) throws Exception
 | 
			
		||||
    {
 | 
			
		||||
        int retryCount = 0;
 | 
			
		||||
        while (retryCount < maxRetry)
 | 
			
		||||
@@ -992,7 +1007,7 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                HttpResponse response;
 | 
			
		||||
                if ((versionId != null) && (! versionId.isEmpty()))
 | 
			
		||||
                if ((versionId != null) && (!versionId.isEmpty()))
 | 
			
		||||
                {
 | 
			
		||||
                    response = getSingle(getNodeVersionRenditionsUrl(sourceNodeId, versionId), renditionId, 200);
 | 
			
		||||
                }
 | 
			
		||||
@@ -1011,7 +1026,7 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
 | 
			
		||||
                // wait for 'PAUSE_TIME' and try again.
 | 
			
		||||
                retryCount++;
 | 
			
		||||
 | 
			
		||||
                System.out.println("waitAndGetRendition: "+retryCount);
 | 
			
		||||
                System.out.println("waitAndGetRendition: " + retryCount);
 | 
			
		||||
                Thread.sleep(pauseTime);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@@ -1024,7 +1039,8 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
 | 
			
		||||
        return createAndGetRendition(sourceNodeId, null, renditionId);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected Rendition createAndGetRendition(String sourceNodeId, String versionId, String renditionId) throws Exception
 | 
			
		||||
    protected Rendition createAndGetRendition(String sourceNodeId, String versionId, String renditionId)
 | 
			
		||||
            throws Exception
 | 
			
		||||
    {
 | 
			
		||||
        Rendition renditionRequest = new Rendition();
 | 
			
		||||
        renditionRequest.setId(renditionId);
 | 
			
		||||
@@ -1035,9 +1051,10 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                HttpResponse response;
 | 
			
		||||
                if ((versionId != null) && (! versionId.isEmpty()))
 | 
			
		||||
                if ((versionId != null) && (!versionId.isEmpty()))
 | 
			
		||||
                {
 | 
			
		||||
                    response = post(getNodeVersionRenditionsUrl(sourceNodeId, versionId), toJsonAsString(renditionRequest), 202);
 | 
			
		||||
                    response = post(getNodeVersionRenditionsUrl(sourceNodeId, versionId),
 | 
			
		||||
                            toJsonAsString(renditionRequest), 202);
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
@@ -1052,7 +1069,7 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
 | 
			
		||||
                // wait for 'PAUSE_TIME' and try again.
 | 
			
		||||
                retryCount++;
 | 
			
		||||
 | 
			
		||||
                System.out.println("waitAndGetRendition: "+retryCount);
 | 
			
		||||
                System.out.println("waitAndGetRendition: " + retryCount);
 | 
			
		||||
                Thread.sleep(PAUSE_TIME);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@@ -1072,7 +1089,8 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
 | 
			
		||||
 | 
			
		||||
    protected String getNodeVersionRenditionIdUrl(String nodeId, String versionId, String renditionID)
 | 
			
		||||
    {
 | 
			
		||||
        return URL_NODES + "/" + nodeId + "/" + URL_VERSIONS + "/" + versionId + "/" + URL_RENDITIONS + "/" + renditionID;
 | 
			
		||||
        return URL_NODES + "/" + nodeId + "/" + URL_VERSIONS + "/" + versionId + "/" + URL_RENDITIONS + "/"
 | 
			
		||||
                + renditionID;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected String getNodeVersionsUrl(String nodeId)
 | 
			
		||||
@@ -1120,5 +1138,14 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
 | 
			
		||||
        RestApiDirectUrlConfig restDauConfig = (RestApiDirectUrlConfig) applicationContext.getBean("restApiDirectUrlConfig");
 | 
			
		||||
        restDauConfig.setEnabled(false);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
    protected String generateNodeSizeDetailsUrl(String nodeId)
 | 
			
		||||
    {
 | 
			
		||||
        return URL_NODES + "/" + nodeId + "/" + URL_CALCULATEFOLDERSIZE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected String getNodeSizeDetailsUrl(String nodeId, String jobId)
 | 
			
		||||
    {
 | 
			
		||||
        return URL_NODES + "/" + nodeId + "/" + URL_CALCULATEFOLDERSIZE + "/" + jobId;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,41 @@
 | 
			
		||||
/*
 | 
			
		||||
 * #%L
 | 
			
		||||
 * Alfresco Remote API
 | 
			
		||||
 * %%
 | 
			
		||||
 * Copyright (C) 2005 - 2024 Alfresco Software Limited
 | 
			
		||||
 * %%
 | 
			
		||||
 * This file is part of the Alfresco software.
 | 
			
		||||
 * If the software was purchased under a paid Alfresco license, the terms of
 | 
			
		||||
 * the paid license agreement will prevail.  Otherwise, the software is
 | 
			
		||||
 * provided under the following open source license terms:
 | 
			
		||||
 *
 | 
			
		||||
 * Alfresco is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU Lesser General Public License as published by
 | 
			
		||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * Alfresco is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 * #L%
 | 
			
		||||
 */
 | 
			
		||||
package org.alfresco.repo.node.sizedetails;
 | 
			
		||||
 | 
			
		||||
import java.util.Optional;
 | 
			
		||||
 | 
			
		||||
import org.alfresco.repo.node.sizedetails.NodeSizeDetailsServiceImpl.NodeSizeDetails;
 | 
			
		||||
import org.alfresco.service.cmr.repository.NodeRef;
 | 
			
		||||
 | 
			
		||||
public interface NodeSizeDetailsService
 | 
			
		||||
{
 | 
			
		||||
    void invokeSizeDetailsExecutor(NodeRef nodeRef, String jobId);
 | 
			
		||||
 | 
			
		||||
    void putSizeDetails(String id, NodeSizeDetails nodeSizeDetails);
 | 
			
		||||
 | 
			
		||||
    Optional<NodeSizeDetails> getSizeDetails(String id);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,402 @@
 | 
			
		||||
/*
 | 
			
		||||
 * #%L
 | 
			
		||||
 * Alfresco Repository
 | 
			
		||||
 * %%
 | 
			
		||||
 * Copyright (C) 2005 - 2024 Alfresco Software Limited
 | 
			
		||||
 * %%
 | 
			
		||||
 * This file is part of the Alfresco software.
 | 
			
		||||
 * If the software was purchased under a paid Alfresco license, the terms of
 | 
			
		||||
 * the paid license agreement will prevail.  Otherwise, the software is
 | 
			
		||||
 * provided under the following open source license terms:
 | 
			
		||||
 *
 | 
			
		||||
 * Alfresco is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU Lesser General Public License as published by
 | 
			
		||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * Alfresco is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 * #L%
 | 
			
		||||
 */
 | 
			
		||||
package org.alfresco.repo.node.sizedetails;
 | 
			
		||||
 | 
			
		||||
import java.io.Serializable;
 | 
			
		||||
import java.util.Date;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
import java.util.Optional;
 | 
			
		||||
import java.util.concurrent.ThreadPoolExecutor;
 | 
			
		||||
 | 
			
		||||
import org.slf4j.Logger;
 | 
			
		||||
import org.slf4j.LoggerFactory;
 | 
			
		||||
import org.springframework.beans.factory.InitializingBean;
 | 
			
		||||
 | 
			
		||||
import org.alfresco.repo.cache.SimpleCache;
 | 
			
		||||
import org.alfresco.repo.node.sizedetails.NodeSizeDetailsServiceImpl.NodeSizeDetails.STATUS;
 | 
			
		||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
 | 
			
		||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
 | 
			
		||||
import org.alfresco.service.cmr.repository.NodeRef;
 | 
			
		||||
import org.alfresco.service.cmr.repository.StoreRef;
 | 
			
		||||
import org.alfresco.service.cmr.search.ResultSet;
 | 
			
		||||
import org.alfresco.service.cmr.search.SearchParameters;
 | 
			
		||||
import org.alfresco.service.cmr.search.SearchParameters.FieldFacet;
 | 
			
		||||
import org.alfresco.service.cmr.search.SearchService;
 | 
			
		||||
import org.alfresco.service.transaction.TransactionService;
 | 
			
		||||
import org.alfresco.util.Pair;
 | 
			
		||||
import org.alfresco.util.ParameterCheck;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * NodeSizeDetailsServiceImpl Executing Alfresco FTS Query to find size details of Folder Node
 | 
			
		||||
 */
 | 
			
		||||
public class NodeSizeDetailsServiceImpl implements NodeSizeDetailsService, InitializingBean
 | 
			
		||||
{
 | 
			
		||||
    private static final Logger LOG = LoggerFactory.getLogger(NodeSizeDetailsServiceImpl.class);
 | 
			
		||||
    private static final String FIELD_FACET = "content.size";
 | 
			
		||||
    private static final String FACET_QUERY = "content.size:[0 TO " + Integer.MAX_VALUE + "] \"label\": \"large\",\"group\":\"Size\"";
 | 
			
		||||
    private SearchService searchService;
 | 
			
		||||
    private SimpleCache<Serializable, NodeSizeDetails> simpleCache;
 | 
			
		||||
    private TransactionService transactionService;
 | 
			
		||||
    private ThreadPoolExecutor threadPoolExecutor;
 | 
			
		||||
    private int defaultItems;
 | 
			
		||||
 | 
			
		||||
    public void setSearchService(SearchService searchService)
 | 
			
		||||
    {
 | 
			
		||||
        this.searchService = searchService;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Optional<NodeSizeDetails> getSizeDetails(String id)
 | 
			
		||||
    {
 | 
			
		||||
        NodeSizeDetails details = simpleCache.get(id);
 | 
			
		||||
        return Optional.ofNullable(details)
 | 
			
		||||
                .or(() -> {
 | 
			
		||||
                    LOG.error("No Size details found for ID: " + id);
 | 
			
		||||
                    return Optional.empty();
 | 
			
		||||
                });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setSimpleCache(SimpleCache<Serializable, NodeSizeDetails> simpleCache)
 | 
			
		||||
    {
 | 
			
		||||
        this.simpleCache = simpleCache;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setTransactionService(TransactionService transactionService)
 | 
			
		||||
    {
 | 
			
		||||
        this.transactionService = transactionService;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setThreadPoolExecutor(ThreadPoolExecutor threadPoolExecutor)
 | 
			
		||||
    {
 | 
			
		||||
        this.threadPoolExecutor = threadPoolExecutor;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setDefaultItems(int defaultItems)
 | 
			
		||||
    {
 | 
			
		||||
        this.defaultItems = defaultItems;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void invokeSizeDetailsExecutor(NodeRef nodeRef, String jobId)
 | 
			
		||||
    {
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            executeSizeCalculation(nodeRef, jobId);
 | 
			
		||||
        }
 | 
			
		||||
        catch (Exception e)
 | 
			
		||||
        {
 | 
			
		||||
            LOG.error("Exception occurred while executing invokeSizeDetailsExecutor method ", e);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void putSizeDetails(String id, NodeSizeDetails nodeSizeDetails)
 | 
			
		||||
    {
 | 
			
		||||
        simpleCache.put(id, nodeSizeDetails);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void executeSizeCalculation(NodeRef nodeRef, String jobId)
 | 
			
		||||
    {
 | 
			
		||||
        String authenticatedUserName = AuthenticationUtil.getFullyAuthenticatedUser();
 | 
			
		||||
        RetryingTransactionCallback<NodeSizeDetails> executionCallback = () -> {
 | 
			
		||||
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                return calculateTotalSizeFromFacet(nodeRef, jobId);
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception ex)
 | 
			
		||||
            {
 | 
			
		||||
                LOG.error("Exception occurred in executeSizeCalculation:RetryingTransactionCallback ", ex);
 | 
			
		||||
                throw ex;
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        threadPoolExecutor.execute(() -> {
 | 
			
		||||
            NodeSizeDetails nodeSizeDetails = new NodeSizeDetails(nodeRef.getId(), jobId, STATUS.IN_PROGRESS);
 | 
			
		||||
            putSizeDetails(nodeRef.getId(), nodeSizeDetails);
 | 
			
		||||
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                nodeSizeDetails = AuthenticationUtil.runAs(() -> transactionService.getRetryingTransactionHelper()
 | 
			
		||||
                        .doInTransaction(executionCallback, true), authenticatedUserName);
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception e)
 | 
			
		||||
            {
 | 
			
		||||
                LOG.error("Exception occurred in executeSizeCalculation", e);
 | 
			
		||||
                nodeSizeDetails = new NodeSizeDetails(nodeRef.getId(), 0L, jobId, STATUS.FAILED);
 | 
			
		||||
            }
 | 
			
		||||
            finally
 | 
			
		||||
            {
 | 
			
		||||
                putSizeDetails(nodeRef.getId(), nodeSizeDetails);
 | 
			
		||||
                AuthenticationUtil.clearCurrentSecurityContext();
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private NodeSizeDetails calculateTotalSizeFromFacet(NodeRef nodeRef, String jobId)
 | 
			
		||||
    {
 | 
			
		||||
        long totalSizeFromFacet = 0;
 | 
			
		||||
        int skipCount = 0;
 | 
			
		||||
        int totalItems = defaultItems;
 | 
			
		||||
        boolean isCalculationCompleted = false;
 | 
			
		||||
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            ResultSet results = facetQuery(nodeRef);
 | 
			
		||||
            int resultsSize = results.getFieldFacet(FIELD_FACET)
 | 
			
		||||
                    .size();
 | 
			
		||||
 | 
			
		||||
            while (!isCalculationCompleted)
 | 
			
		||||
            {
 | 
			
		||||
                List<Pair<String, Integer>> facetPairs = results.getFieldFacet(FIELD_FACET)
 | 
			
		||||
                        .subList(skipCount, Math.min(totalItems, resultsSize));
 | 
			
		||||
                totalSizeFromFacet += facetPairs.parallelStream()
 | 
			
		||||
                        .mapToLong(pair -> Long.parseLong(pair.getFirst()) * pair.getSecond())
 | 
			
		||||
                        .sum();
 | 
			
		||||
 | 
			
		||||
                if (resultsSize <= totalItems || resultsSize <= defaultItems)
 | 
			
		||||
                {
 | 
			
		||||
                    isCalculationCompleted = true;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    skipCount += defaultItems;
 | 
			
		||||
                    resultsSize -= totalItems;
 | 
			
		||||
                    totalItems += Math.min(resultsSize, defaultItems);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            Date calculationDate = new Date(System.currentTimeMillis());
 | 
			
		||||
            NodeSizeDetails nodeSizeDetails = new NodeSizeDetails(nodeRef.getId(), totalSizeFromFacet, calculationDate,
 | 
			
		||||
                    results.getNodeRefs()
 | 
			
		||||
                            .size(),
 | 
			
		||||
                    STATUS.COMPLETED, jobId);
 | 
			
		||||
            return nodeSizeDetails;
 | 
			
		||||
        }
 | 
			
		||||
        catch (Exception e)
 | 
			
		||||
        {
 | 
			
		||||
            LOG.error("Exception occurred while calculating total size from facet", e);
 | 
			
		||||
            throw e;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private ResultSet facetQuery(NodeRef nodeRef)
 | 
			
		||||
    {
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            SearchParameters searchParameters = createSearchParameters(nodeRef);
 | 
			
		||||
            ResultSet resultsWithoutFacet = searchService.query(searchParameters);
 | 
			
		||||
            if (LOG.isDebugEnabled())
 | 
			
		||||
            {
 | 
			
		||||
                LOG.debug(" After Executing facet query, no. of records found " + resultsWithoutFacet.getNumberFound());
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            searchParameters.addFacetQuery(FACET_QUERY);
 | 
			
		||||
            FieldFacet fieldFacet = new FieldFacet(FIELD_FACET);
 | 
			
		||||
            fieldFacet.setLimitOrNull((int) resultsWithoutFacet.getNumberFound());
 | 
			
		||||
            searchParameters.addFieldFacet(fieldFacet);
 | 
			
		||||
            resultsWithoutFacet.close();
 | 
			
		||||
            return searchService.query(searchParameters);
 | 
			
		||||
        }
 | 
			
		||||
        catch (Exception e)
 | 
			
		||||
        {
 | 
			
		||||
            LOG.error("Exception occurred while executing facetQuery ", e);
 | 
			
		||||
            throw e;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private SearchParameters createSearchParameters(NodeRef nodeRef)
 | 
			
		||||
    {
 | 
			
		||||
        SearchParameters searchParameters = new SearchParameters();
 | 
			
		||||
        searchParameters.addStore(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE);
 | 
			
		||||
        searchParameters.setLanguage(SearchService.LANGUAGE_FTS_ALFRESCO);
 | 
			
		||||
        searchParameters.setQuery("ANCESTOR:\"" + nodeRef + "\" AND TYPE:content");
 | 
			
		||||
        searchParameters.setTrackTotalHits(-1);
 | 
			
		||||
        return searchParameters;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void afterPropertiesSet() throws Exception
 | 
			
		||||
    {
 | 
			
		||||
        ParameterCheck.mandatory("searchService", this.searchService);
 | 
			
		||||
        ParameterCheck.mandatory("simpleCache", this.simpleCache);
 | 
			
		||||
        ParameterCheck.mandatory("transactionService", this.transactionService);
 | 
			
		||||
        ParameterCheck.mandatory("threadPoolExecutor", this.threadPoolExecutor);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * POJO class to hold node size details.
 | 
			
		||||
     */
 | 
			
		||||
    public static class NodeSizeDetails implements Serializable
 | 
			
		||||
    {
 | 
			
		||||
        private static final long serialVersionUID = 1L;
 | 
			
		||||
        private String id;
 | 
			
		||||
        private Long sizeInBytes;
 | 
			
		||||
        private Date calculatedAt;
 | 
			
		||||
        private Integer numberOfFiles;
 | 
			
		||||
        private String jobId;
 | 
			
		||||
        private STATUS status;
 | 
			
		||||
 | 
			
		||||
        public NodeSizeDetails()
 | 
			
		||||
        {}
 | 
			
		||||
 | 
			
		||||
        public NodeSizeDetails(String jobId)
 | 
			
		||||
        {
 | 
			
		||||
            this.jobId = jobId;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public NodeSizeDetails(String id, STATUS status)
 | 
			
		||||
        {
 | 
			
		||||
            this.id = id;
 | 
			
		||||
            this.status = status;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public NodeSizeDetails(String id, String jobId, STATUS status)
 | 
			
		||||
        {
 | 
			
		||||
            this.id = id;
 | 
			
		||||
            this.jobId = jobId;
 | 
			
		||||
            this.status = status;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public NodeSizeDetails(String id, Long sizeInBytes, String jobId, STATUS status)
 | 
			
		||||
        {
 | 
			
		||||
            this.id = id;
 | 
			
		||||
            this.sizeInBytes = sizeInBytes;
 | 
			
		||||
            this.jobId = jobId;
 | 
			
		||||
            this.status = status;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public NodeSizeDetails(String id, Long sizeInBytes, Date calculatedAt, Integer numberOfFiles,
 | 
			
		||||
                STATUS currentStatus, String jobId)
 | 
			
		||||
        {
 | 
			
		||||
            this.id = id;
 | 
			
		||||
            this.sizeInBytes = sizeInBytes;
 | 
			
		||||
            this.calculatedAt = calculatedAt;
 | 
			
		||||
            this.numberOfFiles = numberOfFiles;
 | 
			
		||||
            this.status = currentStatus;
 | 
			
		||||
            this.jobId = jobId;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public String getId()
 | 
			
		||||
        {
 | 
			
		||||
            return id;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void setId(String id)
 | 
			
		||||
        {
 | 
			
		||||
            this.id = id;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Long getSizeInBytes()
 | 
			
		||||
        {
 | 
			
		||||
            return sizeInBytes;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void setSizeInBytes(Long sizeInBytes)
 | 
			
		||||
        {
 | 
			
		||||
            this.sizeInBytes = sizeInBytes;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Date getCalculatedAt()
 | 
			
		||||
        {
 | 
			
		||||
            return calculatedAt;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void setCalculatedAt(Date calculatedAt)
 | 
			
		||||
        {
 | 
			
		||||
            this.calculatedAt = calculatedAt;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Integer getNumberOfFiles()
 | 
			
		||||
        {
 | 
			
		||||
            return numberOfFiles;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void setNumberOfFiles(Integer numberOfFiles)
 | 
			
		||||
        {
 | 
			
		||||
            this.numberOfFiles = numberOfFiles;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public String getJobId()
 | 
			
		||||
        {
 | 
			
		||||
            return jobId;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void setJobId(String jobId)
 | 
			
		||||
        {
 | 
			
		||||
            this.jobId = jobId;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public STATUS getStatus()
 | 
			
		||||
        {
 | 
			
		||||
            return status;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void setStatus(STATUS status)
 | 
			
		||||
        {
 | 
			
		||||
            this.status = status;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public boolean equals(Object o)
 | 
			
		||||
        {
 | 
			
		||||
            if (this == o)
 | 
			
		||||
            {
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
            if (o == null || getClass() != o.getClass())
 | 
			
		||||
            {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
            NodeSizeDetails that = (NodeSizeDetails) o;
 | 
			
		||||
            return Objects.equals(id, that.id) && Objects.equals(sizeInBytes, that.sizeInBytes) && Objects.equals(
 | 
			
		||||
                    calculatedAt, that.calculatedAt) && Objects.equals(numberOfFiles, that.numberOfFiles)
 | 
			
		||||
                    && Objects.equals(jobId, that.jobId) && status == that.status;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public int hashCode()
 | 
			
		||||
        {
 | 
			
		||||
            return Objects.hash(id, sizeInBytes, calculatedAt, numberOfFiles, jobId, status);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public String toString()
 | 
			
		||||
        {
 | 
			
		||||
            return "NodeSizeDetails{" + "id='" + id + '\'' + ", sizeInBytes=" + sizeInBytes + ", calculatedAt="
 | 
			
		||||
                    + calculatedAt + ", numberOfFiles=" + numberOfFiles + ", jobId='" + jobId + '\'' + ", status="
 | 
			
		||||
                    + status + '}';
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public enum STATUS
 | 
			
		||||
        {
 | 
			
		||||
            NOT_INITIATED, PENDING, IN_PROGRESS, COMPLETED, FAILED
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -514,4 +514,10 @@
 | 
			
		||||
    <bean name="ldapInitialDirContextCache" factory-bean="cacheFactory" factory-method="createCache">
 | 
			
		||||
        <constructor-arg value="cache.ldapInitialDirContextCache"/>
 | 
			
		||||
    </bean>
 | 
			
		||||
 | 
			
		||||
   <!-- The shared cache for Folder Node -->
 | 
			
		||||
   <bean name="folderSizeSharedCache" factory-bean="cacheFactory" factory-method="createCache">
 | 
			
		||||
      <constructor-arg value="cache.folderSizeSharedCache"/>
 | 
			
		||||
   </bean>
 | 
			
		||||
 | 
			
		||||
</beans>
 | 
			
		||||
 
 | 
			
		||||
@@ -710,3 +710,12 @@ cache.ldapInitialDirContextCache.backup-count=1
 | 
			
		||||
cache.ldapInitialDirContextCache.eviction-policy=NONE
 | 
			
		||||
cache.ldapInitialDirContextCache.merge-policy=com.hazelcast.spi.merge.LatestUpdateMergePolicy
 | 
			
		||||
cache.ldapInitialDirContextCache.readBackupData=false
 | 
			
		||||
 | 
			
		||||
cache.folderSizeSharedCache.maxItems=1000
 | 
			
		||||
cache.folderSizeSharedCache.timeToLiveSeconds=300
 | 
			
		||||
cache.folderSizeSharedCache.maxIdleSeconds=0
 | 
			
		||||
cache.folderSizeSharedCache.cluster.type=fully-distributed
 | 
			
		||||
cache.folderSizeSharedCache.backup-count=1
 | 
			
		||||
cache.folderSizeSharedCache.eviction-policy=LRU
 | 
			
		||||
cache.folderSizeSharedCache.merge-policy=com.hazelcast.spi.merge.PutIfAbsentMergePolicy
 | 
			
		||||
cache.folderSizeSharedCache.readBackupData=false
 | 
			
		||||
@@ -330,6 +330,42 @@
 | 
			
		||||
        <property name="nodeService" ref="nodeService"/>
 | 
			
		||||
        <property name="policyComponent" ref="policyComponent"/>
 | 
			
		||||
        <property name="searchTrackingComponent" ref="searchTrackingComponent" />
 | 
			
		||||
    </bean>   
 | 
			
		||||
    </bean>
 | 
			
		||||
 | 
			
		||||
    <bean id="nodeSizeThreadPool" class="org.alfresco.util.ThreadPoolExecutorFactoryBean">
 | 
			
		||||
        <property name="poolName">
 | 
			
		||||
            <value>defaultThreadPool</value>
 | 
			
		||||
        </property>
 | 
			
		||||
        <property name="corePoolSize">
 | 
			
		||||
            <value>${default.nodeSize.corePoolSize}</value>
 | 
			
		||||
        </property>
 | 
			
		||||
        <property name="maximumPoolSize">
 | 
			
		||||
            <value>${default.nodeSize.maximumPoolSize}</value>
 | 
			
		||||
        </property>
 | 
			
		||||
        <property name="workQueueSize">
 | 
			
		||||
            <value>${default.nodeSize.workQueueSize}</value>
 | 
			
		||||
        </property>
 | 
			
		||||
    </bean>
 | 
			
		||||
 | 
			
		||||
    <bean id="NodeSizeDetailsServiceImpl" class="org.alfresco.repo.node.sizedetails.NodeSizeDetailsServiceImpl">
 | 
			
		||||
        <property name="searchService" ref="SearchService"/>
 | 
			
		||||
        <property name="simpleCache" ref="folderSizeSharedCache" />
 | 
			
		||||
        <property name="transactionService" ref="transactionService"/>
 | 
			
		||||
        <property name="threadPoolExecutor">
 | 
			
		||||
            <ref bean="nodeSizeThreadPool"/>
 | 
			
		||||
        </property>
 | 
			
		||||
        <property name="defaultItems" value="${default.async.folder.items}"/>
 | 
			
		||||
    </bean>
 | 
			
		||||
 | 
			
		||||
    <bean id="NodeSizeDetailsService" class="org.springframework.aop.framework.ProxyFactoryBean" >
 | 
			
		||||
        <property name="targetName">
 | 
			
		||||
            <value>NodeSizeDetailsServiceImpl</value>
 | 
			
		||||
        </property>
 | 
			
		||||
        <property name="proxyInterfaces">
 | 
			
		||||
            <list>
 | 
			
		||||
                <value>org.alfresco.repo.node.sizedetails.NodeSizeDetailsService</value>
 | 
			
		||||
            </list>
 | 
			
		||||
        </property>
 | 
			
		||||
    </bean>
 | 
			
		||||
       
 | 
			
		||||
</beans>
 | 
			
		||||
 
 | 
			
		||||
@@ -1385,3 +1385,12 @@ scripts.execution.maxMemoryUsedInBytes=-1
 | 
			
		||||
 | 
			
		||||
# Number of instructions that will trigger the observer
 | 
			
		||||
scripts.execution.observerInstructionCount=5000
 | 
			
		||||
 | 
			
		||||
# Default value being used in POST/size-details endpoint to partition a huge folder into smaller chunks
 | 
			
		||||
# so that we can compute more efficiently and consolidate all sizes into a single unit.
 | 
			
		||||
default.async.folder.items=1000
 | 
			
		||||
 | 
			
		||||
# Default NodeSize Thread pool
 | 
			
		||||
default.nodeSize.corePoolSize=5
 | 
			
		||||
default.nodeSize.maximumPoolSize=10
 | 
			
		||||
default.nodeSize.workQueueSize=100
 | 
			
		||||
		Reference in New Issue
	
	Block a user