mirror of
https://github.com/datahub-project/datahub.git
synced 2025-11-06 13:51:50 +00:00
fix(bootstrap): Creating dedicated thread pool for executing async bootstrap steps + misc fixes (#5798)
This commit is contained in:
parent
af1fc8d91d
commit
ca29f8b679
@ -71,8 +71,8 @@ export const LogIn: React.VFC<LogInProps> = () => {
|
|||||||
analytics.event({ type: EventType.LogInEvent });
|
analytics.event({ type: EventType.LogInEvent });
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((_) => {
|
||||||
message.error(`Failed to log in! ${error}`);
|
message.error(`Failed to log in! An unexpected error occurred.`);
|
||||||
})
|
})
|
||||||
.finally(() => setLoading(false));
|
.finally(() => setLoading(false));
|
||||||
},
|
},
|
||||||
|
|||||||
@ -75,8 +75,8 @@ export const ResetCredentials: React.VFC<ResetCredentialsProps> = () => {
|
|||||||
analytics.event({ type: EventType.ResetCredentialsEvent });
|
analytics.event({ type: EventType.ResetCredentialsEvent });
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((_) => {
|
||||||
message.error(`Failed to log in! ${error}`);
|
message.error(`Failed to log in!`);
|
||||||
})
|
})
|
||||||
.finally(() => setLoading(false));
|
.finally(() => setLoading(false));
|
||||||
},
|
},
|
||||||
|
|||||||
@ -90,8 +90,8 @@ export const SignUp: React.VFC<SignUpProps> = () => {
|
|||||||
analytics.event({ type: EventType.SignUpEvent, title: values.title });
|
analytics.event({ type: EventType.SignUpEvent, title: values.title });
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((_) => {
|
||||||
message.error(`Failed to log in! ${error}`);
|
message.error(`Failed to log in! An unexpected error occurred.`);
|
||||||
})
|
})
|
||||||
.finally(() => setLoading(false));
|
.finally(() => setLoading(false));
|
||||||
},
|
},
|
||||||
|
|||||||
@ -52,6 +52,7 @@ export function HeaderLinks(props: Props) {
|
|||||||
const showSettings = true;
|
const showSettings = true;
|
||||||
const showIngestion =
|
const showIngestion =
|
||||||
isIngestionEnabled && me && me.platformPrivileges.manageIngestion && me.platformPrivileges.manageSecrets;
|
isIngestionEnabled && me && me.platformPrivileges.manageIngestion && me.platformPrivileges.manageSecrets;
|
||||||
|
const showDomains = me?.platformPrivileges.createDomains || me?.platformPrivileges.manageDomains;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<LinksWrapper areLinksHidden={areLinksHidden}>
|
<LinksWrapper areLinksHidden={areLinksHidden}>
|
||||||
@ -82,11 +83,13 @@ export function HeaderLinks(props: Props) {
|
|||||||
<BookOutlined style={{ fontSize: '14px', fontWeight: 'bold' }} /> Glossary
|
<BookOutlined style={{ fontSize: '14px', fontWeight: 'bold' }} /> Glossary
|
||||||
</Link>
|
</Link>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem key="1">
|
{showDomains && (
|
||||||
<Link to="/domains">
|
<MenuItem key="1">
|
||||||
<FolderOutlined style={{ fontSize: '14px', fontWeight: 'bold' }} /> Domains
|
<Link to="/domains">
|
||||||
</Link>
|
<FolderOutlined style={{ fontSize: '14px', fontWeight: 'bold' }} /> Domains
|
||||||
</MenuItem>
|
</Link>
|
||||||
|
</MenuItem>
|
||||||
|
)}
|
||||||
</Menu>
|
</Menu>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
|||||||
@ -61,7 +61,7 @@ public class NativeUserService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void createNativeUser(@Nonnull String userUrnString, @Nonnull String fullName, @Nonnull String email,
|
public void createNativeUser(@Nonnull String userUrnString, @Nonnull String fullName, @Nonnull String email,
|
||||||
@Nonnull String title, @Nonnull String password, @Nonnull String inviteToken, Authentication authentication)
|
@Nonnull String title, @Nonnull String password, @Nonnull String inviteToken, @Nonnull Authentication authentication)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
Objects.requireNonNull(userUrnString, "userUrnSting must not be null!");
|
Objects.requireNonNull(userUrnString, "userUrnSting must not be null!");
|
||||||
Objects.requireNonNull(fullName, "fullName must not be null!");
|
Objects.requireNonNull(fullName, "fullName must not be null!");
|
||||||
@ -69,6 +69,7 @@ public class NativeUserService {
|
|||||||
Objects.requireNonNull(title, "title must not be null!");
|
Objects.requireNonNull(title, "title must not be null!");
|
||||||
Objects.requireNonNull(password, "password must not be null!");
|
Objects.requireNonNull(password, "password must not be null!");
|
||||||
Objects.requireNonNull(inviteToken, "inviteToken must not be null!");
|
Objects.requireNonNull(inviteToken, "inviteToken must not be null!");
|
||||||
|
Objects.requireNonNull(inviteToken, "authentication must not be null!");
|
||||||
|
|
||||||
InviteToken inviteTokenAspect =
|
InviteToken inviteTokenAspect =
|
||||||
(InviteToken) _entityService.getLatestAspect(Urn.createFromString(GLOBAL_INVITE_TOKEN),
|
(InviteToken) _entityService.getLatestAspect(Urn.createFromString(GLOBAL_INVITE_TOKEN),
|
||||||
@ -125,7 +126,7 @@ public class NativeUserService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void updateCorpUserCredentials(@Nonnull Urn userUrn, @Nonnull String password,
|
void updateCorpUserCredentials(@Nonnull Urn userUrn, @Nonnull String password,
|
||||||
Authentication authentication) throws Exception {
|
@Nonnull Authentication authentication) throws Exception {
|
||||||
// Construct corpUserCredentials
|
// Construct corpUserCredentials
|
||||||
CorpUserCredentials corpUserCredentials = new CorpUserCredentials();
|
CorpUserCredentials corpUserCredentials = new CorpUserCredentials();
|
||||||
final byte[] salt = getRandomBytes(SALT_TOKEN_LENGTH);
|
final byte[] salt = getRandomBytes(SALT_TOKEN_LENGTH);
|
||||||
|
|||||||
@ -165,11 +165,12 @@ public class AuthServiceController {
|
|||||||
String titleString = title.asText();
|
String titleString = title.asText();
|
||||||
String passwordString = password.asText();
|
String passwordString = password.asText();
|
||||||
String inviteTokenString = inviteToken.asText();
|
String inviteTokenString = inviteToken.asText();
|
||||||
|
Authentication auth = AuthenticationContext.getAuthentication();
|
||||||
log.debug(String.format("Attempting to create credentials for native user %s", userUrnString));
|
log.debug(String.format("Attempting to create credentials for native user %s", userUrnString));
|
||||||
return CompletableFuture.supplyAsync(() -> {
|
return CompletableFuture.supplyAsync(() -> {
|
||||||
try {
|
try {
|
||||||
_nativeUserService.createNativeUser(userUrnString, fullNameString, emailString, titleString, passwordString,
|
_nativeUserService.createNativeUser(userUrnString, fullNameString, emailString, titleString, passwordString,
|
||||||
inviteTokenString, AuthenticationContext.getAuthentication());
|
inviteTokenString, auth);
|
||||||
String response = buildSignUpResponse();
|
String response = buildSignUpResponse();
|
||||||
return new ResponseEntity<>(response, HttpStatus.OK);
|
return new ResponseEntity<>(response, HttpStatus.OK);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -225,11 +226,12 @@ public class AuthServiceController {
|
|||||||
String userUrnString = userUrn.asText();
|
String userUrnString = userUrn.asText();
|
||||||
String passwordString = password.asText();
|
String passwordString = password.asText();
|
||||||
String resetTokenString = resetToken.asText();
|
String resetTokenString = resetToken.asText();
|
||||||
|
Authentication auth = AuthenticationContext.getAuthentication();
|
||||||
log.debug(String.format("Attempting to reset credentials for native user %s", userUrnString));
|
log.debug(String.format("Attempting to reset credentials for native user %s", userUrnString));
|
||||||
return CompletableFuture.supplyAsync(() -> {
|
return CompletableFuture.supplyAsync(() -> {
|
||||||
try {
|
try {
|
||||||
_nativeUserService.resetCorpUserCredentials(userUrnString, passwordString, resetTokenString,
|
_nativeUserService.resetCorpUserCredentials(userUrnString, passwordString, resetTokenString,
|
||||||
AuthenticationContext.getAuthentication());
|
auth);
|
||||||
String response = buildResetNativeUserCredentialsResponse();
|
String response = buildResetNativeUserCredentialsResponse();
|
||||||
return new ResponseEntity<>(response, HttpStatus.OK);
|
return new ResponseEntity<>(response, HttpStatus.OK);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|||||||
@ -2,6 +2,8 @@ package com.linkedin.metadata.boot;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
@ -13,6 +15,7 @@ import org.springframework.stereotype.Component;
|
|||||||
@Component
|
@Component
|
||||||
public class BootstrapManager {
|
public class BootstrapManager {
|
||||||
|
|
||||||
|
private final ExecutorService _asyncExecutor = Executors.newFixedThreadPool(5);
|
||||||
private final List<BootstrapStep> _bootSteps;
|
private final List<BootstrapStep> _bootSteps;
|
||||||
|
|
||||||
public BootstrapManager(final List<BootstrapStep> bootSteps) {
|
public BootstrapManager(final List<BootstrapStep> bootSteps) {
|
||||||
@ -42,7 +45,7 @@ public class BootstrapManager {
|
|||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error(String.format("Caught exception while executing bootstrap step %s. Continuing...", step.name()), e);
|
log.error(String.format("Caught exception while executing bootstrap step %s. Continuing...", step.name()), e);
|
||||||
}
|
}
|
||||||
});
|
}, _asyncExecutor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,6 +15,7 @@ import com.linkedin.mxe.GenericAspect;
|
|||||||
import com.linkedin.mxe.MetadataChangeProposal;
|
import com.linkedin.mxe.MetadataChangeProposal;
|
||||||
import com.linkedin.policy.DataHubRoleInfo;
|
import com.linkedin.policy.DataHubRoleInfo;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.core.io.ClassPathResource;
|
import org.springframework.core.io.ClassPathResource;
|
||||||
@ -25,6 +26,7 @@ import static com.linkedin.metadata.Constants.*;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class IngestRolesStep implements BootstrapStep {
|
public class IngestRolesStep implements BootstrapStep {
|
||||||
|
private static final int SLEEP_SECONDS = 60;
|
||||||
private final EntityService _entityService;
|
private final EntityService _entityService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -32,10 +34,19 @@ public class IngestRolesStep implements BootstrapStep {
|
|||||||
return this.getClass().getSimpleName();
|
return this.getClass().getSimpleName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public ExecutionMode getExecutionMode() {
|
||||||
|
return ExecutionMode.ASYNC;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute() throws Exception {
|
public void execute() throws Exception {
|
||||||
final ObjectMapper mapper = new ObjectMapper();
|
final ObjectMapper mapper = new ObjectMapper();
|
||||||
|
|
||||||
|
// Sleep to ensure deployment process finishes.
|
||||||
|
Thread.sleep(SLEEP_SECONDS * 1000);
|
||||||
|
|
||||||
// 0. Execute preflight check to see whether we need to ingest Roles
|
// 0. Execute preflight check to see whether we need to ingest Roles
|
||||||
log.info("Ingesting default Roles...");
|
log.info("Ingesting default Roles...");
|
||||||
|
|
||||||
|
|||||||
@ -437,8 +437,10 @@ public class JavaEntityClient implements EntityClient {
|
|||||||
// TODO: Factor out ingest logic into a util that can be accessed by the java client and the resource
|
// TODO: Factor out ingest logic into a util that can be accessed by the java client and the resource
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
@Override
|
@Override
|
||||||
public String ingestProposal(@Nonnull MetadataChangeProposal metadataChangeProposal,
|
public String ingestProposal(
|
||||||
|
@Nonnull final MetadataChangeProposal metadataChangeProposal,
|
||||||
@Nonnull final Authentication authentication) throws RemoteInvocationException {
|
@Nonnull final Authentication authentication) throws RemoteInvocationException {
|
||||||
|
|
||||||
String actorUrnStr = authentication.getActor() != null ? authentication.getActor().toUrnStr() : Constants.UNKNOWN_ACTOR;
|
String actorUrnStr = authentication.getActor() != null ? authentication.getActor().toUrnStr() : Constants.UNKNOWN_ACTOR;
|
||||||
final AuditStamp auditStamp =
|
final AuditStamp auditStamp =
|
||||||
new AuditStamp().setTime(_clock.millis()).setActor(Urn.createFromString(actorUrnStr));
|
new AuditStamp().setTime(_clock.millis()).setActor(Urn.createFromString(actorUrnStr));
|
||||||
|
|||||||
@ -239,9 +239,6 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"privileges":[
|
"privileges":[
|
||||||
"MANAGE_INGESTION",
|
|
||||||
"MANAGE_SECRETS",
|
|
||||||
"VIEW_ANALYTICS",
|
|
||||||
"GENERATE_PERSONAL_ACCESS_TOKENS",
|
"GENERATE_PERSONAL_ACCESS_TOKENS",
|
||||||
"MANAGE_DOMAINS",
|
"MANAGE_DOMAINS",
|
||||||
"MANAGE_GLOSSARIES",
|
"MANAGE_GLOSSARIES",
|
||||||
@ -314,9 +311,7 @@
|
|||||||
"urn:li:dataHubRole:Reader"
|
"urn:li:dataHubRole:Reader"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"privileges":[
|
"privileges":[],
|
||||||
"VIEW_ANALYTICS"
|
|
||||||
],
|
|
||||||
"displayName":"Readers - Platform Policy",
|
"displayName":"Readers - Platform Policy",
|
||||||
"description":"Readers can view analytics.",
|
"description":"Readers can view analytics.",
|
||||||
"state":"ACTIVE",
|
"state":"ACTIVE",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user