Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add an api to add bulk import users #927

Closed
wants to merge 16 commits into from
78 changes: 78 additions & 0 deletions src/main/java/io/supertokens/bulkimport/BulkImport.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* Copyright (c) 2024, VRAI Labs and/or its affiliates. All rights reserved.
*
* This software is licensed under the Apache License, Version 2.0 (the
* "License") as published by the Apache Software Foundation.
*
* You may not use this file except in compliance with the License. You may
* obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/

package io.supertokens.bulkimport;

import io.supertokens.pluginInterface.bulkimport.BulkImportStorage.BulkImportUserStatus;
import io.supertokens.pluginInterface.bulkimport.BulkImportUser;
import io.supertokens.pluginInterface.exceptions.StorageQueryException;
import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage;
import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException;
import io.supertokens.utils.Utils;


import java.util.List;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

public class BulkImport {

public static final int MAX_USERS_TO_ADD = 10000;
public static final int GET_USERS_PAGINATION_LIMIT = 500;
public static final int GET_USERS_DEFAULT_LIMIT = 100;

public static void addUsers(AppIdentifierWithStorage appIdentifierWithStorage, List<BulkImportUser> users)
throws StorageQueryException, TenantOrAppNotFoundException {
rishabhpoddar marked this conversation as resolved.
Show resolved Hide resolved
while (true) {
try {
appIdentifierWithStorage.getBulkImportStorage().addBulkImportUsers(appIdentifierWithStorage, users);
break;
} catch (io.supertokens.pluginInterface.bulkimport.exceptions.DuplicateUserIdException ignored) {
// We re-generate the user id for every user and retry
for (BulkImportUser user : users) {
user.id = Utils.getUUID();
}
}
}
}

public static BulkImportUserPaginationContainer getUsers(AppIdentifierWithStorage appIdentifierWithStorage,
@Nonnull Integer limit, @Nullable BulkImportUserStatus status, @Nullable String paginationToken)
throws StorageQueryException, BulkImportUserPaginationToken.InvalidTokenException {
List<BulkImportUser> users;

if (paginationToken == null) {
users = appIdentifierWithStorage.getBulkImportStorage()
.getBulkImportUsers(appIdentifierWithStorage, limit + 1, status, null, null);
} else {
BulkImportUserPaginationToken tokenInfo = BulkImportUserPaginationToken.extractTokenInfo(paginationToken);
users = appIdentifierWithStorage.getBulkImportStorage()
.getBulkImportUsers(appIdentifierWithStorage, limit + 1, status, tokenInfo.bulkImportUserId, tokenInfo.createdAt);
}

String nextPaginationToken = null;
int maxLoop = users.size();
if (users.size() == limit + 1) {
maxLoop = limit;
BulkImportUser user = users.get(limit);
nextPaginationToken = new BulkImportUserPaginationToken(user.id, user.createdAt).generateToken();
}

List<BulkImportUser> resultUsers = users.subList(0, maxLoop);
return new BulkImportUserPaginationContainer(resultUsers, nextPaginationToken);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright (c) 2024, VRAI Labs and/or its affiliates. All rights reserved.
*
* This software is licensed under the Apache License, Version 2.0 (the
* "License") as published by the Apache Software Foundation.
*
* You may not use this file except in compliance with the License. You may
* obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/

package io.supertokens.bulkimport;

import java.util.List;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

import io.supertokens.pluginInterface.bulkimport.BulkImportUser;

public class BulkImportUserPaginationContainer {
public final List<BulkImportUser> users;
public final String nextPaginationToken;

public BulkImportUserPaginationContainer(@Nonnull List<BulkImportUser> users, @Nullable String nextPaginationToken) {
this.users = users;
this.nextPaginationToken = nextPaginationToken;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* Copyright (c) 2024, VRAI Labs and/or its affiliates. All rights reserved.
*
* This software is licensed under the Apache License, Version 2.0 (the
* "License") as published by the Apache Software Foundation.
*
* You may not use this file except in compliance with the License. You may
* obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/

package io.supertokens.bulkimport;

import java.util.Base64;

public class BulkImportUserPaginationToken {
rishabhpoddar marked this conversation as resolved.
Show resolved Hide resolved
public final String bulkImportUserId;
public final long createdAt;

public BulkImportUserPaginationToken(String bulkImportUserId, long createdAt) {
this.bulkImportUserId = bulkImportUserId;
this.createdAt = createdAt;
}

public static BulkImportUserPaginationToken extractTokenInfo(String token) throws InvalidTokenException {
try {
String decodedPaginationToken = new String(Base64.getDecoder().decode(token));
String[] splitDecodedToken = decodedPaginationToken.split(";");
if (splitDecodedToken.length != 2) {
throw new InvalidTokenException();
}
String bulkImportUserId = splitDecodedToken[0];
long createdAt = Long.parseLong(splitDecodedToken[1]);
return new BulkImportUserPaginationToken(bulkImportUserId, createdAt);
} catch (Exception e) {
throw new InvalidTokenException();
}
}

public String generateToken() {
return new String(Base64.getEncoder().encode((this.bulkImportUserId + ";" + this.createdAt).getBytes()));
}

public static class InvalidTokenException extends Exception {

private static final long serialVersionUID = 6289026174830695478L;
}
}
Loading
Loading