-
Notifications
You must be signed in to change notification settings - Fork 191
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Avgustin Marinov <[email protected]>
- Loading branch information
1 parent
af50e8c
commit 00116c7
Showing
41 changed files
with
1,292 additions
and
216 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# hawkBit JPA EclipseLink Vendor integration | ||
|
||
Implementation of [EclipseLink](http://www.eclipse.org/eclipselink/) JPA vendor. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
<!-- | ||
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> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>org.eclipse.persistence</groupId> | ||
<artifactId>org.eclipse.persistence.jpa</artifactId> | ||
<version>${eclipselink.version}</version> | ||
</dependency> | ||
</dependencies> | ||
</project> |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
213 changes: 213 additions & 0 deletions
213
...jpa-api/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaBaseEntity.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,213 @@ | ||
/** | ||
* 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.Serial; | ||
|
||
import jakarta.persistence.Access; | ||
import jakarta.persistence.AccessType; | ||
import jakarta.persistence.Column; | ||
import jakarta.persistence.EntityListeners; | ||
import jakarta.persistence.GeneratedValue; | ||
import jakarta.persistence.GenerationType; | ||
import jakarta.persistence.Id; | ||
import jakarta.persistence.MappedSuperclass; | ||
import jakarta.persistence.PostPersist; | ||
import jakarta.persistence.PostRemove; | ||
import jakarta.persistence.PostUpdate; | ||
import jakarta.persistence.Version; | ||
|
||
import lombok.AccessLevel; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
import lombok.Setter; | ||
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.annotation.CreatedBy; | ||
import org.springframework.data.annotation.CreatedDate; | ||
import org.springframework.data.annotation.LastModifiedBy; | ||
import org.springframework.data.annotation.LastModifiedDate; | ||
import org.springframework.data.jpa.domain.support.AuditingEntityListener; | ||
import org.springframework.security.core.context.SecurityContextHolder; | ||
|
||
/** | ||
* Base hawkBit entity class containing the common attributes. | ||
*/ | ||
@NoArgsConstructor(access = AccessLevel.PROTECTED) // Default constructor needed for JPA entities. | ||
@MappedSuperclass | ||
@EntityListeners({ AuditingEntityListener.class, EntityInterceptorListener.class }) | ||
public abstract class AbstractJpaBaseEntity implements BaseEntity { | ||
|
||
protected static final int USERNAME_FIELD_LENGTH = 64; | ||
|
||
@Serial | ||
private static final long serialVersionUID = 1L; | ||
|
||
@Setter // should be used just for test purposes | ||
@Getter | ||
@Id | ||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
@Column(name = "id") | ||
private Long id; | ||
|
||
@Setter // should be used just for test purposes | ||
@Getter | ||
@Version | ||
@Column(name = "optlock_revision") | ||
private int optLockRevision; | ||
|
||
// Audit fields. use property access to ensure that setters will be called and checked for modification | ||
// (touch implementation depends on setLastModifiedAt(1). | ||
@Column(name = "created_by", updatable = false, nullable = false, length = USERNAME_FIELD_LENGTH) | ||
private String createdBy; | ||
@Column(name = "created_at", updatable = false, nullable = false) | ||
private long createdAt; | ||
@Column(name = "last_modified_by", nullable = false, length = USERNAME_FIELD_LENGTH) | ||
private String lastModifiedBy; | ||
@Column(name = "last_modified_at", nullable = false) | ||
private long lastModifiedAt; | ||
|
||
@CreatedBy | ||
public void setCreatedBy(final String createdBy) { | ||
this.createdBy = createdBy; | ||
} | ||
|
||
@Column(name = "created_by", updatable = false, nullable = false, length = USERNAME_FIELD_LENGTH) | ||
@Access(AccessType.PROPERTY) | ||
public String getCreatedBy() { | ||
return createdBy; | ||
} | ||
|
||
@CreatedDate | ||
public void setCreatedAt(final long createdAt) { | ||
this.createdAt = createdAt; | ||
} | ||
|
||
@Column(name = "created_at", updatable = false, nullable = false) | ||
@Access(AccessType.PROPERTY) | ||
public long getCreatedAt() { | ||
return createdAt; | ||
} | ||
|
||
@LastModifiedBy | ||
public void setLastModifiedBy(final String lastModifiedBy) { | ||
if (this.lastModifiedBy != null && isController()) { | ||
// initialized and controller = doesn't update | ||
return; | ||
} | ||
|
||
this.lastModifiedBy = lastModifiedBy; | ||
} | ||
|
||
@Column(name = "last_modified_by", nullable = false, length = USERNAME_FIELD_LENGTH) | ||
@Access(AccessType.PROPERTY) | ||
public String getLastModifiedBy() { | ||
return lastModifiedBy == null ? createdBy : lastModifiedBy; | ||
} | ||
|
||
@LastModifiedDate | ||
public void setLastModifiedAt(final long lastModifiedAt) { | ||
if (this.lastModifiedAt != 0 && isController()) { | ||
// initialized and controller = doesn't update | ||
return; | ||
} | ||
|
||
this.lastModifiedAt = lastModifiedAt; | ||
} | ||
|
||
@Column(name = "last_modified_at", nullable = false) | ||
@Access(AccessType.PROPERTY) | ||
public long getLastModifiedAt() { | ||
return lastModifiedAt == 0 ? createdAt : lastModifiedAt; | ||
} | ||
|
||
/** | ||
* 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 + (id == null ? 0 : id.hashCode()); | ||
result = prime * result + optLockRevision; | ||
result = prime * result + this.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 (!(this.getClass().isInstance(obj))) { | ||
return false; | ||
} | ||
final AbstractJpaBaseEntity other = (AbstractJpaBaseEntity) 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 this.getClass().getSimpleName() + " [id=" + id + "]"; | ||
} | ||
|
||
@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); | ||
} | ||
|
||
private boolean isController() { | ||
return SecurityContextHolder.getContext().getAuthentication() != null | ||
&& SecurityContextHolder.getContext().getAuthentication() | ||
.getDetails() instanceof TenantAwareAuthenticationDetails tenantAwareDetails | ||
&& tenantAwareDetails.isController(); | ||
} | ||
} |
51 changes: 51 additions & 0 deletions
51
...repository-jpa-api/src/main/java/org/eclipse/hawkbit/repository/jpa/model/BaseEntity.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
/** | ||
* 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.model; | ||
|
||
import java.io.Serializable; | ||
import java.util.concurrent.TimeUnit; | ||
|
||
import org.eclipse.hawkbit.repository.Identifiable; | ||
|
||
/** | ||
* Core information of all entities. | ||
*/ | ||
public interface BaseEntity extends Serializable, Identifiable<Long> { | ||
|
||
static Long getIdOrNull(final BaseEntity entity) { | ||
return entity == null ? null : entity.getId(); | ||
} | ||
|
||
/** | ||
* @return user that created the {@link BaseEntity}. | ||
*/ | ||
String getCreatedBy(); | ||
|
||
/** | ||
* @return time in {@link TimeUnit#MILLISECONDS} when the {@link BaseEntity} was created. | ||
*/ | ||
long getCreatedAt(); | ||
|
||
/** | ||
* @return user that updated the {@link BaseEntity} last. | ||
*/ | ||
String getLastModifiedBy(); | ||
|
||
/** | ||
* @return time in {@link TimeUnit#MILLISECONDS} when the {@link BaseEntity} | ||
* was last time changed. | ||
*/ | ||
long getLastModifiedAt(); | ||
|
||
/** | ||
* @return version of the {@link BaseEntity}. | ||
*/ | ||
int getOptLockRevision(); | ||
} |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
3 changes: 3 additions & 0 deletions
3
hawkbit-repository/hawkbit-repository-jpa-eclipselink/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# hawkBit JPA EclipseLink Vendor integration | ||
|
||
Implementation of [EclipseLink](http://www.eclipse.org/eclipselink/) JPA vendor. |
Oops, something went wrong.