/* Copyright [2013-2014] eBay Software Foundation Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /** * */ /* Copyright 2012 eBay Software Foundation Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package com.ebay.cloud.cms.dal.persistence; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Ignore; import org.junit.Test; import com.ebay.cloud.cms.consts.CMSConsts; import com.ebay.cloud.cms.dal.common.RaptorEntityGenerator; import com.ebay.cloud.cms.dal.entity.impl.BsonEntity; import com.ebay.cloud.cms.dal.exception.CmsDalException; import com.ebay.cloud.cms.dal.exception.CmsDalException.DalErrCodeEnum; import com.ebay.cloud.cms.dal.persistence.PersistenceContext.DBCollectionPolicy; import com.ebay.cloud.cms.dal.persistence.impl.PersistenceServiceImpl; import com.ebay.cloud.cms.dal.search.utils.TestUtils; import com.ebay.cloud.cms.metadata.RepositoryServiceFactory; import com.ebay.cloud.cms.metadata.dataloader.MetadataDataLoader; import com.ebay.cloud.cms.metadata.model.InternalFieldEnum; import com.ebay.cloud.cms.metadata.model.MetaAttribute; import com.ebay.cloud.cms.metadata.model.MetaClass; import com.ebay.cloud.cms.metadata.model.MetaField.DataTypeEnum; import com.ebay.cloud.cms.metadata.sequence.MongoSequence; import com.ebay.cloud.cms.metadata.service.IMetadataService; import com.ebay.cloud.cms.metadata.service.IRepositoryService; import com.ebay.cloud.cms.mongo.MongoDataSource; import com.ebay.cloud.cms.utils.mongo.test.CMSMongoTest; /** * @author liasu * */ public class EntityExpressionTest extends CMSMongoTest { private static IPersistenceService persistenceService = null; private static IRepositoryService repoService = null; private static IMetadataService metaService = null; private static PersistenceContext context = null; private static final String RAPTOR_REPO = "raptor-paas"; private static final String BRANCH_TEST = "test"; private static MetadataDataLoader metaLoader = null; private static MongoSequence sequence = null; private static MetaClass applicationMetadata; private static MetaClass serviceMetadata; @BeforeClass public static void setUp() { String connectionString = CMSMongoTest.getConnectionString(); MongoDataSource dataSource = new MongoDataSource(connectionString); metaLoader = MetadataDataLoader.getInstance(dataSource); metaLoader.loadTestDataFromResource(); repoService = RepositoryServiceFactory.createRepositoryService(dataSource, "localCMSServer"); metaService = repoService.getRepository(RAPTOR_REPO).getMetadataService(); persistenceService = new PersistenceServiceImpl(dataSource); context = new PersistenceContext(metaService, DBCollectionPolicy.SplitByMetadata, ConsistentPolicy.safePolicy(), BRANCH_TEST); context.setRegistration(TestUtils.getTestDalImplemantation(dataSource)); sequence = new MongoSequence(dataSource.getMongoInstance(), CMSConsts.SYS_DB, CMSConsts.SEQUENCE_COLL, CMSConsts.NEXT_FIELD_NAME_SEQ); applicationMetadata = initApplicationServiceExpressionField(); applicationMetadata = initApplicationServiceValidationField(); serviceMetadata = metaService.getMetaClass(RaptorEntityGenerator.TypeEnum.ServiceInstance.name()); } @Test public void createWithExpression() { BsonEntity entity = newExpressEntity(applicationMetadata, "expression-create"); String createId = persistenceService.create(entity, context); BsonEntity queryEntity = buildQueryEntity(BRANCH_TEST, RaptorEntityGenerator.TypeEnum.ApplicationService.name(), createId); BsonEntity getApp = (BsonEntity)persistenceService.get(queryEntity, context); Assert.assertNotNull(getApp.getFieldValues("name")); Assert.assertEquals(entity.getFieldValues("name").get(0), getApp.getFieldValues("name").get(0)); Assert.assertNotNull(getApp.getFieldValues("CalName")); Assert.assertEquals(getApp.getFieldValues("name").get(0), getApp.getFieldValues("CalName").get(0)); } @Test public void moidfyWithExpression() { String oldName = "expression-update"; BsonEntity entity = newExpressEntity(applicationMetadata, oldName); String createId = persistenceService.create(entity, context); BsonEntity queryEntity = buildQueryEntity(BRANCH_TEST, RaptorEntityGenerator.TypeEnum.ApplicationService.name(), createId); BsonEntity getApp = (BsonEntity) persistenceService.get(queryEntity, context); String newName = "expression-update-1"; getApp.addFieldValue("name", newName); persistenceService.modify(getApp, context); getApp = (BsonEntity)persistenceService.get(queryEntity, context); Assert.assertFalse(oldName.equals(getApp.getFieldValues("name").get(0))); Assert.assertTrue(newName.equals(getApp.getFieldValues("name").get(0))); Assert.assertEquals(newName, getApp.getFieldValues("CalName").get(0)); } @Test public void moidfyWithExpression01() { MetaAttribute attribute = new MetaAttribute(false); attribute.setName("newCalName"); attribute.setDataType(DataTypeEnum.STRING); attribute.setExpression("$name + $archTier"); attribute.setDbName(sequence.getNext()); applicationMetadata.addField(attribute); String oldName = "expression-update"; BsonEntity entity = newExpressEntity(applicationMetadata, oldName); String createId = persistenceService.create(entity, context); BsonEntity queryEntity = buildQueryEntity(BRANCH_TEST, RaptorEntityGenerator.TypeEnum.ApplicationService.name(), createId); BsonEntity getApp = (BsonEntity)persistenceService.get(queryEntity, context); // here the modify payload dones't have the name getApp.addFieldValue("archTier", "archTierValue"); persistenceService.modify(getApp, context); getApp = (BsonEntity)persistenceService.get(queryEntity, context); // cal name should not be null, and should be updated even the payload // is only partial of the involved field Assert.assertEquals(getApp.getFieldValues("name").get(0).toString() + getApp.getFieldValues("archTier").get(0).toString(), getApp.getFieldValues("newCalName").get(0)); } @Test public void replaceWithExpression() { String oldName = "expression-replace"; BsonEntity entity = newExpressEntity(applicationMetadata, oldName); String createId = persistenceService.create(entity, context); BsonEntity queryEntity = buildQueryEntity(BRANCH_TEST, RaptorEntityGenerator.TypeEnum.ApplicationService.name(), createId); BsonEntity getApp = (BsonEntity)persistenceService.get(queryEntity, context); String newName = "expression-replace-1"; getApp.addFieldValue("name", newName); persistenceService.modify(getApp, context); queryEntity = buildQueryEntity(BRANCH_TEST, RaptorEntityGenerator.TypeEnum.ApplicationService.name(), createId); getApp = (BsonEntity)persistenceService.get(queryEntity, context); Assert.assertFalse(oldName.equals(getApp.getFieldValues("name").get(0))); Assert.assertTrue(newName.equals(getApp.getFieldValues("name").get(0))); Assert.assertEquals(newName, getApp.getFieldValues("CalName").get(0)); } @Test public void createWithValidation() { BsonEntity entity = newValidationEntity(applicationMetadata, "validation-create"); entity.addFieldValue("ValName", "123456789"); String createId = persistenceService.create(entity, context); BsonEntity queryEntity = buildQueryEntity(BRANCH_TEST, RaptorEntityGenerator.TypeEnum.ApplicationService.name(), createId); BsonEntity getApp = (BsonEntity)persistenceService.get(queryEntity, context); Assert.assertNotNull(getApp.getFieldValues("ValName")); Assert.assertEquals(entity.getFieldValues("ValName").get(0), getApp.getFieldValues("ValName").get(0)); Assert.assertNotNull(getApp.getFieldValues("ValExprName")); Assert.assertEquals(getApp.getFieldValues("name").get(0), getApp.getFieldValues("ValExprName").get(0)); BsonEntity invalidEntity = newValidationEntity(applicationMetadata, "invld"); try { persistenceService.create(invalidEntity, context); Assert.fail(); } catch(CmsDalException e) { Assert.assertEquals(DalErrCodeEnum.VALIDATION_FAILED, e.getErrorEnum()); } invalidEntity = newValidationEntity(applicationMetadata, "invld-creation"); invalidEntity.addFieldValue("invalidValidationName", "invld"); try { persistenceService.create(invalidEntity, context); Assert.fail(); } catch(CmsDalException e) { Assert.assertEquals(DalErrCodeEnum.VALIDATION_FAILED, e.getErrorEnum()); } } @Test public void moidfyWithValidation() { BsonEntity entity = newValidationEntity(applicationMetadata, "validation-modify"); entity.addFieldValue("ValName", "123456789"); String createId = persistenceService.create(entity, context); BsonEntity queryEntity = buildQueryEntity(BRANCH_TEST, RaptorEntityGenerator.TypeEnum.ApplicationService.name(), createId); BsonEntity getApp = (BsonEntity)persistenceService.get(queryEntity, context); getApp.addFieldValue("name", "invld"); try { persistenceService.modify(getApp, context); Assert.fail(); } catch(CmsDalException e) { Assert.assertEquals(DalErrCodeEnum.VALIDATION_FAILED, e.getErrorEnum()); } BsonEntity newGetApp = (BsonEntity) persistenceService.get(queryEntity, context); newGetApp.addFieldValue("invalidValidationName", "invld"); try { persistenceService.modify(newGetApp, context); Assert.fail(); } catch(CmsDalException e) { Assert.assertEquals(DalErrCodeEnum.VALIDATION_FAILED, e.getErrorEnum()); } } @Test public void replaceWithValidation() { BsonEntity entity = newValidationEntity(applicationMetadata, "validation-replace"); entity.addFieldValue("ValName", "123456789"); String createId = persistenceService.create(entity, context); BsonEntity queryEntity = buildQueryEntity(BRANCH_TEST, RaptorEntityGenerator.TypeEnum.ApplicationService.name(), createId); BsonEntity invalidEntity = (BsonEntity)persistenceService.get(queryEntity, context); invalidEntity.addFieldValue("name", "invld"); try { persistenceService.replace(invalidEntity, context); Assert.fail(); } catch(CmsDalException e) { Assert.assertEquals(DalErrCodeEnum.VALIDATION_FAILED, e.getErrorEnum()); } invalidEntity = (BsonEntity) persistenceService.get(queryEntity, context); invalidEntity.addFieldValue("invalidValidationName", "invld"); try { persistenceService.replace(invalidEntity, context); Assert.fail(); } catch(CmsDalException e) { Assert.assertEquals(DalErrCodeEnum.VALIDATION_FAILED, e.getErrorEnum()); } } @Test public void manifestDiffUsingExpression() { BsonEntity newApp = newExpressEntity(applicationMetadata, "manifestDiffUsingExpression"); newApp.addFieldValue("activeManifestCur", "manifest-1.0"); newApp.addFieldValue("activeManifestRef", "manifest-2.0"); newApp.addFieldValue("activeManifestRef", "manifest-1.0"); String newId = persistenceService.create(newApp, context); BsonEntity queryEntity = buildQueryEntity(BRANCH_TEST, RaptorEntityGenerator.TypeEnum.ApplicationService.name(), newId); BsonEntity getApp = (BsonEntity) persistenceService.get(queryEntity, context); Assert.assertNotNull(getApp); Assert.assertNotNull(getApp.getFieldValues("activeManifestDiff").get(0)); Assert.assertTrue((Boolean) getApp.getFieldValues("activeManifestDiff").get(0)); } @Test public void referenceInExpression() { BsonEntity newApp = newExpressEntity(applicationMetadata, "referenceInExpression"); BsonEntity service1 = new BsonEntity(serviceMetadata); service1.setId("faked-id-1");// just use a fake id here BsonEntity service2 = new BsonEntity(serviceMetadata); service2.setId("faked-id-2");// just use a fake id here newApp.addFieldValue("services", service1); newApp.addFieldValue("services", service2); String newId = persistenceService.create(newApp, context); BsonEntity queryEntity = buildQueryEntity(BRANCH_TEST, RaptorEntityGenerator.TypeEnum.ApplicationService.name(), newId); BsonEntity getApp = (BsonEntity) persistenceService.get(queryEntity, context); Assert.assertNotNull(getApp); Assert.assertNotNull(getApp.getFieldValues("refDiff").get(0)); Assert.assertTrue((Boolean) getApp.getFieldValues("refDiff").get(0)); } @Ignore @Test public void fieldPropertyExpression() { BsonEntity newApp = newExpressEntity(applicationMetadata, "fieldPropertyExpression"); String newId = persistenceService.create(newApp, context); BsonEntity queryEntity = buildQueryEntity(BRANCH_TEST, RaptorEntityGenerator.TypeEnum.ApplicationService.name(), newId); BsonEntity getApp = (BsonEntity) persistenceService.get(queryEntity, context); Assert.assertNotNull(getApp); Assert.assertNotNull(getApp.getFieldValues("nameLastModifedTime").get(0)); Assert.assertTrue(getApp.getFieldTimestamp("name").equals(getApp.getFieldValues("nameLastModifedTime").get(0))); } private BsonEntity newExpressEntity(MetaClass metaClass, String name) { BsonEntity entity = new BsonEntity(metaClass); entity.setBranchId(BRANCH_TEST); entity.addFieldValue("name", generateRandomName(name)); entity.addFieldValue(InternalFieldEnum.CREATOR.getName(), "unitTestUser"); return entity; } private BsonEntity newValidationEntity(MetaClass metaClass, String name) { BsonEntity entity = new BsonEntity(metaClass); entity.setBranchId(BRANCH_TEST); entity.addFieldValue("name", name); entity.addFieldValue(InternalFieldEnum.CREATOR.getName(), "unitTestUser"); return entity; } private static MetaClass initApplicationServiceExpressionField() { MetaClass metaClass = metaService.getMetaClass(RaptorEntityGenerator.TypeEnum.ApplicationService.name()); MetaAttribute attribute = new MetaAttribute(false); attribute.setName("CalName"); attribute.setDataType(DataTypeEnum.STRING); attribute.setExpression("$name"); attribute.setDbName(sequence.getNext()); metaClass.addField(attribute); // sample for diff between reference MetaAttribute refDiffAttribute = new MetaAttribute(false); refDiffAttribute.setName("refDiff"); refDiffAttribute.setDataType(DataTypeEnum.BOOLEAN); refDiffAttribute.setDbName(sequence.getNext()); refDiffAttribute.setExpression("if ($services != null && $services.length >=2) {$services[0].getId() != $services[1].getId()} else false;"); metaClass.addField(refDiffAttribute); // sample field for using field property. // FIXME: currently not support field properties. One solution is to add a reserved variable called self // MetaAttribute fieldPropertyCheckAttribute = new MetaAttribute(false); // fieldPropertyCheckAttribute.setName("nameLastModifedTime"); // fieldPropertyCheckAttribute.setDataType(DataTypeEnum.DATE); // fieldPropertyCheckAttribute.setDbName(sequence.getNext()); // fieldPropertyCheckAttribute.setExpression("$self.getFieldTimestamp(\"name\")");// TODO // metaClass.addField(fieldPropertyCheckAttribute); return metaClass; } private static MetaClass initApplicationServiceValidationField() { MetaClass metaClass = metaService.getMetaClass(RaptorEntityGenerator.TypeEnum.ApplicationService.name()); MetaAttribute attribute1 = new MetaAttribute(false); attribute1.setName("ValName"); attribute1.setDataType(DataTypeEnum.STRING); attribute1.setValidation("$ValName.length > 6"); attribute1.setDbName(sequence.getNext()); metaClass.addField(attribute1); MetaAttribute attribute2 = new MetaAttribute(false); attribute2.setName("ValExprName"); attribute2.setDataType(DataTypeEnum.STRING); attribute2.setExpression("$name"); attribute2.setValidation("$ValExprName.length > 10"); attribute2.setDbName(sequence.getNext()); metaClass.addField(attribute2); MetaAttribute attribute3 = new MetaAttribute(false); attribute3.setName("invalidValidationName"); attribute3.setDataType(DataTypeEnum.STRING); attribute3.setValidation("$invalidValidationName.length"); attribute3.setDbName(sequence.getNext()); metaClass.addField(attribute3); return metaClass; } private BsonEntity buildQueryEntity(String branchname, String metadata, String oid) { MetaClass meta = metaService.getMetaClass(metadata); BsonEntity queryEntity = new BsonEntity(meta); queryEntity.setId(oid); queryEntity.setBranchId(branchname); return queryEntity; } }