dhis2-devs team mailing list archive
-
dhis2-devs team
-
Mailing list archive
-
Message #43908
[Branch ~dhis2-devs-core/dhis2/trunk] Rev 22274: wip, uniqueness checks for preheater
------------------------------------------------------------
revno: 22274
committer: Morten Olav Hansen <morten@xxxxxxxxx>
branch nick: dhis2
timestamp: Sun 2016-03-13 17:19:38 +0700
message:
wip, uniqueness checks for preheater
modified:
dhis-2/dhis-api/src/main/java/org/hisp/dhis/feedback/ErrorCode.java
dhis-2/dhis-api/src/main/java/org/hisp/dhis/preheat/Preheat.java
dhis-2/dhis-api/src/main/java/org/hisp/dhis/preheat/PreheatIdentifier.java
dhis-2/dhis-api/src/main/java/org/hisp/dhis/preheat/PreheatParams.java
dhis-2/dhis-api/src/main/java/org/hisp/dhis/preheat/PreheatService.java
dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/preheat/DefaultPreheatService.java
dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata2/objectbundle/DefaultObjectBundleService.java
dhis-2/dhis-services/dhis-service-dxf2/src/test/java/org/hisp/dhis/dxf2/metadata2/objectbundle/ObjectBundleServiceTest.java
--
lp:dhis2
https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk
Your team DHIS 2 developers is subscribed to branch lp:dhis2.
To unsubscribe from this branch go to https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk/+edit-subscription
=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/feedback/ErrorCode.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/feedback/ErrorCode.java 2016-03-03 05:13:32 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/feedback/ErrorCode.java 2016-03-13 10:19:38 +0000
@@ -54,7 +54,8 @@
/* Preheat Errors */
E5000( "Found matching object for given reference, but import mode is CREATE. Identifier was {0}, and object was {1}." ),
E5001( "No matching object for given reference. Identifier was {0}, and object was {1}." ),
- E5002( "Invalid reference {0} on object {1} for association \"{2}\"." );
+ E5002( "Invalid reference {0} on object {1} for association \"{2}\"." ),
+ E5003( "Property \"{0}\" with value \"{1}\" on object {2} already exists on object {3}." );
private String message;
=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/preheat/Preheat.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/preheat/Preheat.java 2016-03-12 09:00:34 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/preheat/Preheat.java 2016-03-13 10:19:38 +0000
@@ -55,6 +55,8 @@
private Map<String, UserCredentials> usernames = new HashMap<>();
+ private Map<Class<? extends IdentifiableObject>, Map<String, Map<Object, String>>> uniquenessMap = new HashMap<>();
+
public Preheat()
{
}
@@ -309,4 +311,14 @@
return klass;
}
+
+ public void setUniquenessMap( Map<Class<? extends IdentifiableObject>, Map<String, Map<Object, String>>> uniquenessMap )
+ {
+ this.uniquenessMap = uniquenessMap;
+ }
+
+ public Map<Class<? extends IdentifiableObject>, Map<String, Map<Object, String>>> getUniquenessMap()
+ {
+ return uniquenessMap;
+ }
}
=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/preheat/PreheatIdentifier.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/preheat/PreheatIdentifier.java 2016-03-12 09:00:34 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/preheat/PreheatIdentifier.java 2016-03-13 10:19:38 +0000
@@ -97,9 +97,9 @@
if ( name == null )
{
- return identifiers.toString();
+ return identifiers.toString() + " (" + object.getClass().getSimpleName() + ")";
}
- return name + " " + identifiers.toString();
+ return name + " " + identifiers.toString() + " (" + object.getClass().getSimpleName() + ")";
}
}
=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/preheat/PreheatParams.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/preheat/PreheatParams.java 2016-03-04 11:51:15 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/preheat/PreheatParams.java 2016-03-13 10:19:38 +0000
@@ -1,6 +1,14 @@
package org.hisp.dhis.preheat;
import com.google.common.base.MoreObjects;
+import org.hisp.dhis.common.IdentifiableObject;
+import org.hisp.dhis.user.User;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
/*
* Copyright (c) 2004-2016, University of Oslo
@@ -30,14 +38,6 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-import org.hisp.dhis.common.IdentifiableObject;
-import org.hisp.dhis.user.User;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
/**
* @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
*/
@@ -53,6 +53,8 @@
private Map<PreheatIdentifier, Map<Class<? extends IdentifiableObject>, Set<String>>> references = new HashMap<>();
+ private Map<Class<? extends IdentifiableObject>, List<IdentifiableObject>> objects = new HashMap<>();
+
public PreheatParams()
{
}
@@ -100,6 +102,16 @@
return this;
}
+ public Map<Class<? extends IdentifiableObject>, List<IdentifiableObject>> getObjects()
+ {
+ return objects;
+ }
+
+ public void setObjects( Map<Class<? extends IdentifiableObject>, List<IdentifiableObject>> objects )
+ {
+ this.objects = objects;
+ }
+
public Map<PreheatIdentifier, Map<Class<? extends IdentifiableObject>, Set<String>>> getReferences()
{
return references;
@@ -111,7 +123,6 @@
return this;
}
-
@Override
public String toString()
{
=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/preheat/PreheatService.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/preheat/PreheatService.java 2016-03-13 08:51:26 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/preheat/PreheatService.java 2016-03-13 10:19:38 +0000
@@ -80,6 +80,14 @@
*/
Map<PreheatIdentifier, Map<Class<? extends IdentifiableObject>, Set<String>>> collectReferences( Map<Class<? extends IdentifiableObject>, List<IdentifiableObject>> objects );
+ /**
+ * Scan objects and collect unique values (used to verify object properties with unique=true)
+ *
+ * @param objects Objects to scan
+ * @return Klass -> Property.name -> Value -> UID
+ */
+ Map<Class<? extends IdentifiableObject>, Map<String, Map<Object, String>>> collectUniqueness( Map<Class<? extends IdentifiableObject>, List<IdentifiableObject>> objects );
+
Map<Class<?>, Map<String, Map<String, Object>>> collectObjectReferences( Map<Class<? extends IdentifiableObject>, List<IdentifiableObject>> objects );
/**
@@ -103,10 +111,11 @@
/**
* Check for properties that are unique.
*
- * @param objects Object to check
- * @param preheat Preheat Cache to use
+ * @param objects Object to check
+ * @param preheat Preheat Cache to use
+ * @param identifier Use this identifier type report issues
*/
- List<ObjectErrorReport> checkUniqueness( List<IdentifiableObject> objects, Preheat preheat );
+ List<ObjectErrorReport> checkUniqueness( List<IdentifiableObject> objects, Preheat preheat, PreheatIdentifier identifier );
/**
* Check for properties that are unique.
@@ -114,7 +123,7 @@
* @param object Object to check
* @param preheat Preheat Cache to use
*/
- List<ErrorReport> checkUniqueness( IdentifiableObject object, Preheat preheat );
+ List<ErrorReport> checkUniqueness( IdentifiableObject object, Preheat preheat, PreheatIdentifier identifier );
/**
* Connects id object references on a given object using a given identifier + a preheated Preheat cache.
=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/preheat/DefaultPreheatService.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/preheat/DefaultPreheatService.java 2016-03-13 08:52:19 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/preheat/DefaultPreheatService.java 2016-03-13 10:19:38 +0000
@@ -161,6 +161,35 @@
}
}
+ Set<Class<? extends IdentifiableObject>> klasses = new HashSet<>();
+
+ if ( params.getReferences().containsKey( PreheatIdentifier.UID ) )
+ {
+ klasses.addAll( params.getReferences().get( PreheatIdentifier.UID ).keySet() );
+ }
+
+ if ( params.getReferences().containsKey( PreheatIdentifier.CODE ) )
+ {
+ klasses.addAll( params.getReferences().get( PreheatIdentifier.CODE ).keySet() );
+ }
+
+ Map<Class<? extends IdentifiableObject>, List<IdentifiableObject>> uniqueCollectionMap = new HashMap<>();
+
+ // TODO fix this, should be part of main preheat process, this will slow things down.. but we need all objects to check for uniqueness
+ for ( Class<? extends IdentifiableObject> klass : klasses )
+ {
+ Query query = Query.from( schemaService.getDynamicSchema( klass ) );
+ query.setUser( preheat.getUser() );
+ List<? extends IdentifiableObject> objects = queryService.query( query );
+
+ if ( !objects.isEmpty() )
+ {
+ uniqueCollectionMap.put( klass, new ArrayList<>( objects ) );
+ }
+ }
+
+ preheat.setUniquenessMap( collectUniqueness( uniqueCollectionMap ) );
+
return preheat;
}
@@ -370,11 +399,51 @@
if ( uidMap.get( UserGroup.class ).isEmpty() ) uidMap.remove( UserGroup.class );
if ( codeMap.get( UserGroup.class ).isEmpty() ) codeMap.remove( UserGroup.class );
}
-
+ }
+
+ return map;
+ }
+
+ @Override
+ @SuppressWarnings( "unchecked" )
+ public Map<Class<? extends IdentifiableObject>, Map<String, Map<Object, String>>> collectUniqueness( Map<Class<? extends IdentifiableObject>, List<IdentifiableObject>> objects )
+ {
+ Map<Class<? extends IdentifiableObject>, Map<String, Map<Object, String>>> uniqueMap = new HashMap<>();
+
+ if ( objects.isEmpty() )
+ {
+ return uniqueMap;
+ }
+
+ Map<Class<? extends IdentifiableObject>, List<IdentifiableObject>> scanObjects = new HashMap<>();
+ scanObjects.putAll( objects ); // clone objects list, we don't want to modify it
+
+ if ( scanObjects.containsKey( User.class ) )
+ {
+ List<IdentifiableObject> users = scanObjects.get( User.class );
+ List<IdentifiableObject> userCredentials = new ArrayList<>();
+
+ for ( IdentifiableObject identifiableObject : users )
+ {
+ User user = (User) identifiableObject;
+
+ if ( user.getUserCredentials() != null )
+ {
+ userCredentials.add( user.getUserCredentials() );
+ }
+ }
+
+ scanObjects.put( UserCredentials.class, userCredentials );
+ }
+
+ for ( Class<? extends IdentifiableObject> objectClass : scanObjects.keySet() )
+ {
+ Schema schema = schemaService.getDynamicSchema( objectClass );
+ List<IdentifiableObject> identifiableObjects = scanObjects.get( objectClass );
uniqueMap.put( objectClass, handleUniqueProperties( schema, identifiableObjects ) );
}
- return map;
+ return uniqueMap;
}
private Map<String, Map<Object, String>> handleUniqueProperties( Schema schema, List<IdentifiableObject> objects )
@@ -594,7 +663,7 @@
}
@Override
- public List<ObjectErrorReport> checkUniqueness( List<IdentifiableObject> objects, Preheat preheat )
+ public List<ObjectErrorReport> checkUniqueness( List<IdentifiableObject> objects, Preheat preheat, PreheatIdentifier identifier )
{
List<ObjectErrorReport> objectErrorReports = new ArrayList<>();
@@ -606,7 +675,7 @@
for ( int i = 0; i < objects.size(); i++ )
{
IdentifiableObject object = objects.get( i );
- List<ErrorReport> errorReports = checkUniqueness( object, preheat );
+ List<ErrorReport> errorReports = checkUniqueness( object, preheat, identifier );
if ( errorReports.isEmpty() ) continue;
@@ -620,14 +689,41 @@
}
@Override
- public List<ErrorReport> checkUniqueness( IdentifiableObject object, Preheat preheat )
+ public List<ErrorReport> checkUniqueness( IdentifiableObject object, Preheat preheat, PreheatIdentifier identifier )
{
List<ErrorReport> errorReports = new ArrayList<>();
- if ( object == null )
- {
- return errorReports;
- }
+ if ( object == null || Preheat.isDefault( object ) ) return errorReports;
+
+ Map<String, Map<Object, String>> uniquenessMap = preheat.getUniquenessMap().get( object.getClass() );
+
+ if ( uniquenessMap == null ) return errorReports;
+
+ Schema schema = schemaService.getDynamicSchema( object.getClass() );
+ List<Property> uniqueProperties = schema.getProperties().stream()
+ .filter( p -> p.isPersisted() && p.isOwner() && p.isUnique() )
+ .collect( Collectors.toList() );
+
+ uniqueProperties.forEach( property -> {
+ Object value = ReflectionUtils.invokeMethod( object, property.getGetterMethod() );
+
+ if ( value != null )
+ {
+ if ( uniquenessMap.containsKey( property.getName() ) && !uniquenessMap.get( property.getName() ).isEmpty() )
+ {
+ String persistedUid = uniquenessMap.get( property.getName() ).get( value );
+
+ if ( persistedUid != null )
+ {
+ if ( !object.getUid().equals( persistedUid ) )
+ {
+ errorReports.add( new ErrorReport( object.getClass(), ErrorCode.E5003, property.getName(), value,
+ identifier.getIdentifiersWithName( object ), persistedUid ) );
+ }
+ }
+ }
+ }
+ } );
return errorReports;
}
=== modified file 'dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata2/objectbundle/DefaultObjectBundleService.java'
--- dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata2/objectbundle/DefaultObjectBundleService.java 2016-03-13 08:51:26 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata2/objectbundle/DefaultObjectBundleService.java 2016-03-13 10:19:38 +0000
@@ -105,6 +105,7 @@
}
preheatParams.setUser( params.getUser() );
+ preheatParams.setObjects( params.getObjects() );
if ( PreheatMode.REFERENCE == preheatParams.getPreheatMode() )
{
@@ -164,7 +165,8 @@
objectBundleValidation.addObjectErrorReports( validateBySchemas( klass, bundle.getObjectMap().get( klass ), bundle ) );
objectBundleValidation.addObjectErrorReports( preheatService.checkReferences( bundle.getObjectMap().get( klass ),
bundle.getPreheat(), bundle.getPreheatIdentifier() ) );
- objectBundleValidation.addObjectErrorReports( preheatService.checkUniqueness( bundle.getObjectMap().get( klass ), bundle.getPreheat() ) );
+ objectBundleValidation.addObjectErrorReports( preheatService.checkUniqueness( bundle.getObjectMap().get( klass ), bundle.getPreheat(),
+ bundle.getPreheatIdentifier() ) );
}
if ( bundle.getImportMode().isCreate() )
@@ -173,7 +175,8 @@
objectBundleValidation.addObjectErrorReports( validateBySchemas( klass, bundle.getObjects( klass, false ), bundle ) );
objectBundleValidation.addObjectErrorReports( preheatService.checkReferences( bundle.getObjectMap().get( klass ),
bundle.getPreheat(), bundle.getPreheatIdentifier() ) );
- objectBundleValidation.addObjectErrorReports( preheatService.checkUniqueness( bundle.getObjectMap().get( klass ), bundle.getPreheat() ) );
+ objectBundleValidation.addObjectErrorReports( preheatService.checkUniqueness( bundle.getObjectMap().get( klass ), bundle.getPreheat(),
+ bundle.getPreheatIdentifier() ) );
}
if ( bundle.getImportMode().isUpdate() )
@@ -182,7 +185,8 @@
objectBundleValidation.addObjectErrorReports( validateBySchemas( klass, bundle.getObjects( klass, true ), bundle ) );
objectBundleValidation.addObjectErrorReports( preheatService.checkReferences( bundle.getObjectMap().get( klass ),
bundle.getPreheat(), bundle.getPreheatIdentifier() ) );
- objectBundleValidation.addObjectErrorReports( preheatService.checkUniqueness( bundle.getObjectMap().get( klass ), bundle.getPreheat() ) );
+ objectBundleValidation.addObjectErrorReports( preheatService.checkUniqueness( bundle.getObjectMap().get( klass ), bundle.getPreheat(),
+ bundle.getPreheatIdentifier() ) );
}
if ( bundle.getImportMode().isDelete() )
=== modified file 'dhis-2/dhis-services/dhis-service-dxf2/src/test/java/org/hisp/dhis/dxf2/metadata2/objectbundle/ObjectBundleServiceTest.java'
--- dhis-2/dhis-services/dhis-service-dxf2/src/test/java/org/hisp/dhis/dxf2/metadata2/objectbundle/ObjectBundleServiceTest.java 2016-03-13 07:52:55 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/test/java/org/hisp/dhis/dxf2/metadata2/objectbundle/ObjectBundleServiceTest.java 2016-03-13 10:19:38 +0000
@@ -64,7 +64,6 @@
import org.hisp.dhis.user.UserGroup;
import org.hisp.dhis.user.UserService;
import org.hisp.dhis.validation.ValidationRule;
-import org.junit.Ignore;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
@@ -1371,7 +1370,6 @@
}
@Test
- @Ignore
public void testCreateMetadataWithSuperuserRoleInjected() throws IOException
{
createUserAndInjectSecurityContext( true );
@@ -1385,8 +1383,10 @@
params.setObjects( metadata );
ObjectBundle bundle = objectBundleService.create( params );
- assertTrue( objectBundleService.validate( bundle ).getObjectErrorReports().isEmpty() );
- objectBundleService.commit( bundle );
+ ObjectBundleValidation validate = objectBundleService.validate( bundle );
+
+ assertFalse( validate.getObjectErrorReports().isEmpty() );
+ assertEquals( 1, validate.getErrorReportsByCode( UserAuthorityGroup.class, ErrorCode.E5003 ).size() );
}
private void defaultSetup()