2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.openecomp.sdc.common.transaction.mngr;
23 import fj.data.Either;
24 import org.openecomp.sdc.be.config.BeEcompErrorManager;
25 import org.openecomp.sdc.be.dao.impl.ESCatalogDAO;
26 import org.openecomp.sdc.be.dao.titan.TitanGenericDao;
27 import org.openecomp.sdc.be.resources.data.ESArtifactData;
28 import org.openecomp.sdc.common.log.wrappers.Logger;
29 import org.openecomp.sdc.common.transaction.api.*;
30 import org.openecomp.sdc.common.transaction.api.TransactionUtils.*;
31 import org.openecomp.sdc.common.transaction.impl.ESAction;
32 import org.openecomp.sdc.common.transaction.impl.ESRollbackHandler;
33 import org.openecomp.sdc.common.transaction.impl.TitanCommitHandler;
34 import org.openecomp.sdc.common.transaction.impl.TitanRollbackHandler;
35 import org.openecomp.sdc.common.util.MethodActivationStatusEnum;
37 import java.util.ArrayList;
38 import java.util.List;
40 public class TransactionSdncImpl implements ITransactionSdnc {
42 // TODO test using slf4j-test and make this final
43 private static Logger log = Logger.getLogger(TransactionSdncImpl.class);
44 private boolean lastActionAlreadyCalled;
45 private RollbackManager rollbackManager;
46 private CommitManager commitManager;
47 private ESCatalogDAO esCatalogDao;
48 private TitanGenericDao titanGenericDao;
49 private Integer transactionId;
50 private TransactionStatusEnum status;
51 private String userId, actionType;
53 TransactionSdncImpl(Integer transactionId, String userId, ActionTypeEnum actionTypeEnum, ESCatalogDAO esCatalogDao, TitanGenericDao titanGenericDao) {
54 this.esCatalogDao = esCatalogDao;
55 this.titanGenericDao = titanGenericDao;
56 this.transactionId = transactionId;
58 actionType = actionTypeEnum.name();
59 rollbackManager = new RollbackManager(transactionId, userId, actionType, initRollbackHandlers());
60 commitManager = new CommitManager(transactionId, userId, actionType, initCommitHandlers());
61 status = TransactionStatusEnum.OPEN;
65 private List<ICommitHandler> initCommitHandlers() {
66 List<ICommitHandler> commitHandlers = new ArrayList<>();
67 commitHandlers.add(new TitanCommitHandler(titanGenericDao));
68 return commitHandlers;
71 private List<RollbackHandler> initRollbackHandlers() {
72 List<RollbackHandler> rolebackHandlers = new ArrayList<>();
73 rolebackHandlers.add(new TitanRollbackHandler(transactionId, userId, actionType, titanGenericDao));
74 rolebackHandlers.add(new ESRollbackHandler(transactionId, userId, actionType));
75 return rolebackHandlers;
78 private <T> Either<T, TransactionCodeEnum> invokeAction(boolean isLastAction, IDBAction dbAction, DBTypeEnum dbType) {
80 Either<T, DBActionCodeEnum> actionResult;
81 log.debug(LogMessages.INVOKE_ACTION, transactionId, dbType.name(), userId, actionType);
83 actionResult = getLastActionResult(dbAction, dbType);
85 actionResult = getActionResult(dbAction, dbType);
88 Either<T, TransactionCodeEnum> result;
89 boolean isRollbackNedded = actionResult.isRight();
90 if (isRollbackNedded) {
91 TransactionCodeEnum transactionCode = transactionRollback();
92 result = Either.right(transactionCode);
94 result = Either.left(actionResult.left().value());
99 private TransactionCodeEnum transactionRollback() {
101 TransactionCodeEnum result;
102 DBActionCodeEnum transactionRollback = rollbackManager.transactionRollback();
103 if (transactionRollback == DBActionCodeEnum.SUCCESS) {
104 result = TransactionCodeEnum.ROLLBACK_SUCCESS;
105 log.info(LogMessages.ROLLBACK_SUCCEEDED_GENERAL, transactionId, userId, actionType);
106 log.info(TransactionUtils.TRANSACTION_MARKER, LogMessages.ROLLBACK_SUCCEEDED_GENERAL, transactionId, userId, actionType);
109 result = TransactionCodeEnum.ROLLBACK_FAILED;
110 BeEcompErrorManager.getInstance().logBeSystemError("transactionCommit for transaction " + transactionId);
112 log.info(LogMessages.ROLLBACK_FAILED_GENERAL, transactionId, userId, actionType);
113 log.debug(TransactionUtils.TRANSACTION_MARKER, LogMessages.ROLLBACK_FAILED_GENERAL, transactionId, userId, actionType);
118 public <T> Either<T, TransactionCodeEnum> invokeTitanAction(boolean isLastAction, IDBAction dbAction) {
119 Either<T, TransactionCodeEnum> result;
120 if (status == TransactionStatusEnum.OPEN) {
121 result = invokeAction(isLastAction, dbAction, DBTypeEnum.TITAN);
123 result = handleActionOnClosedTransaction();
125 updateTransactionStatus(result);
129 public <T> Either<T, TransactionCodeEnum> invokeGeneralDBAction(boolean isLastAction, DBTypeEnum dbType, IDBAction dbAction, IDBAction dbRollbackAction) {
131 Either<T, TransactionCodeEnum> result;
132 MethodActivationStatusEnum addingHandlerResult;
133 if (status == TransactionStatusEnum.OPEN) {
134 log.debug(LogMessages.PRE_INVOKE_ACTION, transactionId, dbType.name(), userId, actionType);
135 Either<RollbackHandler, MethodActivationStatusEnum> eitherRollbackHandler = rollbackManager.getRollbackHandler(dbType);
137 if (eitherRollbackHandler.isLeft()) {
138 RollbackHandler rollbackHandler = eitherRollbackHandler.left().value();
139 addingHandlerResult = rollbackHandler.addRollbackAction(dbRollbackAction);
141 addingHandlerResult = addToNewRollbackHandler(dbType, dbRollbackAction);
144 if (addingHandlerResult == MethodActivationStatusEnum.SUCCESS) {
145 result = invokeAction(isLastAction, dbAction, dbType);
147 result = Either.right(TransactionCodeEnum.PREPARE_ROLLBACK_FAILED);
150 result = handleActionOnClosedTransaction();
152 updateTransactionStatus(result);
156 private MethodActivationStatusEnum addToNewRollbackHandler(DBTypeEnum dbType, IDBAction dbRollbackAction) {
157 log.debug(LogMessages.CREATE_ROLLBACK_HANDLER, dbType.name(), transactionId, userId, actionType);
158 MethodActivationStatusEnum result;
160 Either<RollbackHandler, MethodActivationStatusEnum> eitherRollbackHandler = rollbackManager.createRollbackHandler(dbType);
161 if (eitherRollbackHandler.isRight()) {
162 result = eitherRollbackHandler.right().value();
163 BeEcompErrorManager.getInstance().logBeSystemError("TransactionManager - addToNewRollbackHandler");
164 log.info(LogMessages.FAILED_CREATE_ROLLBACK, dbType.name(), transactionId, userId, actionType);
165 log.debug(TransactionUtils.TRANSACTION_MARKER, LogMessages.FAILED_CREATE_ROLLBACK, dbType.name(), transactionId, userId, actionType);
167 RollbackHandler rollbackHandler = eitherRollbackHandler.left().value();
168 rollbackHandler.addRollbackAction(dbRollbackAction);
169 result = MethodActivationStatusEnum.SUCCESS;
175 public Either<DBActionCodeEnum, TransactionCodeEnum> invokeESAction(boolean isLastAction, ESActionTypeEnum esActiontype, ESArtifactData artifactData) {
177 Either<DBActionCodeEnum, TransactionCodeEnum> result;
178 if (status == TransactionStatusEnum.OPEN) {
179 Either<RollbackHandler, MethodActivationStatusEnum> eitherEsHandler = rollbackManager.getRollbackHandler(DBTypeEnum.ELASTIC_SEARCH);
180 if (eitherEsHandler.isRight()) {
181 result = Either.right(TransactionCodeEnum.INTERNAL_ERROR);
183 ESRollbackHandler esHandler = (ESRollbackHandler) eitherEsHandler.left().value();
185 Either<ESAction, MethodActivationStatusEnum> eitherEsRollbackAction = esHandler.buildEsRollbackAction(esCatalogDao, artifactData, esActiontype);
186 if (eitherEsRollbackAction.isLeft()) {
187 esHandler.addRollbackAction(eitherEsRollbackAction.left().value());
188 result = invokeAction(isLastAction, new ESAction(esCatalogDao, artifactData, esActiontype), DBTypeEnum.ELASTIC_SEARCH);
190 result = Either.right(TransactionCodeEnum.PREPARE_ROLLBACK_FAILED);
195 result = handleActionOnClosedTransaction();
197 updateTransactionStatus(result);
201 private <T> void updateTransactionStatus(Either<T, TransactionCodeEnum> result) {
202 if (result.isRight()) {
203 updateTransactionStatus(result.right().value());
208 private <T> Either<T, TransactionCodeEnum> handleActionOnClosedTransaction() {
209 Either<T, TransactionCodeEnum> result = Either.right(TransactionCodeEnum.TRANSACTION_CLOSED);
210 log.debug(LogMessages.ACTION_ON_CLOSED_TRANSACTION, transactionId, userId, actionType);
211 log.info(TransactionUtils.TRANSACTION_MARKER, LogMessages.ACTION_ON_CLOSED_TRANSACTION, transactionId, userId, actionType);
215 private <T> Either<T, DBActionCodeEnum> getLastActionResult(IDBAction dataBaseAction, DBTypeEnum dbType) {
216 Either<T, DBActionCodeEnum> result;
217 if (isLastActionAlreadyCalled()) {
218 result = Either.right(DBActionCodeEnum.FAIL_MULTIPLE_LAST_ACTION);
219 BeEcompErrorManager.getInstance().logBeSystemError("TransactionManager - getLastActionResult");
220 log.debug(LogMessages.DOUBLE_FINISH_FLAG_ACTION, transactionId, dbType.name(), userId, actionType);
221 log.info(TransactionUtils.TRANSACTION_MARKER, LogMessages.DOUBLE_FINISH_FLAG_ACTION, transactionId, dbType.name(), userId, actionType);
223 setLastActionAlreadyCalled(true);
224 result = getActionResult(dataBaseAction, dbType);
229 private <T> Either<T, DBActionCodeEnum> getActionResult(IDBAction dataBaseAction, DBTypeEnum dbType) {
230 Either<T, DBActionCodeEnum> result;
232 T doAction = dataBaseAction.doAction();
233 result = Either.left(doAction);
234 } catch (Exception e) {
235 BeEcompErrorManager.getInstance().logBeSystemError("TransactionManager - getActionResult");
236 log.debug(LogMessages.DB_ACTION_FAILED_WITH_EXCEPTION, dbType.name(), transactionId, e.getMessage(), userId, actionType, e);
237 log.info(TransactionUtils.TRANSACTION_MARKER, LogMessages.DB_ACTION_FAILED_WITH_EXCEPTION, dbType.name(), transactionId, e.getMessage(), userId, actionType);
239 result = Either.right(DBActionCodeEnum.FAIL_GENERAL);
244 public TransactionCodeEnum finishTransaction() {
245 TransactionCodeEnum result;
246 if (status == TransactionStatusEnum.OPEN) {
247 DBActionCodeEnum transactionCommit = commitManager.transactionCommit();
248 if (transactionCommit == DBActionCodeEnum.SUCCESS) {
249 result = TransactionCodeEnum.SUCCESS;
250 status = TransactionStatusEnum.CLOSED;
252 result = transactionRollback();
255 BeEcompErrorManager.getInstance().logBeSystemError("TransactionManager - finishTransaction");
256 log.debug(LogMessages.COMMIT_ON_CLOSED_TRANSACTION, transactionId, status.name(), userId, actionType);
257 log.info(TransactionUtils.TRANSACTION_MARKER, LogMessages.COMMIT_ON_CLOSED_TRANSACTION, transactionId, status.name(), userId, actionType);
258 result = TransactionCodeEnum.TRANSACTION_CLOSED;
260 updateTransactionStatus(result);
264 private void updateTransactionStatus(TransactionCodeEnum result) {
267 status = TransactionStatusEnum.CLOSED;
269 case ROLLBACK_SUCCESS:
270 status = TransactionStatusEnum.CLOSED;
272 case ROLLBACK_FAILED:
273 status = TransactionStatusEnum.FAILED_ROLLBACK;
281 private boolean isLastActionAlreadyCalled() {
282 return lastActionAlreadyCalled;
285 private void setLastActionAlreadyCalled(boolean lastAction) {
286 this.lastActionAlreadyCalled = lastAction;
289 // TODO test using slf4j-test and remove this
290 static void setLog(Logger log) {
291 TransactionSdncImpl.log = log;
294 TransactionStatusEnum getStatus() {