Search in sources :

Example 41 with BusinessObjectDataCreateRequest

use of org.finra.herd.model.api.xml.BusinessObjectDataCreateRequest in project herd by FINRAOS.

the class BusinessObjectDataServiceCreateBusinessObjectDataTest method testCreateBusinessObjectDataDuplicateParents.

@Test
public void testCreateBusinessObjectDataDuplicateParents() {
    // This will create a business object data create request with parents.
    BusinessObjectDataCreateRequest businessObjectDataCreateRequest = businessObjectDataServiceTestHelper.getNewBusinessObjectDataCreateRequest(true);
    // Add a duplicate parent.
    List<BusinessObjectDataKey> businessObjectDataKeys = businessObjectDataCreateRequest.getBusinessObjectDataParents();
    businessObjectDataKeys.add(businessObjectDataKeys.get(0));
    // Try to create a business object data with duplicate parents.
    try {
        businessObjectDataService.createBusinessObjectData(businessObjectDataCreateRequest);
        fail("Should throw an IllegalArgumentException when business object data create request contains duplicate parents.");
    } catch (IllegalArgumentException e) {
        assertEquals("Business object data keys can not contain duplicates.", e.getMessage());
    }
}
Also used : BusinessObjectDataCreateRequest(org.finra.herd.model.api.xml.BusinessObjectDataCreateRequest) BusinessObjectDataKey(org.finra.herd.model.api.xml.BusinessObjectDataKey) Test(org.junit.Test)

Example 42 with BusinessObjectDataCreateRequest

use of org.finra.herd.model.api.xml.BusinessObjectDataCreateRequest in project herd by FINRAOS.

the class BusinessObjectDataServiceCreateBusinessObjectDataTest method testCreateBusinessObjectDataDiscoverStorageFiles.

@Test
public void testCreateBusinessObjectDataDiscoverStorageFiles() throws Exception {
    // Create a business object format entity.
    businessObjectFormatDaoTestHelper.createBusinessObjectFormatEntity(NAMESPACE, BDEF_NAME, FORMAT_USAGE_CODE, FORMAT_FILE_TYPE_CODE, INITIAL_FORMAT_VERSION, FORMAT_DESCRIPTION, LATEST_VERSION_FLAG_SET, PARTITION_KEY);
    // Create a business object data status entity.
    businessObjectDataStatusDaoTestHelper.createBusinessObjectDataStatusEntity(BDATA_STATUS);
    // Create and upload to S3 managed storage a set of test files.
    businessObjectDataServiceTestHelper.prepareTestS3Files(testS3KeyPrefix, localTempPath, LOCAL_FILES);
    // Build a new business object data create request with enabled discovery of storage files.
    BusinessObjectDataCreateRequest request = new BusinessObjectDataCreateRequest(NAMESPACE, BDEF_NAME, FORMAT_USAGE_CODE, FORMAT_FILE_TYPE_CODE, INITIAL_FORMAT_VERSION, PARTITION_KEY, PARTITION_VALUE, NO_SUBPARTITION_VALUES, BDATA_STATUS, Arrays.asList(new StorageUnitCreateRequest(StorageEntity.MANAGED_STORAGE, new StorageDirectory(testS3KeyPrefix), NO_STORAGE_FILES, DISCOVER_STORAGE_FILES)), NO_ATTRIBUTES, NO_BUSINESS_OBJECT_DATA_PARENTS, NO_CREATE_NEW_VERSION);
    // Create the business object data.
    BusinessObjectData resultBusinessObjectData = businessObjectDataService.createBusinessObjectData(request);
    // Verify the results.
    assertEquals(new BusinessObjectData(resultBusinessObjectData.getId(), NAMESPACE, BDEF_NAME, FORMAT_USAGE_CODE, FORMAT_FILE_TYPE_CODE, INITIAL_FORMAT_VERSION, PARTITION_KEY, PARTITION_VALUE, NO_SUBPARTITION_VALUES, INITIAL_DATA_VERSION, LATEST_VERSION_FLAG_SET, BDATA_STATUS, Arrays.asList(new StorageUnit(new Storage(StorageEntity.MANAGED_STORAGE, StoragePlatformEntity.S3, Arrays.asList(new Attribute(configurationHelper.getProperty(ConfigurationValue.S3_ATTRIBUTE_NAME_BUCKET_NAME), storageDaoTestHelper.getS3ManagedBucketName()), new Attribute(configurationHelper.getProperty(ConfigurationValue.S3_ATTRIBUTE_NAME_KEY_PREFIX_VELOCITY_TEMPLATE), S3_KEY_PREFIX_VELOCITY_TEMPLATE), new Attribute(configurationHelper.getProperty(ConfigurationValue.S3_ATTRIBUTE_NAME_VALIDATE_FILE_EXISTENCE), Boolean.TRUE.toString()), new Attribute(configurationHelper.getProperty(ConfigurationValue.S3_ATTRIBUTE_NAME_VALIDATE_FILE_SIZE), Boolean.TRUE.toString()), new Attribute(configurationHelper.getProperty(ConfigurationValue.S3_ATTRIBUTE_NAME_VALIDATE_PATH_PREFIX), Boolean.TRUE.toString()))), new StorageDirectory(testS3KeyPrefix), businessObjectDataServiceTestHelper.getTestStorageFiles(testS3KeyPrefix, SORTED_LOCAL_FILES, false), StorageUnitStatusEntity.ENABLED, NO_STORAGE_UNIT_STATUS_HISTORY, NO_STORAGE_POLICY_TRANSITION_FAILED_ATTEMPTS, NO_RESTORE_EXPIRATION_ON)), NO_ATTRIBUTES, NO_BUSINESS_OBJECT_DATA_PARENTS, NO_BUSINESS_OBJECT_DATA_CHILDREN, NO_BUSINESS_OBJECT_DATA_STATUS_HISTORY), resultBusinessObjectData);
}
Also used : Storage(org.finra.herd.model.api.xml.Storage) BusinessObjectData(org.finra.herd.model.api.xml.BusinessObjectData) Attribute(org.finra.herd.model.api.xml.Attribute) BusinessObjectDataCreateRequest(org.finra.herd.model.api.xml.BusinessObjectDataCreateRequest) StorageUnit(org.finra.herd.model.api.xml.StorageUnit) StorageDirectory(org.finra.herd.model.api.xml.StorageDirectory) StorageUnitCreateRequest(org.finra.herd.model.api.xml.StorageUnitCreateRequest) Test(org.junit.Test)

Example 43 with BusinessObjectDataCreateRequest

use of org.finra.herd.model.api.xml.BusinessObjectDataCreateRequest in project herd by FINRAOS.

the class BusinessObjectDataServiceCreateBusinessObjectDataTest method testCreateBusinessObjectDataMissingRequiredParameters.

@Test
public void testCreateBusinessObjectDataMissingRequiredParameters() {
    // Create relative database entities.
    businessObjectFormatDaoTestHelper.createBusinessObjectFormatEntity(NAMESPACE, BDEF_NAME, FORMAT_USAGE_CODE, FORMAT_FILE_TYPE_CODE, INITIAL_FORMAT_VERSION, FORMAT_DESCRIPTION, true, PARTITION_KEY);
    storageDaoTestHelper.createStorageEntity(STORAGE_NAME);
    BusinessObjectDataCreateRequest request;
    List<StorageFile> storageFiles;
    // Try to create a business object data instance when business object definition name is not specified.
    request = businessObjectDataServiceTestHelper.createBusinessObjectDataCreateRequest(NAMESPACE, BLANK_TEXT, FORMAT_USAGE_CODE, FORMAT_FILE_TYPE_CODE, INITIAL_FORMAT_VERSION, PARTITION_KEY, PARTITION_VALUE, BusinessObjectDataStatusEntity.VALID, STORAGE_NAME, testS3KeyPrefix, businessObjectDataServiceTestHelper.getTestStorageFiles(testS3KeyPrefix, LOCAL_FILES));
    try {
        businessObjectDataService.createBusinessObjectData(request);
        fail("Should throw an IllegalArgumentException when business object definition name is not specified.");
    } catch (IllegalArgumentException e) {
        assertEquals("A business object definition name must be specified.", e.getMessage());
    }
    // Try to create a business object data instance when business object format usage is not specified.
    request = businessObjectDataServiceTestHelper.createBusinessObjectDataCreateRequest(NAMESPACE, BDEF_NAME, BLANK_TEXT, FORMAT_FILE_TYPE_CODE, INITIAL_FORMAT_VERSION, PARTITION_KEY, PARTITION_VALUE, BusinessObjectDataStatusEntity.VALID, STORAGE_NAME, testS3KeyPrefix, businessObjectDataServiceTestHelper.getTestStorageFiles(testS3KeyPrefix, LOCAL_FILES));
    try {
        businessObjectDataService.createBusinessObjectData(request);
        fail("Should throw an IllegalArgumentException when business object format usage is not specified.");
    } catch (IllegalArgumentException e) {
        assertEquals("A business object format usage must be specified.", e.getMessage());
    }
    // Try to create a business object data instance when business object format file type is not specified.
    request = businessObjectDataServiceTestHelper.createBusinessObjectDataCreateRequest(NAMESPACE, BDEF_NAME, FORMAT_USAGE_CODE, BLANK_TEXT, INITIAL_FORMAT_VERSION, PARTITION_KEY, PARTITION_VALUE, BusinessObjectDataStatusEntity.VALID, STORAGE_NAME, testS3KeyPrefix, businessObjectDataServiceTestHelper.getTestStorageFiles(testS3KeyPrefix, LOCAL_FILES));
    try {
        businessObjectDataService.createBusinessObjectData(request);
        fail("Should throw an IllegalArgumentException when business object format file type is not specified.");
    } catch (IllegalArgumentException e) {
        assertEquals("A business object format file type must be specified.", e.getMessage());
    }
    // Try to create a business object data instance when business object format version is not specified.
    request = businessObjectDataServiceTestHelper.createBusinessObjectDataCreateRequest(NAMESPACE, BDEF_NAME, FORMAT_USAGE_CODE, FORMAT_FILE_TYPE_CODE, null, PARTITION_KEY, PARTITION_VALUE, BusinessObjectDataStatusEntity.VALID, STORAGE_NAME, testS3KeyPrefix, businessObjectDataServiceTestHelper.getTestStorageFiles(testS3KeyPrefix, LOCAL_FILES));
    try {
        businessObjectDataService.createBusinessObjectData(request);
        fail("Should throw an IllegalArgumentException when business object format version is not specified.");
    } catch (IllegalArgumentException e) {
        assertEquals("A business object format version must be specified.", e.getMessage());
    }
    // Try to create a business object data instance when business object format partition key is not specified.
    request = businessObjectDataServiceTestHelper.createBusinessObjectDataCreateRequest(NAMESPACE, BDEF_NAME, FORMAT_USAGE_CODE, FORMAT_FILE_TYPE_CODE, INITIAL_FORMAT_VERSION, BLANK_TEXT, PARTITION_VALUE, BusinessObjectDataStatusEntity.VALID, STORAGE_NAME, testS3KeyPrefix, businessObjectDataServiceTestHelper.getTestStorageFiles(testS3KeyPrefix, LOCAL_FILES));
    try {
        businessObjectDataService.createBusinessObjectData(request);
        fail("Should throw an IllegalArgumentException when business object format partition key is not specified.");
    } catch (IllegalArgumentException e) {
        assertEquals("A partition key must be specified.", e.getMessage());
    }
    // Try to create a business object data instance when partition value is not specified.
    request = businessObjectDataServiceTestHelper.createBusinessObjectDataCreateRequest(NAMESPACE, BDEF_NAME, FORMAT_USAGE_CODE, FORMAT_FILE_TYPE_CODE, INITIAL_FORMAT_VERSION, PARTITION_KEY, BLANK_TEXT, BusinessObjectDataStatusEntity.VALID, STORAGE_NAME, testS3KeyPrefix, businessObjectDataServiceTestHelper.getTestStorageFiles(testS3KeyPrefix, LOCAL_FILES));
    try {
        businessObjectDataService.createBusinessObjectData(request);
        fail("Should throw an IllegalArgumentException when partition value is not specified.");
    } catch (IllegalArgumentException e) {
        assertEquals("A partition value must be specified.", e.getMessage());
    }
    // Try to create a business object data instance when request contains no storage units element.
    request = businessObjectDataServiceTestHelper.createBusinessObjectDataCreateRequest(NAMESPACE, BDEF_NAME, FORMAT_USAGE_CODE, FORMAT_FILE_TYPE_CODE, INITIAL_FORMAT_VERSION, PARTITION_KEY, PARTITION_VALUE, BusinessObjectDataStatusEntity.VALID, STORAGE_NAME, testS3KeyPrefix, businessObjectDataServiceTestHelper.getTestStorageFiles(testS3KeyPrefix, LOCAL_FILES));
    request.setStorageUnits(null);
    try {
        businessObjectDataService.createBusinessObjectData(request);
        fail("Should throw an IllegalArgumentException when when request contains no storage units element.");
    } catch (IllegalArgumentException e) {
        assertEquals("At least one storage unit must be specified.", e.getMessage());
    }
    // Try to create a business object data instance when no storage units are specified.
    request = businessObjectDataServiceTestHelper.createBusinessObjectDataCreateRequest(NAMESPACE, BDEF_NAME, FORMAT_USAGE_CODE, FORMAT_FILE_TYPE_CODE, INITIAL_FORMAT_VERSION, PARTITION_KEY, PARTITION_VALUE, BusinessObjectDataStatusEntity.VALID, STORAGE_NAME, testS3KeyPrefix, businessObjectDataServiceTestHelper.getTestStorageFiles(testS3KeyPrefix, LOCAL_FILES));
    request.setStorageUnits(new ArrayList<StorageUnitCreateRequest>());
    try {
        businessObjectDataService.createBusinessObjectData(request);
        fail("Should throw an IllegalArgumentException when when no storage units are specified.");
    } catch (IllegalArgumentException e) {
        assertEquals("At least one storage unit must be specified.", e.getMessage());
    }
    // Try to create a business object data instance when request contains an empty storage unit element.
    request = businessObjectDataServiceTestHelper.createBusinessObjectDataCreateRequest(NAMESPACE, BDEF_NAME, FORMAT_USAGE_CODE, FORMAT_FILE_TYPE_CODE, INITIAL_FORMAT_VERSION, PARTITION_KEY, PARTITION_VALUE, BusinessObjectDataStatusEntity.VALID, STORAGE_NAME, testS3KeyPrefix, businessObjectDataServiceTestHelper.getTestStorageFiles(testS3KeyPrefix, LOCAL_FILES));
    List<StorageUnitCreateRequest> storageUnits = new ArrayList<>();
    storageUnits.add(null);
    request.setStorageUnits(storageUnits);
    try {
        businessObjectDataService.createBusinessObjectData(request);
        fail("Should throw an IllegalArgumentException when when no storage units are specified.");
    } catch (IllegalArgumentException e) {
        assertEquals("A storage unit can't be null.", e.getMessage());
    }
    // Try to create a business object data instance when storage name is not specified for a storage unit.
    request = businessObjectDataServiceTestHelper.createBusinessObjectDataCreateRequest(NAMESPACE, BDEF_NAME, FORMAT_USAGE_CODE, FORMAT_FILE_TYPE_CODE, INITIAL_FORMAT_VERSION, PARTITION_KEY, PARTITION_VALUE, BusinessObjectDataStatusEntity.VALID, STORAGE_NAME, testS3KeyPrefix, businessObjectDataServiceTestHelper.getTestStorageFiles(testS3KeyPrefix, LOCAL_FILES));
    request.getStorageUnits().get(0).setStorageName(BLANK_TEXT);
    try {
        businessObjectDataService.createBusinessObjectData(request);
        fail("Should throw an IllegalArgumentException when storage name is not specified for a storage unit.");
    } catch (IllegalArgumentException e) {
        assertEquals("A storage name is required for each storage unit.", e.getMessage());
    }
    // Try to create a business object data instance when both storage directory and storage files are not specified.
    request = businessObjectDataServiceTestHelper.createBusinessObjectDataCreateRequest(NAMESPACE, BDEF_NAME, FORMAT_USAGE_CODE, FORMAT_FILE_TYPE_CODE, INITIAL_FORMAT_VERSION, PARTITION_KEY, PARTITION_VALUE, BusinessObjectDataStatusEntity.VALID, STORAGE_NAME, null, null);
    try {
        businessObjectDataService.createBusinessObjectData(request);
        fail("Should throw an IllegalArgumentException when both storage directory and storage files are not specified.");
    } catch (IllegalArgumentException e) {
        assertEquals("A storage directory or at least one storage file must be specified for each storage unit.", e.getMessage());
    }
    // Try to create a business object data instance when storage directory element is present, but the actual directory path value is not specified.
    request = businessObjectDataServiceTestHelper.createBusinessObjectDataCreateRequest(NAMESPACE, BDEF_NAME, FORMAT_USAGE_CODE, FORMAT_FILE_TYPE_CODE, INITIAL_FORMAT_VERSION, PARTITION_KEY, PARTITION_VALUE, BusinessObjectDataStatusEntity.VALID, STORAGE_NAME, BLANK_TEXT, businessObjectDataServiceTestHelper.getTestStorageFiles(testS3KeyPrefix, LOCAL_FILES));
    try {
        businessObjectDataService.createBusinessObjectData(request);
        fail("Should throw an IllegalArgumentException when storage directory element is present, but the actual directory path value is not specified.");
    } catch (IllegalArgumentException e) {
        assertEquals("A storage directory path must be specified.", e.getMessage());
    }
    // Try to create a business object data instance when storage file element is present, but the actual file path value is not specified.
    storageFiles = businessObjectDataServiceTestHelper.getTestStorageFiles(testS3KeyPrefix, Arrays.asList(LOCAL_FILE));
    storageFiles.get(0).setFilePath(BLANK_TEXT);
    request = businessObjectDataServiceTestHelper.createBusinessObjectDataCreateRequest(NAMESPACE, BDEF_NAME, FORMAT_USAGE_CODE, FORMAT_FILE_TYPE_CODE, INITIAL_FORMAT_VERSION, PARTITION_KEY, PARTITION_VALUE, BusinessObjectDataStatusEntity.VALID, STORAGE_NAME, testS3KeyPrefix, storageFiles);
    try {
        businessObjectDataService.createBusinessObjectData(request);
        fail("Should throw an IllegalArgumentException when storage file element is present, but the actual file path value is not specified.");
    } catch (IllegalArgumentException e) {
        assertEquals("A file path must be specified.", e.getMessage());
    }
    // Try to create a business object data instance when storage file size is not specified.
    storageFiles = businessObjectDataServiceTestHelper.getTestStorageFiles(testS3KeyPrefix, Arrays.asList(LOCAL_FILE));
    storageFiles.get(0).setFileSizeBytes(null);
    request = businessObjectDataServiceTestHelper.createBusinessObjectDataCreateRequest(NAMESPACE, BDEF_NAME, FORMAT_USAGE_CODE, FORMAT_FILE_TYPE_CODE, INITIAL_FORMAT_VERSION, PARTITION_KEY, PARTITION_VALUE, BusinessObjectDataStatusEntity.VALID, STORAGE_NAME, testS3KeyPrefix, storageFiles);
    try {
        businessObjectDataService.createBusinessObjectData(request);
        fail("Should throw an IllegalArgumentException when storage file size is not specified.");
    } catch (IllegalArgumentException e) {
        assertEquals("A file size must be specified.", e.getMessage());
    }
}
Also used : BusinessObjectDataCreateRequest(org.finra.herd.model.api.xml.BusinessObjectDataCreateRequest) StorageFile(org.finra.herd.model.api.xml.StorageFile) ArrayList(java.util.ArrayList) StorageUnitCreateRequest(org.finra.herd.model.api.xml.StorageUnitCreateRequest) Test(org.junit.Test)

Example 44 with BusinessObjectDataCreateRequest

use of org.finra.herd.model.api.xml.BusinessObjectDataCreateRequest in project herd by FINRAOS.

the class BusinessObjectDataServiceCreateBusinessObjectDataTest method testCreateBusinessObjectBusinessObjectStatusCodeNoExists.

@Test
public void testCreateBusinessObjectBusinessObjectStatusCodeNoExists() {
    // Create database entities required for testing.
    businessObjectFormatDaoTestHelper.createBusinessObjectFormatEntity(NAMESPACE, BDEF_NAME, FORMAT_USAGE_CODE, FORMAT_FILE_TYPE_CODE, FORMAT_VERSION, FORMAT_DESCRIPTION, true, PARTITION_KEY);
    storageDaoTestHelper.createStorageEntity(STORAGE_NAME);
    // Build a business object data create request with a non-existing business object data status code.
    String invalidStatusCode = "I_DO_NOT_EXIST";
    BusinessObjectDataCreateRequest businessObjectDataCreateRequest = businessObjectDataServiceTestHelper.createBusinessObjectDataCreateRequest(NAMESPACE, BDEF_NAME, FORMAT_USAGE_CODE, FORMAT_FILE_TYPE_CODE, FORMAT_VERSION, PARTITION_KEY, PARTITION_VALUE, invalidStatusCode, STORAGE_NAME, testS3KeyPrefix, businessObjectDataServiceTestHelper.getTestStorageFiles(testS3KeyPrefix, Arrays.asList(LOCAL_FILE)));
    try {
        // Try to create a business object data instance using non-existing business object data status code.
        businessObjectDataService.createBusinessObjectData(businessObjectDataCreateRequest);
        fail("Should throw an ObjectNotFoundException when business object data status code does not exist.");
    } catch (ObjectNotFoundException e) {
        assertEquals(String.format("Business object data status \"%s\" doesn't exist.", invalidStatusCode), e.getMessage());
    }
}
Also used : ObjectNotFoundException(org.finra.herd.model.ObjectNotFoundException) BusinessObjectDataCreateRequest(org.finra.herd.model.api.xml.BusinessObjectDataCreateRequest) Test(org.junit.Test)

Example 45 with BusinessObjectDataCreateRequest

use of org.finra.herd.model.api.xml.BusinessObjectDataCreateRequest in project herd by FINRAOS.

the class BusinessObjectDataServiceCreateBusinessObjectDataTest method testCreateBusinessObjectDataAttributeValueTooLarge.

@Test(expected = PersistenceException.class)
public void testCreateBusinessObjectDataAttributeValueTooLarge() throws Exception {
    final BusinessObjectDataCreateRequest businessObjectDataCreateRequest = businessObjectDataServiceTestHelper.getNewBusinessObjectDataCreateRequest();
    // Create and add a duplicate attribute which is not allowed.
    Attribute newAttribute = new Attribute();
    newAttribute.setName("Valid Name");
    // Test value greater than 4000 byte limit.
    newAttribute.setValue(new String(new char[4001]).replace('\0', 'A'));
    businessObjectDataCreateRequest.getAttributes().add(newAttribute);
    executeWithoutLogging(SqlExceptionHelper.class, new Command() {

        @Override
        public void execute() {
            // Create the business object data which is invalid.
            businessObjectDataService.createBusinessObjectData(businessObjectDataCreateRequest);
        }
    });
}
Also used : Attribute(org.finra.herd.model.api.xml.Attribute) Command(org.finra.herd.core.Command) BusinessObjectDataCreateRequest(org.finra.herd.model.api.xml.BusinessObjectDataCreateRequest) Test(org.junit.Test)

Aggregations

BusinessObjectDataCreateRequest (org.finra.herd.model.api.xml.BusinessObjectDataCreateRequest)56 Test (org.junit.Test)50 BusinessObjectData (org.finra.herd.model.api.xml.BusinessObjectData)18 ArrayList (java.util.ArrayList)16 StorageUnitCreateRequest (org.finra.herd.model.api.xml.StorageUnitCreateRequest)14 BusinessObjectDataKey (org.finra.herd.model.api.xml.BusinessObjectDataKey)11 StorageFile (org.finra.herd.model.api.xml.StorageFile)11 Attribute (org.finra.herd.model.api.xml.Attribute)10 StorageDirectory (org.finra.herd.model.api.xml.StorageDirectory)9 ObjectNotFoundException (org.finra.herd.model.ObjectNotFoundException)6 BusinessObjectFormatEntity (org.finra.herd.model.jpa.BusinessObjectFormatEntity)6 BusinessObjectDataEntity (org.finra.herd.model.jpa.BusinessObjectDataEntity)5 AlreadyExistsException (org.finra.herd.model.AlreadyExistsException)4 StorageUnit (org.finra.herd.model.api.xml.StorageUnit)3 StorageEntity (org.finra.herd.model.jpa.StorageEntity)3 HashMap (java.util.HashMap)2 FieldExtension (org.activiti.bpmn.model.FieldExtension)2 BusinessObjectDataStorageUnitCreateRequest (org.finra.herd.model.api.xml.BusinessObjectDataStorageUnitCreateRequest)2 Parameter (org.finra.herd.model.api.xml.Parameter)2 Storage (org.finra.herd.model.api.xml.Storage)2