TransactionMongoManager.java

1
package io.github.marcopaglio.booking.transaction.manager.mongo;
2
3
import com.mongodb.MongoCommandException;
4
import com.mongodb.ReadConcern;
5
import com.mongodb.ReadPreference;
6
import com.mongodb.TransactionOptions;
7
import com.mongodb.WriteConcern;
8
import com.mongodb.client.MongoClient;
9
10
import io.github.marcopaglio.booking.exception.TransactionException;
11
import io.github.marcopaglio.booking.repository.factory.ClientRepositoryFactory;
12
import io.github.marcopaglio.booking.repository.factory.ReservationRepositoryFactory;
13
import io.github.marcopaglio.booking.repository.mongo.ClientMongoRepository;
14
import io.github.marcopaglio.booking.repository.mongo.ReservationMongoRepository;
15
import io.github.marcopaglio.booking.transaction.code.ClientReservationTransactionCode;
16
import io.github.marcopaglio.booking.transaction.code.ClientTransactionCode;
17
import io.github.marcopaglio.booking.transaction.code.ReservationTransactionCode;
18
import io.github.marcopaglio.booking.transaction.handler.factory.TransactionHandlerFactory;
19
import io.github.marcopaglio.booking.transaction.handler.mongo.TransactionMongoHandler;
20
import io.github.marcopaglio.booking.transaction.manager.TransactionManager;
21
22
/**
23
 * An implementation of {@code TransactionManager} for managing code executed
24
 * on MongoDB within transactions.
25
 */
26
public class TransactionMongoManager extends TransactionManager {
27
	/**
28
	 * Specifies that the reason the transaction fails is a commitment failure.
29
	 */
30
	private static final String COMMIT_FAILURE = "a commitment failure";
31
32
	/**
33
	 * Options used to configure transactions.
34
	 * Note: casually consistency is applied when both read and write concerns
35
	 * has value 'majority'.
36
	 */
37
	public static final TransactionOptions TXN_OPTIONS = TransactionOptions.builder()
38
			.readPreference(ReadPreference.primary())
39
			.readConcern(ReadConcern.MAJORITY)
40
			.writeConcern(WriteConcern.MAJORITY)
41
			.build();
42
43
	/**
44
	 * Used for executing code on {@code ClientRepository} and/or {@code ReservationRepository}
45
	 * into transactions.
46
	 * Particularly, it allows to create sessions, transactions and repositories.
47
	 */
48
	private MongoClient mongoClient;
49
50
	/**
51
	 * Name of the mongoDB database in which the repository works.
52
	 */
53
	private String databaseName;
54
55
	/**
56
	 * Constructs a manager for applying code that uses entity repositories 
57
	 * using MongoDB transactions.
58
	 * 
59
	 * @param mongoClient					the client connected to the MongoDB database.
60
	 * @param databaseName					the name of the MongoDB database.
61
	 * @param transactionHandlerFactory		the factory to create {@code ClientSession} instances.
62
	 * @param clientRepositoryFactory		the factory to create
63
	 * 										{@code ClientMongoRepository} instances.
64
	 * @param reservationRepositoryFactory	the factory to create
65
	 * 										{@code ReservationMongoRepository} instances.
66
	 */
67
	public TransactionMongoManager(MongoClient mongoClient, String databaseName,
68
			TransactionHandlerFactory transactionHandlerFactory,
69
			ClientRepositoryFactory clientRepositoryFactory,
70
			ReservationRepositoryFactory reservationRepositoryFactory) {
71
		super(transactionHandlerFactory, clientRepositoryFactory, reservationRepositoryFactory);
72
		this.databaseName = databaseName;
73
		this.mongoClient = mongoClient;
74
	}
75
76
	/**
77
	 * Prepares to execution of code that involves the {@code ClientRepository}'s method(s)
78
	 * on MongoDB in a single transaction.
79
	 * 
80
	 * @param <R>					the returned type of executed code.
81
	 * @param code					the code to execute.
82
	 * @return						something depending on execution code.
83
	 * @throws TransactionException	if the execution or the commitment of the transaction fails.
84
	 */
85
	@Override
86
	public <R> R doInTransaction(ClientTransactionCode<R> code) throws TransactionException {
87
		TransactionMongoHandler sessionHandler =
88
				transactionHandlerFactory.createTransactionHandler(mongoClient, TXN_OPTIONS);
89
		ClientMongoRepository clientRepository = clientRepositoryFactory
90
				.createClientRepository(mongoClient, sessionHandler.getHandler(), databaseName);
91
		try {
92 1 1. doInTransaction : replaced return value with null for io/github/marcopaglio/booking/transaction/manager/mongo/TransactionMongoManager::doInTransaction → KILLED
			return executeInTransaction(code, sessionHandler, clientRepository);
93
		} catch(MongoCommandException e) {
94
			LOGGER.warn(e.getMessage());
95
			throw new TransactionException(
96
					transactionFailureMsg(COMMIT_FAILURE), e.getCause());
97
		}
98
	}
99
100
	/**
101
	 * Prepares to execution of code that involves the {@code ReservationRepository}'s method(s)
102
	 * on MongoDB in a single transaction.
103
	 * 
104
	 * @param <R>					the returned type of executed code.
105
	 * @param code					the code to execute.
106
	 * @return						something depending on execution code.
107
	 * @throws TransactionException	if the execution or the commitment of the transaction fails.
108
	 */
109
	@Override
110
	public <R> R doInTransaction(ReservationTransactionCode<R> code) throws TransactionException {
111
		TransactionMongoHandler sessionHandler =
112
				transactionHandlerFactory.createTransactionHandler(mongoClient, TXN_OPTIONS);
113
		ReservationMongoRepository reservationRepository = reservationRepositoryFactory
114
				.createReservationRepository(mongoClient, sessionHandler.getHandler(), databaseName);
115
		try {
116 1 1. doInTransaction : replaced return value with null for io/github/marcopaglio/booking/transaction/manager/mongo/TransactionMongoManager::doInTransaction → KILLED
			return executeInTransaction(code, sessionHandler, reservationRepository);
117
		} catch(MongoCommandException e) {
118
			LOGGER.warn(e.getMessage());
119
			throw new TransactionException(
120
					transactionFailureMsg(COMMIT_FAILURE), e.getCause());
121
		}
122
	}
123
124
	/**
125
	 * Prepares to execution of code that involves both {@code ClientRepository}'s and
126
	 * {@code ReservationRepository}'s methods on MongoDB in a single transaction.
127
	 * 
128
	 * @param <R>					the returned type of executed code.
129
	 * @param code					the code to execute.
130
	 * @return						something depending on execution code.
131
	 * @throws TransactionException	if the execution or the commitment of the transaction fails.
132
	 */
133
	@Override
134
	public <R> R doInTransaction(ClientReservationTransactionCode<R> code) throws TransactionException {
135
		TransactionMongoHandler sessionHandler =
136
				transactionHandlerFactory.createTransactionHandler(mongoClient, TXN_OPTIONS);
137
		ClientMongoRepository clientRepository = clientRepositoryFactory
138
				.createClientRepository(mongoClient, sessionHandler.getHandler(), databaseName);
139
		ReservationMongoRepository reservationRepository = reservationRepositoryFactory
140
				.createReservationRepository(mongoClient, sessionHandler.getHandler(), databaseName);
141
		try {
142 1 1. doInTransaction : replaced return value with null for io/github/marcopaglio/booking/transaction/manager/mongo/TransactionMongoManager::doInTransaction → KILLED
			return executeInTransaction(code, sessionHandler, clientRepository, reservationRepository);
143
		} catch(MongoCommandException e) {
144
			LOGGER.warn(e.getMessage());
145
			throw new TransactionException(
146
					transactionFailureMsg(COMMIT_FAILURE), e.getCause());
147
		}
148
	}
149
}

Mutations

92

1.1
Location : doInTransaction
Killed by : io.github.marcopaglio.booking.transaction.manager.mongo.TransactionMongoManagerTest.[engine:junit-jupiter]/[class:io.github.marcopaglio.booking.transaction.manager.mongo.TransactionMongoManagerTest]/[nested-class:ClientTransactionCodeTest]/[method:testDoInTransactionWhenCallsAMethodShouldApplyAndReturn()]
replaced return value with null for io/github/marcopaglio/booking/transaction/manager/mongo/TransactionMongoManager::doInTransaction → KILLED

116

1.1
Location : doInTransaction
Killed by : io.github.marcopaglio.booking.transaction.manager.mongo.TransactionMongoManagerTest.[engine:junit-jupiter]/[class:io.github.marcopaglio.booking.transaction.manager.mongo.TransactionMongoManagerTest]/[nested-class:ReservationTransactionCodeTest]/[method:testDoInTransactionWhenCallsAMethodShouldApplyAndReturn()]
replaced return value with null for io/github/marcopaglio/booking/transaction/manager/mongo/TransactionMongoManager::doInTransaction → KILLED

142

1.1
Location : doInTransaction
Killed by : io.github.marcopaglio.booking.transaction.manager.mongo.TransactionMongoManagerTest.[engine:junit-jupiter]/[class:io.github.marcopaglio.booking.transaction.manager.mongo.TransactionMongoManagerTest]/[nested-class:ClientReservationTransactionCodeTest]/[method:testDoInTransactionWhenCodeCallsMethodsShouldApplyAndReturn()]
replaced return value with null for io/github/marcopaglio/booking/transaction/manager/mongo/TransactionMongoManager::doInTransaction → KILLED

Active mutators

Tests examined


Report generated by PIT 1.15.6