← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 9715: FRED-API: UUIDs as system identifiers, wip

 

------------------------------------------------------------
revno: 9715
committer: Morten Olav Hansen <mortenoh@xxxxxxxxx>
branch nick: dhis2
timestamp: Tue 2013-02-05 01:03:10 +0700
message:
  FRED-API: UUIDs as system identifiers, wip
modified:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/organisationunit/OrganisationUnit.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/common/IdentityPopulator.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/startup/TableAlteror.java
  dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/organisationunit/hibernate/OrganisationUnit.hbm.xml
  dhis-2/dhis-web/dhis-web-api-fred/src/main/java/org/hisp/dhis/web/webapi/v1/controller/FacilityController.java
  dhis-2/dhis-web/dhis-web-api-fred/src/main/java/org/hisp/dhis/web/webapi/v1/domain/Identifier.java
  dhis-2/dhis-web/dhis-web-api-fred/src/main/java/org/hisp/dhis/web/webapi/v1/utils/FacilityToOrganisationUnitConverter.java
  dhis-2/dhis-web/dhis-web-api-fred/src/main/java/org/hisp/dhis/web/webapi/v1/utils/OrganisationUnitToFacilityConverter.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/organisationunit/OrganisationUnit.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/organisationunit/OrganisationUnit.java	2012-12-17 10:16:35 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/organisationunit/OrganisationUnit.java	2013-02-04 18:03:10 +0000
@@ -35,6 +35,7 @@
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
+import java.util.UUID;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -82,6 +83,8 @@
 
     private static final String NAME_SEPARATOR = " - ";
 
+    private String uuid;
+
     private OrganisationUnit parent;
 
     private Date openingDate;
@@ -142,10 +145,12 @@
 
     public OrganisationUnit()
     {
+        this.uuid = UUID.randomUUID().toString();
     }
 
     public OrganisationUnit( String name )
     {
+        this();
         this.name = name;
     }
 
@@ -160,7 +165,7 @@
     public OrganisationUnit( String name, String shortName, String code, Date openingDate, Date closedDate,
         boolean active, String comment )
     {
-        this.name = name;
+        this(name);
         this.shortName = shortName;
         this.code = code;
         this.openingDate = openingDate;
@@ -181,7 +186,7 @@
     public OrganisationUnit( String name, OrganisationUnit parent, String shortName, String code, Date openingDate,
         Date closedDate, boolean active, String comment )
     {
-        this.name = name;
+        this(name);
         this.parent = parent;
         this.shortName = shortName;
         this.code = code;
@@ -599,6 +604,16 @@
     // Getters and setters
     // -------------------------------------------------------------------------
 
+    public String getUuid()
+    {
+        return uuid;
+    }
+
+    public void setUuid( String uuid )
+    {
+        this.uuid = uuid;
+    }
+
     @JsonProperty
     @JsonSerialize( as = BaseIdentifiableObject.class )
     @JsonView( { DetailedView.class, ExportView.class } )

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/common/IdentityPopulator.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/common/IdentityPopulator.java	2013-02-04 17:13:05 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/common/IdentityPopulator.java	2013-02-04 18:03:10 +0000
@@ -40,6 +40,7 @@
 import java.sql.Statement;
 import java.sql.Timestamp;
 import java.util.Date;
+import java.util.UUID;
 
 /**
  * @author bobj
@@ -148,6 +149,39 @@
             }
         }
 
+        try
+        {
+            Connection conn = dummyStatement.getConnection();
+
+            statement = conn.createStatement( ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE );
+
+            ResultSet resultSet = statement.executeQuery( "SELECT * from organisationunit WHERE uuid IS NULL" );
+            int count = 0;
+
+            while ( resultSet.next() )
+            {
+                ++count;
+                resultSet.updateString( "uuid", UUID.randomUUID().toString() );
+                resultSet.updateRow();
+            }
+
+            if ( count > 0 )
+            {
+                log.info( count + " UUIDs updated on organisationunit" );
+            }
+        }
+        catch ( SQLException ex )
+        {
+            log.info( "Problem updating organisationunit: ", ex );
+        }
+        finally
+        {
+            if ( statement != null )
+            {
+                statement.close();
+            }
+        }
+
         createUidConstraints();
     }
 

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/startup/TableAlteror.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/startup/TableAlteror.java	2013-02-04 14:57:16 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/startup/TableAlteror.java	2013-02-04 18:03:10 +0000
@@ -377,7 +377,7 @@
         executeSql( "ALTER TABLE indicatorgroup DROP COLUMN uuid" );
         executeSql( "ALTER TABLE indicatorgroupset DROP COLUMN uuid" );
         executeSql( "ALTER TABLE indicatortype DROP COLUMN uuid" );
-        executeSql( "ALTER TABLE organisationunit DROP COLUMN uuid" );
+        // executeSql( "ALTER TABLE organisationunit DROP COLUMN uuid" );
         executeSql( "ALTER TABLE orgunitgroup DROP COLUMN uuid" );
         executeSql( "ALTER TABLE orgunitgroupset DROP COLUMN uuid" );
         executeSql( "ALTER TABLE orgunitlevel DROP COLUMN uuid" );

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/organisationunit/hibernate/OrganisationUnit.hbm.xml'
--- dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/organisationunit/hibernate/OrganisationUnit.hbm.xml	2012-05-24 05:13:57 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/organisationunit/hibernate/OrganisationUnit.hbm.xml	2013-02-04 18:03:10 +0000
@@ -24,6 +24,8 @@
     <many-to-one name="parent" class="org.hisp.dhis.organisationunit.OrganisationUnit" column="parentid"
         foreign-key="fk_parentid" index="in_parentid" />
 
+    <property name="uuid" unique="true" length="36"/>
+
     <property name="shortName" column="shortname" not-null="true" unique="false" length="50" />
 
     <property name="description" type="text" />

=== modified file 'dhis-2/dhis-web/dhis-web-api-fred/src/main/java/org/hisp/dhis/web/webapi/v1/controller/FacilityController.java'
--- dhis-2/dhis-web/dhis-web-api-fred/src/main/java/org/hisp/dhis/web/webapi/v1/controller/FacilityController.java	2013-02-04 14:57:16 +0000
+++ dhis-2/dhis-web/dhis-web-api-fred/src/main/java/org/hisp/dhis/web/webapi/v1/controller/FacilityController.java	2013-02-04 18:03:10 +0000
@@ -40,6 +40,7 @@
 import org.hisp.dhis.user.CurrentUserService;
 import org.hisp.dhis.web.webapi.v1.domain.Facilities;
 import org.hisp.dhis.web.webapi.v1.domain.Facility;
+import org.hisp.dhis.web.webapi.v1.domain.Identifier;
 import org.hisp.dhis.web.webapi.v1.utils.ContextUtils;
 import org.hisp.dhis.web.webapi.v1.utils.MessageResponseUtils;
 import org.hisp.dhis.web.webapi.v1.utils.ObjectMapperFactoryBean;
@@ -86,9 +87,9 @@
 /**
  * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
  */
-@Controller(value = "facility-controller-" + FredController.PREFIX)
-@RequestMapping(FacilityController.RESOURCE_PATH)
-@PreAuthorize("hasRole('M_dhis-web-api-fred') or hasRole('ALL')")
+@Controller( value = "facility-controller-" + FredController.PREFIX )
+@RequestMapping( FacilityController.RESOURCE_PATH )
+@PreAuthorize( "hasRole('M_dhis-web-api-fred') or hasRole('ALL')" )
 public class FacilityController
 {
     public static final String RESOURCE_PATH = "/" + FredController.PREFIX + "/facilities";
@@ -234,13 +235,13 @@
         return facility;
     }
 
-    @RequestMapping(value = "", method = RequestMethod.GET)
-    public String readFacilities( Model model, @RequestParam(required = false) Boolean active,
-        @RequestParam(value = "updatedSince", required = false) Date lastUpdated,
-        @RequestParam(value = "allProperties", required = false, defaultValue = "true") Boolean allProperties,
-        @RequestParam(value = "fields", required = false) String fields,
-        @RequestParam(value = "limit", required = false) Integer limit,
-        @RequestParam(value = "offset", required = false, defaultValue = "0") Integer offset,
+    @RequestMapping( value = "", method = RequestMethod.GET )
+    public String readFacilities( Model model, @RequestParam( required = false ) Boolean active,
+        @RequestParam( value = "updatedSince", required = false ) Date lastUpdated,
+        @RequestParam( value = "allProperties", required = false, defaultValue = "true" ) Boolean allProperties,
+        @RequestParam( value = "fields", required = false ) String fields,
+        @RequestParam( value = "limit", required = false ) Integer limit,
+        @RequestParam( value = "offset", required = false, defaultValue = "0" ) Integer offset,
         HttpServletRequest request )
     {
         Facilities facilities = new Facilities();
@@ -317,10 +318,10 @@
         return FredController.PREFIX + "/layout";
     }
 
-    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
+    @RequestMapping( value = "/{id}", method = RequestMethod.GET )
     public String readFacility( Model model, @PathVariable String id,
-        @RequestParam(value = "allProperties", required = false, defaultValue = "true") Boolean allProperties,
-        @RequestParam(value = "fields", required = false) String fields,
+        @RequestParam( value = "allProperties", required = false, defaultValue = "true" ) Boolean allProperties,
+        @RequestParam( value = "fields", required = false ) String fields,
         HttpServletRequest request )
     {
         OrganisationUnit organisationUnit = organisationUnitService.getOrganisationUnit( id );
@@ -390,8 +391,8 @@
     // POST JSON
     //--------------------------------------------------------------------------
 
-    @RequestMapping(value = "", method = RequestMethod.POST)
-    @PreAuthorize("hasRole('F_FRED_CREATE') or hasRole('ALL')")
+    @RequestMapping( value = "", method = RequestMethod.POST )
+    @PreAuthorize( "hasRole('F_FRED_CREATE') or hasRole('ALL')" )
     public ResponseEntity<String> createFacility( @RequestBody Facility facility ) throws Exception
     {
         Set<ConstraintViolation<Facility>> constraintViolations = validator.validate( facility, Default.class, Create.class );
@@ -405,9 +406,13 @@
         {
             OrganisationUnit organisationUnit = conversionService.convert( facility, OrganisationUnit.class );
 
+            if ( organisationUnitService.getOrganisationUnit( organisationUnit.getUuid() ) != null )
+            {
+                return new ResponseEntity<String>( MessageResponseUtils.jsonMessage( "An object with that UUID already exists." ), headers, HttpStatus.CONFLICT );
+            }
             if ( organisationUnitService.getOrganisationUnit( organisationUnit.getUid() ) != null )
             {
-                return new ResponseEntity<String>( MessageResponseUtils.jsonMessage( "An object with that ID already exists." ), headers, HttpStatus.CONFLICT );
+                return new ResponseEntity<String>( MessageResponseUtils.jsonMessage( "An object with that UID already exists." ), headers, HttpStatus.CONFLICT );
             }
             else if ( organisationUnitService.getOrganisationUnitByName( organisationUnit.getName() ) != null )
             {
@@ -453,11 +458,43 @@
         return builder.toString();
     }
 
-    @RequestMapping(value = "/{id}", method = RequestMethod.PUT, consumes = MediaType.APPLICATION_JSON_VALUE)
-    @PreAuthorize("hasRole('F_FRED_UPDATE') or hasRole('ALL')")
+    protected void checkUidIdentifier( Facility facility, String id )
+    {
+        Identifier identifier = new Identifier();
+
+        identifier.setAgency( Identifier.DHIS2_AGENCY );
+        identifier.setContext( Identifier.DHIS2_UID_CONTEXT );
+        identifier.setId( id );
+
+        if ( facility.getIdentifiers().isEmpty() )
+        {
+            facility.getIdentifiers().add( identifier );
+        }
+        else
+        {
+            boolean found = false;
+
+            for ( Identifier i : facility.getIdentifiers() )
+            {
+                if ( i.getAgency().equals( Identifier.DHIS2_AGENCY ) && i.getContext().equals( Identifier.DHIS2_UID_CONTEXT ) )
+                {
+                    i.setId( id );
+                    found = true;
+                }
+            }
+
+            if ( !found )
+            {
+                facility.getIdentifiers().add( identifier );
+            }
+        }
+    }
+
+    @RequestMapping( value = "/{id}", method = RequestMethod.PUT, consumes = MediaType.APPLICATION_JSON_VALUE )
+    @PreAuthorize( "hasRole('F_FRED_UPDATE') or hasRole('ALL')" )
     public ResponseEntity<String> updateFacility( @PathVariable String id, @RequestBody Facility facility, HttpServletRequest request ) throws Exception
     {
-        facility.setId( id );
+        checkUidIdentifier( facility, id );
         Set<ConstraintViolation<Facility>> constraintViolations = validator.validate( facility, Default.class, Update.class );
 
         String json = ValidationUtils.constraintViolationsToJson( constraintViolations );
@@ -536,8 +573,8 @@
     // DELETE JSON
     //--------------------------------------------------------------------------
 
-    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
-    @PreAuthorize("hasRole('F_FRED_DELETE') or hasRole('ALL')")
+    @RequestMapping( value = "/{id}", method = RequestMethod.DELETE )
+    @PreAuthorize( "hasRole('F_FRED_DELETE') or hasRole('ALL')" )
     public ResponseEntity<Void> deleteFacility( @PathVariable String id ) throws HierarchyViolationException
     {
         OrganisationUnit organisationUnit = organisationUnitService.getOrganisationUnit( id );
@@ -556,7 +593,7 @@
     // EXCEPTION HANDLERS
     //--------------------------------------------------------------------------
 
-    @ExceptionHandler({ DeleteNotAllowedException.class, HierarchyViolationException.class })
+    @ExceptionHandler( { DeleteNotAllowedException.class, HierarchyViolationException.class } )
     public ResponseEntity<String> exceptionHandler( Exception ex )
     {
         return new ResponseEntity<String>( ex.getMessage(), HttpStatus.FORBIDDEN );

=== modified file 'dhis-2/dhis-web/dhis-web-api-fred/src/main/java/org/hisp/dhis/web/webapi/v1/domain/Identifier.java'
--- dhis-2/dhis-web/dhis-web-api-fred/src/main/java/org/hisp/dhis/web/webapi/v1/domain/Identifier.java	2013-01-31 02:31:35 +0000
+++ dhis-2/dhis-web/dhis-web-api-fred/src/main/java/org/hisp/dhis/web/webapi/v1/domain/Identifier.java	2013-02-04 18:03:10 +0000
@@ -34,6 +34,7 @@
 {
     public static final String DHIS2_AGENCY = "DHIS2";
     public static final String DHIS2_CODE_CONTEXT = "DHIS2_CODE";
+    public static final String DHIS2_UID_CONTEXT = "DHIS2_UID";
 
     private String id;
 

=== modified file 'dhis-2/dhis-web/dhis-web-api-fred/src/main/java/org/hisp/dhis/web/webapi/v1/utils/FacilityToOrganisationUnitConverter.java'
--- dhis-2/dhis-web/dhis-web-api-fred/src/main/java/org/hisp/dhis/web/webapi/v1/utils/FacilityToOrganisationUnitConverter.java	2013-01-31 03:22:50 +0000
+++ dhis-2/dhis-web/dhis-web-api-fred/src/main/java/org/hisp/dhis/web/webapi/v1/utils/FacilityToOrganisationUnitConverter.java	2013-02-04 18:03:10 +0000
@@ -77,12 +77,17 @@
         {
             for ( Identifier identifier : facility.getIdentifiers() )
             {
-                // for now, this is the only known identifier
+                // two known system identifiers, uid and code
                 if ( identifier.getAgency().equalsIgnoreCase( Identifier.DHIS2_AGENCY )
                     && identifier.getContext().equalsIgnoreCase( Identifier.DHIS2_CODE_CONTEXT ) )
                 {
                     organisationUnit.setCode( identifier.getId() );
                 }
+                else if ( identifier.getAgency().equalsIgnoreCase( Identifier.DHIS2_AGENCY )
+                    && identifier.getContext().equalsIgnoreCase( Identifier.DHIS2_UID_CONTEXT ) )
+                {
+                    organisationUnit.setUid( identifier.getId() );
+                }
             }
         }
 

=== modified file 'dhis-2/dhis-web/dhis-web-api-fred/src/main/java/org/hisp/dhis/web/webapi/v1/utils/OrganisationUnitToFacilityConverter.java'
--- dhis-2/dhis-web/dhis-web-api-fred/src/main/java/org/hisp/dhis/web/webapi/v1/utils/OrganisationUnitToFacilityConverter.java	2013-01-25 20:45:07 +0000
+++ dhis-2/dhis-web/dhis-web-api-fred/src/main/java/org/hisp/dhis/web/webapi/v1/utils/OrganisationUnitToFacilityConverter.java	2013-02-04 18:03:10 +0000
@@ -27,11 +27,6 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
-
-import java.util.ArrayList;
-import java.util.List;
-
 import org.hisp.dhis.dataset.DataSet;
 import org.hisp.dhis.organisationunit.OrganisationUnit;
 import org.hisp.dhis.organisationunit.OrganisationUnitService;
@@ -42,6 +37,11 @@
 import org.springframework.core.convert.converter.Converter;
 import org.springframework.stereotype.Component;
 
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
+
 /**
  * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
  */
@@ -55,12 +55,12 @@
     public Facility convert( OrganisationUnit organisationUnit )
     {
         Facility facility = new Facility();
-        facility.setId( organisationUnit.getUid() );
+        facility.setId( organisationUnit.getUuid() );
         facility.setName( organisationUnit.getDisplayName() );
         facility.setActive( organisationUnit.isActive() );
         facility.setCreatedAt( organisationUnit.getCreated() );
         facility.setUpdatedAt( organisationUnit.getLastUpdated() );
-        facility.setUrl( linkTo( FacilityController.class ).slash( facility.getId() ).toString() );
+        facility.setUrl( linkTo( FacilityController.class ).slash( organisationUnit.getUid() ).toString() );
 
         if ( organisationUnit.getFeatureType() != null && organisationUnit.getFeatureType().equalsIgnoreCase( "POINT" )
             && organisationUnit.getCoordinates() != null )
@@ -82,9 +82,17 @@
             facility.getProperties().put( "parent", organisationUnit.getParent().getUid() );
         }
 
+        Identifier identifier = new Identifier();
+
+        identifier.setAgency( Identifier.DHIS2_AGENCY );
+        identifier.setContext( Identifier.DHIS2_UID_CONTEXT );
+        identifier.setId( organisationUnit.getUid() );
+
+        facility.getIdentifiers().add( identifier );
+
         if ( organisationUnit.getCode() != null )
         {
-            Identifier identifier = new Identifier();
+            identifier = new Identifier();
             identifier.setAgency( Identifier.DHIS2_AGENCY );
             identifier.setContext( Identifier.DHIS2_CODE_CONTEXT );
             identifier.setId( organisationUnit.getCode() );