Hibernate support (#2147)
* Hibernate support --------- Signed-off-by: Avgustin Marinov <Avgustin.Marinov@bosch.com>
This commit is contained in:
3
hawkbit-repository/hawkbit-repository-jpa-api/README.md
Normal file
3
hawkbit-repository/hawkbit-repository-jpa-api/README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# hawkBit JPA EclipseLink Vendor integration
|
||||
|
||||
Implementation of [EclipseLink](http://www.eclipse.org/eclipselink/) JPA vendor.
|
||||
54
hawkbit-repository/hawkbit-repository-jpa-api/pom.xml
Normal file
54
hawkbit-repository/hawkbit-repository-jpa-api/pom.xml
Normal file
@@ -0,0 +1,54 @@
|
||||
<!--
|
||||
|
||||
Copyright (c) 2015 Bosch Software Innovations GmbH and others
|
||||
|
||||
This program and the accompanying materials are made
|
||||
available under the terms of the Eclipse Public License 2.0
|
||||
which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
|
||||
SPDX-License-Identifier: EPL-2.0
|
||||
|
||||
-->
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.eclipse.hawkbit</groupId>
|
||||
<version>${revision}</version>
|
||||
<artifactId>hawkbit-repository</artifactId>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>hawkbit-repository-jpa-api</artifactId>
|
||||
<name>hawkBit :: Repository :: JPA API</name>
|
||||
|
||||
<properties>
|
||||
<apt.source.dir>${project.build.directory}/generated-sources/apt/</apt.source.dir>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.hawkbit</groupId>
|
||||
<artifactId>hawkbit-repository-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.hibernate.orm</groupId>
|
||||
<artifactId>hibernate-core</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<!-- Static class generation -->
|
||||
<dependency>
|
||||
<groupId>org.hibernate.orm</groupId>
|
||||
<artifactId>hibernate-jpamodelgen</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -0,0 +1,84 @@
|
||||
/**
|
||||
* Copyright (c) 2015 Bosch Software Innovations GmbH and others
|
||||
*
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository.jpa;
|
||||
|
||||
import jakarta.persistence.PostLoad;
|
||||
import jakarta.persistence.PostPersist;
|
||||
import jakarta.persistence.PostRemove;
|
||||
import jakarta.persistence.PostUpdate;
|
||||
import jakarta.persistence.PrePersist;
|
||||
import jakarta.persistence.PreRemove;
|
||||
import jakarta.persistence.PreUpdate;
|
||||
|
||||
/**
|
||||
* Interface for the entity interceptor lifecycle.
|
||||
*/
|
||||
// Exception squid:EmptyStatementUsageCheck - don't want to force users to
|
||||
// implement all methods
|
||||
@SuppressWarnings("squid:EmptyStatementUsageCheck")
|
||||
public interface EntityInterceptor {
|
||||
|
||||
/**
|
||||
* Callback for the {@link PrePersist} lifecycle event.
|
||||
*
|
||||
* @param entity the model entity
|
||||
*/
|
||||
default void prePersist(final Object entity) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for the {@link PostPersist} lifecycle event.
|
||||
*
|
||||
* @param entity the model entity
|
||||
*/
|
||||
default void postPersist(final Object entity) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for the {@link PostRemove} lifecycle event.
|
||||
*
|
||||
* @param entity the model entity
|
||||
*/
|
||||
default void postRemove(final Object entity) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for the {@link PreRemove} lifecycle event.
|
||||
*
|
||||
* @param entity the model entity
|
||||
*/
|
||||
default void preRemove(final Object entity) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for the {@link PostLoad} lifecycle event.
|
||||
*
|
||||
* @param entity the model entity
|
||||
*/
|
||||
default void postLoad(final Object entity) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for the {@link PreUpdate} lifecycle event.
|
||||
*
|
||||
* @param entity the model entity
|
||||
*/
|
||||
default void preUpdate(final Object entity) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for the {@link PostUpdate} lifecycle event.
|
||||
*
|
||||
* @param entity the model entity
|
||||
*/
|
||||
default void postUpdate(final Object entity) {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/**
|
||||
* Copyright (c) 2015 Bosch Software Innovations GmbH and others
|
||||
*
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository.jpa.executor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.transaction.support.TransactionSynchronization;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
|
||||
/**
|
||||
* A Service which calls register runnable. This runnables will be executed after a successful spring transaction commit.
|
||||
* The class is thread safe.
|
||||
*/
|
||||
@Slf4j
|
||||
public class AfterTransactionCommitDefaultServiceExecutor implements AfterTransactionCommitExecutor {
|
||||
|
||||
private static class TransactionSynchronizationImpl implements TransactionSynchronization {
|
||||
|
||||
private final List<Runnable> afterCommitRunnables = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
// Exception squid:S1217 - Is aspectJ proxy
|
||||
@SuppressWarnings({ "squid:S1217" })
|
||||
public void afterCommit() {
|
||||
log.debug("Transaction successfully committed, executing {} runnables", afterCommitRunnables.size());
|
||||
for (final Runnable afterCommitRunnable : afterCommitRunnables) {
|
||||
log.debug("Executing runnable {}", afterCommitRunnable);
|
||||
try {
|
||||
afterCommitRunnable.run();
|
||||
} catch (final RuntimeException e) {
|
||||
log.error("Failed to execute runnable {}", afterCommitRunnable, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings({ "squid:S1217" })
|
||||
public void afterCompletion(final int status) {
|
||||
log.debug("Transaction completed after commit with status {}", status == TransactionSynchronization.STATUS_COMMITTED ? "COMMITTED" : "ROLLEDBACK");
|
||||
}
|
||||
|
||||
private void afterCommit(final Runnable runnable) {
|
||||
afterCommitRunnables.add(runnable);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
// Exception squid:S1217 - we want to run this synchronous
|
||||
@SuppressWarnings("squid:S1217")
|
||||
public void afterCommit(final Runnable runnable) {
|
||||
log.debug("Submitting new runnable {} to run after transaction commit", runnable);
|
||||
if (TransactionSynchronizationManager.isSynchronizationActive()) {
|
||||
TransactionSynchronizationManager.getSynchronizations().stream().filter(TransactionSynchronizationImpl.class::isInstance)
|
||||
.map(TransactionSynchronizationImpl.class::cast).findAny().orElseGet(() -> {
|
||||
final TransactionSynchronizationImpl newTS = new TransactionSynchronizationImpl();
|
||||
TransactionSynchronizationManager.registerSynchronization(newTS);
|
||||
return newTS;
|
||||
}).afterCommit(runnable);
|
||||
} else {
|
||||
log.info("Transaction synchronization is NOT ACTIVE/ INACTIVE. Executing right now runnable {}", runnable);
|
||||
runnable.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Copyright (c) 2015 Bosch Software Innovations GmbH and others
|
||||
*
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository.jpa.executor;
|
||||
|
||||
/**
|
||||
* A interface to register a runnable, which will be executed after a successful
|
||||
* spring transaction.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface AfterTransactionCommitExecutor {
|
||||
|
||||
/**
|
||||
* Register a runnable which will be executed after a successful spring
|
||||
* transaction.
|
||||
*
|
||||
* @param runnable the after commit runnable
|
||||
*/
|
||||
void afterCommit(Runnable runnable);
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
/**
|
||||
* Copyright (c) 2015 Bosch Software Innovations GmbH and others
|
||||
*
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository.jpa.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import jakarta.persistence.EntityListeners;
|
||||
import jakarta.persistence.MappedSuperclass;
|
||||
import jakarta.persistence.PostPersist;
|
||||
import jakarta.persistence.PostRemove;
|
||||
import jakarta.persistence.PostUpdate;
|
||||
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder;
|
||||
import org.eclipse.hawkbit.repository.model.BaseEntity;
|
||||
import org.eclipse.hawkbit.tenancy.TenantAwareAuthenticationDetails;
|
||||
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
|
||||
/**
|
||||
* Core information of all entities.
|
||||
*/
|
||||
@MappedSuperclass
|
||||
@EntityListeners({ AuditingEntityListener.class, EntityInterceptorListener.class })
|
||||
public abstract class AbstractBaseEntity implements BaseEntity, Serializable {
|
||||
|
||||
/**
|
||||
* Defined equals/hashcode strategy for the repository in general is that an entity is equal if it has the same {@link #getId()} and
|
||||
* {@link #getOptLockRevision()} and class.
|
||||
*/
|
||||
@Override
|
||||
// Exception squid:S864 - generated code
|
||||
@SuppressWarnings({ "squid:S864" })
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + (getId() == null ? 0 : getId().hashCode());
|
||||
result = prime * result + getOptLockRevision();
|
||||
result = prime * result + getClass().getName().hashCode();
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defined equals/hashcode strategy for the repository in general is that an entity is equal if it has the same {@link #getId()} and
|
||||
* {@link #getOptLockRevision()} and class.
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (!getClass().isInstance(obj)) {
|
||||
return false;
|
||||
}
|
||||
final BaseEntity other = (BaseEntity) obj;
|
||||
final Long id = getId();
|
||||
final Long otherId = other.getId();
|
||||
if (id == null) {
|
||||
if (otherId != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!id.equals(otherId)) {
|
||||
return false;
|
||||
}
|
||||
return getOptLockRevision() == other.getOptLockRevision();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getClass().getSimpleName() + " [id=" + getId() + "]";
|
||||
}
|
||||
|
||||
@PostPersist
|
||||
public void postInsert() {
|
||||
if (this instanceof EventAwareEntity eventAwareEntity) {
|
||||
doNotify(eventAwareEntity::fireCreateEvent);
|
||||
}
|
||||
}
|
||||
|
||||
@PostUpdate
|
||||
public void postUpdate() {
|
||||
if (this instanceof EventAwareEntity eventAwareEntity) {
|
||||
doNotify(eventAwareEntity::fireUpdateEvent);
|
||||
}
|
||||
}
|
||||
|
||||
@PostRemove
|
||||
public void postDelete() {
|
||||
if (this instanceof EventAwareEntity eventAwareEntity) {
|
||||
doNotify(eventAwareEntity::fireDeleteEvent);
|
||||
}
|
||||
}
|
||||
|
||||
protected static void doNotify(final Runnable runnable) {
|
||||
// fire events onl AFTER transaction commit
|
||||
AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit(runnable);
|
||||
}
|
||||
|
||||
protected boolean isController() {
|
||||
return SecurityContextHolder.getContext().getAuthentication() != null
|
||||
&& SecurityContextHolder.getContext().getAuthentication()
|
||||
.getDetails() instanceof TenantAwareAuthenticationDetails tenantAwareDetails
|
||||
&& tenantAwareDetails.isController();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/**
|
||||
* Copyright (c) 2015 Bosch Software Innovations GmbH and others
|
||||
*
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository.jpa.model;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import jakarta.persistence.PostLoad;
|
||||
import jakarta.persistence.PostPersist;
|
||||
import jakarta.persistence.PostRemove;
|
||||
import jakarta.persistence.PostUpdate;
|
||||
import jakarta.persistence.PrePersist;
|
||||
import jakarta.persistence.PreRemove;
|
||||
import jakarta.persistence.PreUpdate;
|
||||
|
||||
import org.eclipse.hawkbit.repository.jpa.EntityInterceptor;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.EntityInterceptorHolder;
|
||||
|
||||
/**
|
||||
* Entity listener which calls the callback's of all registered entity interceptors.
|
||||
*/
|
||||
public class EntityInterceptorListener {
|
||||
|
||||
/**
|
||||
* Callback for lifecyle event <i>pre persist</i>.
|
||||
*
|
||||
* @param entity the JPA entity which this listener is associated with
|
||||
*/
|
||||
@PrePersist
|
||||
public void prePersist(final Object entity) {
|
||||
notifyAll(interceptor -> interceptor.prePersist(entity));
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for lifecyle event <i>post persist</i>.
|
||||
*
|
||||
* @param entity the JPA entity which this listener is associated with
|
||||
*/
|
||||
@PostPersist
|
||||
public void postPersist(final Object entity) {
|
||||
notifyAll(interceptor -> interceptor.postPersist(entity));
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for lifecyle event <i>post remove</i>.
|
||||
*
|
||||
* @param entity the JPA entity which this listener is associated with
|
||||
*/
|
||||
@PostRemove
|
||||
public void postRemove(final Object entity) {
|
||||
notifyAll(interceptor -> interceptor.postRemove(entity));
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for lifecyle event <i>pre remove</i>.
|
||||
*
|
||||
* @param entity the JPA entity which this listener is associated with
|
||||
*/
|
||||
@PreRemove
|
||||
public void preRemove(final Object entity) {
|
||||
notifyAll(interceptor -> interceptor.preRemove(entity));
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for lifecyle event <i>post load</i>.
|
||||
*
|
||||
* @param entity the JPA entity which this listener is associated with
|
||||
*/
|
||||
@PostLoad
|
||||
public void postLoad(final Object entity) {
|
||||
notifyAll(interceptor -> interceptor.postLoad(entity));
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for lifecyle event <i>pre update</i>.
|
||||
*
|
||||
* @param entity the JPA entity which this listener is associated with
|
||||
*/
|
||||
@PreUpdate
|
||||
public void preUpdate(final Object entity) {
|
||||
notifyAll(interceptor -> interceptor.preUpdate(entity));
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for lifecyle event <i>post update</i>.
|
||||
*
|
||||
* @param entity the JPA entity which this listener is associated with
|
||||
*/
|
||||
@PostUpdate
|
||||
public void postUpdate(final Object entity) {
|
||||
notifyAll(interceptor -> interceptor.postUpdate(entity));
|
||||
}
|
||||
|
||||
private static void notifyAll(final Consumer<? super EntityInterceptor> action) {
|
||||
EntityInterceptorHolder.getInstance().getEntityInterceptors().forEach(action);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/**
|
||||
* Copyright (c) 2015 Bosch Software Innovations GmbH and others
|
||||
*
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository.jpa.model;
|
||||
|
||||
/**
|
||||
* Interfaces which can be implemented by entities to be called when the entity should fire an event because the entity has been created,
|
||||
* updated or deleted.
|
||||
*/
|
||||
public interface EventAwareEntity {
|
||||
|
||||
/**
|
||||
* Fired for the Entity creation.
|
||||
*/
|
||||
void fireCreateEvent();
|
||||
|
||||
/**
|
||||
* Fired for the Entity update.
|
||||
*/
|
||||
void fireUpdateEvent();
|
||||
|
||||
/**
|
||||
* Fired for the Entity deletion.
|
||||
*/
|
||||
void fireDeleteEvent();
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* Copyright (c) 2015 Bosch Software Innovations GmbH and others
|
||||
*
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository.jpa.model.helper;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.eclipse.hawkbit.repository.jpa.executor.AfterTransactionCommitExecutor;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
/**
|
||||
* A singleton bean which holds the {@link AfterTransactionCommitExecutor} to provide it to in beans not instantiated by spring e.g. JPA
|
||||
* entities which cannot be autowired.
|
||||
*/
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public final class AfterTransactionCommitExecutorHolder {
|
||||
|
||||
private static final AfterTransactionCommitExecutorHolder SINGLETON = new AfterTransactionCommitExecutorHolder();
|
||||
|
||||
@Autowired
|
||||
private AfterTransactionCommitExecutor afterCommit;
|
||||
|
||||
/**
|
||||
* @return the cache manager holder singleton instance
|
||||
*/
|
||||
public static AfterTransactionCommitExecutorHolder getInstance() {
|
||||
return SINGLETON;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the afterCommit
|
||||
*/
|
||||
public AfterTransactionCommitExecutor getAfterCommit() {
|
||||
return afterCommit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param afterCommit the afterCommit to set
|
||||
*/
|
||||
public void setAfterCommit(final AfterTransactionCommitExecutor afterCommit) {
|
||||
this.afterCommit = afterCommit;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* Copyright (c) 2015 Bosch Software Innovations GmbH and others
|
||||
*
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository.jpa.model.helper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.hawkbit.repository.jpa.EntityInterceptor;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
/**
|
||||
* A singleton bean which holds the {@link EntityInterceptor} to have all
|
||||
* interceptors in spring beans.
|
||||
*/
|
||||
public final class EntityInterceptorHolder {
|
||||
|
||||
private static final EntityInterceptorHolder SINGLETON = new EntityInterceptorHolder();
|
||||
|
||||
@Autowired(required = false)
|
||||
private final List<EntityInterceptor> entityInterceptors = new ArrayList<>();
|
||||
|
||||
private EntityInterceptorHolder() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the entity intreceptor holder singleton instance
|
||||
*/
|
||||
public static EntityInterceptorHolder getInstance() {
|
||||
return SINGLETON;
|
||||
}
|
||||
|
||||
public List<EntityInterceptor> getEntityInterceptors() {
|
||||
return entityInterceptors;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* Copyright (c) 2015 Bosch Software Innovations GmbH and others
|
||||
*
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository.jpa.model.helper;
|
||||
|
||||
import org.eclipse.hawkbit.security.SecurityTokenGenerator;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
/**
|
||||
* A singleton bean which holds the {@link SecurityTokenGenerator} and make it
|
||||
* accessible to beans which are not managed by spring, e.g. JPA entities.
|
||||
*/
|
||||
public final class SecurityTokenGeneratorHolder {
|
||||
|
||||
private static final SecurityTokenGeneratorHolder INSTANCE = new SecurityTokenGeneratorHolder();
|
||||
|
||||
@Autowired
|
||||
private SecurityTokenGenerator securityTokenGenerator;
|
||||
|
||||
/**
|
||||
* private constructor.
|
||||
*/
|
||||
private SecurityTokenGeneratorHolder() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a singleton instance of the security token generator holder.
|
||||
*/
|
||||
public static SecurityTokenGeneratorHolder getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* delegates to {@link SecurityTokenGenerator#generateToken()}.
|
||||
*
|
||||
* @return the result {@link SecurityTokenGenerator#generateToken()}
|
||||
*/
|
||||
public String generateToken() {
|
||||
return securityTokenGenerator.generateToken();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* Copyright (c) 2015 Bosch Software Innovations GmbH and others
|
||||
*
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository.jpa.model.helper;
|
||||
|
||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
/**
|
||||
* A singleton bean which holds {@link TenantAware} service and makes it
|
||||
* accessible to beans which are not managed by spring, e.g. JPA entities.
|
||||
*/
|
||||
public final class TenantAwareHolder {
|
||||
|
||||
private static final TenantAwareHolder INSTANCE = new TenantAwareHolder();
|
||||
|
||||
@Autowired
|
||||
private TenantAware tenantAware;
|
||||
|
||||
private TenantAwareHolder() {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the singleton {@link TenantAwareHolder} instance
|
||||
*/
|
||||
public static TenantAwareHolder getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the {@link TenantAware} service
|
||||
*/
|
||||
public TenantAware getTenantAware() {
|
||||
return tenantAware;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* Copyright (c) 2024 Contributors to the Eclipse Foundation
|
||||
*
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository.jpa.utils;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import jakarta.persistence.AttributeConverter;
|
||||
|
||||
public class MapAttributeConverter<JAVA_TYPE extends Enum<JAVA_TYPE>, DB_TYPE> implements AttributeConverter<JAVA_TYPE, DB_TYPE> {
|
||||
|
||||
private final Map<JAVA_TYPE, DB_TYPE> javaToDbMap;
|
||||
private final Map<DB_TYPE, JAVA_TYPE> dbToJavaMap;
|
||||
private final DB_TYPE nullMapping;
|
||||
|
||||
protected MapAttributeConverter(final Map<JAVA_TYPE, DB_TYPE> javaToDbMap, final DB_TYPE nullMapping) {
|
||||
this.javaToDbMap = javaToDbMap;
|
||||
this.nullMapping = nullMapping;
|
||||
this.dbToJavaMap = javaToDbMap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey));
|
||||
if (javaToDbMap.size() != dbToJavaMap.size()) {
|
||||
throw new IllegalArgumentException("Duplicate values in javaToDbMap");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public DB_TYPE convertToDatabaseColumn(final JAVA_TYPE attribute) {
|
||||
if (attribute == null) {
|
||||
return nullMapping;
|
||||
}
|
||||
return javaToDbMap.get(attribute);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JAVA_TYPE convertToEntityAttribute(final DB_TYPE dbData) {
|
||||
if (Objects.equals(dbData, nullMapping)) {
|
||||
return null;
|
||||
}
|
||||
return dbToJavaMap.get(dbData);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user