Prevent race conditions on same distributionId. 69/79069/2
authorBenjamin, Max (mb388a) <mb388a@us.att.com>
Sun, 24 Feb 2019 15:42:15 +0000 (10:42 -0500)
committerBenjamin, Max (mb388a) <mb388a@us.att.com>
Sun, 24 Feb 2019 21:10:26 +0000 (16:10 -0500)
- Code to include optimistic lock to prevent race conditions on same
distributionId.

Change-Id: Ibe110b32f2472d991a4a3e03e3d15d5e4deefd65
Issue-ID: SO-1566
Signed-off-by: Benjamin, Max (mb388a) <mb388a@us.att.com>
12 files changed:
adapters/mso-requests-db-adapter/src/main/resources/db/migration/V5.3.1__Watchdog_Lock_Version_Column.sql [new file with mode: 0644]
adapters/mso-requests-db-adapter/src/test/resources/db/migration/afterMigrate.sql
asdc-controller/src/main/java/org/onap/so/asdc/client/ASDCController.java
asdc-controller/src/main/java/org/onap/so/asdc/installer/heat/ToscaResourceInstaller.java
asdc-controller/src/test/resources/data.sql
asdc-controller/src/test/resources/schema.sql
mso-api-handlers/mso-api-handler-infra/src/test/resources/data.sql
mso-api-handlers/mso-api-handler-infra/src/test/resources/schema.sql
mso-api-handlers/mso-requests-db-repositories/src/main/java/org/onap/so/db/request/data/repository/WatchdogDistributionStatusRepository.java
mso-api-handlers/mso-requests-db-repositories/src/test/resources/afterMigrate.sql
mso-api-handlers/mso-requests-db-repositories/src/test/resources/schema.sql
mso-api-handlers/mso-requests-db/src/main/java/org/onap/so/db/request/beans/WatchdogDistributionStatus.java

diff --git a/adapters/mso-requests-db-adapter/src/main/resources/db/migration/V5.3.1__Watchdog_Lock_Version_Column.sql b/adapters/mso-requests-db-adapter/src/main/resources/db/migration/V5.3.1__Watchdog_Lock_Version_Column.sql
new file mode 100644 (file)
index 0000000..6379bc6
--- /dev/null
@@ -0,0 +1,3 @@
+use requestdb;
+
+ALTER TABLE watchdog_distributionid_status ADD LOCK_VERSION int NOT NULL;
index adfc731..de1ae85 100644 (file)
@@ -12,10 +12,10 @@ insert into infra_active_requests(request_id, client_request_id, action, request
 ('00173cc9-5ce2-4673-a810-f87fefb2829e', null, 'createInstance', 'FAILED', 'Error parsing request.  No valid instanceName is specified', '100', '2017-04-14 21:08:46', '2017-04-14 21:08:46', 'VID', null, null, null, null, null, 'a259ae7b7c3f493cb3d91f95a7c18149', null, null, null, '{"requestDetails":{"modelInfo":{"modelInvariantId":"ff6163d4-7214-459e-9f76-507b4eb00f51","modelType":"service","modelName":"ConstraintsSrvcVID","modelVersion":"2.0","modelVersionId":"722d256c-a374-4fba-a14f-a59b76bb7656"},"requestInfo":{"productFamilyId":"LRSI-OSPF","source":"VID","requestorId":"xxxxxx"},"subscriberInfo":{"globalSubscriberId":"a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb"},"cloudConfiguration":{"tenantId":"a259ae7b7c3f493cb3d91f95a7c18149","lcpCloudRegionId":"mtn16"},"requestParameters":{"subscriptionServiceType":"Mobility","userParams":[{"name":"neutronport6_name","value":"8"},{"name":"neutronnet5_network_name","value":"8"},{"name":"contrailv2vlansubinterface3_name","value":"false"}]}}}', null, 'APIH', '2016-12-22 19:00:28', null, null, null, null, null, null, null, 'mtn16', null, null, null, null, null, 'service', 'createInstance', null, null, null, null, null, null, null, 'http://localhost:8080/onap/so/infra/serviceInstantiation/v7/serviceInstances'),
 ('0017f68c-eb2d-45bb-b7c7-ec31b37dc349', null, 'activateInstance', 'UNLOCKED', null, '20', '2017-09-26 16:09:29', '2017-09-28 12:45:53', 'VID', null, null, null, null, null, null, null, null, null, '{"requestDetails":{"modelInfo":{"modelCustomizationName":null,"modelInvariantId":"1587cf0e-f12f-478d-8530-5c55ac578c39","modelType":"configuration","modelNameVersionId":null,"modelName":null,"modelVersion":null,"modelCustomizationUuid":null,"modelVersionId":"36a3a8ea-49a6-4ac8-b06c-89a545444455","modelCustomizationId":"68dc9a92-214c-11e7-93ae-92361f002671","modelUuid":null,"modelInvariantUuid":null,"modelInstanceName":null},"requestInfo":{"billingAccountNumber":null,"callbackUrl":null,"correlator":null,"orderNumber":null,"productFamilyId":null,"orderVersion":null,"source":"VID","instanceName":null,"suppressRollback":false,"requestorId":"xxxxxx"},"relatedInstanceList":[{"relatedInstance":{"instanceName":null,"instanceId":"9e15a443-af65-4f05-9000-47ae495e937d","modelInfo":{"modelCustomizationName":null,"modelInvariantId":"de19ae10-9a25-11e7-abc4-cec278b6b50a","modelType":"service","modelNameVersionId":null,"modelName":"MSOTADevInfra_Configuration_Service","modelVersion":"1.0","modelCustomizationUuid":null,"modelVersionId":"ee938612-9a25-11e7-abc4-cec278b6b50a","modelCustomizationId":null,"modelUuid":null,"modelInvariantUuid":null,"modelInstanceName":null},"instanceDirection":null}}],"subscriberInfo":null,"cloudConfiguration":{"aicNodeClli":null,"tenantId":null,"lcpCloudRegionId":"mtn6"},"requestParameters":{"subscriptionServiceType":null,"userParams":[],"aLaCarte":false,"autoBuildVfModules":false,"cascadeDelete":false,"usePreload":true,"alaCarte":false},"project":null,"owningEntity":null,"platform":null,"lineOfBusiness":null}}', null, 'APIH', '2017-09-26 16:09:29', null, null, null, null, null, null, null, 'mtn6', null, null, null, null, null, 'configuration', 'activateInstance', '9e15a443-af65-4f05-9000-47ae495e937d', null, 'xxxxxx', '26ef7f15-57bb-48df-8170-e59edc26234c', null, null, null, 'http://localhost:8080/onap/so/infra/serviceInstantiation/v7/serviceInstances');        
         
-insert into watchdog_distributionid_status(distribution_id, distribution_id_status, create_time, modify_time) values
-('1533c4bd-a3e3-493f-a16d-28c20614415e', '', '2017-11-30 15:48:09', '2017-11-30 15:48:09'),
-('55429711-809b-4a3b-9ee5-5120d46d9de0', '', '2017-11-30 16:35:36', '2017-11-30 16:35:36'),
-('67f0b2d1-9013-4b2b-9914-bbe2288284fb', '', '2017-11-30 15:54:39', '2017-11-30 15:54:39');   
+insert into watchdog_distributionid_status(distribution_id, distribution_id_status, lock_version, create_time, modify_time) values
+('1533c4bd-a3e3-493f-a16d-28c20614415e', '', 0, '2017-11-30 15:48:09', '2017-11-30 15:48:09'),
+('55429711-809b-4a3b-9ee5-5120d46d9de0', '', 0, '2017-11-30 16:35:36', '2017-11-30 16:35:36'),
+('67f0b2d1-9013-4b2b-9914-bbe2288284fb', '', 0, '2017-11-30 15:54:39', '2017-11-30 15:54:39');   
 
 insert into watchdog_per_component_distribution_status(distribution_id, component_name, component_distribution_status, create_time, modify_time) values
 ('1533c4bd-a3e3-493f-a16d-28c20614415e', 'MSO', 'COMPONENT_DONE_OK', '2017-11-30 15:48:09', '2017-11-30 15:48:09'),
index 7a02f47..a21deee 100644 (file)
@@ -30,6 +30,7 @@ import java.nio.file.Paths;
 import java.util.List;
 import java.util.Optional;
 
+import org.hibernate.StaleObjectStateException;
 import org.onap.sdc.api.IDistributionClient;
 import org.onap.sdc.api.consumer.IDistributionStatusMessage;
 import org.onap.sdc.api.consumer.IFinalDistrStatusMessage;
@@ -58,6 +59,7 @@ import org.onap.so.db.request.data.repository.WatchdogDistributionStatusReposito
 import org.onap.so.logger.MessageEnum;
 import org.onap.so.logger.MsoLogger;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.orm.ObjectOptimisticLockingFailureException;
 import org.springframework.stereotype.Component;
 
 import com.fasterxml.jackson.annotation.JsonInclude.Include;
@@ -592,6 +594,7 @@ public class ASDCController {
         try {
                LOGGER.debug(ASDCNotificationLogging.dumpASDCNotification(iNotif));
                        LOGGER.info(MessageEnum.ASDC_RECEIVE_SERVICE_NOTIF, iNotif.getServiceUUID(), "ASDC", "treatNotification");
+                                               
                        this.changeControllerStatus(ASDCControllerStatus.BUSY);
                        Optional<String> notificationMessage = getNotificationJson(iNotif);
                        toscaInstaller.processWatchdog(iNotif.getDistributionID(), iNotif.getServiceUUID(), notificationMessage,
@@ -619,7 +622,7 @@ public class ASDCController {
                                distributionStatus = wd.getOverallDistributionStatus(iNotif.getDistributionID());
                                Thread.sleep(watchDogTimeout / 10);             
                        }catch(Exception e){
-                               LOGGER.debug ("Exception in Watchdog Loop " + e);
+                               LOGGER.debug ("Exception in Watchdog Loop " + e.getMessage());
                                Thread.sleep(watchDogTimeout / 10);
                        }
                        
@@ -651,7 +654,7 @@ public class ASDCController {
                        LOGGER.debug ("A&AI Updated succefully with Distribution Status!");
                }
                catch(Exception e) {
-                       LOGGER.debug ("Exception in Watchdog executePatchAAI(): " + e);
+                       LOGGER.debug ("Exception in Watchdog executePatchAAI(): " + e.getMessage());
                        watchdogError = "Error calling A&AI " + e.getMessage();
                        if(e.getCause() != null) {
                                LOGGER.debug ("Exception caused by: " + e.getCause().getMessage());
@@ -671,8 +674,14 @@ public class ASDCController {
                        wdsRepo.save(wds);
                }
                
-               
 
+        } catch(ObjectOptimisticLockingFailureException e) {
+               
+               LOGGER.debug ("OptimisticLockingFailure for DistributionId: " + iNotif.getDistributionID() + " Another process has already altered this distribution, so not going to process it on this site.");
+               LOGGER.error (MessageEnum.ASDC_GENERAL_EXCEPTION_ARG,
+                    "Database concurrency exception: ",  "ASDC", "treatNotification", MsoLogger.ErrorCode.BusinessProcesssError, "RuntimeException in treatNotification",
+                    e);
+               
         } catch (Exception e) {
             LOGGER.error (MessageEnum.ASDC_GENERAL_EXCEPTION_ARG,
                           "Unexpected exception caught during the notification processing",  "ASDC", "treatNotification", MsoLogger.ErrorCode.SchemaError, "RuntimeException in treatNotification",
index 10b8ba7..60d5d7e 100644 (file)
@@ -34,6 +34,7 @@ import java.util.Optional;
 import java.util.Set;
 import java.util.stream.Collectors;
 
+import org.hibernate.StaleObjectStateException;
 import org.hibernate.exception.ConstraintViolationException;
 import org.hibernate.exception.LockAcquisitionException;
 import org.onap.sdc.api.notification.IArtifactInfo;
@@ -124,6 +125,7 @@ import org.onap.so.db.request.data.repository.WatchdogServiceModVerIdLookupRepos
 import org.onap.so.logger.MessageEnum;
 import org.onap.so.logger.MsoLogger;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.orm.ObjectOptimisticLockingFailureException;
 import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -701,10 +703,17 @@ public class ToscaResourceInstaller {
                                distributionNotification, consumerId);
                watchdogModVerIdLookupRepository.saveAndFlush(modVerIdLookup);
                
-               WatchdogDistributionStatus distributionStatus = new WatchdogDistributionStatus(distributionId);
-               watchdogDistributionStatusRepository.saveAndFlush(distributionStatus);
+               try{
+               
+                       WatchdogDistributionStatus distributionStatus = new WatchdogDistributionStatus(distributionId);
+                       watchdogDistributionStatusRepository.saveAndFlush(distributionStatus);
+                       
+               } catch(ObjectOptimisticLockingFailureException e){
+                       logger.debug("ObjectOptimisticLockingFailureException in processWatchdog : " + e.toString());
+                       throw e;
+               }
        }
-
+       
        protected void extractHeatInformation(ToscaResourceStructure toscaResourceStruct,
                        VfResourceStructure vfResourceStructure) {
                for (VfModuleArtifact vfModuleArtifact : vfResourceStructure.getArtifactsMapByUUID().values()) {
index 70737ab..7cd972c 100644 (file)
@@ -24,19 +24,19 @@ INSERT INTO temp_network_heat_template_lookup(NETWORK_RESOURCE_MODEL_NAME, HEAT_
 
 
 --------START Request DB INSERTS --------
-insert into requestdb.watchdog_distributionid_status(DISTRIBUTION_ID, DISTRIBUTION_ID_STATUS) values 
-('watchdogTestStatusSuccess', 'SUCCESS'),
-('watchdogTestStatusFailure', 'FAILURE'),
-('watchdogTestStatusTimeout', 'TIMEOUT'),
-('watchdogTestStatusIncomplete', 'INCOMPLETE'),
-('watchdogTestStatusException', 'EXCEPTION'),
-('watchdogTestStatusNull', 'NULL'),
-('testStatusSuccessTosca', 'SUCCESS'),
-('testStatusFailureTosca', 'FAILURE'),
-('testStatusTimeoutTosca', 'TIMEOUT'),
-('testStatusIncompleteTosca', 'INCOMPLETE'),
-('testStatusExceptionTosca', 'EXCEPTION'),
-('testStatusNullTosca', 'NULL');
+insert into requestdb.watchdog_distributionid_status(DISTRIBUTION_ID, DISTRIBUTION_ID_STATUS,LOCK_VERSION) values 
+('watchdogTestStatusSuccess', 'SUCCESS',0),
+('watchdogTestStatusFailure', 'FAILURE',0),
+('watchdogTestStatusTimeout', 'TIMEOUT',0),
+('watchdogTestStatusIncomplete', 'INCOMPLETE',0),
+('watchdogTestStatusException', 'EXCEPTION',0),
+('watchdogTestStatusNull', 'NULL',0),
+('testStatusSuccessTosca', 'SUCCESS',0),
+('testStatusFailureTosca', 'FAILURE',0),
+('testStatusTimeoutTosca', 'TIMEOUT',0),
+('testStatusIncompleteTosca', 'INCOMPLETE',0),
+('testStatusExceptionTosca', 'EXCEPTION',0),
+('testStatusNullTosca', 'NULL',0);
 
 --WatchdogDistrubutionTest
 insert into requestdb.watchdog_per_component_distribution_status(DISTRIBUTION_ID, COMPONENT_NAME, COMPONENT_DISTRIBUTION_STATUS) values
index 010b36d..43572c4 100644 (file)
@@ -990,6 +990,7 @@ CREATE TABLE `site_status` (
 CREATE TABLE `watchdog_distributionid_status` (
   `DISTRIBUTION_ID` varchar(45) NOT NULL,
   `DISTRIBUTION_ID_STATUS` varchar(45) DEFAULT NULL,
+  `LOCK_VERSION` int NOT NULL,
   `CREATE_TIME` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
   `MODIFY_TIME` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
   PRIMARY KEY (`DISTRIBUTION_ID`)
index 712cb98..f99f896 100644 (file)
@@ -31,10 +31,10 @@ INSERT INTO requestdb.activate_operational_env_per_distributionid_status(DISTRIB
     ('TEST_distributionId_2', 'DISTRIBUTION_COMPLETE_OK', NULL, '2018-02-02 18:44:27', '2018-02-02 18:45:06', '1dfe7154-eae0-44f2-8e7a-8e5e7882e55d', '37305814-4949-45ce-ae24-c378c7ed07d1', '483646fe-36cc-4e90-895a-c472f6da3f74');
     
     
-INSERT INTO requestdb.watchdog_distributionid_status(DISTRIBUTION_ID, DISTRIBUTION_ID_STATUS, CREATE_TIME, MODIFY_TIME) VALUES
-('1533c4bd-a3e3-493f-a16d-28c20614415e', '', '2017-11-30 15:48:09', '2017-11-30 15:48:09'),
-('55429711-809b-4a3b-9ee5-5120d46d9de0', '', '2017-11-30 16:35:36', '2017-11-30 16:35:36'),
-('67f0b2d1-9013-4b2b-9914-bbe2288284fb', '', '2017-11-30 15:54:39', '2017-11-30 15:54:39');   
+INSERT INTO requestdb.watchdog_distributionid_status(DISTRIBUTION_ID, DISTRIBUTION_ID_STATUS, LOCK_VERSION, CREATE_TIME, MODIFY_TIME) VALUES
+('1533c4bd-a3e3-493f-a16d-28c20614415e', '', 0, '2017-11-30 15:48:09', '2017-11-30 15:48:09'),
+('55429711-809b-4a3b-9ee5-5120d46d9de0', '', 0, '2017-11-30 16:35:36', '2017-11-30 16:35:36'),
+('67f0b2d1-9013-4b2b-9914-bbe2288284fb', '', 0, '2017-11-30 15:54:39', '2017-11-30 15:54:39');   
 
 
            
index 95db1c2..5873e14 100644 (file)
@@ -946,6 +946,7 @@ CREATE TABLE `site_status` (
 CREATE TABLE `watchdog_distributionid_status` (
   `DISTRIBUTION_ID` varchar(45) NOT NULL,
   `DISTRIBUTION_ID_STATUS` varchar(45) DEFAULT NULL,
+  `LOCK_VERSION` int NOT NULL,
   `CREATE_TIME` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
   `MODIFY_TIME` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
   PRIMARY KEY (`DISTRIBUTION_ID`)
index fde8485..6fddf85 100644 (file)
@@ -27,5 +27,7 @@ import org.springframework.stereotype.Repository;
 
 @RepositoryRestResource(collectionResourceRel = "watchdogDistributionStatus", path = "watchdogDistributionStatus")
 public interface WatchdogDistributionStatusRepository extends JpaRepository<WatchdogDistributionStatus, String> {
+       
+       public WatchdogDistributionStatus findOneByDistributionId(String distributionId);
 
 }
index b0e7479..43571e4 100644 (file)
@@ -12,10 +12,10 @@ insert into infra_active_requests(request_id, client_request_id, action, request
 ('00173cc9-5ce2-4673-a810-f87fefb2829e', null, 'createInstance', 'FAILED', 'Error parsing request.  No valid instanceName is specified', '100', '2017-04-14 21:08:46', '2017-04-14 21:08:46', 'VID', null, null, null, null, null, 'a259ae7b7c3f493cb3d91f95a7c18149', null, null, null, '{"requestDetails":{"modelInfo":{"modelInvariantId":"ff6163d4-7214-459e-9f76-507b4eb00f51","modelType":"service","modelName":"ConstraintsSrvcVID","modelVersion":"2.0","modelVersionId":"722d256c-a374-4fba-a14f-a59b76bb7656"},"requestInfo":{"productFamilyId":"LRSI-OSPF","source":"VID","requestorId":"xxxxxx"},"subscriberInfo":{"globalSubscriberId":"a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb"},"cloudConfiguration":{"tenantId":"a259ae7b7c3f493cb3d91f95a7c18149","lcpCloudRegionId":"mtn16"},"requestParameters":{"subscriptionServiceType":"Mobility","userParams":[{"name":"neutronport6_name","value":"8"},{"name":"neutronnet5_network_name","value":"8"},{"name":"contrailv2vlansubinterface3_name","value":"false"}]}}}', null, 'APIH', '2016-12-22 19:00:28', null, null, null, null, null, null, null, 'mtn16', null, null, null, null, null, 'service', 'createInstance', null, null, null, null, null, null, null, 'http://localhost:8080/onap/so/infra/serviceInstantiation/v7/serviceInstances'),
 ('0017f68c-eb2d-45bb-b7c7-ec31b37dc349', null, 'activateInstance', 'UNLOCKED', null, '20', '2017-09-26 16:09:29', '2017-09-28 12:45:53', 'VID', null, null, null, null, null, null, null, null, null, '{"requestDetails":{"modelInfo":{"modelCustomizationName":null,"modelInvariantId":"1587cf0e-f12f-478d-8530-5c55ac578c39","modelType":"configuration","modelNameVersionId":null,"modelName":null,"modelVersion":null,"modelCustomizationUuid":null,"modelVersionId":"36a3a8ea-49a6-4ac8-b06c-89a545444455","modelCustomizationId":"68dc9a92-214c-11e7-93ae-92361f002671","modelUuid":null,"modelInvariantUuid":null,"modelInstanceName":null},"requestInfo":{"billingAccountNumber":null,"callbackUrl":null,"correlator":null,"orderNumber":null,"productFamilyId":null,"orderVersion":null,"source":"VID","instanceName":null,"suppressRollback":false,"requestorId":"xxxxxx"},"relatedInstanceList":[{"relatedInstance":{"instanceName":null,"instanceId":"9e15a443-af65-4f05-9000-47ae495e937d","modelInfo":{"modelCustomizationName":null,"modelInvariantId":"de19ae10-9a25-11e7-abc4-cec278b6b50a","modelType":"service","modelNameVersionId":null,"modelName":"MSOTADevInfra_Configuration_Service","modelVersion":"1.0","modelCustomizationUuid":null,"modelVersionId":"ee938612-9a25-11e7-abc4-cec278b6b50a","modelCustomizationId":null,"modelUuid":null,"modelInvariantUuid":null,"modelInstanceName":null},"instanceDirection":null}}],"subscriberInfo":null,"cloudConfiguration":{"aicNodeClli":null,"tenantId":null,"lcpCloudRegionId":"mtn6"},"requestParameters":{"subscriptionServiceType":null,"userParams":[],"aLaCarte":false,"autoBuildVfModules":false,"cascadeDelete":false,"usePreload":true,"alaCarte":false},"project":null,"owningEntity":null,"platform":null,"lineOfBusiness":null}}', null, 'APIH', '2017-09-26 16:09:29', null, null, null, null, null, null, null, 'mtn6', null, null, null, null, null, 'configuration', 'activateInstance', '9e15a443-af65-4f05-9000-47ae495e937d', null, 'xxxxxx', '26ef7f15-57bb-48df-8170-e59edc26234c', null, null, null, 'http://localhost:8080/onap/so/infra/serviceInstantiation/v7/serviceInstances');        
         
-insert into watchdog_distributionid_status(distribution_id, distribution_id_status, create_time, modify_time) values
-('1533c4bd-a3e3-493f-a16d-28c20614415e', '', '2017-11-30 15:48:09', '2017-11-30 15:48:09'),
-('55429711-809b-4a3b-9ee5-5120d46d9de0', '', '2017-11-30 16:35:36', '2017-11-30 16:35:36'),
-('67f0b2d1-9013-4b2b-9914-bbe2288284fb', '', '2017-11-30 15:54:39', '2017-11-30 15:54:39');   
+insert into watchdog_distributionid_status(distribution_id, distribution_id_status, lock_version, create_time, modify_time) values
+('1533c4bd-a3e3-493f-a16d-28c20614415e', '', 0, '2017-11-30 15:48:09', '2017-11-30 15:48:09'),
+('55429711-809b-4a3b-9ee5-5120d46d9de0', '', 0, '2017-11-30 16:35:36', '2017-11-30 16:35:36'),
+('67f0b2d1-9013-4b2b-9914-bbe2288284fb', '', 0, '2017-11-30 15:54:39', '2017-11-30 15:54:39');   
 
 insert into watchdog_per_component_distribution_status(distribution_id, component_name, component_distribution_status, create_time, modify_time) values
 ('1533c4bd-a3e3-493f-a16d-28c20614415e', 'MSO', 'COMPONENT_DONE_OK', '2017-11-30 15:48:09', '2017-11-30 15:48:09'),
index bf9a9e1..541f356 100644 (file)
@@ -177,15 +177,16 @@ INSERT INTO PUBLIC.SITE_STATUS(SITE_NAME, STATUS, CREATION_TIMESTAMP) VALUES
 CREATE CACHED TABLE PUBLIC.WATCHDOG_DISTRIBUTIONID_STATUS(
     DISTRIBUTION_ID VARCHAR NOT NULL,
     DISTRIBUTION_ID_STATUS VARCHAR,
+    LOCK_VERSION int,
     CREATE_TIME VARCHAR,
     MODIFY_TIME VARCHAR
 ); 
            
         
-INSERT INTO PUBLIC.WATCHDOG_DISTRIBUTIONID_STATUS(DISTRIBUTION_ID, DISTRIBUTION_ID_STATUS, CREATE_TIME, MODIFY_TIME) VALUES
-('1533c4bd-a3e3-493f-a16d-28c20614415e', '', '2017-11-30 15:48:09', '2017-11-30 15:48:09'),
-('55429711-809b-4a3b-9ee5-5120d46d9de0', '', '2017-11-30 16:35:36', '2017-11-30 16:35:36'),
-('67f0b2d1-9013-4b2b-9914-bbe2288284fb', '', '2017-11-30 15:54:39', '2017-11-30 15:54:39');   
+INSERT INTO PUBLIC.WATCHDOG_DISTRIBUTIONID_STATUS(DISTRIBUTION_ID, DISTRIBUTION_ID_STATUS, LOCK_VERSION, CREATE_TIME, MODIFY_TIME) VALUES
+('1533c4bd-a3e3-493f-a16d-28c20614415e', '', 0, '2017-11-30 15:48:09', '2017-11-30 15:48:09'),
+('55429711-809b-4a3b-9ee5-5120d46d9de0', '', 0, '2017-11-30 16:35:36', '2017-11-30 16:35:36'),
+('67f0b2d1-9013-4b2b-9914-bbe2288284fb', '', 0, '2017-11-30 15:54:39', '2017-11-30 15:54:39');   
 
 CREATE CACHED TABLE PUBLIC.WATCHDOG_PER_COMPONENT_DISTRIBUTION_STATUS(
     DISTRIBUTION_ID VARCHAR NOT NULL,
index 40c81b9..69d84b7 100644 (file)
@@ -31,6 +31,8 @@ import javax.persistence.PreUpdate;
 import javax.persistence.Table;
 import javax.persistence.Temporal;
 import javax.persistence.TemporalType;
+import javax.persistence.Version;
+
 import java.util.Objects;
 import org.apache.commons.lang3.builder.ToStringBuilder;
 
@@ -54,6 +56,9 @@ public class WatchdogDistributionStatus implements Serializable {
        @Column(name = "MODIFY_TIME")
        @Temporal(TemporalType.TIMESTAMP)
        private Date modifyTime;
+       @Version
+       @Column(name = "LOCK_VERSION")
+    private int version; 
        
        public WatchdogDistributionStatus() {
                
@@ -78,7 +83,15 @@ public class WatchdogDistributionStatus implements Serializable {
        public void setDistributionIdStatus(String distributionIdStatus) {
                this.distributionIdStatus = distributionIdStatus;
        }
-       
+               
+       public int getVersion() {
+               return version;
+       }
+
+       public void setVersion(int version) {
+               this.version = version;
+       }
+
        public Date getCreateTime() {
                return createTime;
        }