use of org.springframework.transaction.annotation.Propagation in project syncope by apache.
the class JPAUserDAO method findDynGroups.
@Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true)
@Override
@SuppressWarnings("unchecked")
public List<Group> findDynGroups(final String key) {
Query query = entityManager().createNativeQuery("SELECT group_id FROM " + JPAGroupDAO.UDYNMEMB_TABLE + " WHERE any_id=?");
query.setParameter(1, key);
List<Group> result = new ArrayList<>();
query.getResultList().stream().map(resultKey -> resultKey instanceof Object[] ? (String) ((Object[]) resultKey)[0] : ((String) resultKey)).forEachOrdered(actualKey -> {
Group group = groupDAO().find(actualKey.toString());
if (group == null) {
LOG.error("Could not find group with id {}, even though returned by the native query", actualKey);
} else if (!result.contains(group)) {
result.add(group);
}
});
return result;
}
use of org.springframework.transaction.annotation.Propagation in project metacat by Netflix.
the class DirectSqlTable method updateIcebergTable.
/**
* Locks and updates the iceberg table for update so that no other request can modify the table at the same time.
* 1. Gets the table parameters and locks the requested records. If lock cannot be attained,
* the request to update fails
* 2. Validates the metadata location
* 3. If validated, updates the table parameters.
* @param tableInfo table info
*/
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void updateIcebergTable(final TableInfo tableInfo) {
final QualifiedName tableName = tableInfo.getName();
final Map<String, String> newTableMetadata = tableInfo.getMetadata();
//
if (newTableMetadata == null || newTableMetadata.isEmpty()) {
final String message = String.format("No parameters defined for iceberg table %s", tableName);
log.warn(message);
throw new InvalidMetaException(tableName, message, null);
}
//
// If the previous metadata location is not empty, check if it is valid.
//
final String previousMetadataLocation = newTableMetadata.get(PARAM_PREVIOUS_METADATA_LOCATION);
if (config.isIcebergPreviousMetadataLocationCheckEnabled() && !StringUtils.isBlank(previousMetadataLocation)) {
boolean doesPathExists = true;
try {
final Path previousMetadataPath = new Path(previousMetadataLocation);
doesPathExists = warehouse.getFs(previousMetadataPath).exists(previousMetadataPath);
} catch (Exception ignored) {
log.warn(String.format("Failed getting the filesystem for %s", previousMetadataLocation));
registry.counter(HiveMetrics.CounterFileSystemReadFailure.name()).increment();
}
if (!doesPathExists) {
throw new InvalidMetaException(tableName, String.format("Invalid metadata for %s..Location %s does not exist", tableName, previousMetadataLocation), null);
}
}
final Long tableId = getTableId(tableName);
Map<String, String> existingTableMetadata = null;
log.debug("Lock Iceberg table {}", tableName);
try {
existingTableMetadata = jdbcTemplate.query(SQL.TABLE_PARAMS_LOCK, new SqlParameterValue[] { new SqlParameterValue(Types.BIGINT, tableId) }, rs -> {
final Map<String, String> result = Maps.newHashMap();
while (rs.next()) {
result.put(rs.getString(COL_PARAM_KEY), rs.getString(COL_PARAM_VALUE));
}
return result;
});
} catch (EmptyResultDataAccessException ex) {
log.info(String.format("No parameters defined for iceberg table %s", tableName));
} catch (Exception ex) {
final String message = String.format("Failed getting a lock on iceberg table %s", tableName);
log.warn(message, ex);
throw new InvalidMetaException(tableName, message, null);
}
if (existingTableMetadata == null) {
existingTableMetadata = Maps.newHashMap();
}
final boolean needUpdate = validateIcebergUpdate(tableName, existingTableMetadata, newTableMetadata);
final String existingMetadataLocation = existingTableMetadata.get(PARAM_METADATA_LOCATION);
final String newMetadataLocation = newTableMetadata.get(PARAM_METADATA_LOCATION);
log.info("Servicing Iceberg commit request with tableId: {}, needUpdate: {}, " + "previousLocation: {}, existingLocation: {}, newLocation: {}", tableId, needUpdate, previousMetadataLocation, existingMetadataLocation, newMetadataLocation);
if (needUpdate) {
final MapDifference<String, String> diff = Maps.difference(existingTableMetadata, newTableMetadata);
insertTableParams(tableId, diff.entriesOnlyOnRight());
final Map<String, String> updateParams = diff.entriesDiffering().entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, s -> s.getValue().rightValue()));
updateTableParams(tableId, updateParams);
//
// In addition to updating the table params, the table location in HMS needs to be updated for usage by
// external tools, that access HMS directly
//
updateTableLocation(tableId, tableInfo);
log.info("Finished updating Iceberg table with tableId: {}", tableId);
}
log.debug("Unlocked Iceberg table {}", tableName);
}
use of org.springframework.transaction.annotation.Propagation in project webofneeds by researchstudio-sat.
the class WonWebSocketHandler method process.
/**
* Sends a message coming from the WoN node to the client.
*/
@Override
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED)
public WonMessage process(final WonMessage wonMessage) {
try {
logger.debug("processing message {} incoming from node", wonMessage.getMessageURI());
String wonMessageJsonLdString = WonMessageEncoder.encodeAsJsonLd(wonMessage);
WebSocketMessage<String> webSocketMessage = new TextMessage(wonMessageJsonLdString);
logger.debug("determining which owned atom is to be informed of message {} ", wonMessage.getMessageURI());
URI atomUri = getOwnedAtomURIForMessageFromNode(wonMessage);
logger.debug("obtaining WebSocketSessions for message {} ", wonMessage.getMessageURI());
Set<WebSocketSession> webSocketSessions = webSocketSessionService.getWebSocketSessions(atomUri);
Optional<User> userOpt = webSocketSessions == null ? Optional.empty() : webSocketSessions.stream().filter(s -> s.isOpen()).findFirst().map(s -> getUserForSession(s));
logger.debug("found {} sessions for message {} ", webSocketSessions.size(), wonMessage.getMessageURI());
logger.debug("found user for message {} via session: {} ", wonMessage.getMessageURI(), userOpt.isPresent());
if (!userOpt.isPresent()) {
userOpt = Optional.ofNullable(userRepository.findByAtomUri(atomUri));
}
logger.debug("found user for message {} atom uri: {} ", wonMessage.getMessageURI(), userOpt.isPresent());
// it's quite possible that we don't find the user object this way.
User user = userOpt.orElse(null);
// Methods below can handle that.
logger.debug("updating user-atom association for message {}, user has been found:{} ", wonMessage.getMessageURI(), userOpt.isPresent());
userAtomService.updateUserAtomAssociation(wonMessage, user);
logger.debug("trying to find WebSocketSessions for message{}, atom {}, user has been found:{}", new Object[] { wonMessage.getMessageURI(), atomUri, userOpt.isPresent() });
webSocketSessions = webSocketSessionService.findWebSocketSessionsForAtomAndUser(atomUri, user);
// check if we can deliver the message. If not, send email.
if (webSocketSessions.size() == 0) {
if (logger.isDebugEnabled()) {
logger.debug("cannot deliver message {}: no websocket session found. Trying to send message by email.", wonMessage.toShortStringForDebug());
}
notifyUserOnDifferentChannel(wonMessage, atomUri, user);
return wonMessage;
}
// we can send it - pre-cache the delivery chain:
logger.debug("put message {} into cache before sending on websocket", wonMessage.getMessageURI());
eagerlyCachePopulatingProcessor.process(wonMessage);
// send to owner webapp
int successfullySent = 0;
for (WebSocketSession session : webSocketSessions) {
logger.debug("sending message {} via websocket session", wonMessage.getMessageURI());
successfullySent += sendMessageForSession(wonMessage, webSocketMessage, session, atomUri, user) ? 1 : 0;
}
logger.debug("sent message {} via {} websocket sessions", wonMessage.getMessageURI(), successfullySent);
if (successfullySent == 0) {
// we did not manage to send the message via the websocket, send it by email.
if (logger.isDebugEnabled()) {
logger.debug("cannot deliver message {}: none of the associated websocket sessions worked. Trying to send message by webpush and email.", wonMessage.toShortStringForDebug());
}
// TODO: ideally in this case
// 1. collect multiple events occurring in close succession
// 2. try to push
// 3. email only if push was not successful
notifyUserOnDifferentChannel(wonMessage, atomUri, user);
} else {
// Always send possible pushNotifications:
// - maybe session is active -> message was send, but Tab is not focused
// - Browser is running in background -> user needs to get push notification
Optional<URI> connectionURI = WonLinkedDataUtils.getConnectionURIForIncomingMessage(wonMessage, linkedDataSource);
if (connectionURI.isPresent()) {
logger.debug("notifying user per web push for message {}", wonMessage.getMessageURI());
UserAtom userAtom = getAtomOfUser(user, atomUri);
if (userAtom == null) {
userOpt = Optional.ofNullable(userRepository.findByAtomUri(atomUri));
user = userOpt.orElse(null);
}
notifyPerPush(user, atomUri, wonMessage, connectionURI.get());
}
logger.debug("cannot notify user: cannot determine connection URI");
}
return wonMessage;
} finally {
// in any case, let the serversideactionservice do its work, if there is any to
// do:
logger.debug("processing server side actions for message {} if any are registered", wonMessage.getMessageURI());
serverSideActionService.process(wonMessage);
}
}
Aggregations