Skip to content

Commit

Permalink
feat(user): added email addresses and phone numbers
Browse files Browse the repository at this point in the history
  • Loading branch information
zZHorizonZz committed Aug 26, 2024
1 parent fce11ce commit 77b6eaa
Show file tree
Hide file tree
Showing 58 changed files with 1,716 additions and 127 deletions.
1 change: 1 addition & 0 deletions extensions/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
<module>external-authentication</module>
<module>core</module>
<module>zenei-user-account</module>
<module>zenei-user-account-jdbc-reactive</module>
<module>rest</module>
<module>jdbc-panache</module>
</modules>
Expand Down
70 changes: 70 additions & 0 deletions extensions/zenei-user-account-jdbc-reactive/deployment/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>dev.cloudeko</groupId>
<artifactId>zenei-user-account-jdbc-reactive-extension-parent</artifactId>
<version>0.0.1</version>
</parent>

<name>Zenei - Extensions - User Account JDBC Reactive - Deployment</name>
<artifactId>zenei-user-account-jdbc-reactive-extension-deployment</artifactId>

<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-core-deployment</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-vertx-http-deployment</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-vertx-deployment</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-security-deployment</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-devservices-deployment</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-jsonp-deployment</artifactId>
</dependency>

<dependency>
<groupId>dev.cloudeko</groupId>
<artifactId>zenei-user-account-jdbc-reactive-extension</artifactId>
</dependency>

<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5-internal</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
<annotationProcessorPaths>
<path>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-extension-processor</artifactId>
<version>${quarkus.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package dev.cloudeko.zenei.user.deployment;

import dev.cloudeko.zenei.user.runtime.DefaultUserAccountInitializer;
import dev.cloudeko.zenei.user.runtime.DefaultUserAccountReactiveProvider;
import dev.cloudeko.zenei.user.runtime.DefaultUserAccountRecorder;
import dev.cloudeko.zenei.user.runtime.DefaultUserAccountRepository;
import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
import io.quarkus.arc.deployment.SyntheticBeanBuildItem;
import io.quarkus.builder.item.SimpleBuildItem;
import io.quarkus.deployment.Capabilities;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.annotations.Record;
import jakarta.enterprise.context.Dependent;
import jakarta.inject.Singleton;
import org.jboss.jandex.DotName;

import java.util.Arrays;
import java.util.Map;
import java.util.stream.Collectors;

import static io.quarkus.deployment.Capability.*;
import static io.quarkus.deployment.annotations.ExecutionTime.STATIC_INIT;

public class BasicUserAccountManagerProcessor {

private static final String[] SUPPORTED_REACTIVE_CLIENTS = new String[] { REACTIVE_PG_CLIENT, REACTIVE_MYSQL_CLIENT,
REACTIVE_MSSQL_CLIENT, REACTIVE_DB2_CLIENT, REACTIVE_ORACLE_CLIENT };

@BuildStep
ReactiveClientBuildItem findReactiveClient(Capabilities capabilities) {
final String reactiveClient = capabilities.getCapabilities().stream()
.filter(c -> Arrays.asList(SUPPORTED_REACTIVE_CLIENTS).contains(c))
.findFirst()
.orElseThrow(() -> new RuntimeException("No supported reactive SQL client found"));

return new ReactiveClientBuildItem(reactiveClient);
}

@BuildStep
@Record(STATIC_INIT)
SyntheticBeanBuildItem createBasicUserInitializerConfig(DefaultUserAccountRecorder recorder,
Capabilities capabilities) {
final Map<String, Boolean> tableSchemas = Arrays.stream(DefaultTableSchema.schemas(capabilities))
.collect(Collectors.toMap(TableSchema::getDdl, TableSchema::isSupportsIfNotExists));

return SyntheticBeanBuildItem
.configure(DefaultUserAccountInitializer.InitializerProperties.class)
.supplier(recorder.createUserAccountInitializerProps(tableSchemas))
.scope(Dependent.class)
.unremovable()
.done();
}

@BuildStep
@Record(STATIC_INIT)
SyntheticBeanBuildItem createBasicUserAccountRepository(DefaultUserAccountRecorder recorder,
ReactiveClientBuildItem reactiveClient) {
final Map<String, String> config = Arrays.stream(DefaultQuery.values())
.collect(Collectors.toMap(defaultQuery -> defaultQuery.getMetadata().queryKey(),
defaultQuery -> defaultQuery.getMetadata().getQuery(reactiveClient.getReactiveClient())));

return SyntheticBeanBuildItem
.configure(DefaultUserAccountRepository.QueryProvider.class)
.supplier(recorder.createBasicUserAccountRepositoryQueryProvider(config))
.scope(Dependent.class)
.unremovable()
.done();
}

@BuildStep
AdditionalBeanBuildItem setupBeans() {
AdditionalBeanBuildItem.Builder builder = AdditionalBeanBuildItem.builder();
builder.setDefaultScope(DotName.createSimple(Singleton.class.getName()));

builder.addBeanClass(DefaultUserAccountInitializer.class);
builder.addBeanClass(DefaultUserAccountRepository.class);

return builder.build();
}

@BuildStep
AdditionalBeanBuildItem setupManager() {
return new AdditionalBeanBuildItem(DefaultUserAccountReactiveProvider.class);
}

private static final class ReactiveClientBuildItem extends SimpleBuildItem {

private final String reactiveClient;

private ReactiveClientBuildItem(String reactiveClient) {
this.reactiveClient = reactiveClient;
}

public String getReactiveClient() {
return reactiveClient;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package dev.cloudeko.zenei.user.deployment;

import dev.cloudeko.zenei.user.QueryRegistry;

public enum DefaultQuery {
/**
* User Account Queries
*/
USER_ACCOUNT_FIND_BY_IDENTIFIER(QueryMetadata.of(
"SELECT id, username, created_at, updated_at FROM zenei_user_account WHERE id = %s",
1,
QueryRegistry.USER_ACCOUNT_FIND_BY_IDENTIFIER
)),
USER_ACCOUNT_FIND_BY_USERNAME(QueryMetadata.of(
"SELECT id, username, created_at, updated_at FROM zenei_user_account WHERE username = %s",
1,
QueryRegistry.USER_ACCOUNT_FIND_BY_USERNAME
)),
USER_ACCOUNT_FIND_BY_PRIMARY_EMAIL(QueryMetadata.of(
"SELECT id, username, created_at, updated_at FROM zenei_user_account WHERE id = (SELECT user_id FROM zenei_user_email_addresses WHERE email = %s AND primary_email = true)",
1,
QueryRegistry.USER_ACCOUNT_FIND_BY_PRIMARY_EMAIL_ADDRESS
)),
USER_ACCOUNT_FIND_BY_PRIMARY_PHONE_NUMBER(QueryMetadata.of(
"SELECT id, username, created_at, updated_at FROM zenei_user_account WHERE id = (SELECT user_id FROM zenei_user_phone_numbers WHERE phone_number = %s AND primary_phone_number = true)",
1,
QueryRegistry.USER_ACCOUNT_FIND_BY_PRIMARY_PHONE_NUMBER
)),
USER_ACCOUNT_LIST(QueryMetadata.of(
"SELECT id, username, created_at, updated_at FROM zenei_user_account",
0,
QueryRegistry.USER_ACCOUNT_LIST
)),
USER_ACCOUNT_LIST_PAGINATED(QueryMetadata.of(
"SELECT id, username, created_at, updated_at FROM zenei_user_account LIMIT %s OFFSET %s",
2,
QueryRegistry.USER_ACCOUNT_LIST_PAGINATED
)),
USER_ACCOUNT_CREATE(QueryMetadata.of(
"INSERT INTO zenei_user_account (username, created_at, updated_at) VALUES (%s, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP) RETURNING id, username, created_at, updated_at",
1,
QueryRegistry.USER_ACCOUNT_CREATE
)),
USER_ACCOUNT_UPDATE(QueryMetadata.of(
"UPDATE zenei_user_account SET username = %s, updated_at = CURRENT_TIMESTAMP WHERE id = %s RETURNING id, username, created_at, updated_at",
2,
QueryRegistry.USER_ACCOUNT_UPDATE
)),
USER_ACCOUNT_DELETE(QueryMetadata.of(
"DELETE FROM zenei_user_account WHERE id = %s RETURNING id, username, image, created_at, updated_at",
1,
QueryRegistry.USER_ACCOUNT_DELETE
)),

/**
* User Account Email Addresses Queries
*/
USER_ACCOUNT_LIST_EMAIL_ADDRESSES(QueryMetadata.of(
"SELECT id, user_id, email, email_verified, primary_email, created_at, updated_at FROM zenei_user_email_addresses WHERE user_id = %s",
1,
QueryRegistry.USER_ACCOUNT_EMAIL_ADDRESSES_LIST_BY_USER_ID
)),
USER_ACCOUNT_EMAIL_ADDRESSES_CREATE(QueryMetadata.of(
"INSERT INTO zenei_user_email_addresses (user_id, email, email_verified, primary_email, created_at, updated_at) VALUES (%s, %s, %s, %s, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP) RETURNING id, user_id, email, email_verified, primary_email, created_at, updated_at",
4,
QueryRegistry.USER_ACCOUNT_EMAIL_ADDRESSES_CREATE
)),
USER_ACCOUNT_EMAIL_ADDRESSES_UPDATE(QueryMetadata.of(
"UPDATE zenei_user_email_addresses SET email = %s, email_verified = %s, primary_email = %s, updated_at = CURRENT_TIMESTAMP WHERE id = %s RETURNING id, user_id, email, email_verified, primary_email, created_at, updated_at",
4,
QueryRegistry.USER_ACCOUNT_EMAIL_ADDRESSES_UPDATE
)),
USER_ACCOUNT_EMAIL_ADDRESSES_DELETE(QueryMetadata.of(
"DELETE FROM zenei_user_email_addresses WHERE user_id = %s AND email = %s",
2,
QueryRegistry.USER_ACCOUNT_EMAIL_ADDRESSES_DELETE
)),
USER_ACCOUNT_EMAIL_ADDRESSES_DELETE_BY_USER_ID(QueryMetadata.of(
"DELETE FROM zenei_user_email_addresses WHERE user_id = %s",
1,
QueryRegistry.USER_ACCOUNT_EMAIL_ADDRESSES_DELETE_BY_USER_ID
));

private final QueryMetadata metadata;

DefaultQuery(QueryMetadata metadata) {
this.metadata = metadata;
}

public QueryMetadata getMetadata() {
return metadata;
}
}
Loading

0 comments on commit 77b6eaa

Please sign in to comment.