Compare commits

...

51 Commits

Author SHA1 Message Date
Robin Shen
9c756c74ca fix: Websocket not closed when session times out (OD-2622) 2025-12-08 22:40:41 +08:00
Robin Shen
241c70d10d chore: Add missing translations 2025-12-06 12:47:31 +08:00
Robin Shen
abcc00f051 chore: Upgrade tika for avoid potential security vulnerabilities 2025-12-06 11:44:26 +08:00
Robin Shen
4051221b95 Merge branch 'main' of https://code.onedev.io/onedev/server 2025-12-06 11:22:03 +08:00
Robin Shen
eff4d2a658 feat: Able to use variables from workspace files for run container step (OD-2620) 2025-12-06 11:21:29 +08:00
Robin Shen
4e7fcd1807
Edit .trivyignore 2025-12-06 01:07:48 +00:00
Robin Shen
8554de9e13 wip: Add page tools to AI chatter 2025-12-05 20:47:30 +08:00
Robin Shen
b3d207a835 chore: Add migration 2025-11-30 10:34:34 +08:00
Robin Shen
136426bcdd chore: Fix compilation error 2025-11-30 09:35:35 +08:00
Robin Shen
86ed0e4aac Merge branch 'main' of https://code.onedev.io/onedev/server 2025-11-30 09:26:35 +08:00
Robin Shen
b9ee6f987b wip: AI user 2025-11-30 09:20:18 +08:00
Robin Shen
44ec074b93 chore: Bump version 2025-11-27 20:35:30 +08:00
Robin Shen
3b0de1e0ec fix: Git Checkout with LFS: Project not found or inaccessible (OD-2612) 2025-11-27 20:34:26 +08:00
Robin Shen
82fe2253ff chore: Bump version 2025-11-27 09:22:25 +08:00
Robin Shen
d392f3def0 chore: Update server-ee module 2025-11-27 09:20:33 +08:00
Robin Shen
a73df6edd1 chore: Update server-ee 2025-11-27 09:15:22 +08:00
Robin Shen
e2150b12fd fix: Validation error when update board spec via project settings api (OD-2610) 2025-11-27 08:46:14 +08:00
Robin Shen
9fdbf390b3 Merge branch 'main' of https://code.onedev.io/onedev/server 2025-11-22 11:34:37 +08:00
Robin Shen
1875200269 chore: Append .git to clone url for facilitate cloudflare rule config 2025-11-22 11:34:08 +08:00
Robin Shen
7b4e6ef9be
Edit incompatibilities.md 2025-11-22 00:40:27 +00:00
Robin Shen
b6970fb247 chore: Minor format change 2025-11-21 14:51:53 +08:00
Robin Shen
061d672774 Merge branch 'main' of https://code.onedev.io/onedev/server 2025-11-17 22:05:20 +08:00
Robin Shen
4220b1130f chore: Update translations 2025-11-17 22:05:12 +08:00
Robin Shen
3e753b6adc
编辑 incompatibilities.md 2025-11-17 13:43:10 +00:00
Robin Shen
682620965c chore: Refresh page when switch light/dark mode to avoid dropdown issue 2025-11-17 20:50:28 +08:00
Robin Shen
13d9281484 fix: Session timeout setting not respected (OD-2604) 2025-11-17 20:03:13 +08:00
Robin Shen
d54de0ec27 chore: Add missing translations 2025-11-17 17:30:27 +08:00
Robin Shen
c6a74dc008 feat: Use natural language for various queries (OD-2600) 2025-11-17 10:33:20 +08:00
Robin Shen
706b2dbdba feat: Suggest pull request title/description via AI (OD-2602) 2025-11-15 08:01:22 +08:00
Robin Shen
a62db8265f chore: Some refactorings 2025-11-13 22:30:33 +08:00
Robin Shen
1eb8bda97e feat: Accurate symbol navigation with help of AI (OD-2601) 2025-11-13 11:00:12 +08:00
Robin Shen
b465a1fd78 feat: Natural language query for issues/builds/pull requests via AI (OD-2600) 2025-11-11 13:38:00 +08:00
Robin Shen
2b9237b8b1 task: Update minimum required Java version to 17 (OD-2597) 2025-11-02 22:59:43 +08:00
Robin Shen
7e77167833 chore: Update EE module 2025-11-02 10:30:53 +08:00
Robin Shen
1157f4e8ba chore: Minor refactoring 2025-11-01 09:50:56 +08:00
Robin Shen
9104c8eb9a chore: Add missing translations 2025-10-31 23:26:58 +08:00
Robin Shen
cb86f2087e fix: NPE when set up server with session timeout property 2025-10-31 23:01:52 +08:00
Robin Shen
8a45bb03f7 feat: Able to run job in different project in post build action (OD-2596) 2025-10-31 18:02:17 +08:00
Robin Shen
3c44f81687 feat: Allow configurable idle session timeout (OD-2587) 2025-10-31 12:04:00 +08:00
Robin Shen
7400902735 feat: Improve branch/tag protection rule to disallow specific file extensions (OD-2588) 2025-10-31 10:36:21 +08:00
Robin Shen
5f5c114cdd chore: Allow spaces in review requirement criterias 2025-10-30 11:29:05 +08:00
Robin Shen
ecace0afe3 feat: Save uploaded avatar as png instead of jpg to avoid quality loss (OD-2594) 2025-10-30 10:37:54 +08:00
Robin Shen
c40ed5b998 fix: Conventional commits: number in scope not allowed. (OD-2593) 2025-10-30 08:09:01 +08:00
Robin Shen
573cf4ebf2 chore: Bump version 2025-10-18 17:09:55 +08:00
Robin Shen
64e83d995b fix: Publish clover coverage in CI: "Invalid input stream" (OD-2579) 2025-10-18 17:08:45 +08:00
Robin Shen
db28406eeb chore: Refactoring 2025-10-12 16:36:15 +08:00
Robin Shen
e0d5a6682f chore: Add missing translation key 2025-10-09 15:18:00 +08:00
Robin Shen
59315b3f81 chore: Usability improvements 2025-10-09 14:55:23 +08:00
Robin Shen
0a5860d153 chore: Package registry refactoring 2025-10-08 20:36:37 +08:00
Robin Shen
25e3991ba9 fix: Unable to delete obsolete project directories on Windows with Java 25 (OD-2574) 2025-10-08 16:28:58 +08:00
Robin Shen
618dbaf297 chore: Refactoring 2025-10-07 21:40:34 +08:00
1791 changed files with 20923 additions and 15424 deletions

3
.gitignore vendored
View File

@ -1,6 +1,7 @@
server-product/docker/build/
server-product/docker/onedev-*/
**/target/
target/
bin/
**/.classpath
**/.gitignore
**/.settings

2
.gitmodules vendored
View File

@ -1,3 +1,3 @@
[submodule "server-ee"]
path = server-ee
url = https://code.onedev.io/onedev/server-ee
url = https://code.onedev.io/onedev/server-ee.git

View File

@ -1,2 +1,2 @@
CVE-2024-53299
CVE-2024-57699
CVE-2024-57699

7
development.md Normal file
View File

@ -0,0 +1,7 @@
# Conventions
## Service Methods
1. Various service methods will not check permissions, except for those with subject param
1. User param of service methods are used to indicate who performs the action, instead of requiring permission check
1. Service methods will not audit changes, unless stated explicitly

30
pom.xml
View File

@ -6,10 +6,10 @@
<parent>
<groupId>io.onedev</groupId>
<artifactId>parent</artifactId>
<version>1.2.3</version>
<version>1.3.0</version>
</parent>
<artifactId>server</artifactId>
<version>13.0.7</version>
<version>13.1.3</version>
<packaging>pom</packaging>
<build>
<finalName>${project.groupId}.${project.artifactId}-${project.version}</finalName>
@ -38,7 +38,7 @@
<plugin>
<groupId>io.onedev</groupId>
<artifactId>plugin-maven</artifactId>
<version>2.6.9</version>
<version>2.7.0</version>
<executions>
<execution>
<?m2e execute onConfiguration,onIncremental?>
@ -227,6 +227,11 @@
<artifactId>wicket-native-websocket-core</artifactId>
<version>${wicket.version}</version>
</dependency>
<dependency>
<groupId>org.apache.wicket</groupId>
<artifactId>wicket-guice</artifactId>
<version>${wicket.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
@ -315,7 +320,7 @@
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>32.0.1-jre</version>
<version>33.5.0-jre</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
@ -622,6 +627,16 @@
<artifactId>fastexcel</artifactId>
<version>0.15.7</version>
</dependency>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j</artifactId>
<version>${langchain4j.version}</version>
</dependency>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-open-ai</artifactId>
<version>${langchain4j.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<repositories>
@ -641,8 +656,8 @@
</repository>
</repositories>
<properties>
<commons.version>3.0.14</commons.version>
<agent.version>2.2.19</agent.version>
<commons.version>3.1.1</commons.version>
<agent.version>2.3.3</agent.version>
<slf4j.version>2.0.9</slf4j.version>
<logback.version>1.4.14</logback.version>
<antlr.version>4.7.2</antlr.version>
@ -657,6 +672,7 @@
<groovy.version>3.0.25</groovy.version>
<servlet.version>3.1.0</servlet.version>
<jackson.version>2.15.0</jackson.version>
<tika.version>1.28.3</tika.version>
<tika.version>3.2.2</tika.version>
<langchain4j.version>1.8.0</langchain4j.version>
</properties>
</project>

View File

@ -7,7 +7,7 @@
<parent>
<groupId>io.onedev</groupId>
<artifactId>server</artifactId>
<version>13.0.7</version>
<version>13.1.3</version>
</parent>
<build>
<plugins>
@ -274,6 +274,10 @@
<groupId>org.apache.wicket</groupId>
<artifactId>wicket-native-websocket-core</artifactId>
</dependency>
<dependency>
<groupId>org.apache.wicket</groupId>
<artifactId>wicket-guice</artifactId>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
@ -371,20 +375,18 @@
<version>1.10.0</version>
</dependency>
<dependency>
<groupId>com.openai</groupId>
<artifactId>openai-java</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
<version>${kotlin.version}</version>
<groupId>org.ow2.asm</groupId>
<artifactId>asm-util</artifactId>
<version>9.2</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk7</artifactId>
<version>${kotlin.version}</version>
</dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-open-ai</artifactId>
</dependency>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j</artifactId>
</dependency>
</dependencies>
<properties>
<kotlin.version>1.9.23</kotlin.version>

View File

@ -0,0 +1,327 @@
package dev.langchain4j.internal;
import java.util.Random;
import java.util.concurrent.Callable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import dev.langchain4j.Internal;
import dev.langchain4j.exception.LangChain4jException;
import dev.langchain4j.exception.NonRetriableException;
import io.onedev.server.exception.ExceptionUtils;
/**
* Utility class for retrying actions.
*/
@Internal
public final class RetryUtils {
private static final Random RANDOM = new Random();
private RetryUtils() {}
private static final Logger log = LoggerFactory.getLogger(RetryUtils.class);
/**
* This method returns a RetryPolicy.Builder.
*
* @return A RetryPolicy.Builder.
*/
public static RetryPolicy.Builder retryPolicyBuilder() {
return new RetryPolicy.Builder();
}
/**
* This class encapsulates a retry policy.
*/
public static final class RetryPolicy {
/**
* This class encapsulates a retry policy builder.
*/
public static final class Builder {
private int maxRetries = 2;
private int delayMillis = 1000;
private double jitterScale = 0.2;
private double backoffExp = 1.5;
/**
* Construct a RetryPolicy.Builder.
*/
public Builder() {}
/**
* Sets the default maximum number of retries.
*
* @param maxRetries The maximum number of retries.
* The action can be executed up to {@code maxRetries + 1} times.
* @return {@code this}
*/
public Builder maxRetries(int maxRetries) {
this.maxRetries = maxRetries;
return this;
}
/**
* Sets the base delay in milliseconds.
*
* <p>The delay is calculated as follows:
* <ol>
* <li>Calculate the raw delay in milliseconds as
* {@code delayMillis * Math.pow(backoffExp, retry)}.</li>
* <li>Calculate the jitter delay in milliseconds as
* {@code rawDelayMs + rand.nextInt((int) (rawDelayMs * jitterScale))}.</li>
* <li>Sleep for the jitter delay in milliseconds.</li>
* </ol>
*
* @param delayMillis The delay in milliseconds.
* @return {@code this}
*/
public Builder delayMillis(int delayMillis) {
this.delayMillis = delayMillis;
return this;
}
/**
* Sets the jitter scale.
*
* <p>The jitter delay in milliseconds is calculated as
* {@code rawDelayMs + rand.nextInt((int) (rawDelayMs * jitterScale))}.
*
* @param jitterScale The jitter scale.
* @return {@code this}
*/
public Builder jitterScale(double jitterScale) {
this.jitterScale = jitterScale;
return this;
}
/**
* Sets the backoff exponent.
*
* @param backoffExp The backoff exponent.
* @return {@code this}
*/
public Builder backoffExp(double backoffExp) {
this.backoffExp = backoffExp;
return this;
}
/**
* Builds a RetryPolicy.
*
* @return A RetryPolicy.
*/
public RetryPolicy build() {
return new RetryPolicy(maxRetries, delayMillis, jitterScale, backoffExp);
}
}
private final int maxRetries;
private final int delayMillis;
private final double jitterScale;
private final double backoffExp;
/**
* Construct a RetryPolicy.
*
* @param maxRetries The maximum number of retries.
* The action can be executed up to {@code maxRetries + 1} times.
* @param delayMillis The delay in milliseconds.
* @param jitterScale The jitter scale.
* @param backoffExp The backoff exponent.
*/
public RetryPolicy(int maxRetries, int delayMillis, double jitterScale, double backoffExp) {
this.maxRetries = maxRetries;
this.delayMillis = delayMillis;
this.jitterScale = jitterScale;
this.backoffExp = backoffExp;
}
/**
* This method returns the raw delay in milliseconds after a given retry.
*
* @param retry The retry number.
* @return The raw delay in milliseconds.
*/
public double rawDelayMs(int retry) {
return delayMillis * Math.pow(backoffExp, retry);
}
/**
* This method returns the jitter delay in milliseconds after a given retry.
*
* @param retry The retry number.
* @return The jitter delay in milliseconds.
*/
public int jitterDelayMillis(int retry) {
double delay = rawDelayMs(retry);
double jitter = delay * jitterScale;
return (int) (delay + RANDOM.nextInt((int) jitter));
}
/**
* This method sleeps after a given retry.
*
* @param retry The retry number.
*/
@JacocoIgnoreCoverageGenerated
public void sleep(int retry) {
try {
Thread.sleep(jitterDelayMillis(retry));
} catch (InterruptedException ignored) {
// pass
}
}
/**
* This method attempts to execute a given action up to 3 times with an exponential backoff.
* If the action fails on all attempts, it throws a RuntimeException.
*
* @param action The action to be executed.
* @param <T> The type of the result of the action.
* @return The result of the action if it is successful.
* @throws RuntimeException if the action fails on all attempts.
*/
public <T> T withRetry(Callable<T> action) {
return withRetry(action, maxRetries);
}
/**
* This method attempts to execute a given action up to a specified number of times with an exponential backoff.
* If the action fails on all attempts, it throws a RuntimeException.
*
* @param action The action to be executed.
* @param maxRetries The maximum number of retries.
* The action can be executed up to {@code maxRetries + 1} times.
* @param <T> The type of the result of the action.
* @return The result of the action if it is successful.
* @throws RuntimeException if the action fails on all attempts.
*/
public <T> T withRetry(Callable<T> action, int maxRetries) {
int retry = 0;
while (true) {
try {
return action.call();
} catch (NonRetriableException e) {
throw e;
} catch (Exception e) {
if (retry >= maxRetries || ExceptionUtils.find(e, InterruptedException.class) != null) {
throw e instanceof RuntimeException re ? re : new LangChain4jException(e);
}
log.warn(
"A retriable exception occurred. Remaining retries: %s of %s"
.formatted(maxRetries - retry, maxRetries),
e);
sleep(retry);
}
retry++;
}
}
}
/**
* Default retry policy used by {@link #withRetry(Callable)}.
*/
public static final RetryPolicy DEFAULT_RETRY_POLICY = retryPolicyBuilder()
.maxRetries(2)
.delayMillis(500)
.jitterScale(0.2)
.backoffExp(1.5)
.build();
/**
* This method attempts to execute a given action up to 3 times with an exponential backoff.
* If the action fails on all attempts, it throws a RuntimeException.
*
* @param action The action to be executed.
* @param <T> The type of the result of the action.
* @return The result of the action if it is successful.
* @throws RuntimeException if the action fails on all attempts.
*/
public static <T> T withRetry(Callable<T> action) {
return DEFAULT_RETRY_POLICY.withRetry(action);
}
/**
* This method attempts to execute a given action up to a specified number of times with an exponential backoff.
* If the action fails on all attempts, it throws a RuntimeException.
*
* @param action The action to be executed.
* @param maxRetries The maximum number of retries.
* The action can be executed up to {@code maxRetries + 1} times.
* @param <T> The type of the result of the action.
* @return The result of the action if it is successful.
* @throws RuntimeException if the action fails on all attempts.
*/
public static <T> T withRetry(Callable<T> action, int maxRetries) {
return DEFAULT_RETRY_POLICY.withRetry(action, maxRetries);
}
/**
* This method attempts to execute a given action up to a specified number of times with an exponential backoff.
* If the action fails on all attempts, it throws a RuntimeException.
*
* @param action The action to be executed.
* @param maxRetries The maximum number of retries.
* The action can be executed up to {@code maxRetries + 1} times.
* @throws RuntimeException if the action fails on all attempts.
*/
public static void withRetry(Runnable action, int maxRetries) {
DEFAULT_RETRY_POLICY.withRetry(
() -> {
action.run();
return null;
},
maxRetries);
}
/**
* This method attempts to execute a given action up to 3 times with an exponential backoff.
* If the action fails, the Exception causing the failure will be mapped with the default {@link ExceptionMapper}.
*
* @param action The action to be executed.
* @param <T> The type of the result of the action.
* @return The result of the action if it is successful.
* @throws RuntimeException if the action fails on all attempts.
*/
public static <T> T withRetryMappingExceptions(Callable<T> action) {
return withRetry(() -> ExceptionMapper.DEFAULT.withExceptionMapper(action));
}
/**
* This method attempts to execute a given action up to a specified number of times with an exponential backoff.
* If the action fails, the Exception causing the failure will be mapped with the default {@link ExceptionMapper}.
*
* @param action The action to be executed.
* @param maxRetries The maximum number of retries.
* The action can be executed up to {@code maxRetries + 1} times.
* @param <T> The type of the result of the action.
* @return The result of the action if it is successful.
* @throws RuntimeException if the action fails on all attempts.
*/
public static <T> T withRetryMappingExceptions(Callable<T> action, int maxRetries) {
return withRetryMappingExceptions(action, maxRetries, ExceptionMapper.DEFAULT);
}
/**
* This method attempts to execute a given action up to a specified number of times with an exponential backoff.
* If the action fails, the Exception causing the failure will be mapped with the provided {@link ExceptionMapper}.
*
* @param action The action to be executed.
* @param maxRetries The maximum number of retries.
* The action can be executed up to {@code maxRetries + 1} times.
* @param exceptionMapper The ExceptionMapper used to translate the exception that caused the failure of the action invocation.
* @param <T> The type of the result of the action.
* @return The result of the action if it is successful.
* @throws RuntimeException if the action fails on all attempts.
*/
public static <T> T withRetryMappingExceptions(
Callable<T> action, int maxRetries, ExceptionMapper exceptionMapper) {
return withRetry(() -> exceptionMapper.withExceptionMapper(action), maxRetries);
}
}

View File

@ -75,9 +75,10 @@ import io.onedev.commons.utils.ExceptionUtils;
import io.onedev.commons.utils.StringUtils;
import io.onedev.k8shelper.KubernetesHelper;
import io.onedev.k8shelper.OsInfo;
import io.onedev.server.ai.McpHelperResource;
import io.onedev.server.annotation.Shallow;
import io.onedev.server.attachment.AttachmentManager;
import io.onedev.server.attachment.DefaultAttachmentManager;
import io.onedev.server.attachment.AttachmentService;
import io.onedev.server.attachment.DefaultAttachmentService;
import io.onedev.server.buildspec.BuildSpecSchemaResource;
import io.onedev.server.buildspec.job.log.instruction.LogInstruction;
import io.onedev.server.cluster.ClusterResource;
@ -91,186 +92,10 @@ import io.onedev.server.commandhandler.ResetAdminPassword;
import io.onedev.server.commandhandler.RestoreDatabase;
import io.onedev.server.commandhandler.Translate;
import io.onedev.server.commandhandler.Upgrade;
import io.onedev.server.data.DataManager;
import io.onedev.server.data.DefaultDataManager;
import io.onedev.server.entitymanager.AccessTokenAuthorizationManager;
import io.onedev.server.entitymanager.AccessTokenManager;
import io.onedev.server.entitymanager.AgentAttributeManager;
import io.onedev.server.entitymanager.AgentLastUsedDateManager;
import io.onedev.server.entitymanager.AgentManager;
import io.onedev.server.entitymanager.AgentTokenManager;
import io.onedev.server.entitymanager.AlertManager;
import io.onedev.server.entitymanager.BaseAuthorizationManager;
import io.onedev.server.entitymanager.BuildDependenceManager;
import io.onedev.server.entitymanager.BuildLabelManager;
import io.onedev.server.entitymanager.BuildManager;
import io.onedev.server.entitymanager.BuildMetricManager;
import io.onedev.server.entitymanager.BuildParamManager;
import io.onedev.server.entitymanager.BuildQueryPersonalizationManager;
import io.onedev.server.entitymanager.CodeCommentManager;
import io.onedev.server.entitymanager.CodeCommentMentionManager;
import io.onedev.server.entitymanager.CodeCommentQueryPersonalizationManager;
import io.onedev.server.entitymanager.CodeCommentReplyManager;
import io.onedev.server.entitymanager.CodeCommentStatusChangeManager;
import io.onedev.server.entitymanager.CodeCommentTouchManager;
import io.onedev.server.entitymanager.CommitQueryPersonalizationManager;
import io.onedev.server.entitymanager.DashboardGroupShareManager;
import io.onedev.server.entitymanager.DashboardManager;
import io.onedev.server.entitymanager.DashboardUserShareManager;
import io.onedev.server.entitymanager.DashboardVisitManager;
import io.onedev.server.entitymanager.EmailAddressManager;
import io.onedev.server.entitymanager.GitLfsLockManager;
import io.onedev.server.entitymanager.GpgKeyManager;
import io.onedev.server.entitymanager.GroupAuthorizationManager;
import io.onedev.server.entitymanager.GroupManager;
import io.onedev.server.entitymanager.IssueAuthorizationManager;
import io.onedev.server.entitymanager.IssueChangeManager;
import io.onedev.server.entitymanager.IssueCommentManager;
import io.onedev.server.entitymanager.IssueCommentReactionManager;
import io.onedev.server.entitymanager.IssueCommentRevisionManager;
import io.onedev.server.entitymanager.IssueDescriptionRevisionManager;
import io.onedev.server.entitymanager.IssueFieldManager;
import io.onedev.server.entitymanager.IssueLinkManager;
import io.onedev.server.entitymanager.IssueManager;
import io.onedev.server.entitymanager.IssueMentionManager;
import io.onedev.server.entitymanager.IssueQueryPersonalizationManager;
import io.onedev.server.entitymanager.IssueReactionManager;
import io.onedev.server.entitymanager.IssueScheduleManager;
import io.onedev.server.entitymanager.IssueStateHistoryManager;
import io.onedev.server.entitymanager.IssueTouchManager;
import io.onedev.server.entitymanager.IssueVoteManager;
import io.onedev.server.entitymanager.IssueWatchManager;
import io.onedev.server.entitymanager.IssueWorkManager;
import io.onedev.server.entitymanager.IterationManager;
import io.onedev.server.entitymanager.JobCacheManager;
import io.onedev.server.entitymanager.LabelSpecManager;
import io.onedev.server.entitymanager.LinkAuthorizationManager;
import io.onedev.server.entitymanager.LinkSpecManager;
import io.onedev.server.entitymanager.MembershipManager;
import io.onedev.server.entitymanager.PackBlobManager;
import io.onedev.server.entitymanager.PackBlobReferenceManager;
import io.onedev.server.entitymanager.PackLabelManager;
import io.onedev.server.entitymanager.PackManager;
import io.onedev.server.entitymanager.PackQueryPersonalizationManager;
import io.onedev.server.entitymanager.PendingSuggestionApplyManager;
import io.onedev.server.entitymanager.ProjectLabelManager;
import io.onedev.server.entitymanager.ProjectLastEventDateManager;
import io.onedev.server.entitymanager.ProjectManager;
import io.onedev.server.entitymanager.PullRequestAssignmentManager;
import io.onedev.server.entitymanager.PullRequestChangeManager;
import io.onedev.server.entitymanager.PullRequestCommentManager;
import io.onedev.server.entitymanager.PullRequestCommentReactionManager;
import io.onedev.server.entitymanager.PullRequestCommentRevisionManager;
import io.onedev.server.entitymanager.PullRequestDescriptionRevisionManager;
import io.onedev.server.entitymanager.PullRequestLabelManager;
import io.onedev.server.entitymanager.PullRequestManager;
import io.onedev.server.entitymanager.PullRequestMentionManager;
import io.onedev.server.entitymanager.PullRequestQueryPersonalizationManager;
import io.onedev.server.entitymanager.PullRequestReactionManager;
import io.onedev.server.entitymanager.PullRequestReviewManager;
import io.onedev.server.entitymanager.PullRequestTouchManager;
import io.onedev.server.entitymanager.PullRequestUpdateManager;
import io.onedev.server.entitymanager.PullRequestWatchManager;
import io.onedev.server.entitymanager.ReviewedDiffManager;
import io.onedev.server.entitymanager.RoleManager;
import io.onedev.server.entitymanager.SettingManager;
import io.onedev.server.entitymanager.SshKeyManager;
import io.onedev.server.entitymanager.SsoAccountManager;
import io.onedev.server.entitymanager.SsoProviderManager;
import io.onedev.server.entitymanager.StopwatchManager;
import io.onedev.server.entitymanager.UserAuthorizationManager;
import io.onedev.server.entitymanager.UserInvitationManager;
import io.onedev.server.entitymanager.UserManager;
import io.onedev.server.entitymanager.impl.DefaultAccessTokenAuthorizationManager;
import io.onedev.server.entitymanager.impl.DefaultAccessTokenManager;
import io.onedev.server.entitymanager.impl.DefaultAgentAttributeManager;
import io.onedev.server.entitymanager.impl.DefaultAgentLastUsedDateManager;
import io.onedev.server.entitymanager.impl.DefaultAgentManager;
import io.onedev.server.entitymanager.impl.DefaultAgentTokenManager;
import io.onedev.server.entitymanager.impl.DefaultAlertManager;
import io.onedev.server.entitymanager.impl.DefaultBaseAuthorizationManager;
import io.onedev.server.entitymanager.impl.DefaultBuildDependenceManager;
import io.onedev.server.entitymanager.impl.DefaultBuildLabelManager;
import io.onedev.server.entitymanager.impl.DefaultBuildManager;
import io.onedev.server.entitymanager.impl.DefaultBuildMetricManager;
import io.onedev.server.entitymanager.impl.DefaultBuildParamManager;
import io.onedev.server.entitymanager.impl.DefaultBuildQueryPersonalizationManager;
import io.onedev.server.entitymanager.impl.DefaultCodeCommentManager;
import io.onedev.server.entitymanager.impl.DefaultCodeCommentMentionManager;
import io.onedev.server.entitymanager.impl.DefaultCodeCommentQueryPersonalizationManager;
import io.onedev.server.entitymanager.impl.DefaultCodeCommentReplyManager;
import io.onedev.server.entitymanager.impl.DefaultCodeCommentStatusChangeManager;
import io.onedev.server.entitymanager.impl.DefaultCodeCommentTouchManager;
import io.onedev.server.entitymanager.impl.DefaultCommitQueryPersonalizationManager;
import io.onedev.server.entitymanager.impl.DefaultDashboardGroupShareManager;
import io.onedev.server.entitymanager.impl.DefaultDashboardManager;
import io.onedev.server.entitymanager.impl.DefaultDashboardUserShareManager;
import io.onedev.server.entitymanager.impl.DefaultDashboardVisitManager;
import io.onedev.server.entitymanager.impl.DefaultEmailAddressManager;
import io.onedev.server.entitymanager.impl.DefaultGitLfsLockManager;
import io.onedev.server.entitymanager.impl.DefaultGpgKeyManager;
import io.onedev.server.entitymanager.impl.DefaultGroupAuthorizationManager;
import io.onedev.server.entitymanager.impl.DefaultGroupManager;
import io.onedev.server.entitymanager.impl.DefaultIssueAuthorizationManager;
import io.onedev.server.entitymanager.impl.DefaultIssueChangeManager;
import io.onedev.server.entitymanager.impl.DefaultIssueCommentManager;
import io.onedev.server.entitymanager.impl.DefaultIssueCommentReactionManager;
import io.onedev.server.entitymanager.impl.DefaultIssueCommentRevisionManager;
import io.onedev.server.entitymanager.impl.DefaultIssueDescriptionRevisionManager;
import io.onedev.server.entitymanager.impl.DefaultIssueFieldManager;
import io.onedev.server.entitymanager.impl.DefaultIssueLinkManager;
import io.onedev.server.entitymanager.impl.DefaultIssueManager;
import io.onedev.server.entitymanager.impl.DefaultIssueMentionManager;
import io.onedev.server.entitymanager.impl.DefaultIssueQueryPersonalizationManager;
import io.onedev.server.entitymanager.impl.DefaultIssueReactionManager;
import io.onedev.server.entitymanager.impl.DefaultIssueScheduleManager;
import io.onedev.server.entitymanager.impl.DefaultIssueStateHistoryManager;
import io.onedev.server.entitymanager.impl.DefaultIssueTouchManager;
import io.onedev.server.entitymanager.impl.DefaultIssueVoteManager;
import io.onedev.server.entitymanager.impl.DefaultIssueWatchManager;
import io.onedev.server.entitymanager.impl.DefaultIssueWorkManager;
import io.onedev.server.entitymanager.impl.DefaultIterationManager;
import io.onedev.server.entitymanager.impl.DefaultJobCacheManager;
import io.onedev.server.entitymanager.impl.DefaultLabelSpecManager;
import io.onedev.server.entitymanager.impl.DefaultLinkAuthorizationManager;
import io.onedev.server.entitymanager.impl.DefaultLinkSpecManager;
import io.onedev.server.entitymanager.impl.DefaultMembershipManager;
import io.onedev.server.entitymanager.impl.DefaultPackBlobManager;
import io.onedev.server.entitymanager.impl.DefaultPackBlobReferenceManager;
import io.onedev.server.entitymanager.impl.DefaultPackLabelManager;
import io.onedev.server.entitymanager.impl.DefaultPackManager;
import io.onedev.server.entitymanager.impl.DefaultPackQueryPersonalizationManager;
import io.onedev.server.entitymanager.impl.DefaultPendingSuggestionApplyManager;
import io.onedev.server.entitymanager.impl.DefaultProjectLabelManager;
import io.onedev.server.entitymanager.impl.DefaultProjectLastEventDateManager;
import io.onedev.server.entitymanager.impl.DefaultProjectManager;
import io.onedev.server.entitymanager.impl.DefaultPullRequestAssignmentManager;
import io.onedev.server.entitymanager.impl.DefaultPullRequestChangeManager;
import io.onedev.server.entitymanager.impl.DefaultPullRequestCommentManager;
import io.onedev.server.entitymanager.impl.DefaultPullRequestCommentReactionManager;
import io.onedev.server.entitymanager.impl.DefaultPullRequestCommentRevisionManager;
import io.onedev.server.entitymanager.impl.DefaultPullRequestDescriptionRevisionManager;
import io.onedev.server.entitymanager.impl.DefaultPullRequestLabelManager;
import io.onedev.server.entitymanager.impl.DefaultPullRequestManager;
import io.onedev.server.entitymanager.impl.DefaultPullRequestMentionManager;
import io.onedev.server.entitymanager.impl.DefaultPullRequestQueryPersonalizationManager;
import io.onedev.server.entitymanager.impl.DefaultPullRequestReactionManager;
import io.onedev.server.entitymanager.impl.DefaultPullRequestReviewManager;
import io.onedev.server.entitymanager.impl.DefaultPullRequestTouchManager;
import io.onedev.server.entitymanager.impl.DefaultPullRequestUpdateManager;
import io.onedev.server.entitymanager.impl.DefaultPullRequestWatchManager;
import io.onedev.server.entitymanager.impl.DefaultReviewedDiffManager;
import io.onedev.server.entitymanager.impl.DefaultRoleManager;
import io.onedev.server.entitymanager.impl.DefaultSettingManager;
import io.onedev.server.entitymanager.impl.DefaultSshKeyManager;
import io.onedev.server.entitymanager.impl.DefaultSsoAccountManager;
import io.onedev.server.entitymanager.impl.DefaultSsoProviderManager;
import io.onedev.server.entitymanager.impl.DefaultStopwatchManager;
import io.onedev.server.entitymanager.impl.DefaultUserAuthorizationManager;
import io.onedev.server.entitymanager.impl.DefaultUserInvitationManager;
import io.onedev.server.entitymanager.impl.DefaultUserManager;
import io.onedev.server.entityreference.DefaultReferenceChangeManager;
import io.onedev.server.entityreference.ReferenceChangeManager;
import io.onedev.server.data.DataService;
import io.onedev.server.data.DefaultDataService;
import io.onedev.server.entityreference.DefaultReferenceChangeService;
import io.onedev.server.entityreference.ReferenceChangeService;
import io.onedev.server.event.DefaultListenerRegistry;
import io.onedev.server.event.ListenerRegistry;
import io.onedev.server.exception.handler.ExceptionHandler;
@ -285,23 +110,23 @@ import io.onedev.server.git.hook.GitPreReceiveChecker;
import io.onedev.server.git.location.GitLocation;
import io.onedev.server.git.service.DefaultGitService;
import io.onedev.server.git.service.GitService;
import io.onedev.server.git.signatureverification.DefaultSignatureVerificationManager;
import io.onedev.server.git.signatureverification.SignatureVerificationManager;
import io.onedev.server.git.signatureverification.DefaultSignatureVerificationService;
import io.onedev.server.git.signatureverification.SignatureVerificationService;
import io.onedev.server.git.signatureverification.SignatureVerifier;
import io.onedev.server.jetty.DefaultJettyManager;
import io.onedev.server.jetty.DefaultJettyService;
import io.onedev.server.jetty.DefaultSessionDataStoreFactory;
import io.onedev.server.jetty.JettyManager;
import io.onedev.server.job.DefaultJobManager;
import io.onedev.server.jetty.JettyService;
import io.onedev.server.job.DefaultJobService;
import io.onedev.server.job.DefaultResourceAllocator;
import io.onedev.server.job.JobManager;
import io.onedev.server.job.JobService;
import io.onedev.server.job.ResourceAllocator;
import io.onedev.server.job.log.DefaultLogManager;
import io.onedev.server.job.log.LogManager;
import io.onedev.server.mail.DefaultMailManager;
import io.onedev.server.mail.MailManager;
import io.onedev.server.markdown.DefaultMarkdownManager;
import io.onedev.server.job.log.DefaultLogService;
import io.onedev.server.job.log.LogService;
import io.onedev.server.mail.DefaultMailService;
import io.onedev.server.mail.MailService;
import io.onedev.server.markdown.DefaultMarkdownService;
import io.onedev.server.markdown.HtmlProcessor;
import io.onedev.server.markdown.MarkdownManager;
import io.onedev.server.markdown.MarkdownService;
import io.onedev.server.model.support.administration.GroovyScript;
import io.onedev.server.model.support.administration.authenticator.Authenticator;
import io.onedev.server.notification.BuildNotificationManager;
@ -312,21 +137,21 @@ import io.onedev.server.notification.PackNotificationManager;
import io.onedev.server.notification.PullRequestNotificationManager;
import io.onedev.server.notification.WebHookManager;
import io.onedev.server.pack.PackFilter;
import io.onedev.server.persistence.DefaultIdManager;
import io.onedev.server.persistence.DefaultSessionFactoryManager;
import io.onedev.server.persistence.DefaultSessionManager;
import io.onedev.server.persistence.DefaultTransactionManager;
import io.onedev.server.persistence.DefaultIdService;
import io.onedev.server.persistence.DefaultSessionFactoryService;
import io.onedev.server.persistence.DefaultSessionService;
import io.onedev.server.persistence.DefaultTransactionService;
import io.onedev.server.persistence.HibernateInterceptor;
import io.onedev.server.persistence.IdManager;
import io.onedev.server.persistence.IdService;
import io.onedev.server.persistence.PersistListener;
import io.onedev.server.persistence.PrefixedNamingStrategy;
import io.onedev.server.persistence.SessionFactoryManager;
import io.onedev.server.persistence.SessionFactoryProvider;
import io.onedev.server.persistence.SessionFactoryService;
import io.onedev.server.persistence.SessionInterceptor;
import io.onedev.server.persistence.SessionManager;
import io.onedev.server.persistence.SessionProvider;
import io.onedev.server.persistence.SessionService;
import io.onedev.server.persistence.TransactionInterceptor;
import io.onedev.server.persistence.TransactionManager;
import io.onedev.server.persistence.TransactionService;
import io.onedev.server.persistence.annotation.Sessional;
import io.onedev.server.persistence.annotation.Transactional;
import io.onedev.server.persistence.dao.Dao;
@ -336,18 +161,17 @@ import io.onedev.server.rest.DefaultServletContainer;
import io.onedev.server.rest.JerseyConfigurator;
import io.onedev.server.rest.ResourceConfigProvider;
import io.onedev.server.rest.WebApplicationExceptionHandler;
import io.onedev.server.rest.resource.McpHelperResource;
import io.onedev.server.rest.resource.ProjectResource;
import io.onedev.server.search.code.CodeIndexManager;
import io.onedev.server.search.code.CodeSearchManager;
import io.onedev.server.search.code.DefaultCodeIndexManager;
import io.onedev.server.search.code.DefaultCodeSearchManager;
import io.onedev.server.search.entitytext.CodeCommentTextManager;
import io.onedev.server.search.entitytext.DefaultCodeCommentTextManager;
import io.onedev.server.search.entitytext.DefaultIssueTextManager;
import io.onedev.server.search.entitytext.DefaultPullRequestTextManager;
import io.onedev.server.search.entitytext.IssueTextManager;
import io.onedev.server.search.entitytext.PullRequestTextManager;
import io.onedev.server.search.code.CodeIndexService;
import io.onedev.server.search.code.CodeSearchService;
import io.onedev.server.search.code.DefaultCodeIndexService;
import io.onedev.server.search.code.DefaultCodeSearchService;
import io.onedev.server.search.entitytext.CodeCommentTextService;
import io.onedev.server.search.entitytext.DefaultCodeCommentTextService;
import io.onedev.server.search.entitytext.DefaultIssueTextService;
import io.onedev.server.search.entitytext.DefaultPullRequestTextService;
import io.onedev.server.search.entitytext.IssueTextService;
import io.onedev.server.search.entitytext.PullRequestTextService;
import io.onedev.server.security.BasicAuthenticationFilter;
import io.onedev.server.security.BearerAuthenticationFilter;
import io.onedev.server.security.CodePullAuthorizationSource;
@ -359,26 +183,208 @@ import io.onedev.server.security.DefaultWebSecurityManager;
import io.onedev.server.security.FilterChainConfigurator;
import io.onedev.server.security.SecurityUtils;
import io.onedev.server.security.realm.GeneralAuthorizingRealm;
import io.onedev.server.service.AccessTokenAuthorizationService;
import io.onedev.server.service.AccessTokenService;
import io.onedev.server.service.AgentAttributeService;
import io.onedev.server.service.AgentLastUsedDateService;
import io.onedev.server.service.AgentService;
import io.onedev.server.service.AgentTokenService;
import io.onedev.server.service.AlertService;
import io.onedev.server.service.BaseAuthorizationService;
import io.onedev.server.service.BuildDependenceService;
import io.onedev.server.service.BuildLabelService;
import io.onedev.server.service.BuildMetricService;
import io.onedev.server.service.BuildParamService;
import io.onedev.server.service.BuildQueryPersonalizationService;
import io.onedev.server.service.BuildService;
import io.onedev.server.service.CodeCommentMentionService;
import io.onedev.server.service.CodeCommentQueryPersonalizationService;
import io.onedev.server.service.CodeCommentReplyService;
import io.onedev.server.service.CodeCommentService;
import io.onedev.server.service.CodeCommentStatusChangeService;
import io.onedev.server.service.CodeCommentTouchService;
import io.onedev.server.service.CommitQueryPersonalizationService;
import io.onedev.server.service.DashboardGroupShareService;
import io.onedev.server.service.DashboardService;
import io.onedev.server.service.DashboardUserShareService;
import io.onedev.server.service.DashboardVisitService;
import io.onedev.server.service.EmailAddressService;
import io.onedev.server.service.GitLfsLockService;
import io.onedev.server.service.GpgKeyService;
import io.onedev.server.service.GroupAuthorizationService;
import io.onedev.server.service.GroupEntitlementService;
import io.onedev.server.service.GroupService;
import io.onedev.server.service.IssueAuthorizationService;
import io.onedev.server.service.IssueChangeService;
import io.onedev.server.service.IssueCommentReactionService;
import io.onedev.server.service.IssueCommentRevisionService;
import io.onedev.server.service.IssueCommentService;
import io.onedev.server.service.IssueDescriptionRevisionService;
import io.onedev.server.service.IssueFieldService;
import io.onedev.server.service.IssueLinkService;
import io.onedev.server.service.IssueMentionService;
import io.onedev.server.service.IssueQueryPersonalizationService;
import io.onedev.server.service.IssueReactionService;
import io.onedev.server.service.IssueScheduleService;
import io.onedev.server.service.IssueService;
import io.onedev.server.service.IssueStateHistoryService;
import io.onedev.server.service.IssueTouchService;
import io.onedev.server.service.IssueVoteService;
import io.onedev.server.service.IssueWatchService;
import io.onedev.server.service.IssueWorkService;
import io.onedev.server.service.IterationService;
import io.onedev.server.service.JobCacheService;
import io.onedev.server.service.LabelSpecService;
import io.onedev.server.service.LinkAuthorizationService;
import io.onedev.server.service.LinkSpecService;
import io.onedev.server.service.MembershipService;
import io.onedev.server.service.PackBlobReferenceService;
import io.onedev.server.service.PackBlobService;
import io.onedev.server.service.PackLabelService;
import io.onedev.server.service.PackQueryPersonalizationService;
import io.onedev.server.service.PackService;
import io.onedev.server.service.PendingSuggestionApplyService;
import io.onedev.server.service.ProjectEntitlementService;
import io.onedev.server.service.ProjectLabelService;
import io.onedev.server.service.ProjectLastEventDateService;
import io.onedev.server.service.ProjectService;
import io.onedev.server.service.PullRequestAssignmentService;
import io.onedev.server.service.PullRequestChangeService;
import io.onedev.server.service.PullRequestCommentReactionService;
import io.onedev.server.service.PullRequestCommentRevisionService;
import io.onedev.server.service.PullRequestCommentService;
import io.onedev.server.service.PullRequestDescriptionRevisionService;
import io.onedev.server.service.PullRequestLabelService;
import io.onedev.server.service.PullRequestMentionService;
import io.onedev.server.service.PullRequestQueryPersonalizationService;
import io.onedev.server.service.PullRequestReactionService;
import io.onedev.server.service.PullRequestReviewService;
import io.onedev.server.service.PullRequestService;
import io.onedev.server.service.PullRequestTouchService;
import io.onedev.server.service.PullRequestUpdateService;
import io.onedev.server.service.PullRequestWatchService;
import io.onedev.server.service.ReviewedDiffService;
import io.onedev.server.service.RoleService;
import io.onedev.server.service.SettingService;
import io.onedev.server.service.SshKeyService;
import io.onedev.server.service.SsoAccountService;
import io.onedev.server.service.SsoProviderService;
import io.onedev.server.service.StopwatchService;
import io.onedev.server.service.UserAuthorizationService;
import io.onedev.server.service.UserEntitlementService;
import io.onedev.server.service.UserInvitationService;
import io.onedev.server.service.UserService;
import io.onedev.server.service.impl.DefaultAccessTokenAuthorizationService;
import io.onedev.server.service.impl.DefaultAccessTokenService;
import io.onedev.server.service.impl.DefaultAgentAttributeService;
import io.onedev.server.service.impl.DefaultAgentLastUsedDateService;
import io.onedev.server.service.impl.DefaultAgentService;
import io.onedev.server.service.impl.DefaultAgentTokenService;
import io.onedev.server.service.impl.DefaultAlertService;
import io.onedev.server.service.impl.DefaultBaseAuthorizationService;
import io.onedev.server.service.impl.DefaultBuildDependenceService;
import io.onedev.server.service.impl.DefaultBuildLabelService;
import io.onedev.server.service.impl.DefaultBuildMetricService;
import io.onedev.server.service.impl.DefaultBuildParamService;
import io.onedev.server.service.impl.DefaultBuildQueryPersonalizationService;
import io.onedev.server.service.impl.DefaultBuildService;
import io.onedev.server.service.impl.DefaultCodeCommentMentionService;
import io.onedev.server.service.impl.DefaultCodeCommentQueryPersonalizationService;
import io.onedev.server.service.impl.DefaultCodeCommentReplyService;
import io.onedev.server.service.impl.DefaultCodeCommentService;
import io.onedev.server.service.impl.DefaultCodeCommentStatusChangeService;
import io.onedev.server.service.impl.DefaultCodeCommentTouchService;
import io.onedev.server.service.impl.DefaultCommitQueryPersonalizationService;
import io.onedev.server.service.impl.DefaultDashboardGroupShareService;
import io.onedev.server.service.impl.DefaultDashboardService;
import io.onedev.server.service.impl.DefaultDashboardUserShareService;
import io.onedev.server.service.impl.DefaultDashboardVisitService;
import io.onedev.server.service.impl.DefaultEmailAddressService;
import io.onedev.server.service.impl.DefaultGitLfsLockService;
import io.onedev.server.service.impl.DefaultGpgKeyService;
import io.onedev.server.service.impl.DefaultGroupAuthorizationService;
import io.onedev.server.service.impl.DefaultGroupEntitlementService;
import io.onedev.server.service.impl.DefaultGroupService;
import io.onedev.server.service.impl.DefaultIssueAuthorizationService;
import io.onedev.server.service.impl.DefaultIssueChangeService;
import io.onedev.server.service.impl.DefaultIssueCommentReactionService;
import io.onedev.server.service.impl.DefaultIssueCommentRevisionService;
import io.onedev.server.service.impl.DefaultIssueCommentService;
import io.onedev.server.service.impl.DefaultIssueDescriptionRevisionService;
import io.onedev.server.service.impl.DefaultIssueFieldService;
import io.onedev.server.service.impl.DefaultIssueLinkService;
import io.onedev.server.service.impl.DefaultIssueMentionService;
import io.onedev.server.service.impl.DefaultIssueQueryPersonalizationService;
import io.onedev.server.service.impl.DefaultIssueReactionService;
import io.onedev.server.service.impl.DefaultIssueScheduleService;
import io.onedev.server.service.impl.DefaultIssueService;
import io.onedev.server.service.impl.DefaultIssueStateHistoryService;
import io.onedev.server.service.impl.DefaultIssueTouchService;
import io.onedev.server.service.impl.DefaultIssueVoteService;
import io.onedev.server.service.impl.DefaultIssueWatchService;
import io.onedev.server.service.impl.DefaultIssueWorkService;
import io.onedev.server.service.impl.DefaultIterationService;
import io.onedev.server.service.impl.DefaultJobCacheService;
import io.onedev.server.service.impl.DefaultLabelSpecService;
import io.onedev.server.service.impl.DefaultLinkAuthorizationService;
import io.onedev.server.service.impl.DefaultLinkSpecService;
import io.onedev.server.service.impl.DefaultMembershipService;
import io.onedev.server.service.impl.DefaultPackBlobReferenceService;
import io.onedev.server.service.impl.DefaultPackBlobService;
import io.onedev.server.service.impl.DefaultPackLabelService;
import io.onedev.server.service.impl.DefaultPackQueryPersonalizationService;
import io.onedev.server.service.impl.DefaultPackService;
import io.onedev.server.service.impl.DefaultPendingSuggestionApplyService;
import io.onedev.server.service.impl.DefaultProjectEntitlementService;
import io.onedev.server.service.impl.DefaultProjectLabelService;
import io.onedev.server.service.impl.DefaultProjectLastEventDateService;
import io.onedev.server.service.impl.DefaultProjectService;
import io.onedev.server.service.impl.DefaultPullRequestAssignmentService;
import io.onedev.server.service.impl.DefaultPullRequestChangeService;
import io.onedev.server.service.impl.DefaultPullRequestCommentReactionService;
import io.onedev.server.service.impl.DefaultPullRequestCommentRevisionService;
import io.onedev.server.service.impl.DefaultPullRequestCommentService;
import io.onedev.server.service.impl.DefaultPullRequestDescriptionRevisionService;
import io.onedev.server.service.impl.DefaultPullRequestLabelService;
import io.onedev.server.service.impl.DefaultPullRequestMentionService;
import io.onedev.server.service.impl.DefaultPullRequestQueryPersonalizationService;
import io.onedev.server.service.impl.DefaultPullRequestReactionService;
import io.onedev.server.service.impl.DefaultPullRequestReviewService;
import io.onedev.server.service.impl.DefaultPullRequestService;
import io.onedev.server.service.impl.DefaultPullRequestTouchService;
import io.onedev.server.service.impl.DefaultPullRequestUpdateService;
import io.onedev.server.service.impl.DefaultPullRequestWatchService;
import io.onedev.server.service.impl.DefaultReviewedDiffService;
import io.onedev.server.service.impl.DefaultRoleService;
import io.onedev.server.service.impl.DefaultSettingService;
import io.onedev.server.service.impl.DefaultSshKeyService;
import io.onedev.server.service.impl.DefaultSsoAccountService;
import io.onedev.server.service.impl.DefaultSsoProviderService;
import io.onedev.server.service.impl.DefaultStopwatchService;
import io.onedev.server.service.impl.DefaultUserAuthorizationService;
import io.onedev.server.service.impl.DefaultUserEntitlementService;
import io.onedev.server.service.impl.DefaultUserInvitationService;
import io.onedev.server.service.impl.DefaultUserService;
import io.onedev.server.ssh.CommandCreator;
import io.onedev.server.ssh.DefaultSshAuthenticator;
import io.onedev.server.ssh.DefaultSshManager;
import io.onedev.server.ssh.DefaultSshService;
import io.onedev.server.ssh.SshAuthenticator;
import io.onedev.server.ssh.SshManager;
import io.onedev.server.ssh.SshService;
import io.onedev.server.taskschedule.DefaultTaskScheduler;
import io.onedev.server.taskschedule.TaskScheduler;
import io.onedev.server.updatecheck.DefaultUpdateCheckManager;
import io.onedev.server.updatecheck.UpdateCheckManager;
import io.onedev.server.updatecheck.DefaultUpdateCheckService;
import io.onedev.server.updatecheck.UpdateCheckService;
import io.onedev.server.util.ScriptContribution;
import io.onedev.server.util.concurrent.BatchWorkManager;
import io.onedev.server.util.concurrent.DefaultBatchWorkManager;
import io.onedev.server.util.concurrent.DefaultWorkExecutor;
import io.onedev.server.util.concurrent.WorkExecutor;
import io.onedev.server.util.concurrent.BatchWorkExecutionService;
import io.onedev.server.util.concurrent.DefaultBatchWorkExecutionService;
import io.onedev.server.util.concurrent.DefaultWorkExecutionService;
import io.onedev.server.util.concurrent.WorkExecutionService;
import io.onedev.server.util.jackson.ObjectMapperConfigurator;
import io.onedev.server.util.jackson.ObjectMapperProvider;
import io.onedev.server.util.jackson.git.GitObjectMapperConfigurator;
import io.onedev.server.util.jackson.hibernate.HibernateObjectMapperConfigurator;
import io.onedev.server.util.oauth.DefaultOAuthTokenManager;
import io.onedev.server.util.oauth.OAuthTokenManager;
import io.onedev.server.util.oauth.DefaultOAuthTokenService;
import io.onedev.server.util.oauth.OAuthTokenService;
import io.onedev.server.util.xstream.CollectionConverter;
import io.onedev.server.util.xstream.HibernateProxyConverter;
import io.onedev.server.util.xstream.MapConverter;
@ -389,14 +395,15 @@ import io.onedev.server.util.xstream.VersionedDocumentConverter;
import io.onedev.server.validation.MessageInterpolator;
import io.onedev.server.validation.ShallowValidatorProvider;
import io.onedev.server.validation.ValidatorProvider;
import io.onedev.server.web.DefaultUrlManager;
import io.onedev.server.web.DefaultUrlService;
import io.onedev.server.web.DefaultWicketFilter;
import io.onedev.server.web.DefaultWicketServlet;
import io.onedev.server.web.ResourcePackScopeContribution;
import io.onedev.server.web.UrlManager;
import io.onedev.server.web.SessionListener;
import io.onedev.server.web.UrlService;
import io.onedev.server.web.WebApplication;
import io.onedev.server.web.avatar.AvatarManager;
import io.onedev.server.web.avatar.DefaultAvatarManager;
import io.onedev.server.web.avatar.AvatarService;
import io.onedev.server.web.avatar.DefaultAvatarService;
import io.onedev.server.web.component.diff.DiffRenderer;
import io.onedev.server.web.component.markdown.SourcePositionTrackExtension;
import io.onedev.server.web.component.markdown.emoji.EmojiExtension;
@ -409,24 +416,24 @@ import io.onedev.server.web.exceptionhandler.PageExpiredExceptionHandler;
import io.onedev.server.web.page.layout.AdministrationSettingContribution;
import io.onedev.server.web.page.project.blob.render.BlobRenderer;
import io.onedev.server.web.page.project.setting.ProjectSettingContribution;
import io.onedev.server.web.upload.DefaultUploadManager;
import io.onedev.server.web.upload.UploadManager;
import io.onedev.server.web.upload.DefaultUploadService;
import io.onedev.server.web.upload.UploadService;
import io.onedev.server.web.websocket.AlertEventBroadcaster;
import io.onedev.server.web.websocket.BuildEventBroadcaster;
import io.onedev.server.web.websocket.CodeCommentEventBroadcaster;
import io.onedev.server.web.websocket.CommitIndexedBroadcaster;
import io.onedev.server.web.websocket.DefaultWebSocketManager;
import io.onedev.server.web.websocket.DefaultWebSocketService;
import io.onedev.server.web.websocket.IssueEventBroadcaster;
import io.onedev.server.web.websocket.PullRequestEventBroadcaster;
import io.onedev.server.web.websocket.WebSocketManager;
import io.onedev.server.xodus.CommitInfoManager;
import io.onedev.server.xodus.DefaultCommitInfoManager;
import io.onedev.server.xodus.DefaultIssueInfoManager;
import io.onedev.server.xodus.DefaultPullRequestInfoManager;
import io.onedev.server.xodus.DefaultVisitInfoManager;
import io.onedev.server.xodus.IssueInfoManager;
import io.onedev.server.xodus.PullRequestInfoManager;
import io.onedev.server.xodus.VisitInfoManager;
import io.onedev.server.web.websocket.WebSocketService;
import io.onedev.server.xodus.CommitInfoService;
import io.onedev.server.xodus.DefaultCommitInfoService;
import io.onedev.server.xodus.DefaultIssueInfoService;
import io.onedev.server.xodus.DefaultPullRequestInfoService;
import io.onedev.server.xodus.DefaultVisitInfoService;
import io.onedev.server.xodus.IssueInfoService;
import io.onedev.server.xodus.PullRequestInfoService;
import io.onedev.server.xodus.VisitInfoService;
import nl.altindag.ssl.SSLFactory;
/**
@ -440,8 +447,8 @@ public class CoreModule extends AbstractPluginModule {
super.configure();
bind(ListenerRegistry.class).to(DefaultListenerRegistry.class);
bind(JettyManager.class).to(DefaultJettyManager.class);
bind(ServletContextHandler.class).toProvider(DefaultJettyManager.class);
bind(JettyService.class).to(DefaultJettyService.class);
bind(ServletContextHandler.class).toProvider(DefaultJettyService.class);
bind(ObjectMapper.class).toProvider(ObjectMapperProvider.class).in(Singleton.class);
@ -490,124 +497,127 @@ public class CoreModule extends AbstractPluginModule {
* HK2 to guice bridge can only search in explicit bindings in Guice
*/
bind(SshAuthenticator.class).to(DefaultSshAuthenticator.class);
bind(SshManager.class).to(DefaultSshManager.class);
bind(MarkdownManager.class).to(DefaultMarkdownManager.class);
bind(SettingManager.class).to(DefaultSettingManager.class);
bind(DataManager.class).to(DefaultDataManager.class);
bind(SshService.class).to(DefaultSshService.class);
bind(MarkdownService.class).to(DefaultMarkdownService.class);
bind(SettingService.class).to(DefaultSettingService.class);
bind(DataService.class).to(DefaultDataService.class);
bind(TaskScheduler.class).to(DefaultTaskScheduler.class);
bind(PullRequestCommentManager.class).to(DefaultPullRequestCommentManager.class);
bind(CodeCommentManager.class).to(DefaultCodeCommentManager.class);
bind(PullRequestManager.class).to(DefaultPullRequestManager.class);
bind(PullRequestUpdateManager.class).to(DefaultPullRequestUpdateManager.class);
bind(ProjectManager.class).to(DefaultProjectManager.class);
bind(ProjectLastEventDateManager.class).to(DefaultProjectLastEventDateManager.class);
bind(UserInvitationManager.class).to(DefaultUserInvitationManager.class);
bind(PullRequestReviewManager.class).to(DefaultPullRequestReviewManager.class);
bind(BuildManager.class).to(DefaultBuildManager.class);
bind(BuildDependenceManager.class).to(DefaultBuildDependenceManager.class);
bind(JobManager.class).to(DefaultJobManager.class);
bind(JobCacheManager.class).to(DefaultJobCacheManager.class);
bind(LogManager.class).to(DefaultLogManager.class);
bind(MailManager.class).to(DefaultMailManager.class);
bind(IssueManager.class).to(DefaultIssueManager.class);
bind(IssueFieldManager.class).to(DefaultIssueFieldManager.class);
bind(BuildParamManager.class).to(DefaultBuildParamManager.class);
bind(UserAuthorizationManager.class).to(DefaultUserAuthorizationManager.class);
bind(GroupAuthorizationManager.class).to(DefaultGroupAuthorizationManager.class);
bind(PullRequestWatchManager.class).to(DefaultPullRequestWatchManager.class);
bind(RoleManager.class).to(DefaultRoleManager.class);
bind(CommitInfoManager.class).to(DefaultCommitInfoManager.class);
bind(IssueInfoManager.class).to(DefaultIssueInfoManager.class);
bind(VisitInfoManager.class).to(DefaultVisitInfoManager.class);
bind(BatchWorkManager.class).to(DefaultBatchWorkManager.class);
bind(WorkExecutor.class).to(DefaultWorkExecutor.class);
bind(GroupManager.class).to(DefaultGroupManager.class);
bind(IssueMentionManager.class).to(DefaultIssueMentionManager.class);
bind(PullRequestMentionManager.class).to(DefaultPullRequestMentionManager.class);
bind(CodeCommentMentionManager.class).to(DefaultCodeCommentMentionManager.class);
bind(MembershipManager.class).to(DefaultMembershipManager.class);
bind(PullRequestChangeManager.class).to(DefaultPullRequestChangeManager.class);
bind(CodeCommentReplyManager.class).to(DefaultCodeCommentReplyManager.class);
bind(CodeCommentStatusChangeManager.class).to(DefaultCodeCommentStatusChangeManager.class);
bind(AttachmentManager.class).to(DefaultAttachmentManager.class);
bind(PullRequestInfoManager.class).to(DefaultPullRequestInfoManager.class);
bind(PullRequestCommentService.class).to(DefaultPullRequestCommentService.class);
bind(CodeCommentService.class).to(DefaultCodeCommentService.class);
bind(PullRequestService.class).to(DefaultPullRequestService.class);
bind(PullRequestUpdateService.class).to(DefaultPullRequestUpdateService.class);
bind(ProjectService.class).to(DefaultProjectService.class);
bind(ProjectLastEventDateService.class).to(DefaultProjectLastEventDateService.class);
bind(UserInvitationService.class).to(DefaultUserInvitationService.class);
bind(PullRequestReviewService.class).to(DefaultPullRequestReviewService.class);
bind(BuildService.class).to(DefaultBuildService.class);
bind(BuildDependenceService.class).to(DefaultBuildDependenceService.class);
bind(JobService.class).to(DefaultJobService.class);
bind(JobCacheService.class).to(DefaultJobCacheService.class);
bind(LogService.class).to(DefaultLogService.class);
bind(MailService.class).to(DefaultMailService.class);
bind(IssueService.class).to(DefaultIssueService.class);
bind(IssueFieldService.class).to(DefaultIssueFieldService.class);
bind(BuildParamService.class).to(DefaultBuildParamService.class);
bind(UserAuthorizationService.class).to(DefaultUserAuthorizationService.class);
bind(GroupAuthorizationService.class).to(DefaultGroupAuthorizationService.class);
bind(PullRequestWatchService.class).to(DefaultPullRequestWatchService.class);
bind(RoleService.class).to(DefaultRoleService.class);
bind(CommitInfoService.class).to(DefaultCommitInfoService.class);
bind(IssueInfoService.class).to(DefaultIssueInfoService.class);
bind(VisitInfoService.class).to(DefaultVisitInfoService.class);
bind(BatchWorkExecutionService.class).to(DefaultBatchWorkExecutionService.class);
bind(WorkExecutionService.class).to(DefaultWorkExecutionService.class);
bind(GroupService.class).to(DefaultGroupService.class);
bind(IssueMentionService.class).to(DefaultIssueMentionService.class);
bind(PullRequestMentionService.class).to(DefaultPullRequestMentionService.class);
bind(CodeCommentMentionService.class).to(DefaultCodeCommentMentionService.class);
bind(MembershipService.class).to(DefaultMembershipService.class);
bind(PullRequestChangeService.class).to(DefaultPullRequestChangeService.class);
bind(CodeCommentReplyService.class).to(DefaultCodeCommentReplyService.class);
bind(CodeCommentStatusChangeService.class).to(DefaultCodeCommentStatusChangeService.class);
bind(AttachmentService.class).to(DefaultAttachmentService.class);
bind(PullRequestInfoService.class).to(DefaultPullRequestInfoService.class);
bind(PullRequestNotificationManager.class);
bind(CommitNotificationManager.class);
bind(BuildNotificationManager.class);
bind(PackNotificationManager.class);
bind(IssueNotificationManager.class);
bind(CodeCommentNotificationManager.class);
bind(CodeCommentManager.class).to(DefaultCodeCommentManager.class);
bind(AccessTokenManager.class).to(DefaultAccessTokenManager.class);
bind(UserManager.class).to(DefaultUserManager.class);
bind(IssueWatchManager.class).to(DefaultIssueWatchManager.class);
bind(IssueChangeManager.class).to(DefaultIssueChangeManager.class);
bind(IssueVoteManager.class).to(DefaultIssueVoteManager.class);
bind(IssueWorkManager.class).to(DefaultIssueWorkManager.class);
bind(IterationManager.class).to(DefaultIterationManager.class);
bind(IssueCommentManager.class).to(DefaultIssueCommentManager.class);
bind(IssueQueryPersonalizationManager.class).to(DefaultIssueQueryPersonalizationManager.class);
bind(PullRequestQueryPersonalizationManager.class).to(DefaultPullRequestQueryPersonalizationManager.class);
bind(CodeCommentQueryPersonalizationManager.class).to(DefaultCodeCommentQueryPersonalizationManager.class);
bind(CommitQueryPersonalizationManager.class).to(DefaultCommitQueryPersonalizationManager.class);
bind(BuildQueryPersonalizationManager.class).to(DefaultBuildQueryPersonalizationManager.class);
bind(PackQueryPersonalizationManager.class).to(DefaultPackQueryPersonalizationManager.class);
bind(PullRequestAssignmentManager.class).to(DefaultPullRequestAssignmentManager.class);
bind(SshKeyManager.class).to(DefaultSshKeyManager.class);
bind(BuildMetricManager.class).to(DefaultBuildMetricManager.class);
bind(ReferenceChangeManager.class).to(DefaultReferenceChangeManager.class);
bind(GitLfsLockManager.class).to(DefaultGitLfsLockManager.class);
bind(IssueScheduleManager.class).to(DefaultIssueScheduleManager.class);
bind(LinkSpecManager.class).to(DefaultLinkSpecManager.class);
bind(IssueLinkManager.class).to(DefaultIssueLinkManager.class);
bind(IssueStateHistoryManager.class).to(DefaultIssueStateHistoryManager.class);
bind(LinkAuthorizationManager.class).to(DefaultLinkAuthorizationManager.class);
bind(EmailAddressManager.class).to(DefaultEmailAddressManager.class);
bind(GpgKeyManager.class).to(DefaultGpgKeyManager.class);
bind(IssueTextManager.class).to(DefaultIssueTextManager.class);
bind(PullRequestTextManager.class).to(DefaultPullRequestTextManager.class);
bind(CodeCommentTextManager.class).to(DefaultCodeCommentTextManager.class);
bind(PendingSuggestionApplyManager.class).to(DefaultPendingSuggestionApplyManager.class);
bind(IssueAuthorizationManager.class).to(DefaultIssueAuthorizationManager.class);
bind(DashboardManager.class).to(DefaultDashboardManager.class);
bind(DashboardUserShareManager.class).to(DefaultDashboardUserShareManager.class);
bind(DashboardGroupShareManager.class).to(DefaultDashboardGroupShareManager.class);
bind(DashboardVisitManager.class).to(DefaultDashboardVisitManager.class);
bind(LabelSpecManager.class).to(DefaultLabelSpecManager.class);
bind(ProjectLabelManager.class).to(DefaultProjectLabelManager.class);
bind(BuildLabelManager.class).to(DefaultBuildLabelManager.class);
bind(PackLabelManager.class).to(DefaultPackLabelManager.class);
bind(PullRequestLabelManager.class).to(DefaultPullRequestLabelManager.class);
bind(IssueTouchManager.class).to(DefaultIssueTouchManager.class);
bind(PullRequestTouchManager.class).to(DefaultPullRequestTouchManager.class);
bind(CodeCommentTouchManager.class).to(DefaultCodeCommentTouchManager.class);
bind(AlertManager.class).to(DefaultAlertManager.class);
bind(UpdateCheckManager.class).to(DefaultUpdateCheckManager.class);
bind(StopwatchManager.class).to(DefaultStopwatchManager.class);
bind(PackManager.class).to(DefaultPackManager.class);
bind(PackBlobManager.class).to(DefaultPackBlobManager.class);
bind(PackBlobReferenceManager.class).to(DefaultPackBlobReferenceManager.class);
bind(AccessTokenAuthorizationManager.class).to(DefaultAccessTokenAuthorizationManager.class);
bind(ReviewedDiffManager.class).to(DefaultReviewedDiffManager.class);
bind(OAuthTokenManager.class).to(DefaultOAuthTokenManager.class);
bind(IssueReactionManager.class).to(DefaultIssueReactionManager.class);
bind(IssueCommentReactionManager.class).to(DefaultIssueCommentReactionManager.class);
bind(PullRequestReactionManager.class).to(DefaultPullRequestReactionManager.class);
bind(PullRequestCommentReactionManager.class).to(DefaultPullRequestCommentReactionManager.class);
bind(IssueCommentRevisionManager.class).to(DefaultIssueCommentRevisionManager.class);
bind(PullRequestCommentRevisionManager.class).to(DefaultPullRequestCommentRevisionManager.class);
bind(IssueDescriptionRevisionManager.class).to(DefaultIssueDescriptionRevisionManager.class);
bind(PullRequestDescriptionRevisionManager.class).to(DefaultPullRequestDescriptionRevisionManager.class);
bind(SsoProviderManager.class).to(DefaultSsoProviderManager.class);
bind(SsoAccountManager.class).to(DefaultSsoAccountManager.class);
bind(BaseAuthorizationManager.class).to(DefaultBaseAuthorizationManager.class);
bind(CodeCommentService.class).to(DefaultCodeCommentService.class);
bind(AccessTokenService.class).to(DefaultAccessTokenService.class);
bind(UserService.class).to(DefaultUserService.class);
bind(IssueWatchService.class).to(DefaultIssueWatchService.class);
bind(IssueChangeService.class).to(DefaultIssueChangeService.class);
bind(IssueVoteService.class).to(DefaultIssueVoteService.class);
bind(IssueWorkService.class).to(DefaultIssueWorkService.class);
bind(IterationService.class).to(DefaultIterationService.class);
bind(IssueCommentService.class).to(DefaultIssueCommentService.class);
bind(IssueQueryPersonalizationService.class).to(DefaultIssueQueryPersonalizationService.class);
bind(PullRequestQueryPersonalizationService.class).to(DefaultPullRequestQueryPersonalizationService.class);
bind(CodeCommentQueryPersonalizationService.class).to(DefaultCodeCommentQueryPersonalizationService.class);
bind(CommitQueryPersonalizationService.class).to(DefaultCommitQueryPersonalizationService.class);
bind(BuildQueryPersonalizationService.class).to(DefaultBuildQueryPersonalizationService.class);
bind(PackQueryPersonalizationService.class).to(DefaultPackQueryPersonalizationService.class);
bind(PullRequestAssignmentService.class).to(DefaultPullRequestAssignmentService.class);
bind(SshKeyService.class).to(DefaultSshKeyService.class);
bind(BuildMetricService.class).to(DefaultBuildMetricService.class);
bind(ReferenceChangeService.class).to(DefaultReferenceChangeService.class);
bind(GitLfsLockService.class).to(DefaultGitLfsLockService.class);
bind(IssueScheduleService.class).to(DefaultIssueScheduleService.class);
bind(LinkSpecService.class).to(DefaultLinkSpecService.class);
bind(IssueLinkService.class).to(DefaultIssueLinkService.class);
bind(IssueStateHistoryService.class).to(DefaultIssueStateHistoryService.class);
bind(LinkAuthorizationService.class).to(DefaultLinkAuthorizationService.class);
bind(EmailAddressService.class).to(DefaultEmailAddressService.class);
bind(GpgKeyService.class).to(DefaultGpgKeyService.class);
bind(IssueTextService.class).to(DefaultIssueTextService.class);
bind(PullRequestTextService.class).to(DefaultPullRequestTextService.class);
bind(CodeCommentTextService.class).to(DefaultCodeCommentTextService.class);
bind(PendingSuggestionApplyService.class).to(DefaultPendingSuggestionApplyService.class);
bind(IssueAuthorizationService.class).to(DefaultIssueAuthorizationService.class);
bind(DashboardService.class).to(DefaultDashboardService.class);
bind(DashboardUserShareService.class).to(DefaultDashboardUserShareService.class);
bind(DashboardGroupShareService.class).to(DefaultDashboardGroupShareService.class);
bind(DashboardVisitService.class).to(DefaultDashboardVisitService.class);
bind(LabelSpecService.class).to(DefaultLabelSpecService.class);
bind(ProjectLabelService.class).to(DefaultProjectLabelService.class);
bind(BuildLabelService.class).to(DefaultBuildLabelService.class);
bind(PackLabelService.class).to(DefaultPackLabelService.class);
bind(PullRequestLabelService.class).to(DefaultPullRequestLabelService.class);
bind(IssueTouchService.class).to(DefaultIssueTouchService.class);
bind(PullRequestTouchService.class).to(DefaultPullRequestTouchService.class);
bind(CodeCommentTouchService.class).to(DefaultCodeCommentTouchService.class);
bind(AlertService.class).to(DefaultAlertService.class);
bind(UpdateCheckService.class).to(DefaultUpdateCheckService.class);
bind(StopwatchService.class).to(DefaultStopwatchService.class);
bind(PackService.class).to(DefaultPackService.class);
bind(PackBlobService.class).to(DefaultPackBlobService.class);
bind(PackBlobReferenceService.class).to(DefaultPackBlobReferenceService.class);
bind(AccessTokenAuthorizationService.class).to(DefaultAccessTokenAuthorizationService.class);
bind(ReviewedDiffService.class).to(DefaultReviewedDiffService.class);
bind(OAuthTokenService.class).to(DefaultOAuthTokenService.class);
bind(IssueReactionService.class).to(DefaultIssueReactionService.class);
bind(IssueCommentReactionService.class).to(DefaultIssueCommentReactionService.class);
bind(PullRequestReactionService.class).to(DefaultPullRequestReactionService.class);
bind(PullRequestCommentReactionService.class).to(DefaultPullRequestCommentReactionService.class);
bind(IssueCommentRevisionService.class).to(DefaultIssueCommentRevisionService.class);
bind(PullRequestCommentRevisionService.class).to(DefaultPullRequestCommentRevisionService.class);
bind(IssueDescriptionRevisionService.class).to(DefaultIssueDescriptionRevisionService.class);
bind(PullRequestDescriptionRevisionService.class).to(DefaultPullRequestDescriptionRevisionService.class);
bind(SsoProviderService.class).to(DefaultSsoProviderService.class);
bind(SsoAccountService.class).to(DefaultSsoAccountService.class);
bind(BaseAuthorizationService.class).to(DefaultBaseAuthorizationService.class);
bind(GroupEntitlementService.class).to(DefaultGroupEntitlementService.class);
bind(UserEntitlementService.class).to(DefaultUserEntitlementService.class);
bind(ProjectEntitlementService.class).to(DefaultProjectEntitlementService.class);
bind(WebHookManager.class);
contribute(CodePullAuthorizationSource.class, DefaultJobManager.class);
contribute(CodePullAuthorizationSource.class, DefaultJobService.class);
bind(CodeIndexManager.class).to(DefaultCodeIndexManager.class);
bind(CodeSearchManager.class).to(DefaultCodeSearchManager.class);
bind(CodeIndexService.class).to(DefaultCodeIndexService.class);
bind(CodeSearchService.class).to(DefaultCodeSearchService.class);
Bootstrap.executorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS,
new SynchronousQueue<>()) {
@ -628,8 +638,7 @@ public class CoreModule extends AbstractPluginModule {
bind(OsInfo.class).toProvider(() -> ExecutorUtils.getOsInfo()).in(Singleton.class);
contributeFromPackage(LogInstruction.class, LogInstruction.class);
contributeFromPackage(LogInstruction.class, LogInstruction.class);
contribute(CodeProblemContribution.class, (build, blobPath, reportName) -> newArrayList());
@ -672,7 +681,7 @@ public class CoreModule extends AbstractPluginModule {
bind(GitLfsFilter.class);
bind(GitPreReceiveCallback.class);
bind(GitPostReceiveCallback.class);
bind(SignatureVerificationManager.class).to(DefaultSignatureVerificationManager.class);
bind(SignatureVerificationService.class).to(DefaultSignatureVerificationService.class);
contribute(CommandCreator.class, SshCommandCreator.class);
contributeFromPackage(SignatureVerifier.class, SignatureVerifier.class);
}
@ -692,15 +701,15 @@ public class CoreModule extends AbstractPluginModule {
bind(WicketServlet.class).to(DefaultWicketServlet.class);
bind(WicketFilter.class).to(DefaultWicketFilter.class);
bind(EditSupportRegistry.class).to(DefaultEditSupportRegistry.class);
bind(WebSocketManager.class).to(DefaultWebSocketManager.class);
bind(WebSocketService.class).to(DefaultWebSocketService.class);
bind(SessionDataStoreFactory.class).to(DefaultSessionDataStoreFactory.class);
contributeFromPackage(EditSupport.class, EditSupport.class);
bind(org.apache.wicket.protocol.http.WebApplication.class).to(WebApplication.class);
bind(Application.class).to(WebApplication.class);
bind(AvatarManager.class).to(DefaultAvatarManager.class);
bind(WebSocketManager.class).to(DefaultWebSocketManager.class);
bind(AvatarService.class).to(DefaultAvatarService.class);
bind(WebSocketService.class).to(DefaultWebSocketService.class);
contributeFromPackage(EditSupport.class, EditSupportLocator.class);
@ -720,24 +729,26 @@ public class CoreModule extends AbstractPluginModule {
contributeFromPackage(ExceptionHandler.class, ConstraintViolationExceptionHandler.class);
contributeFromPackage(ExceptionHandler.class, PageExpiredExceptionHandler.class);
contributeFromPackage(ExceptionHandler.class, WebApplicationExceptionHandler.class);
contribute(SessionListener.class, DefaultWebSocketService.class);
bind(UrlManager.class).to(DefaultUrlManager.class);
bind(UrlService.class).to(DefaultUrlService.class);
bind(CodeCommentEventBroadcaster.class);
bind(PullRequestEventBroadcaster.class);
bind(IssueEventBroadcaster.class);
bind(BuildEventBroadcaster.class);
bind(AlertEventBroadcaster.class);
bind(UploadManager.class).to(DefaultUploadManager.class);
bind(UploadService.class).to(DefaultUploadService.class);
bind(TaskButton.TaskFutureManager.class);
}
private void configureBuild() {
bind(ResourceAllocator.class).to(DefaultResourceAllocator.class);
bind(AgentManager.class).to(DefaultAgentManager.class);
bind(AgentTokenManager.class).to(DefaultAgentTokenManager.class);
bind(AgentAttributeManager.class).to(DefaultAgentAttributeManager.class);
bind(AgentLastUsedDateManager.class).to(DefaultAgentLastUsedDateManager.class);
bind(AgentService.class).to(DefaultAgentService.class);
bind(AgentTokenService.class).to(DefaultAgentTokenService.class);
bind(AgentAttributeService.class).to(DefaultAgentAttributeService.class);
bind(AgentLastUsedDateService.class).to(DefaultAgentLastUsedDateService.class);
contribute(ScriptContribution.class, new ScriptContribution() {
@ -775,22 +786,22 @@ public class CoreModule extends AbstractPluginModule {
}
private void configurePersistence() {
bind(DataManager.class).to(DefaultDataManager.class);
bind(DataService.class).to(DefaultDataService.class);
bind(Session.class).toProvider(SessionProvider.class);
bind(EntityManager.class).toProvider(SessionProvider.class);
bind(SessionFactory.class).toProvider(SessionFactoryProvider.class);
bind(EntityManagerFactory.class).toProvider(SessionFactoryProvider.class);
bind(SessionFactoryManager.class).to(DefaultSessionFactoryManager.class);
bind(SessionFactoryService.class).to(DefaultSessionFactoryService.class);
contribute(ObjectMapperConfigurator.class, HibernateObjectMapperConfigurator.class);
bind(Interceptor.class).to(HibernateInterceptor.class);
bind(PhysicalNamingStrategy.class).toInstance(new PrefixedNamingStrategy("o_"));
bind(SessionManager.class).to(DefaultSessionManager.class);
bind(TransactionManager.class).to(DefaultTransactionManager.class);
bind(IdManager.class).to(DefaultIdManager.class);
bind(SessionService.class).to(DefaultSessionService.class);
bind(TransactionService.class).to(DefaultTransactionService.class);
bind(IdService.class).to(DefaultIdService.class);
bind(Dao.class).to(DefaultDao.class);
TransactionInterceptor transactionInterceptor = new TransactionInterceptor();

View File

@ -22,7 +22,7 @@ import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
import javax.inject.Inject;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
@ -44,20 +44,20 @@ import io.onedev.commons.loader.AppLoader;
import io.onedev.commons.loader.ManagedSerializedForm;
import io.onedev.commons.utils.FileUtils;
import io.onedev.commons.utils.TarUtils;
import io.onedev.server.cluster.ClusterManager;
import io.onedev.server.data.DataManager;
import io.onedev.server.entitymanager.SettingManager;
import io.onedev.server.cluster.ClusterService;
import io.onedev.server.data.DataService;
import io.onedev.server.service.SettingService;
import io.onedev.server.event.ListenerRegistry;
import io.onedev.server.event.system.SystemStarted;
import io.onedev.server.event.system.SystemStarting;
import io.onedev.server.event.system.SystemStopped;
import io.onedev.server.event.system.SystemStopping;
import io.onedev.server.exception.ServerNotReadyException;
import io.onedev.server.jetty.JettyManager;
import io.onedev.server.jetty.JettyService;
import io.onedev.server.model.support.administration.SystemSetting;
import io.onedev.server.persistence.IdManager;
import io.onedev.server.persistence.SessionFactoryManager;
import io.onedev.server.persistence.SessionManager;
import io.onedev.server.persistence.IdService;
import io.onedev.server.persistence.SessionFactoryService;
import io.onedev.server.persistence.SessionService;
import io.onedev.server.persistence.annotation.Sessional;
import io.onedev.server.security.SecurityUtils;
import io.onedev.server.taskschedule.TaskScheduler;
@ -66,59 +66,60 @@ import io.onedev.server.util.init.InitStage;
import io.onedev.server.util.init.ManualConfig;
public class OneDev extends AbstractPlugin implements Serializable, Runnable {
private static final Logger logger = LoggerFactory.getLogger(OneDev.class);
private final Provider<JettyManager> jettyLauncherProvider;
private final SessionManager sessionManager;
private final DataManager dataManager;
private final Provider<JettyService> jettyLauncherProvider;
private final SessionService sessionService;
private final DataService dataService;
private final Provider<ServerConfig> serverConfigProvider;
private final ListenerRegistry listenerRegistry;
private final TaskScheduler taskScheduler;
private final ExecutorService executorService;
private final ClusterManager clusterManager;
private final SettingManager settingManager;
private final IdManager idManager;
private final SessionFactoryManager sessionFactoryManager;
private final ClusterService clusterService;
private final SettingService settingService;
private final IdService idService;
private final SessionFactoryService sessionFactoryService;
private final Date bootDate = new Date();
private volatile InitStage initStage;
private Class<?> wrapperManagerClass;
private Class<?> wrapperManagerClass;
private volatile Thread thread;
// Some are injected via provider as instantiation might encounter problem during upgrade
// Some are injected via provider as instantiation might encounter problem
// during upgrade
@Inject
public OneDev(Provider<JettyManager> jettyLauncherProvider, TaskScheduler taskScheduler,
SessionManager sessionManager, Provider<ServerConfig> serverConfigProvider,
DataManager dataManager, ExecutorService executorService,
ListenerRegistry listenerRegistry, ClusterManager clusterManager,
IdManager idManager, SessionFactoryManager sessionFactoryManager,
SettingManager settingManager) {
public OneDev(Provider<JettyService> jettyLauncherProvider, TaskScheduler taskScheduler,
SessionService sessionService, Provider<ServerConfig> serverConfigProvider,
DataService dataService, ExecutorService executorService,
ListenerRegistry listenerRegistry, ClusterService clusterService,
IdService idService, SessionFactoryService sessionFactoryService,
SettingService settingService) {
this.jettyLauncherProvider = jettyLauncherProvider;
this.taskScheduler = taskScheduler;
this.sessionManager = sessionManager;
this.dataManager = dataManager;
this.sessionService = sessionService;
this.dataService = dataService;
this.serverConfigProvider = serverConfigProvider;
this.executorService = executorService;
this.listenerRegistry = listenerRegistry;
this.clusterManager = clusterManager;
this.idManager = idManager;
this.sessionFactoryManager = sessionFactoryManager;
this.settingManager = settingManager;
this.clusterService = clusterService;
this.idService = idService;
this.sessionFactoryService = sessionFactoryService;
this.settingService = settingService;
try {
wrapperManagerClass = Class.forName("org.tanukisoftware.wrapper.WrapperManager");
} catch (ClassNotFoundException e) {
@ -127,7 +128,7 @@ public class OneDev extends AbstractPlugin implements Serializable, Runnable {
initStage = new InitStage("Server is Starting...");
}
@Override
public void start() {
var maintenanceFile = getMaintenanceFile(Bootstrap.installDir);
@ -139,33 +140,34 @@ public class OneDev extends AbstractPlugin implements Serializable, Runnable {
throw new RuntimeException(e);
}
}
SecurityUtils.bindAsSystem();
System.setProperty("hsqldb.reconfig_logging", "false");
System.setProperty("hsqldb.method_class_names", "java.lang.Math");
clusterManager.start();
sessionFactoryManager.start();
var databasePopulated = clusterManager.getHazelcastInstance().getCPSubsystem().getAtomicLong("databasePopulated");
// Do not use database lock as schema update will commit transaction immediately
// in MySQL
clusterManager.initWithLead(databasePopulated, () -> {
try (var conn = dataManager.openConnection()) {
clusterService.start();
sessionFactoryService.start();
var databasePopulated = clusterService.getHazelcastInstance().getCPSubsystem()
.getAtomicLong("databasePopulated");
// Do not use database lock as schema update will commit transaction immediately
// in MySQL
clusterService.initWithLead(databasePopulated, () -> {
try (var conn = dataService.openConnection()) {
callWithTransaction(conn, () -> {
dataManager.populateDatabase(conn);
dataService.populateDatabase(conn);
return null;
});
} catch (SQLException e) {
throw new RuntimeException(e);
};
}
return 1L;
});
idManager.init();
sessionManager.run(() -> listenerRegistry.post(new SystemStarting()));
idService.init();
sessionService.run(() -> listenerRegistry.post(new SystemStarting()));
jettyLauncherProvider.get().start();
var manualConfigs = checkData();
@ -175,16 +177,16 @@ public class OneDev extends AbstractPlugin implements Serializable, Runnable {
else
logger.warn("Please set up the server at " + guessServerUrl());
initStage = new InitStage("Server Setup", manualConfigs);
var localServer = clusterManager.getLocalServerAddress();
var localServer = clusterService.getLocalServerAddress();
while (true) {
if (maintenanceFile.exists()) {
logger.info("Maintenance requested, trying to stop all servers...");
clusterManager.submitToAllServers(() -> {
if (!localServer.equals(clusterManager.getLocalServerAddress()))
clusterService.submitToAllServers(() -> {
if (!localServer.equals(clusterService.getLocalServerAddress()))
restart();
return null;
});
while (thread != null && clusterManager.getServerAddresses().size() != 1) {
while (thread != null && clusterService.getServerAddresses().size() != 1) {
try {
Thread.sleep(1000);
} catch (InterruptedException ignored) {
@ -200,7 +202,7 @@ public class OneDev extends AbstractPlugin implements Serializable, Runnable {
}
if (thread == null)
return;
manualConfigs = checkData();
if (manualConfigs.isEmpty()) {
initStage = new InitStage("Please wait...");
@ -210,21 +212,21 @@ public class OneDev extends AbstractPlugin implements Serializable, Runnable {
}
}
}
var leadServer = clusterManager.getLeaderServerAddress();
if (!leadServer.equals(clusterManager.getLocalServerAddress())) {
var leadServer = clusterService.getLeaderServerAddress();
if (!leadServer.equals(clusterService.getLocalServerAddress())) {
logger.info("Syncing assets...");
Client client = ClientBuilder.newClient();
try {
String fromServerUrl = clusterManager.getServerUrl(leadServer);
String fromServerUrl = clusterService.getServerUrl(leadServer);
WebTarget target = client.target(fromServerUrl).path("/~api/cluster/assets");
Invocation.Builder builder = target.request();
builder.header(AUTHORIZATION,
BEARER + " " + clusterManager.getCredential());
BEARER + " " + clusterService.getCredential());
try (Response response = builder.get()) {
checkStatus(response);
try (InputStream is = response.readEntity(InputStream.class)) {
try (InputStream is = response.readEntity(InputStream.class)) {
TarUtils.untar(is, getAssetsDir(), false);
} catch (IOException e) {
throw new RuntimeException(e);
@ -234,44 +236,44 @@ public class OneDev extends AbstractPlugin implements Serializable, Runnable {
client.close();
}
}
// workaround for issue https://bugs.eclipse.org/bugs/show_bug.cgi?id=566170
FileStoreAttributes.setBackground(true);
taskScheduler.start();
}
@Sessional
@Override
public void postStart() {
if (thread == null)
if (thread == null)
return;
SecurityUtils.bindAsSystem();
initStage = null;
listenerRegistry.post(new SystemStarted());
clusterManager.postStart();
clusterService.postStart();
thread.start();
SystemSetting systemSetting = settingManager.getSystemSetting();
SystemSetting systemSetting = settingService.getSystemSetting();
logger.info("Server is ready at " + systemSetting.getServerUrl() + ".");
}
@Override
public void preStop() {
thread = null;
clusterManager.preStop();
clusterService.preStop();
SecurityUtils.bindAsSystem();
try {
sessionManager.run(() -> listenerRegistry.post(new SystemStopping()));
sessionService.run(() -> listenerRegistry.post(new SystemStopping()));
} catch (ServerNotReadyException ignore) {
}
}
private List<ManualConfig> checkData() {
HazelcastInstance hazelcastInstance = clusterManager.getHazelcastInstance();
HazelcastInstance hazelcastInstance = clusterService.getHazelcastInstance();
var lock = hazelcastInstance.getCPSubsystem().getLock("checkData");
lock.lock();
try {
return dataManager.checkData();
return dataService.checkData();
} finally {
lock.unlock();
}
@ -285,10 +287,10 @@ public class OneDev extends AbstractPlugin implements Serializable, Runnable {
taskScheduler.stop();
jettyLauncherProvider.get().stop();
sessionManager.run(() -> listenerRegistry.post(new SystemStopped()));
sessionService.run(() -> listenerRegistry.post(new SystemStopped()));
sessionFactoryManager.stop();
clusterManager.stop();
sessionFactoryService.stop();
clusterService.stop();
executorService.shutdown();
} catch (ServerNotReadyException ignore) {
}
@ -307,11 +309,11 @@ public class OneDev extends AbstractPlugin implements Serializable, Runnable {
return null;
}
}
public static String getK8sService() {
return System.getenv("k8s_service");
}
public String guessServerUrl() {
String serviceHost = System.getenv("ONEDEV_SERVICE_HOST");
if (serviceHost != null) {
@ -332,36 +334,38 @@ public class OneDev extends AbstractPlugin implements Serializable, Runnable {
return UrlUtils.toString(serverUrl);
}
}
private Url buildServerUrl(String host, String protocol, int port) {
Url serverUrl = new Url(StandardCharsets.UTF_8);
serverUrl.setHost(host);
serverUrl.setProtocol(protocol);
serverUrl.setPort(port);
private Url buildServerUrl(String host, String protocol, int port) {
Url serverUrl = new Url(StandardCharsets.UTF_8);
serverUrl.setHost(host);
serverUrl.setProtocol(protocol);
serverUrl.setPort(port);
return serverUrl;
}
/**
* This method can be called from different UI threads, so we clone initStage to
* This method can be called from different UI threads, so we clone initStage to
* make it thread-safe.
* <p>
*
* @return
* cloned initStage, or <tt>null</tt> if system initialization is completed
* cloned initStage, or <tt>null</tt> if system initialization is
* completed
*/
public @Nullable InitStage getInitStage() {
return initStage;
}
public boolean isReady() {
return initStage == null;
}
public static OneDev getInstance() {
return AppLoader.getInstance(OneDev.class);
}
public static <T> T getInstance(Class<T> type) {
return AppLoader.getInstance(type);
}
@ -380,8 +384,8 @@ public class OneDev extends AbstractPlugin implements Serializable, Runnable {
public Object writeReplace() throws ObjectStreamException {
return new ManagedSerializedForm(OneDev.class);
}
}
public static boolean isServerRunning(File installDir) {
var serverConfig = new ServerConfig(installDir);
try (ServerSocket ignored = new ServerSocket(serverConfig.getClusterPort())) {
@ -391,7 +395,7 @@ public class OneDev extends AbstractPlugin implements Serializable, Runnable {
return true;
else
throw new RuntimeException(e);
}
}
}
public static File getIndexDir() {
@ -399,15 +403,15 @@ public class OneDev extends AbstractPlugin implements Serializable, Runnable {
FileUtils.createDir(indexDir);
return indexDir;
}
public static File getAssetsDir() {
return new File(Bootstrap.getSiteDir(), "assets");
}
public static File getMaintenanceFile(File installDir) {
return new File(installDir, "maintenance");
}
private void restart() {
if (wrapperManagerClass != null) {
try {
@ -423,17 +427,17 @@ public class OneDev extends AbstractPlugin implements Serializable, Runnable {
@Override
public void run() {
var localServer = clusterManager.getLocalServerAddress();
var localServer = clusterService.getLocalServerAddress();
var maintenanceFile = getMaintenanceFile(Bootstrap.installDir);
while (thread != null) {
if (maintenanceFile.exists()) {
logger.info("Maintenance requested, trying to stop all servers...");
clusterManager.submitToAllServers(() -> {
if (!localServer.equals(clusterManager.getLocalServerAddress()))
clusterService.submitToAllServers(() -> {
if (!localServer.equals(clusterService.getLocalServerAddress()))
restart();
return null;
});
while (thread != null && clusterManager.getServerAddresses().size() != 1) {
while (thread != null && clusterService.getServerAddresses().size() != 1) {
try {
Thread.sleep(1000);
} catch (InterruptedException ignored) {
@ -441,7 +445,7 @@ public class OneDev extends AbstractPlugin implements Serializable, Runnable {
}
restart();
break;
}
}
try {
Thread.sleep(1000);
} catch (InterruptedException ignored) {

View File

@ -1,13 +1,16 @@
package io.onedev.server;
import io.onedev.server.annotation.NoDBAccess;
import java.io.File;
public interface StorageManager {
public interface StorageService {
File initLfsDir(Long projectId);
File initArtifactsDir(Long projectId, Long buildNumber);
@NoDBAccess
File initPacksDir(Long projectId);
}

View File

@ -1,11 +1,13 @@
package io.onedev.server;
import io.onedev.server.annotation.NoDBAccess;
import org.apache.wicket.Component;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
public interface SubscriptionManager {
public interface SubscriptionService {
@NoDBAccess
boolean isSubscriptionActive();
@Nullable

View File

@ -8,7 +8,7 @@ import java.util.concurrent.ExecutorService;
import io.onedev.agent.*;
import io.onedev.commons.utils.ExceptionUtils;
import io.onedev.server.OneDev;
import io.onedev.server.entitymanager.AgentManager;
import io.onedev.server.service.AgentService;
import org.apache.commons.lang3.SerializationUtils;
import org.eclipse.jetty.websocket.api.Session;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose;
@ -24,9 +24,9 @@ import io.onedev.commons.utils.StringUtils;
import io.onedev.commons.utils.TaskLogger;
import io.onedev.server.exception.ServerNotReadyException;
import io.onedev.server.job.JobContext;
import io.onedev.server.job.JobManager;
import io.onedev.server.job.JobService;
import io.onedev.server.job.ResourceAllocator;
import io.onedev.server.job.log.LogManager;
import io.onedev.server.job.log.LogService;
import io.onedev.server.terminal.AgentShell;
@WebSocket
@ -42,7 +42,7 @@ public class ServerSocket {
public void onClose(int statusCode, String reason) {
try {
if (agentId != null)
getAgentManager().agentDisconnected(agentId);
getAgentService().agentDisconnected(agentId);
StringBuilder builder = new StringBuilder("Websocket closed (");
if (session != null && session.getRemoteAddress() != null)
@ -69,15 +69,15 @@ public class ServerSocket {
}
}
private AgentManager getAgentManager() {
return OneDev.getInstance(AgentManager.class);
private AgentService getAgentService() {
return OneDev.getInstance(AgentService.class);
}
@OnWebSocketConnect
public void onConnect(Session session) {
this.session = session;
try {
new Message(MessageTypes.UPDATE, getAgentManager().getAgentVersion()).sendBy(session);
new Message(MessageTypes.UPDATE, getAgentService().getAgentVersion()).sendBy(session);
} catch (Exception e) {
logger.error("Error sending websocket message", e);
try {
@ -98,7 +98,7 @@ public class ServerSocket {
// be assigned via Administrator
AgentData data = SerializationUtils.deserialize(message.getData());
try {
agentId = getAgentManager().agentConnected(data, session);
agentId = getAgentService().agentConnected(data, session);
} catch (Exception e) {
var explicitException = ExceptionUtils.find(e, ExplicitException.class);
if (explicitException != null) {
@ -132,7 +132,7 @@ public class ServerSocket {
if (sessionId.length() == 0)
sessionId = null;
String logMessage = StringUtils.substringAfter(remaining, ":");
TaskLogger logger = OneDev.getInstance(LogManager.class).getJobLogger(jobToken);
TaskLogger logger = OneDev.getInstance(LogService.class).getJobLogger(jobToken);
if (logger != null)
logger.log(logMessage, sessionId);
} catch (Exception e) {
@ -143,15 +143,15 @@ public class ServerSocket {
String dataString = new String(messageData, StandardCharsets.UTF_8);
String jobToken = StringUtils.substringBefore(dataString, ":");
String jobWorkspace = StringUtils.substringAfter(dataString, ":");
JobContext jobContext = getJobManager().getJobContext(jobToken, false);
JobContext jobContext = getJobService().getJobContext(jobToken, false);
if (jobContext != null)
getJobManager().reportJobWorkspace(jobContext, jobWorkspace);
getJobService().reportJobWorkspace(jobContext, jobWorkspace);
break;
case SHELL_OUTPUT:
dataString = new String(messageData, StandardCharsets.UTF_8);
String sessionId = StringUtils.substringBefore(dataString, ":");
String output = StringUtils.substringAfter(dataString, ":");
AgentShell shell = (AgentShell) getJobManager().getShell(sessionId);
AgentShell shell = (AgentShell) getJobService().getShell(sessionId);
if (shell != null)
shell.getTerminal().sendOutput(output);
break;
@ -159,13 +159,13 @@ public class ServerSocket {
dataString = new String(messageData, StandardCharsets.UTF_8);
sessionId = StringUtils.substringBefore(dataString, ":");
String error = StringUtils.substringAfter(dataString, ":");
shell = (AgentShell) getJobManager().getShell(sessionId);
shell = (AgentShell) getJobService().getShell(sessionId);
if (shell != null)
shell.getTerminal().sendError(error);
break;
case SHELL_CLOSED:
sessionId = new String(messageData, StandardCharsets.UTF_8);
shell = (AgentShell) getJobManager().getShell(sessionId);
shell = (AgentShell) getJobService().getShell(sessionId);
if (shell != null)
shell.getTerminal().close();
break;
@ -180,8 +180,8 @@ public class ServerSocket {
}
}
private JobManager getJobManager() {
return OneDev.getInstance(JobManager.class);
private JobService getJobService() {
return OneDev.getInstance(JobService.class);
}
private Serializable service(Serializable request) {

View File

@ -3,7 +3,7 @@ package io.onedev.server.agent;
import io.onedev.agent.Agent;
import io.onedev.server.OneDev;
import io.onedev.server.exception.ServerNotReadyException;
import io.onedev.server.entitymanager.AgentTokenManager;
import io.onedev.server.service.AgentTokenService;
import io.onedev.server.security.SecurityUtils;
import org.eclipse.jetty.websocket.servlet.WebSocketServlet;
import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory;
@ -22,11 +22,11 @@ public class ServerSocketServlet extends WebSocketServlet {
private static final long serialVersionUID = 1L;
private final AgentTokenManager tokenManager;
private final AgentTokenService tokenService;
@Inject
public ServerSocketServlet(AgentTokenManager tokenManager) {
this.tokenManager = tokenManager;
public ServerSocketServlet(AgentTokenService tokenService) {
this.tokenService = tokenService;
}
@Override
@ -43,7 +43,7 @@ public class ServerSocketServlet extends WebSocketServlet {
if (!OneDev.getInstance().isReady())
throw new ServerNotReadyException();
String tokenValue = SecurityUtils.getBearerToken(request);
if (tokenValue != null && tokenManager.find(tokenValue) != null)
if (tokenValue != null && tokenService.find(tokenValue) != null)
super.service(request, response);
else
response.sendError(SC_FORBIDDEN, "A valid agent token is expected");

View File

@ -0,0 +1,90 @@
package io.onedev.server.ai;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.onedev.server.OneDev;
import io.onedev.server.model.Issue;
import io.onedev.server.model.IssueComment;
import io.onedev.server.model.Project;
import io.onedev.server.web.UrlService;
public class IssueHelper {
private static ObjectMapper getObjectMapper() {
return OneDev.getInstance(ObjectMapper.class);
}
private static UrlService getUrlService() {
return OneDev.getInstance(UrlService.class);
}
public static Map<String, Object> getSummary(Project currentProject, Issue issue) {
var typeReference = new TypeReference<LinkedHashMap<String, Object>>() {};
var summary = getObjectMapper().convertValue(issue, typeReference);
summary.remove("id");
summary.remove("stateOrdinal");
summary.remove("uuid");
summary.remove("messageId");
summary.remove("pinDate");
summary.remove("boardPosition");
summary.remove("numberScopeId");
summary.put("reference", issue.getReference().toString(currentProject));
summary.remove("submitterId");
summary.put("submitter", issue.getSubmitter().getName());
summary.put("Project", issue.getProject().getPath());
summary.remove("lastActivity");
for (var it = summary.entrySet().iterator(); it.hasNext();) {
var entry = it.next();
if (entry.getKey().endsWith("Count"))
it.remove();
}
return summary;
}
public static List<Map<String, Object>> getComments(Issue issue) {
var comments = new ArrayList<Map<String, Object>>();
issue.getComments().stream().sorted(Comparator.comparing(IssueComment::getId)).forEach(comment -> {
var commentMap = new HashMap<String, Object>();
commentMap.put("user", comment.getUser().getName());
commentMap.put("date", comment.getDate());
commentMap.put("content", comment.getContent());
comments.add(commentMap);
});
return comments;
}
public static Map<String, Object> getDetail(Project currentProject, Issue issue) {
var detail = getSummary(currentProject, issue);
for (var entry : issue.getFieldInputs().entrySet()) {
detail.put(entry.getKey(), entry.getValue().getValues());
}
Map<String, Collection<String>> linkedIssues = new HashMap<>();
for (var link: issue.getTargetLinks()) {
linkedIssues.computeIfAbsent(link.getSpec().getName(), k -> new ArrayList<>())
.add(link.getTarget().getReference().toString(currentProject));
}
for (var link : issue.getSourceLinks()) {
if (link.getSpec().getOpposite() != null) {
linkedIssues.computeIfAbsent(link.getSpec().getOpposite().getName(), k -> new ArrayList<>())
.add(link.getSource().getReference().toString(currentProject));
} else {
linkedIssues.computeIfAbsent(link.getSpec().getName(), k -> new ArrayList<>())
.add(link.getSource().getReference().toString(currentProject));
}
}
detail.putAll(linkedIssues);
detail.put("link", getUrlService().urlFor(issue, true));
return detail;
}
}

View File

@ -0,0 +1,102 @@
package io.onedev.server.ai;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.onedev.server.OneDev;
import io.onedev.server.model.Project;
import io.onedev.server.model.PullRequest;
import io.onedev.server.model.PullRequestComment;
import io.onedev.server.model.PullRequestReview;
import io.onedev.server.web.UrlService;
public class PullRequestHelper {
private static ObjectMapper getObjectMapper() {
return OneDev.getInstance(ObjectMapper.class);
}
private static UrlService getUrlService() {
return OneDev.getInstance(UrlService.class);
}
public static Map<String, Object> getSummary(Project currentProject,
PullRequest pullRequest, boolean checkMergeConditionIfOpen) {
var typeReference = new TypeReference<LinkedHashMap<String, Object>>() {};
var summary = getObjectMapper().convertValue(pullRequest, typeReference);
summary.remove("id");
if (pullRequest.isOpen() && checkMergeConditionIfOpen) {
var errorMessage = pullRequest.checkMergeCondition();
if (errorMessage != null)
summary.put("status", PullRequest.Status.OPEN.name() + " (" + errorMessage + ")");
else
summary.put("status", PullRequest.Status.OPEN.name() + " (ready to merge)");
}
summary.remove("uuid");
summary.remove("buildCommitHash");
summary.remove("submitTimeGroups");
summary.remove("closeTimeGroups");
summary.remove("checkError");
summary.remove("numberScopeId");
summary.put("reference", pullRequest.getReference().toString(currentProject));
summary.remove("submitterId");
summary.put("submitter", pullRequest.getSubmitter().getName());
summary.put("targetProject", pullRequest.getTarget().getProject().getPath());
if (pullRequest.getSourceProject() != null)
summary.put("sourceProject", pullRequest.getSourceProject().getPath());
summary.remove("codeCommentsUpdateDate");
summary.remove("lastActivity");
for (var it = summary.entrySet().iterator(); it.hasNext();) {
var entry = it.next();
if (entry.getKey().endsWith("Count"))
it.remove();
}
return summary;
}
public static Map<String, Object> getDetail(Project currentProject, PullRequest pullRequest) {
var detail = getSummary(currentProject, pullRequest, true);
detail.put("headCommitHash", pullRequest.getLatestUpdate().getHeadCommitHash());
detail.put("assignees", pullRequest.getAssignees().stream().map(it->it.getName()).collect(Collectors.toList()));
var reviews = new ArrayList<Map<String, Object>>();
for (var review : pullRequest.getReviews()) {
if (review.getStatus() == PullRequestReview.Status.EXCLUDED)
continue;
var reviewMap = new HashMap<String, Object>();
reviewMap.put("reviewer", review.getUser().getName());
reviewMap.put("status", review.getStatus());
reviews.add(reviewMap);
}
detail.put("reviews", reviews);
var builds = new ArrayList<String>();
for (var build : pullRequest.getBuilds()) {
builds.add(build.getReference().toString(currentProject) + " (job: " + build.getJobName() + ", status: " + build.getStatus() + ")");
}
detail.put("builds", builds);
detail.put("labels", pullRequest.getLabels().stream().map(it->it.getSpec().getName()).collect(Collectors.toList()));
detail.put("link", getUrlService().urlFor(pullRequest, true));
return detail;
}
public static List<Map<String, Object>> getComments(PullRequest pullRequest) {
var comments = new ArrayList<Map<String, Object>>();
pullRequest.getComments().stream().sorted(Comparator.comparing(PullRequestComment::getId)).forEach(comment -> {
var commentMap = new HashMap<String, Object>();
commentMap.put("user", comment.getUser().getName());
commentMap.put("date", comment.getDate());
commentMap.put("content", comment.getContent());
comments.add(commentMap);
});
return comments;
}
}

View File

@ -0,0 +1,639 @@
package io.onedev.server.ai;
import static java.util.stream.Collectors.joining;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.IntStream;
import io.onedev.server.OneDev;
import io.onedev.server.model.Agent;
import io.onedev.server.model.Build;
import io.onedev.server.model.Issue;
import io.onedev.server.model.LabelSpec;
import io.onedev.server.model.Pack;
import io.onedev.server.model.Project;
import io.onedev.server.model.PullRequest;
import io.onedev.server.model.support.issue.field.spec.BooleanField;
import io.onedev.server.model.support.issue.field.spec.BuildChoiceField;
import io.onedev.server.model.support.issue.field.spec.CommitField;
import io.onedev.server.model.support.issue.field.spec.DateField;
import io.onedev.server.model.support.issue.field.spec.DateTimeField;
import io.onedev.server.model.support.issue.field.spec.FloatField;
import io.onedev.server.model.support.issue.field.spec.GroupChoiceField;
import io.onedev.server.model.support.issue.field.spec.IntegerField;
import io.onedev.server.model.support.issue.field.spec.IssueChoiceField;
import io.onedev.server.model.support.issue.field.spec.IterationChoiceField;
import io.onedev.server.model.support.issue.field.spec.PullRequestChoiceField;
import io.onedev.server.model.support.issue.field.spec.TextField;
import io.onedev.server.model.support.issue.field.spec.choicefield.ChoiceField;
import io.onedev.server.model.support.issue.field.spec.userchoicefield.UserChoiceField;
import io.onedev.server.model.support.pullrequest.MergeStrategy;
import io.onedev.server.pack.PackSupport;
import io.onedev.server.service.AgentAttributeService;
import io.onedev.server.service.AgentService;
import io.onedev.server.service.LabelSpecService;
import io.onedev.server.service.LinkSpecService;
import io.onedev.server.service.SettingService;
public class QueryDescriptions {
private static String REACTION_CRITERIAS = """
| '"Reaction: Thumbs Up Count"' 'is' ('not')? '"'Number'"'
| '"Reaction: Thumbs Up Count"' 'is' ('greater'|'less') 'than' '"'Number'"'
| '"Reaction: Thumbs Down Count"' 'is' ('not')? '"'Number'"'
| '"Reaction: Thumbs Down Count"' 'is' ('greater'|'less') 'than' '"'Number'"'
| '"Reaction: Smile Count"' 'is' ('not')? '"'Number'"'
| '"Reaction: Smile Count"' 'is' ('greater'|'less') 'than' '"'Number'"'
| '"Reaction: Tada Count"' 'is' ('not')? '"'Number'"'
| '"Reaction: Tada Count"' 'is' ('greater'|'less') 'than' '"'Number'"'
| '"Reaction: Confused Count"' 'is' ('not')? '"'Number'"'
| '"Reaction: Confused Count"' 'is' ('greater'|'less') 'than' '"'Number'"'
| '"Reaction: Heart Count"' 'is' ('not')? '"'Number'"'
| '"Reaction: Heart Count"' 'is' ('greater'|'less') 'than' '"'Number'"'
| '"Reaction: Rocket Count"' 'is' ('not')? '"'Number'"'
| '"Reaction: Rocket Count"' 'is' ('greater'|'less') 'than' '"'Number'"'
| '"Reaction: Eyes Count"' 'is' ('not')? '"'Number'"'
| '"Reaction: Eyes Count"' 'is' ('greater'|'less') 'than' '"'Number'"'
""".trim();
private static SettingService getSettingService() {
return OneDev.getInstance(SettingService.class);
}
private static LinkSpecService getLinkSpecService() {
return OneDev.getInstance(LinkSpecService.class);
}
public static String getIssueQueryDescription() {
var settingService = getSettingService();
var linkSpecService = getLinkSpecService();
var fieldCriterias = new ArrayList<String>();
var choiceFieldValueRules = new ArrayList<String>();
int choiceFieldValueRuleIndex = 0;
for (var field: settingService.getIssueSetting().getFieldSpecs()) {
if (field instanceof ChoiceField) {
var choiceField = (ChoiceField) field;
var fieldValueRuleName = "ChoiceFieldValue" + (choiceFieldValueRuleIndex++);
fieldCriterias.add("'\"" + field.getName() + "\"' 'is' ('not')? '\"'" + fieldValueRuleName + "'\"'");
choiceFieldValueRules.add(choiceField.getPossibleValues().stream().map(it->"'" + it.replace("'", "\\'") + "'").collect(joining("\n | ")));
} else if (field instanceof UserChoiceField) {
fieldCriterias.add("'\"" + field.getName() + "\"' 'is' ('not')? '\"'LoginNameOfUser'\"'");
fieldCriterias.add("'\"" + field.getName() + "\"' 'is' ('not')? 'me'");
} else if (field instanceof GroupChoiceField) {
fieldCriterias.add("'\"" + field.getName() + "\"' 'is' ('not')? '\"'GroupName'\"'");
} else if (field instanceof BooleanField) {
fieldCriterias.add("'\"" + field.getName() + "\"' 'is' ('not')? '\"'('true'|'false')'\"'");
} else if (field instanceof DateField) {
fieldCriterias.add("'\"" + field.getName() + "\"' 'is' ('before'|'after') '\"'DateDescription'\"'");
} else if (field instanceof DateTimeField) {
fieldCriterias.add("'\"" + field.getName() + "\"' 'is' ('before'|'after') '\"'DateTimeDescription'\"'");
} else if (field instanceof IntegerField) {
fieldCriterias.add("'\"" + field.getName() + "\"' 'is' ('not')? '\"'Integer'\"'");
fieldCriterias.add("'\"" + field.getName() + "\"' 'is' ('greater'|'less') 'than' '\"'Integer'\"'");
} else if (field instanceof FloatField) {
fieldCriterias.add("'\"" + field.getName() + "\"' 'is' ('greater'|'less') 'than' '\"'Float'\"'");
} else if (field instanceof TextField) {
fieldCriterias.add("'\"" + field.getName() + "\"' 'is' ('not')? '\"'Text'\"'");
fieldCriterias.add("'\"" + field.getName() + "\"' 'contains' '\"'Text'\"'");
} else if (field instanceof PullRequestChoiceField || field instanceof BuildChoiceField || field instanceof IssueChoiceField) {
fieldCriterias.add("'\"" + field.getName() + "\"' 'is' ('not')? '\"'EntityReference'\"'");
} else if (field instanceof CommitField) {
fieldCriterias.add("'\"" + field.getName() + "\"' 'is' ('not')? '\"'CommitReference'\"'");
} else if (field instanceof IterationChoiceField) {
fieldCriterias.add("'\"" + field.getName() + "\"' 'is' ('not')? '\"'IterationNameOrPattern'\"'");
}
fieldCriterias.add("'\"" + field.getName() + "\"' 'is' ('not')? 'empty'");
}
var linkCriterias = new ArrayList<String>();
for (var linkSpec: linkSpecService.query()) {
linkCriterias.add("'any' '\"" + linkSpec.getName() + "\"' 'matching' '('criteria')'");
linkCriterias.add("'all' '\"" + linkSpec.getName() + "\"' 'matching' '('criteria')'");
linkCriterias.add("'has any' '\"" + linkSpec.getName() + "\"'");
if (linkSpec.getOpposite() != null) {
linkCriterias.add("'any' '\"" + linkSpec.getOpposite().getName() + "\"' 'matching' '('criteria')'");
linkCriterias.add("'all' '\"" + linkSpec.getOpposite().getName() + "\"' 'matching' '('criteria')'");
linkCriterias.add("'has any' '\"" + linkSpec.getOpposite().getName() + "\"'");
}
}
var description = String.format("""
A structured query should conform to below ANTLR grammar:
issueQuery
: criteria ('order by' '"'OrderField'"' ('asc'|'desc') (',' '"'OrderField'"' ('asc'|'desc'))*)?
;
criteria
: '"Number"' 'is' ('not')? '"'EntityReference'"'
| '"Number"' 'is' ('greater'|'less') 'than' '"'EntityReference'"'
| '"State"' 'is' ('not')? '"'StateName'"'
| '"State"' 'is' ('after'|'before') '"'StateName'"'
%s
%s
| 'submitted by' '"'LoginNameOfUser'"'
| 'submitted by me'
| 'watched by' '"'LoginNameOfUser'"'
| 'watched by me'
| 'ignored by' '"'LoginNameOfUser'"'
| 'ignored by me'
| 'commented by' '"'LoginNameOfUser'"'
| 'commented by me'
| 'mentioned' '"'LoginNameOfUser'"'
| 'mentioned me'
| 'fixed in commit' '"'CommitReference'"'
| 'fixed in current commit'
| 'fixed in build' '"'EntityReference'"'
| 'fixed in current build'
| 'fixed in pull request' '"'EntityReference'"'
| 'fixed in current pull request'
| 'fixed between' revision 'and' revision
| '"Submit Date"' 'is' ('until'|'since') '"'DateDescription'"'
| '"Last Activity Date"' 'is' ('until'|'since') '"'DateDescription'"'
| 'confidential'
| '"Spent Time"' 'is' ('greater'|'less') 'than' '"'TimePeriodDescription'"'
| '"Spent Time"' 'is' ('not')? '"'TimePeriodDescription'"'
| '"Estimated Time"' 'is' ('greater'|'less') 'than' '"'TimePeriodDescription'"'
| '"Estimated Time"' 'is' ('not')? '"'TimePeriodDescription'"'
| '"Progress"' 'is' ('greater'|'less') 'than' '"'Float'"'
| '"Iteration"' 'is' ('not')? '"'IterationNameOrPattern'"'
| '"Iteration"' 'is' ('not')? 'empty'
| '"Title"' 'contains' '"'Text'"'
| '"Description"' 'contains' '"'Text'"'
| '"Comment"' 'contains' '"'Text'"'
| '"Comment Count"' 'is' ('not')? '"'Number'"'
| '"Comment Count"' 'is' ('greater'|'less') 'than' '"'Number'"'
| '"Vote Count"' 'is' ('not')? '"'Number'"'
| '"Vote Count"' 'is' ('greater'|'less') 'than' '"'Number'"'
%s
| '"Project"' 'is current'
| '"Project"' 'is' ('not')? '"'ProjectPathOrPattern'"'
| criteria 'and' criteria
| criteria 'or' criteria
| 'not('criteria')'
| '('criteria')'
;
StateName
: %s
;
%s
revision
: 'commit' '"'CommitReference'"'
| 'build' '"'EntityReference'"'
| 'branch' '"'BranchReference'"'
| 'tag' '"'TagReference'"'
;
EntityReference
: '#'Number
| ProjectPath'#'Number
| ProjectKey'-'Number
;
CommitReference
: (ProjectPath':')?CommitHash
;
BranchReference
: (ProjectPath':')?BranchName
;
TagReference
: (ProjectPath':')?TagName
;
OrderField
: %s
;
WS
: [ ]+ -> skip
;
Please note:
1. "LoginNameOfUser" should be retrieved via tool 'getLoginName' if available, with parameter set to user name
2. Use an empty query to list all accessible issues""",
fieldCriterias.stream().map(it->" | " + it + "\n").collect(joining("")).trim(),
linkCriterias.stream().map(it->" | " + it + "\n").collect(joining("")).trim(),
REACTION_CRITERIAS,
settingService.getIssueSetting().getStateSpecs().stream().map(it->"'" + it.getName() + "'").collect(joining("\n | ")).trim(),
IntStream.range(0, choiceFieldValueRules.size()).mapToObj(i -> "ChoiceFieldValue" + i + "\n : " + choiceFieldValueRules.get(i) + "\n ;\n\n").collect(joining("")).trim(),
Issue.SORT_FIELDS.keySet().stream().map(it->"'" + it + "'").collect(joining("\n | ")).trim());
return description;
}
public static String getPullRequestQueryDescription() {
var description = String.format("""
A structured query should conform to below ANTLR grammar:
pullRequestQuery
: criteria ('order by' '"'OrderField'"' ('asc'|'desc') (',' '"'OrderField'"' ('asc'|'desc'))*)?
;
criteria
: '"Number"' 'is' ('not')? '"'EntityReference'"'
| '"Number"' 'is' ('greater'|'less') 'than' '"'EntityReference'"'
| 'open'
| 'merged'
| 'discarded'
| '"Source Branch"' 'is' ('not')? '"'BranchNameOrPattern'"'
| '"Souce Project"' 'is' ('not')? '"'ProjectPathOrPattern'"'
| '"Target Branch"' 'is' ('not')? '"'BranchNameOrPattern'"'
| '"Merge Strategy"' 'is' ('not')? '"'MergeStrategy'"'
| '"Label"' 'is' ('not')? '"'LabelName'"'
| 'ready to merge'
| 'has pending reviews'
| 'has unsuccessful builds'
| 'has unfinished builds'
| 'has merge conflicts'
| 'assigned to' '"'LoginNameOfUser'"'
| 'approved by' '"'LoginNameOfUser'"'
| 'to be reviewed by' '"'LoginNameOfUser'"'
| 'to be changed by' '"'LoginNameOfUser'"'
| 'to be merged by' '"'LoginNameOfUser'"'
| 'requested for changes by' '"'LoginNameOfUser'"'
| 'need action of' '"'LoginNameOfUser'"'
| 'assigned to me'
| 'approved by me'
| 'to be reviewed by me'
| 'to be changed by me'
| 'to be merged by me'
| 'requested for changes by me'
| 'someone requested for changes'
| 'mentioned' '"'LoginNameOfUser'"'
| 'mentioned me'
| 'need action of' '"'LoginNameOfUser'"'
| 'need my action'
| 'submitted by' '"'LoginNameOfUser'"'
| 'submitted by me'
| '"Submit Date"' 'is' ('until'|'since') '"'DateDescription'"'
| '"Last Activity Date"' 'is' ('until'|'since') '"'DateDescription'"'
| '"Close Date"' 'is' ('until'|'since') '"'DateDescription'"'
| 'includes issue' '"'EntityReference'"'
| 'includes commit' '"'CommitReference'"'
| '"Title"' 'contains' '"'Text'"'
| '"Description"' 'contains' '"'Text'"'
| '"Comment"' 'contains' '"'Text'"'
| '"Comment Count"' 'is' ('not')? '"'Number'"'
| '"Comment Count"' 'is' ('greater'|'less') 'than' '"'Number'"'
%s
| '"Project"' 'is' ('not')? '"'ProjectPathOrPattern'"'
| 'watched by' '"'LoginNameOfUser'"'
| 'watched by me'
| 'ignored by' '"'LoginNameOfUser'"'
| 'ignored by me'
| 'commented by' '"'LoginNameOfUser'"'
| 'commented by me'
| criteria 'and' criteria
| criteria 'or' criteria
| 'not('criteria')'
| '('criteria')'
;
EntityReference
: '#'Number
| ProjectPath'#'Number
| ProjectKey'-'Number
;
CommitReference
: (ProjectPath':')?CommitHash
;
BranchReference
: (ProjectPath':')?BranchName
;
TagReference
: (ProjectPath':')?TagName
;
MergeStrategy
: %s
;
LabelName
: %s
;
OrderField
: %s
;
WS
: [ ]+ -> skip
;
Please note:
1. "LoginNameOfUser" should be retrieved via tool 'getLoginName' if available, with parameter set to user name
2. Use an empty query to list all accessible pull requests""",
REACTION_CRITERIAS,
Arrays.stream(MergeStrategy.values()).map(it->"'" + it.name() + "'").collect(joining("\n | ")).trim(),
getLabelSpecs().stream().map(it->"'" + it.getName() + "'").collect(joining("\n | ")).trim(),
PullRequest.SORT_FIELDS.keySet().stream().map(it->"'" + it + "'").collect(joining("\n | ")).trim());
return description;
}
public static String getBuildQueryDescription() {
var description = String.format("""
A structured query should conform to below ANTLR grammar:
buildQuery
: criteria ('order by' '"'OrderField'"' ('asc'|'desc') (',' '"'OrderField'"' ('asc'|'desc'))*)?
;
criteria
: '"Number"' 'is' ('not')? '"'EntityReference'"'
| '"Number"' 'is' ('greater'|'less') 'than' '"'EntityReference'"'
| 'sucessful'
| 'failed'
| 'cancelled'
| 'timed out'
| 'finished'
| 'running'
| 'waiting'
| 'pending'
| 'submitted by' '"'LoginNameOfUser'"'
| 'submitted by me'
| 'cancelled by' '"'LoginNameOfUser'"'
| 'cancelled by me'
| 'depends on' '"'EntityReference'"'
| 'dependencies of' '"'EntityReference'"'
| 'ran on' '"'AgentName'"'
| 'fixed issue' '"'EntityReference'"'
| '"Project"' 'is' ('not')? '"'ProjectPathOrPattern'"'
| '"Job"' 'is' ('not')? '"'JobNameOrPattern'"'
| '"Version"' 'is' ('not')? '"'VersionNameOrPattern'"'
| '"Branch"' 'is' ('not')? '"'BranchNameOrPattern'"'
| '"Tag"' 'is' ('not')? '"'TagNameOrPattern'"'
| '"Param"' 'is' ('not')? '"'ParamName'"'
| '"Label"' 'is' ('not')? '"'LabelName'"'
| '"Pull Request"' 'is' ('not')? '"'EntityReference'"'
| '"Commit"' 'is' ('not')? '"'CommitReference'"'
| '"Submit Date"' 'is' ('until'|'since') '"'DateDescription'"'
| '"Pending Date"' 'is' ('until'|'since') '"'DateDescription'"'
| '"Running Date"' 'is' ('until'|'since') '"'DateDescription'"'
| '"Finish Date"' 'is' ('until'|'since') '"'DateDescription'"'
| criteria 'and' criteria
| criteria 'or' criteria
| 'not('criteria')'
| '('criteria')'
;
EntityReference
: '#'Number
| ProjectPath'#'Number
| ProjectKey'-'Number
;
CommitReference
: (ProjectPath':')?CommitHash
;
LabelName
: %s
;
OrderField
: %s
;
WS
: [ ]+ -> skip
;
Please note:
1. "LoginNameOfUser" should be retrieved via tool 'getLoginName' if available, with parameter set to user name
2. Use an empty query to list all accessible builds""",
getLabelSpecs().stream().map(it->"'" + it.getName() + "'").collect(joining("\n | ")).trim(),
Build.SORT_FIELDS.keySet().stream().map(it->"'" + it + "'").collect(joining("\n | ")).trim());
return description;
}
private static List<LabelSpec> getLabelSpecs() {
return OneDev.getInstance(LabelSpecService.class).query();
}
public static String getPackQueryDescription() {
var packSupports = new ArrayList<>(OneDev.getExtensions(PackSupport.class));
var description = String.format("""
A structured query should conform to below ANTLR grammar:
packQuery
: criteria ('order by' '"'OrderField'"' ('asc'|'desc') (',' '"'OrderField'"' ('asc'|'desc'))*)?
;
criteria
: 'published by me'
| 'published by user' '"'LoginNameOfUser'"'
| 'published by build' '"'EntityReference'"'
| 'published by project' '"'ProjectPathOrPattern'"'
| '"Project"' 'is' ('not')? '"'ProjectPathOrPattern'"'
| '"Type"' 'is' ('not')? '"'PackType'"'
| '"Name"' 'is' ('not')? '"'PackName'"'
| '"Version"' 'is' ('not')? '"'PackVersion'"'
| '"Label"' 'is' ('not')? '"'LabelName'"'
| '"Publish Date"' 'is' ('until'|'since') '"'DateDescription'"'
| criteria 'and' criteria
| criteria 'or' criteria
| 'not('criteria')'
| '('criteria')'
;
EntityReference
: '#'Number
| ProjectPath'#'Number
| ProjectKey'-'Number
;
PackType
: %s
;
LabelName
: %s
;
OrderField
: %s
;
WS
: [ ]+ -> skip
;
Please note:
1. "LoginNameOfUser" should be retrieved via tool 'getLoginName' if available, with parameter set to user name
2. Use an empty query to list all accessible packages""",
packSupports.stream().map(it->"'" + it.getPackType() + "'").collect(joining("\n | ")).trim(),
getLabelSpecs().stream().map(it->"'" + it.getName() + "'").collect(joining("\n | ")).trim(),
Pack.SORT_FIELDS.keySet().stream().map(it->"'" + it + "'").collect(joining("\n | ")).trim());
return description;
}
public static String getCommitQueryDescription() {
var description = """
A structured query should conform to below ANTLR grammar:
commitQuery
: criteria+
;
criteria
: ('before('|'after(') DateDescription ')'
| 'committer(' CommitterNameAndEmail ')' // committer is specified user
| 'author(' AuthorNameAndEmail ')' // author is specified user
| 'message(' Text ')' // commit message contains specified text
| 'path(' FilePath ')' // commit touches specified file
| 'authored-by-me'
| 'committed-by-me'
| ('until')? revision // until specified revision
| 'since' revision // since specified revision
;
revision
: 'commit(' CommitHash ')'
| 'build(' '#'Number ')'
| 'branch(' BranchName ')'
| 'tag(' TagName ')'
| 'default-branch'
;
WS
: [ ]+ -> skip
;
""";
return description;
}
public static String getProjectQueryDescription() {
var description = String.format("""
A structured query should conform to below ANTLR grammar:
projectQuery
: criteria ('order by' '"'OrderField'"' ('asc'|'desc') (',' '"'OrderField'"' ('asc'|'desc'))*)?
;
criteria
: 'owned by' '"'LoginNameOfUser'"'
| 'owned by me'
| 'owned by none'
| 'has outdated replicas'
| 'without enough replicas'
| 'missing storage'
| 'children of' '"'ProjectPathOrPattern'"'
| 'forks of' '"'ProjectPathOrPattern'"'
| 'roots'
| 'leafs'
| 'fork roots'
| '"Name"' 'is' ('not')? '"'ProjectNameOrPattern'"'
| '"Key"' 'is' ('not')? '"'ProjectKeyOrPattern'"'
| '"Path"' 'is' ('not')? '"'ProjectPathOrPattern'"'
| '"Label"' 'is' ('not')? '"'LabelName'"'
| '"Description"' 'contains' '"'Text'"'
| '"Id"' 'is' ('not')? '"'Number'"'
| '"Id"' 'is' ('greater'|'less') 'than' '"'Number'"'
| '"Service Desk Email Address"' 'is' ('not')? '"'EmailAddressOrPattern'"'
| '"Last Activity Date"' 'is' ('until'|'since') '"'DateDescription'"'
| criteria 'and' criteria
| criteria 'or' criteria
| 'not('criteria')'
| '('criteria')'
;
LabelName
: %s
;
OrderField
: %s
;
WS
: [ ]+ -> skip
;
Please note:
1. "LoginNameOfUser" should be retrieved via tool 'getLoginName' if available, with parameter set to user name
2. Use an empty query to list all accessible projects""",
getLabelSpecs().stream().map(it->"'" + it.getName() + "'").collect(joining("\n | ")).trim(),
Project.SORT_FIELDS.keySet().stream().map(it->"'" + it + "'").collect(joining("\n | ")).trim());
return description;
}
public static String getAgentQueryDescription() {
var agentService = OneDev.getInstance(AgentService.class);
var attributeService = OneDev.getInstance(AgentAttributeService.class);
var description = String.format("""
A structured query should conform to below ANTLR grammar:
agentQuery
: criteria ('order by' '"'OrderField'"' ('asc'|'desc') (',' '"'OrderField'"' ('asc'|'desc'))*)?
;
criteria
: 'online'
| 'offline'
| 'paused'
| 'has running builds'
| 'has attribute' '"'AttributeName'"'
| 'not used since' '"'DateDescription'"'
| 'ever used since' '"'DateDescription'"'
| 'ran build' '"'EntityReference'"'
| '"Name"' 'is' ('not')? '"'AgentNameOrPattern'"'
| '"Ip Address"' 'is' ('not')? '"'IPAddressOrPattern'"'
| '"Os"' 'is' ('not')? '"'(OsName|OsNamePattern)'"'
| '"Os Arch"' 'is' ('not')? '"'(OsArch|OsArchPattern)'"'
| '"Os Version"' 'is' ('not')? '"'OsVersionOrPattern'"'
| '"'AttributeName'"' 'is' ('not')? '"'AttributeValue'"'
| criteria 'and' criteria
| criteria 'or' criteria
| 'not('criteria')'
| '('criteria')'
;
OsName
: %s
;
OsArch
: %s
;
AttributeName
: %s
;
OrderField
: %s
;
WS
: [ ]+ -> skip
;
Please note:
1. "LoginNameOfUser" should be retrieved via tool 'getLoginName' if available, with parameter set to user name
2. Use an empty query to list all accessible agents""",
agentService.getOsNames().stream().map(it->"'" + it + "'").collect(joining("\n | ")).trim(),
agentService.getOsArchs().stream().map(it->"'" + it + "'").collect(joining("\n | ")).trim(),
attributeService.getAttributeNames().stream().map(it->"'" + it + "'").collect(joining("\n | ")).trim(),
Agent.SORT_FIELDS.keySet().stream().map(it->"'" + it + "'").collect(joining("\n | ")).trim());
return description;
}
}

View File

@ -0,0 +1,4 @@
package io.onedev.server.annotation;
public @interface NoDBAccess {
}

View File

@ -6,7 +6,7 @@ import java.util.List;
import io.onedev.server.util.artifact.FileInfo;
public interface AttachmentManager {
public interface AttachmentService {
File getAttachmentGroupDir(Long projectId, String attachmentGroup);

View File

@ -45,12 +45,12 @@ import io.onedev.commons.utils.FileUtils;
import io.onedev.commons.utils.StringUtils;
import io.onedev.commons.utils.TarUtils;
import io.onedev.k8shelper.KubernetesHelper;
import io.onedev.server.cluster.ClusterManager;
import io.onedev.server.cluster.ClusterService;
import io.onedev.server.cluster.ClusterRunnable;
import io.onedev.server.cluster.ClusterTask;
import io.onedev.server.entitymanager.IssueManager;
import io.onedev.server.entitymanager.ProjectManager;
import io.onedev.server.entitymanager.SettingManager;
import io.onedev.server.service.IssueService;
import io.onedev.server.service.ProjectService;
import io.onedev.server.service.SettingService;
import io.onedev.server.event.Listen;
import io.onedev.server.event.entity.EntityRemoved;
import io.onedev.server.event.project.build.BuildSubmitted;
@ -74,7 +74,7 @@ import io.onedev.server.event.system.SystemStopping;
import io.onedev.server.model.Issue;
import io.onedev.server.model.support.issue.changedata.IssueDescriptionChangeData;
import io.onedev.server.model.support.pullrequest.changedata.PullRequestDescriptionChangeData;
import io.onedev.server.persistence.TransactionManager;
import io.onedev.server.persistence.TransactionService;
import io.onedev.server.persistence.annotation.Sessional;
import io.onedev.server.persistence.annotation.Transactional;
import io.onedev.server.persistence.dao.Dao;
@ -82,14 +82,14 @@ import io.onedev.server.taskschedule.SchedulableTask;
import io.onedev.server.taskschedule.TaskScheduler;
import io.onedev.server.util.IOUtils;
import io.onedev.server.util.artifact.FileInfo;
import io.onedev.server.util.concurrent.BatchWorkManager;
import io.onedev.server.util.concurrent.BatchWorkExecutionService;
import io.onedev.server.util.concurrent.BatchWorker;
import io.onedev.server.util.concurrent.Prioritized;
@Singleton
public class DefaultAttachmentManager implements AttachmentManager, SchedulableTask, Serializable {
public class DefaultAttachmentService implements AttachmentService, SchedulableTask, Serializable {
private static final Logger logger = LoggerFactory.getLogger(DefaultAttachmentManager.class);
private static final Logger logger = LoggerFactory.getLogger(DefaultAttachmentService.class);
private static final long TEMP_PRESERVE_PERIOD = 24*3600*1000L;
@ -98,47 +98,40 @@ public class DefaultAttachmentManager implements AttachmentManager, SchedulableT
private static final String PERMANENT = "permanent";
private static final String TEMP = "temp";
private final Dao dao;
private final TransactionManager transactionManager;
private final TaskScheduler taskScheduler;
private final ProjectManager projectManager;
private final ClusterManager clusterManager;
private final SettingManager settingManager;
private final IssueManager issueManager;
private final BatchWorkManager batchWorkManager;
private String taskId;
@Inject
public DefaultAttachmentManager(Dao dao, TransactionManager transactionManager,
TaskScheduler taskScheduler, SettingManager settingManager,
ProjectManager projectManager, ClusterManager clusterManager,
IssueManager issueManager, BatchWorkManager batchWorkManager) {
this.dao = dao;
this.transactionManager = transactionManager;
this.taskScheduler = taskScheduler;
this.settingManager = settingManager;
this.projectManager = projectManager;
this.clusterManager = clusterManager;
this.issueManager = issueManager;
this.batchWorkManager = batchWorkManager;
}
private Dao dao;
@Inject
private TransactionService transactionService;
@Inject
private TaskScheduler taskScheduler;
@Inject
private ProjectService projectService;
@Inject
private ClusterService clusterService;
@Inject
private SettingService settingService;
@Inject
private IssueService issueService;
@Inject
private BatchWorkExecutionService batchWorkExecutionService;
private volatile String taskId;
public Object writeReplace() throws ObjectStreamException {
return new ManagedSerializedForm(AttachmentManager.class);
return new ManagedSerializedForm(AttachmentService.class);
}
@Override
public File getAttachmentGroupDir(Long projectId, String attachmentGroup) {
File baseDir = projectManager.getAttachmentDir(projectId);
File baseDir = projectService.getAttachmentDir(projectId);
File groupDir = getPermanentAttachmentGroupDir(baseDir, attachmentGroup);
if (groupDir.exists())
return groupDir;
@ -151,11 +144,11 @@ public class DefaultAttachmentManager implements AttachmentManager, SchedulableT
public void on(IssuesMoved event) {
Long sourceProjectId = event.getSourceProject().getId();
Long targetProjectId = event.getProject().getId();
File targetBaseDir = projectManager.getAttachmentDir(targetProjectId);
File targetBaseDir = projectService.getAttachmentDir(targetProjectId);
String sourceActiveServer = projectManager.getActiveServer(sourceProjectId, true);
if (sourceActiveServer.equals(clusterManager.getLocalServerAddress())) {
File sourceBaseDir = projectManager.getAttachmentDir(sourceProjectId);
String sourceActiveServer = projectService.getActiveServer(sourceProjectId, true);
if (sourceActiveServer.equals(clusterService.getLocalServerAddress())) {
File sourceBaseDir = projectService.getAttachmentDir(sourceProjectId);
for (Long issueId: event.getIssueIds()) {
Issue issue = dao.load(Issue.class, issueId);
String attachmentGroup = issue.getAttachmentGroup();
@ -184,8 +177,8 @@ public class DefaultAttachmentManager implements AttachmentManager, SchedulableT
} finally {
FileUtils.deleteDir(tempGroupDir);
}
projectManager.directoryModified(targetProjectId, sourceGroupDir.getParentFile());
projectManager.directoryModified(targetProjectId, targetGroupDir.getParentFile());
projectService.directoryModified(targetProjectId, sourceGroupDir.getParentFile());
projectService.directoryModified(targetProjectId, targetGroupDir.getParentFile());
}
} else {
Collection<String> attachmentGroups = new HashSet<>();
@ -211,22 +204,22 @@ public class DefaultAttachmentManager implements AttachmentManager, SchedulableT
} finally {
FileUtils.deleteDir(tempGroupDir);
}
projectManager.directoryModified(targetProjectId, targetGroupDir.getParentFile());
projectService.directoryModified(targetProjectId, targetGroupDir.getParentFile());
}
projectManager.runOnActiveServer(sourceProjectId, new ClusterTask<Void>() {
projectService.runOnActiveServer(sourceProjectId, new ClusterTask<Void>() {
private static final long serialVersionUID = 1L;
@Override
public Void call() {
File sourceBaseDir = projectManager.getAttachmentDir(sourceProjectId);
File sourceBaseDir = projectService.getAttachmentDir(sourceProjectId);
for (var attachmentGroup: attachmentGroups) {
var sourceGroupDir = getPermanentAttachmentGroupDir(sourceBaseDir, attachmentGroup);
write(getAttachmentLockName(sourceProjectId, attachmentGroup), () -> {
FileUtils.deleteDir(sourceGroupDir);
return null;
});
projectManager.directoryModified(sourceProjectId, sourceGroupDir.getParentFile());
projectService.directoryModified(sourceProjectId, sourceGroupDir.getParentFile());
}
return null;
}
@ -241,11 +234,11 @@ public class DefaultAttachmentManager implements AttachmentManager, SchedulableT
Long sourceProjectId = event.getSourceProject().getId();
Long targetProjectId = event.getProject().getId();
File targetBaseDir = projectManager.getAttachmentDir(targetProjectId);
File targetBaseDir = projectService.getAttachmentDir(targetProjectId);
String sourceActiveServer = projectManager.getActiveServer(sourceProjectId, true);
if (sourceActiveServer.equals(clusterManager.getLocalServerAddress())) {
File sourceBaseDir = projectManager.getAttachmentDir(sourceProjectId);
String sourceActiveServer = projectService.getActiveServer(sourceProjectId, true);
if (sourceActiveServer.equals(clusterService.getLocalServerAddress())) {
File sourceBaseDir = projectService.getAttachmentDir(sourceProjectId);
for (var entry: event.getIssueIdMapping().entrySet()) {
Issue sourceIssue = dao.load(Issue.class, entry.getKey());
Issue targetIssue = dao.load(Issue.class, entry.getValue());
@ -273,7 +266,7 @@ public class DefaultAttachmentManager implements AttachmentManager, SchedulableT
} finally {
FileUtils.deleteDir(tempGroupDir);
}
projectManager.directoryModified(targetProjectId, targetGroupDir.getParentFile());
projectService.directoryModified(targetProjectId, targetGroupDir.getParentFile());
}
} else {
for (var entry: event.getIssueIdMapping().entrySet()) {
@ -296,7 +289,7 @@ public class DefaultAttachmentManager implements AttachmentManager, SchedulableT
} finally {
FileUtils.deleteDir(tempGroupDir);
}
projectManager.directoryModified(targetProjectId, targetGroupDir.getParentFile());
projectService.directoryModified(targetProjectId, targetGroupDir.getParentFile());
}
}
@ -306,13 +299,13 @@ public class DefaultAttachmentManager implements AttachmentManager, SchedulableT
Long sourceProjectId, String sourceAttachmentGroup) {
Client client = ClientBuilder.newClient();
try {
String fromServerUrl = clusterManager.getServerUrl(sourceActiveServer);
String fromServerUrl = clusterService.getServerUrl(sourceActiveServer);
WebTarget target = client.target(fromServerUrl).path("/~api/cluster/attachments")
.queryParam("projectId", sourceProjectId)
.queryParam("attachmentGroup", sourceAttachmentGroup);
Invocation.Builder builder = target.request();
builder.header(AUTHORIZATION,
BEARER + " " + clusterManager.getCredential());
BEARER + " " + clusterService.getCredential());
try (Response response = builder.get()) {
KubernetesHelper.checkStatus(response);
@ -333,7 +326,7 @@ public class DefaultAttachmentManager implements AttachmentManager, SchedulableT
}
private void permanentizeAttachmentGroup(Long projectId, String attachmentGroup) {
var baseAttachmentDir = projectManager.getAttachmentDir(projectId);
var baseAttachmentDir = projectService.getAttachmentDir(projectId);
write(getAttachmentLockName(projectId, attachmentGroup), () -> {
File permanentStorage = getPermanentAttachmentGroupDir(baseAttachmentDir, attachmentGroup);
if (!permanentStorage.exists()) {
@ -347,7 +340,7 @@ public class DefaultAttachmentManager implements AttachmentManager, SchedulableT
} else {
FileUtils.createDir(permanentStorage);
}
projectManager.directoryModified(projectId, permanentStorage);
projectService.directoryModified(projectId, permanentStorage);
}
return null;
});
@ -366,13 +359,13 @@ public class DefaultAttachmentManager implements AttachmentManager, SchedulableT
@Override
public void execute() {
batchWorkManager.submit(new BatchWorker("attachment-manager-house-keeping") {
batchWorkExecutionService.submit(new BatchWorker("attachment-manager-house-keeping") {
@Override
public void doWorks(List<Prioritized> works) {
for (var projectId: projectManager.getActiveIds()) {
for (var projectId: projectService.getActiveIds()) {
try {
File tempAttachmentBase = new File(projectManager.getAttachmentDir(projectId), TEMP);
File tempAttachmentBase = new File(projectService.getAttachmentDir(projectId), TEMP);
if (tempAttachmentBase.exists()) {
for (File attachmentGroupDir: tempAttachmentBase.listFiles()) {
if (System.currentTimeMillis() - attachmentGroupDir.lastModified() > TEMP_PRESERVE_PERIOD) {
@ -398,7 +391,7 @@ public class DefaultAttachmentManager implements AttachmentManager, SchedulableT
@Sessional
public void on(IssuesImported event) {
for (var issueId: event.getIssueIds()) {
var issue = issueManager.load(issueId);
var issue = issueService.load(issueId);
var attachmentGroup = issue.getAttachmentGroup();
permanentizeAttachmentGroup(issue.getProject().getId(), attachmentGroup);
}
@ -505,15 +498,15 @@ public class DefaultAttachmentManager implements AttachmentManager, SchedulableT
if (event.getEntity() instanceof AttachmentStorageSupport) {
AttachmentStorageSupport storageSupport = (AttachmentStorageSupport) event.getEntity();
Long projectId = storageSupport.getAttachmentProject().getId();
String activeServer = projectManager.getActiveServer(projectId, false);
String activeServer = projectService.getActiveServer(projectId, false);
if (activeServer != null) {
transactionManager.runAfterCommit(new ClusterRunnable() {
transactionService.runAfterCommit(new ClusterRunnable() {
private static final long serialVersionUID = 1L;
@Override
public void run() {
clusterManager.runOnServer(activeServer, new ClusterTask<Void>() {
clusterService.runOnServer(activeServer, new ClusterTask<Void>() {
private static final long serialVersionUID = 1L;
@ -522,10 +515,10 @@ public class DefaultAttachmentManager implements AttachmentManager, SchedulableT
var attachmentGroup = storageSupport.getAttachmentGroup();
return write(getAttachmentLockName(projectId, attachmentGroup), () -> {
File attachmentDir = getPermanentAttachmentGroupDir(
projectManager.getAttachmentDir(storageSupport.getAttachmentProject().getId()),
projectService.getAttachmentDir(storageSupport.getAttachmentProject().getId()),
attachmentGroup);
FileUtils.deleteDir(attachmentDir);
projectManager.directoryModified(projectId, attachmentDir.getParentFile());
projectService.directoryModified(projectId, attachmentDir.getParentFile());
return null;
});
}
@ -541,21 +534,21 @@ public class DefaultAttachmentManager implements AttachmentManager, SchedulableT
@Override
public String saveAttachment(Long projectId, String attachmentGroup, String preferredAttachmentName,
InputStream attachmentStream) {
String activeServer = projectManager.getActiveServer(projectId, true);
if (activeServer.equals(clusterManager.getLocalServerAddress())) {
String activeServer = projectService.getActiveServer(projectId, true);
if (activeServer.equals(clusterService.getLocalServerAddress())) {
return saveAttachmentLocal(projectId, attachmentGroup, preferredAttachmentName, attachmentStream);
} else {
Client client = ClientBuilder.newClient();
client.property(ClientProperties.REQUEST_ENTITY_PROCESSING, "CHUNKED");
try {
String serverUrl = clusterManager.getServerUrl(activeServer);
String serverUrl = clusterService.getServerUrl(activeServer);
WebTarget target = client.target(serverUrl)
.path("~api/cluster/attachment")
.queryParam("projectId", projectId)
.queryParam("attachmentGroup", attachmentGroup)
.queryParam("suggestedAttachmentName", preferredAttachmentName);
var builder = target.request();
builder.header(AUTHORIZATION, BEARER + " " + clusterManager.getCredential());
builder.header(AUTHORIZATION, BEARER + " " + clusterService.getCredential());
StreamingOutput os = output -> {
try {
@ -598,7 +591,7 @@ public class DefaultAttachmentManager implements AttachmentManager, SchedulableT
index++;
}
long maxUploadFileSize = settingManager.getPerformanceSetting().getMaxUploadFileSize() * 1024L * 1024L;
long maxUploadFileSize = settingService.getPerformanceSetting().getMaxUploadFileSize() * 1024L * 1024L;
Exception ex = null;
File file = new File(attachmentDir, attachmentName);
@ -623,7 +616,7 @@ public class DefaultAttachmentManager implements AttachmentManager, SchedulableT
throw ExceptionUtils.unchecked(ex);
} else {
if (!attachmentDir.getParentFile().getName().equals(TEMP))
projectManager.directoryModified(projectId, attachmentDir);
projectService.directoryModified(projectId, attachmentDir);
return file.getName();
}
});
@ -636,7 +629,7 @@ public class DefaultAttachmentManager implements AttachmentManager, SchedulableT
@Override
public FileInfo getAttachmentInfo(Long projectId, String attachmentGroup, String attachment) {
return projectManager.runOnActiveServer(projectId, () -> read(getAttachmentLockName(projectId, attachmentGroup), () -> {
return projectService.runOnActiveServer(projectId, () -> read(getAttachmentLockName(projectId, attachmentGroup), () -> {
File attachmentFile = new File(getAttachmentGroupDir(projectId, attachmentGroup), attachment);
if (!attachmentFile.exists())
throw new FileNotFoundException("Attachment not found: " + attachment);
@ -647,12 +640,12 @@ public class DefaultAttachmentManager implements AttachmentManager, SchedulableT
@Override
public void deleteAttachment(Long projectId, String attachmentGroup, String attachment) {
projectManager.runOnActiveServer(projectId, () -> write(getAttachmentLockName(projectId, attachmentGroup), () -> {
projectService.runOnActiveServer(projectId, () -> write(getAttachmentLockName(projectId, attachmentGroup), () -> {
var attachmentGroupDir = getAttachmentGroupDir(projectId, attachmentGroup);
File attachmentFile = new File(attachmentGroupDir, attachment);
if (attachmentFile.exists()) {
FileUtils.deleteFile(attachmentFile);
projectManager.directoryModified(projectId, attachmentGroupDir);
projectService.directoryModified(projectId, attachmentGroupDir);
}
return null;
}));
@ -660,7 +653,7 @@ public class DefaultAttachmentManager implements AttachmentManager, SchedulableT
@Override
public List<FileInfo> listAttachments(Long projectId, String attachmentGroup) {
return projectManager.runOnActiveServer(projectId, () -> read(getAttachmentLockName(projectId, attachmentGroup), () -> {
return projectService.runOnActiveServer(projectId, () -> read(getAttachmentLockName(projectId, attachmentGroup), () -> {
List<FileInfo> attachments = new ArrayList<>();
File attachmentGroupDir = getAttachmentGroupDir(projectId, attachmentGroup);
if (attachmentGroupDir.exists()) {
@ -676,12 +669,12 @@ public class DefaultAttachmentManager implements AttachmentManager, SchedulableT
@Override
public void syncAttachments(Long projectId, String activeServer) {
var permanent = ATTACHMENT_DIR + "/" + PERMANENT;
projectManager.syncDirectory(projectId, permanent, prefix -> {
projectService.syncDirectory(projectId, permanent, prefix -> {
var prefixPath = permanent + "/" + prefix;
projectManager.syncDirectory(projectId, prefixPath, attachmentGroup -> {
projectService.syncDirectory(projectId, prefixPath, attachmentGroup -> {
var attachmentGroupPath = permanent + "/" + prefix + "/" + attachmentGroup;
var lockName = getAttachmentLockName(projectId, attachmentGroup);
projectManager.syncDirectory(projectId, attachmentGroupPath, lockName, activeServer);
projectService.syncDirectory(projectId, attachmentGroupPath, lockName, activeServer);
}, activeServer);
}, activeServer);
}

View File

@ -11,9 +11,9 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonTypeInfo.Id;
import io.onedev.server.OneDev;
import io.onedev.server.entitymanager.ProjectManager;
import io.onedev.server.service.ProjectService;
import io.onedev.server.model.Project;
import io.onedev.server.persistence.SessionManager;
import io.onedev.server.persistence.SessionService;
import io.onedev.server.web.resource.AttachmentResource;
import io.onedev.server.web.resource.AttachmentResourceReference;
@ -44,21 +44,21 @@ public class ProjectAttachmentSupport implements AttachmentSupport {
@Override
public List<String> getAttachments() {
return getAttachmentManager().listAttachments(projectId, attachmentGroup).stream()
return getAttachmentService().listAttachments(projectId, attachmentGroup).stream()
.map(it->it.getPath()).collect(Collectors.toList());
}
private ProjectManager getProjectManager() {
return OneDev.getInstance(ProjectManager.class);
private ProjectService getProjectService() {
return OneDev.getInstance(ProjectService.class);
}
private AttachmentManager getAttachmentManager() {
return OneDev.getInstance(AttachmentManager.class);
private AttachmentService getAttachmentService() {
return OneDev.getInstance(AttachmentService.class);
}
@Override
public void deleteAttachemnt(String attachment) {
getAttachmentManager().deleteAttachment(projectId, attachmentGroup, attachment);
getAttachmentService().deleteAttachment(projectId, attachmentGroup, attachment);
}
@Override
@ -67,18 +67,18 @@ public class ProjectAttachmentSupport implements AttachmentSupport {
}
protected Project getProject() {
SessionManager sessionManager = OneDev.getInstance(SessionManager.class);
sessionManager.openSession();
SessionService sessionService = OneDev.getInstance(SessionService.class);
sessionService.openSession();
try {
return getProjectManager().load(projectId);
return getProjectService().load(projectId);
} finally {
sessionManager.closeSession();
sessionService.closeSession();
}
}
@Override
public String saveAttachment(String suggestedAttachmentName, InputStream attachmentStream) {
return getAttachmentManager().saveAttachment(
return getAttachmentService().saveAttachment(
projectId, attachmentGroup, suggestedAttachmentName, attachmentStream);
}

View File

@ -14,7 +14,7 @@ import java.util.Stack;
import java.util.function.Consumer;
import java.util.function.Function;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
import javax.validation.ConstraintValidatorContext;
import javax.validation.ConstraintViolation;
import javax.validation.Valid;
@ -59,7 +59,6 @@ import io.onedev.server.data.migration.XmlBuildSpecMigrator;
import io.onedev.server.job.JobAuthorizationContext;
import io.onedev.server.model.Project;
import io.onedev.server.model.support.build.JobProperty;
import io.onedev.server.security.SecurityUtils;
import io.onedev.server.util.ComponentContext;
import io.onedev.server.validation.Validatable;
import io.onedev.server.web.page.project.blob.ProjectBlobPage;
@ -186,8 +185,7 @@ public class BuildSpec implements Serializable, Validatable {
Collection<String> newCommitChain = new HashSet<>(commitChain);
newCommitChain.add(importCommit.name());
BuildSpec importedBuildSpec = aImport.getBuildSpec();
JobAuthorizationContext.push(new JobAuthorizationContext(
aImport.getProject(), importCommit, SecurityUtils.getUser(), null));
JobAuthorizationContext.push(new JobAuthorizationContext(aImport.getProject(), importCommit, null));
try {
importedBuildSpecs.addAll(importedBuildSpec.getImportedBuildSpecs(newCommitChain));
} finally {

View File

@ -1,6 +1,6 @@
package io.onedev.server.buildspec;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
public interface BuildSpecAware {

View File

@ -10,7 +10,7 @@ import java.util.List;
import java.util.Stack;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
import javax.validation.ConstraintValidatorContext;
import javax.validation.ConstraintViolation;
import javax.validation.ValidationException;
@ -30,7 +30,7 @@ import io.onedev.server.annotation.ChoiceProvider;
import io.onedev.server.annotation.ClassValidating;
import io.onedev.server.annotation.Editable;
import io.onedev.server.annotation.Interpolative;
import io.onedev.server.entitymanager.ProjectManager;
import io.onedev.server.service.ProjectService;
import io.onedev.server.job.JobAuthorizationContext;
import io.onedev.server.model.Project;
import io.onedev.server.security.SecurityUtils;
@ -80,13 +80,13 @@ public class Import implements Serializable, Validatable {
@SuppressWarnings("unused")
private static List<String> getProjectChoices() {
ProjectManager projectManager = OneDev.getInstance(ProjectManager.class);
ProjectService projectService = OneDev.getInstance(ProjectService.class);
Project project = ((ProjectPage)WicketUtils.getPage()).getProject();
Collection<Project> projects = SecurityUtils.getAuthorizedProjects(new AccessProject());
projects.remove(project);
ProjectCache cache = projectManager.cloneCache();
ProjectCache cache = projectService.cloneCache();
List<String> choices = projects.stream().map(it->cache.get(it.getId()).getPath()).collect(Collectors.toList());
Collections.sort(choices);
@ -98,7 +98,7 @@ public class Import implements Serializable, Validatable {
private static Project getInputProject() {
String projectPath = (String) EditContext.get().getInputValue("projectPath");
if (projectPath != null) {
Project project = OneDev.getInstance(ProjectManager.class).findByPath(projectPath);
Project project = OneDev.getInstance(ProjectService.class).findByPath(projectPath);
if (project != null && SecurityUtils.canReadCode(project))
return project;
}
@ -207,8 +207,7 @@ public class Import implements Serializable, Validatable {
try {
Validator validator = OneDev.getInstance(Validator.class);
BuildSpec buildSpec = getBuildSpec();
JobAuthorizationContext.push(new JobAuthorizationContext(
getProject(), getCommit(), SecurityUtils.getUser(), null));
JobAuthorizationContext.push(new JobAuthorizationContext(getProject(), getCommit(), null));
try {
for (int i = 0; i < buildSpec.getImports().size(); i++) {
Import aImport = buildSpec.getImports().get(i);
@ -243,7 +242,7 @@ public class Import implements Serializable, Validatable {
public Project getProject() {
if (project == null) {
project = OneDev.getInstance(ProjectManager.class).findByPath(projectPath);
project = OneDev.getInstance(ProjectService.class).findByPath(projectPath);
if (project == null)
throw new ExplicitException(MessageFormat.format( _T("Unable to find project to import build spec: {0}"), projectPath));
}

View File

@ -17,7 +17,7 @@ import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
import javax.validation.ConstraintValidatorContext;
import javax.validation.Valid;
import javax.validation.constraints.Min;
@ -46,14 +46,13 @@ import io.onedev.server.buildspec.job.trigger.JobTrigger;
import io.onedev.server.buildspec.param.ParamUtils;
import io.onedev.server.buildspec.param.spec.ParamSpec;
import io.onedev.server.buildspec.step.Step;
import io.onedev.server.entitymanager.SettingManager;
import io.onedev.server.event.project.ProjectEvent;
import io.onedev.server.git.GitUtils;
import io.onedev.server.job.match.JobMatch;
import io.onedev.server.job.match.JobMatchContext;
import io.onedev.server.model.PullRequest;
import io.onedev.server.model.support.administration.jobexecutor.JobExecutor;
import io.onedev.server.security.SecurityUtils;
import io.onedev.server.service.SettingService;
import io.onedev.server.util.ComponentContext;
import io.onedev.server.util.EditContext;
import io.onedev.server.util.criteria.Criteria;
@ -151,7 +150,7 @@ public class Job implements NamedElement, Validatable {
@SuppressWarnings("unused")
private static String getJobExecutorPlaceholder() {
if (OneDev.getInstance(SettingManager.class).getJobExecutors().isEmpty())
if (OneDev.getInstance(SettingService.class).getJobExecutors().isEmpty())
return _T("Auto-discovered executor");
else
return _T("First applicable executor");
@ -159,7 +158,7 @@ public class Job implements NamedElement, Validatable {
@SuppressWarnings("unused")
private static String getJobExecutorDescription() {
if (OneDev.getInstance(SettingManager.class).getJobExecutors().isEmpty())
if (OneDev.getInstance(SettingService.class).getJobExecutors().isEmpty())
return _T("Optionally specify executor for this job. Leave empty to use auto-discover executor");
else
return _T("Optionally specify executor for this job. Leave empty to use first applicable executor");
@ -174,8 +173,8 @@ public class Job implements NamedElement, Validatable {
String branch = page.getBlobIdent().revision;
if (branch == null)
branch = "main";
JobMatchContext context = new JobMatchContext(page.getProject(), branch, null, SecurityUtils.getAuthUser(), jobName);
for (JobExecutor executor: OneDev.getInstance(SettingManager.class).getJobExecutors()) {
JobMatchContext context = new JobMatchContext(page.getProject(), branch, null, jobName);
for (JobExecutor executor: OneDev.getInstance(SettingService.class).getJobExecutors()) {
if (executor.isEnabled()) {
if (executor.getJobMatch() == null) {
applicableJobExecutors.add(executor.getName());
@ -352,7 +351,7 @@ public class Job implements NamedElement, Validatable {
public boolean isValid(ConstraintValidatorContext context) {
boolean isValid = true;
var jobExecutors = OneDev.getInstance(SettingManager.class).getJobExecutors();
var jobExecutors = OneDev.getInstance(SettingService.class).getJobExecutors();
if (jobExecutor != null && !jobExecutor.contains("@")
&& jobExecutors.stream().noneMatch(it->it.getName().equals(jobExecutor))) {
isValid = false;

View File

@ -1,6 +1,6 @@
package io.onedev.server.buildspec.job;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
import io.onedev.server.buildspec.ParamSpecAware;

View File

@ -1,6 +1,6 @@
package io.onedev.server.buildspec.job;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
import io.onedev.server.model.support.administration.jobexecutor.JobExecutor;

View File

@ -2,7 +2,7 @@ package io.onedev.server.buildspec.job;
import io.onedev.k8shelper.KubernetesHelper;
import io.onedev.server.OneDev;
import io.onedev.server.entitymanager.SettingManager;
import io.onedev.server.service.SettingService;
import io.onedev.server.model.Build;
import io.onedev.server.util.UrlUtils;
@ -118,14 +118,14 @@ public enum JobVariable {
SERVER {
@Override
public String getValue(Build build) {
var serverUrl = OneDev.getInstance(SettingManager.class).getSystemSetting().getServerUrl();
var serverUrl = OneDev.getInstance(SettingService.class).getSystemSetting().getServerUrl();
return UrlUtils.getServer(serverUrl);
}
},
SERVER_HOST {
@Override
public String getValue(Build build) {
var serverUrl = OneDev.getInstance(SettingManager.class).getSystemSetting().getServerUrl();
var serverUrl = OneDev.getInstance(SettingService.class).getSystemSetting().getServerUrl();
try {
return new URL(serverUrl).getHost();
} catch (MalformedURLException e) {
@ -136,7 +136,7 @@ public enum JobVariable {
SERVER_URL {
@Override
public String getValue(Build build) {
return OneDev.getInstance(SettingManager.class).getSystemSetting().getServerUrl();
return OneDev.getInstance(SettingService.class).getSystemSetting().getServerUrl();
}
};

View File

@ -3,14 +3,14 @@ package io.onedev.server.buildspec.job;
import io.onedev.server.OneDev;
import io.onedev.server.buildspec.param.instance.ParamInstances;
import io.onedev.server.buildspec.param.instance.ParamMap;
import io.onedev.server.entitymanager.IssueManager;
import io.onedev.server.entitymanager.PullRequestManager;
import io.onedev.server.service.IssueService;
import io.onedev.server.service.PullRequestService;
import io.onedev.server.model.Issue;
import io.onedev.server.model.PullRequest;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
import java.io.Serializable;
import java.util.List;
@ -48,7 +48,7 @@ public class TriggerMatch implements Serializable {
@Nullable
public PullRequest getRequest() {
if (requestId != null)
return OneDev.getInstance(PullRequestManager.class).load(requestId);
return OneDev.getInstance(PullRequestService.class).load(requestId);
else
return null;
}
@ -56,7 +56,7 @@ public class TriggerMatch implements Serializable {
@Nullable
public Issue getIssue() {
if (issueId != null)
return OneDev.getInstance(IssueManager.class).load(issueId);
return OneDev.getInstance(IssueService.class).load(issueId);
else
return null;
}

View File

@ -6,7 +6,7 @@ import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
import javax.validation.Valid;
import javax.validation.ValidationException;
import javax.validation.constraints.NotEmpty;
@ -26,9 +26,9 @@ import io.onedev.server.annotation.Multiline;
import io.onedev.server.annotation.OmitName;
import io.onedev.server.buildspec.BuildSpec;
import io.onedev.server.buildspec.job.Job;
import io.onedev.server.entitymanager.IssueManager;
import io.onedev.server.entitymanager.ProjectManager;
import io.onedev.server.entitymanager.SettingManager;
import io.onedev.server.service.IssueService;
import io.onedev.server.service.ProjectService;
import io.onedev.server.service.SettingService;
import io.onedev.server.job.JobAuthorizationContext;
import io.onedev.server.model.Build;
import io.onedev.server.model.Issue;
@ -36,7 +36,7 @@ import io.onedev.server.model.Project;
import io.onedev.server.model.support.administration.GlobalIssueSetting;
import io.onedev.server.model.support.issue.field.FieldUtils;
import io.onedev.server.model.support.issue.field.instance.FieldInstance;
import io.onedev.server.persistence.TransactionManager;
import io.onedev.server.persistence.TransactionService;
import io.onedev.server.security.SecurityUtils;
import io.onedev.server.security.permission.AccessProject;
import io.onedev.server.util.facade.ProjectCache;
@ -73,13 +73,13 @@ public class CreateIssueAction extends PostBuildAction {
@SuppressWarnings("unused")
private static List<String> getProjectChoices() {
ProjectManager projectManager = OneDev.getInstance(ProjectManager.class);
ProjectService projectService = OneDev.getInstance(ProjectService.class);
Project project = ((ProjectPage) WicketUtils.getPage()).getProject();
Collection<Project> projects = SecurityUtils.getAuthorizedProjects(new AccessProject());
projects.remove(project);
ProjectCache cache = projectManager.cloneCache();
ProjectCache cache = projectService.cloneCache();
List<String> choices = projects.stream().map(it->cache.get(it.getId()).getPath()).collect(Collectors.toList());
Collections.sort(choices);
@ -155,15 +155,15 @@ public class CreateIssueAction extends PostBuildAction {
}
private static Collection<String> getFieldNames() {
return OneDev.getInstance(SettingManager.class).getIssueSetting().getFieldNames();
return OneDev.getInstance(SettingService.class).getIssueSetting().getFieldNames();
}
@Override
public void execute(Build build) {
OneDev.getInstance(TransactionManager.class).run(() -> {
OneDev.getInstance(TransactionService.class).run(() -> {
Project project;
if (getProjectPath() != null) {
project = OneDev.getInstance(ProjectManager.class).findByPath(getProjectPath());
project = OneDev.getInstance(ProjectService.class).findByPath(getProjectPath());
if (project == null)
throw new ExplicitException("Unable to find project: " + projectPath);
Subject subject = JobAuthorizationContext.get().getSubject(getAccessTokenSecret());
@ -177,8 +177,8 @@ public class CreateIssueAction extends PostBuildAction {
issue.setTitle(getIssueTitle());
issue.setSubmitter(SecurityUtils.getUser());
issue.setSubmitDate(new Date());
SettingManager settingManager = OneDev.getInstance(SettingManager.class);
GlobalIssueSetting issueSetting = settingManager.getIssueSetting();
SettingService settingService = OneDev.getInstance(SettingService.class);
GlobalIssueSetting issueSetting = settingService.getIssueSetting();
issue.setState(issueSetting.getInitialStateSpec().getName());
issue.setDescription(getIssueDescription());
@ -188,7 +188,7 @@ public class CreateIssueAction extends PostBuildAction {
.convertToObject(instance.getValueProvider().getValue());
issue.setFieldValue(instance.getName(), fieldValue);
}
OneDev.getInstance(IssueManager.class).open(issue);
OneDev.getInstance(IssueService.class).open(issue);
});
}
@ -202,7 +202,7 @@ public class CreateIssueAction extends PostBuildAction {
public void validateWith(BuildSpec buildSpec, Job job) {
super.validateWith(buildSpec, job);
GlobalIssueSetting issueSetting = OneDev.getInstance(SettingManager.class).getIssueSetting();
GlobalIssueSetting issueSetting = OneDev.getInstance(SettingService.class).getIssueSetting();
try {
FieldUtils.validateFields(issueSetting.getFieldSpecMap(getFieldNames()), issueFields);
} catch (ValidationException e) {

View File

@ -1,7 +1,23 @@
package io.onedev.server.buildspec.job.action;
import static io.onedev.server.buildspec.param.ParamUtils.resolveParams;
import java.util.ArrayList;
import java.util.List;
import javax.validation.Valid;
import javax.validation.ValidationException;
import javax.validation.constraints.NotEmpty;
import org.apache.wicket.Component;
import io.onedev.server.OneDev;
import io.onedev.server.annotation.*;
import io.onedev.server.annotation.ChoiceProvider;
import io.onedev.server.annotation.Editable;
import io.onedev.server.annotation.OmitName;
import io.onedev.server.annotation.ParamSpecProvider;
import io.onedev.server.annotation.ShowCondition;
import io.onedev.server.annotation.VariableOption;
import io.onedev.server.buildspec.BuildSpec;
import io.onedev.server.buildspec.BuildSpecAware;
import io.onedev.server.buildspec.job.Job;
@ -9,21 +25,13 @@ import io.onedev.server.buildspec.param.ParamUtils;
import io.onedev.server.buildspec.param.instance.ParamInstances;
import io.onedev.server.buildspec.param.instance.ParamMap;
import io.onedev.server.buildspec.param.spec.ParamSpec;
import io.onedev.server.job.JobManager;
import io.onedev.server.job.JobService;
import io.onedev.server.model.Build;
import io.onedev.server.service.UserService;
import io.onedev.server.util.ComponentContext;
import io.onedev.server.util.EditContext;
import io.onedev.server.web.editable.BeanEditor;
import io.onedev.server.web.util.WicketUtils;
import org.apache.wicket.Component;
import javax.validation.Valid;
import javax.validation.ValidationException;
import javax.validation.constraints.NotEmpty;
import java.util.ArrayList;
import java.util.List;
import static io.onedev.server.buildspec.param.ParamUtils.resolveParams;
@Editable(name="Run job", order=100)
public class RunJobAction extends PostBuildAction {
@ -106,11 +114,11 @@ public class RunJobAction extends PostBuildAction {
@Override
public void execute(Build build) {
for (var paramMap: resolveParams(build, build.getParamCombination(), getParamMatrix(), getExcludeParamMaps())) {
JobManager jobManager = OneDev.getInstance(JobManager.class);
jobManager.submit(build.getProject(), build.getCommitId(),
getJobName(), paramMap, build.getRefName(),
build.getSubmitter(), build.getRequest(), build.getIssue(),
"Post build action of job '" + build.getJobName() + "'");
JobService jobService = OneDev.getInstance(JobService.class);
var userService = OneDev.getInstance(UserService.class);
jobService.submit(userService.getSystem(), build.getProject(), build.getCommitId(),
getJobName(), paramMap, build.getRefName(), build.getRequest(), build.getIssue(),
"Triggered via post build action of job '" + build.getJobName() + "'");
}
}

View File

@ -0,0 +1,308 @@
package io.onedev.server.buildspec.job.action;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
import javax.validation.ConstraintValidatorContext;
import javax.validation.constraints.NotEmpty;
import javax.ws.rs.NotAcceptableException;
import org.apache.shiro.authz.UnauthorizedException;
import org.apache.shiro.util.ThreadContext;
import io.onedev.commons.codeassist.InputSuggestion;
import io.onedev.server.OneDev;
import io.onedev.server.annotation.ChoiceProvider;
import io.onedev.server.annotation.ClassValidating;
import io.onedev.server.annotation.Editable;
import io.onedev.server.annotation.Interpolative;
import io.onedev.server.buildspec.BuildSpec;
import io.onedev.server.git.GitUtils;
import io.onedev.server.job.JobService;
import io.onedev.server.model.Build;
import io.onedev.server.model.Project;
import io.onedev.server.security.SecurityUtils;
import io.onedev.server.security.permission.AccessProject;
import io.onedev.server.service.AccessTokenService;
import io.onedev.server.service.BuildService;
import io.onedev.server.service.ProjectService;
import io.onedev.server.util.EditContext;
import io.onedev.server.util.facade.ProjectCache;
import io.onedev.server.validation.Validatable;
import io.onedev.server.web.page.project.ProjectPage;
import io.onedev.server.web.util.SuggestionUtils;
import io.onedev.server.web.util.WicketUtils;
@Editable(name="Run job in another project", order=150)
@ClassValidating
public class RunProjectJobAction extends PostBuildAction implements Validatable {
private static final long serialVersionUID = 1L;
private String projectPath;
private String branch;
private String tag;
private String jobName;
private List<JobParam> jobParams = new ArrayList<>();
private String accessTokenSecret;
@Editable(order=100, name="Project", description="Specify project to run job in")
@ChoiceProvider("getProjectChoices")
@NotEmpty
public String getProjectPath() {
return projectPath;
}
public void setProjectPath(String projectPath) {
this.projectPath = projectPath;
}
@SuppressWarnings("unused")
private static List<String> getProjectChoices() {
List<String> choices = new ArrayList<>();
Project currentProject = ((ProjectPage)WicketUtils.getPage()).getProject();
ProjectCache cache = getProjectService().cloneCache();
for (Project project: SecurityUtils.getAuthorizedProjects(new AccessProject())) {
if (!project.equals(currentProject))
choices.add(cache.get(project.getId()).getPath());
}
Collections.sort(choices);
return choices;
}
@Editable(order=200, description="Specify branch to run the job against. Either branch or tag can be specified, but not both. Default branch will be used if both not specified")
@Interpolative(variableSuggester="suggestVariables", literalSuggester="suggestBranches")
public String getBranch() {
return branch;
}
public void setBranch(String branch) {
this.branch = branch;
}
@Editable(order=200, description="Specify tag to run the job against. Either branch or tag can be specified, but not both. Default branch will be used if both not specified")
@Interpolative(variableSuggester="suggestVariables", literalSuggester="suggestTags")
public String getTag() {
return tag;
}
public void setTag(String tag) {
this.tag = tag;
}
@SuppressWarnings("unused")
private static List<InputSuggestion> suggestVariables(String matchWith) {
return BuildSpec.suggestVariables(matchWith, false, false, false);
}
@SuppressWarnings("unused")
private static List<InputSuggestion> suggestBranches(String matchWith) {
Project project = getInputProject();
if (project != null)
return SuggestionUtils.suggestBranches(project, matchWith);
else
return new ArrayList<>();
}
@SuppressWarnings("unused")
private static List<InputSuggestion> suggestTags(String matchWith) {
Project project = getInputProject();
if (project != null)
return SuggestionUtils.suggestTags(project, matchWith);
else
return new ArrayList<>();
}
@Editable(order=300, name="Job")
@ChoiceProvider("getJobChoices")
@NotEmpty
public String getJobName() {
return jobName;
}
public void setJobName(String jobName) {
this.jobName = jobName;
}
@Nullable
private static Project getInputProject() {
String projectPath = (String) EditContext.get().getInputValue("projectPath");
if (projectPath != null) {
Project project = getProjectService().findByPath(projectPath);
if (project != null && SecurityUtils.canReadCode(project))
return project;
}
return null;
}
@SuppressWarnings("unused")
private static List<String> getJobChoices() {
Project project = getInputProject();
List<String> jobNames = new ArrayList<>();
if (project != null) {
jobNames.addAll(getBuildService().getAccessibleJobNames(SecurityUtils.getSubject(), project));
Collections.sort(jobNames);
}
return jobNames;
}
@Editable(order=400, name="Job Parameters")
public List<JobParam> getJobParams() {
return jobParams;
}
public void setJobParams(List<JobParam> jobParams) {
this.jobParams = jobParams;
}
@Editable(order=500, placeholder="Access Anonymously", description="Specify a secret to be used as "
+ "access token to trigger job in above project")
@ChoiceProvider("getAccessTokenSecretChoices")
@NotEmpty
public String getAccessTokenSecret() {
return accessTokenSecret;
}
public void setAccessTokenSecret(String accessTokenSecret) {
this.accessTokenSecret = accessTokenSecret;
}
@SuppressWarnings("unused")
private static List<String> getAccessTokenSecretChoices() {
return Project.get().getHierarchyJobSecrets()
.stream().map(it->it.getName()).collect(Collectors.toList());
}
@Override
public void execute(Build build) {
Project project = getProjectService().findByPath(projectPath);
if (project == null)
throw new NotAcceptableException("Project not found: " + projectPath);
String secretValue = build.getJobAuthorizationContext().getSecretValue(accessTokenSecret);
var accessToken = getAccessTokenService().findByValue(secretValue);
if (accessToken == null)
throw new NotAcceptableException("Invalid access token");
var subject = accessToken.asSubject();
if (!SecurityUtils.canRunJob(subject, project, jobName))
throw new UnauthorizedException();
var user = SecurityUtils.getUser(subject);
ThreadContext.bind(subject);
try {
String refName;
if (branch != null) {
refName = GitUtils.branch2ref(branch);
} else if (tag != null) {
refName = GitUtils.tag2ref(tag);
} else {
var defaultBranch = project.getDefaultBranch();
if (defaultBranch == null)
throw new NotAcceptableException("No default branch in project: " + project.getPath());
refName = GitUtils.branch2ref(defaultBranch);
}
var commit = project.getRevCommit(refName, false);
if (commit == null)
throw new NotAcceptableException("Ref not found (project: " + project.getPath() + ", ref: " + refName + ")");
Map<String, List<String>> jobParamMap = new HashMap<>();
for (var jobParam: jobParams) {
jobParamMap.computeIfAbsent(jobParam.getName(), k -> new ArrayList<>()).add(jobParam.getValue());
}
getJobService().submit(user, project, commit.copy(), jobName, jobParamMap, refName, null, null,
"Triggered via post build action of job '" + build.getJobName() + "' in project '" + build.getProject().getPath() + "'");
} finally {
ThreadContext.unbindSubject();
}
}
@Override
public boolean isValid(ConstraintValidatorContext context) {
if (branch != null && tag != null) {
var errorMessage = "Either branch or tag can be specified, but not both";
context.buildConstraintViolationWithTemplate(errorMessage)
.addPropertyNode("branch").addConstraintViolation();
context.buildConstraintViolationWithTemplate(errorMessage)
.addPropertyNode("tag").addConstraintViolation();
return false;
} else {
return true;
}
}
@Override
public String getDescription() {
return "Run job '" + jobName + "' in project '" + projectPath + "'";
}
private static ProjectService getProjectService() {
return OneDev.getInstance(ProjectService.class);
}
private static AccessTokenService getAccessTokenService() {
return OneDev.getInstance(AccessTokenService.class);
}
private static JobService getJobService() {
return OneDev.getInstance(JobService.class);
}
private static BuildService getBuildService() {
return OneDev.getInstance(BuildService.class);
}
@Editable
public static class JobParam implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private String value;
@Editable(order=100)
@Interpolative(variableSuggester="suggestVariables")
@NotEmpty
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Editable(order=200)
@Interpolative(variableSuggester="suggestVariables")
@NotEmpty
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
@SuppressWarnings("unused")
private static List<InputSuggestion> suggestVariables(String matchWith) {
return BuildSpec.suggestVariables(matchWith, false, false, false);
}
}
}

View File

@ -14,7 +14,7 @@ import static io.onedev.server.model.Build.NAME_TAG;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.From;

View File

@ -1,6 +1,6 @@
package io.onedev.server.buildspec.job.action.condition;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.From;

View File

@ -3,7 +3,7 @@ package io.onedev.server.buildspec.job.action.condition;
import static io.onedev.server.buildspec.job.action.condition.ActionCondition.getRuleName;
import static io.onedev.server.model.Build.NAME_BRANCH;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.From;

View File

@ -3,7 +3,7 @@ package io.onedev.server.buildspec.job.action.condition;
import static io.onedev.server.buildspec.job.action.condition.ActionCondition.getRuleName;
import static io.onedev.server.model.Build.NAME_BRANCH;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.From;

View File

@ -1,6 +1,6 @@
package io.onedev.server.buildspec.job.action.condition;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.From;

View File

@ -1,6 +1,6 @@
package io.onedev.server.buildspec.job.action.condition;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.From;

View File

@ -2,14 +2,14 @@ package io.onedev.server.buildspec.job.action.condition;
import java.util.regex.Pattern;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.From;
import javax.persistence.criteria.Predicate;
import io.onedev.server.OneDev;
import io.onedev.server.job.log.LogManager;
import io.onedev.server.job.log.LogService;
import io.onedev.server.model.Build;
import io.onedev.server.util.ProjectScope;
import io.onedev.server.util.criteria.Criteria;
@ -32,7 +32,7 @@ public class LogCriteria extends Criteria<Build> {
@Override
public boolean matches(Build build) {
Pattern pattern = Pattern.compile(value);
return OneDev.getInstance(LogManager.class).matches(build, pattern);
return OneDev.getInstance(LogService.class).matches(build, pattern);
}
@Override

View File

@ -1,6 +1,6 @@
package io.onedev.server.buildspec.job.action.condition;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.From;

View File

@ -2,7 +2,7 @@ package io.onedev.server.buildspec.job.action.condition;
import java.util.List;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.From;

View File

@ -2,7 +2,7 @@ package io.onedev.server.buildspec.job.action.condition;
import java.util.List;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.From;

View File

@ -1,6 +1,6 @@
package io.onedev.server.buildspec.job.action.condition;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.From;

View File

@ -1,6 +1,6 @@
package io.onedev.server.buildspec.job.action.condition;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.From;

View File

@ -1,6 +1,6 @@
package io.onedev.server.buildspec.job.action.condition;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.From;

View File

@ -1,6 +1,6 @@
package io.onedev.server.buildspec.job.action.condition;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.From;

View File

@ -3,7 +3,7 @@ package io.onedev.server.buildspec.job.action.condition;
import static io.onedev.server.buildspec.job.action.condition.ActionCondition.getRuleName;
import static io.onedev.server.model.Build.NAME_PROJECT;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.From;

View File

@ -1,6 +1,6 @@
package io.onedev.server.buildspec.job.action.condition;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.From;

View File

@ -1,6 +1,6 @@
package io.onedev.server.buildspec.job.action.condition;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.From;

View File

@ -3,7 +3,7 @@ package io.onedev.server.buildspec.job.action.condition;
import static io.onedev.server.buildspec.job.action.condition.ActionCondition.getRuleName;
import static io.onedev.server.model.Build.NAME_TAG;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.From;

View File

@ -3,7 +3,7 @@ package io.onedev.server.buildspec.job.action.condition;
import static io.onedev.server.buildspec.job.action.condition.ActionCondition.getRuleName;
import static io.onedev.server.model.Build.NAME_TAG;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.From;

View File

@ -1,6 +1,6 @@
package io.onedev.server.buildspec.job.action.condition;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.From;

View File

@ -4,7 +4,7 @@ import java.util.Collection;
import java.util.HashSet;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
import org.antlr.v4.runtime.BailErrorStrategy;
import org.antlr.v4.runtime.BaseErrorListener;
@ -22,8 +22,8 @@ import io.onedev.commons.utils.ExplicitException;
import io.onedev.commons.utils.StringUtils;
import io.onedev.server.OneDev;
import io.onedev.server.buildspec.job.action.notificationreceiver.NotificationReceiverParser.CriteriaContext;
import io.onedev.server.entitymanager.GroupManager;
import io.onedev.server.entitymanager.UserManager;
import io.onedev.server.service.GroupService;
import io.onedev.server.service.UserService;
import io.onedev.server.model.Build;
import io.onedev.server.model.EmailAddress;
import io.onedev.server.model.Group;
@ -60,14 +60,14 @@ public class NotificationReceiver {
for (CriteriaContext criteria: parser.receiver().criteria()) {
if (criteria.userCriteria() != null) {
String userName = getValue(criteria.userCriteria().Value());
User user = OneDev.getInstance(UserManager.class).findByName(userName);
User user = OneDev.getInstance(UserService.class).findByName(userName);
if (user != null)
addEmailAddress(emailAddresses, user);
else
throw new ExplicitException("Unable to find user '" + userName + "'");
} else if (criteria.groupCriteria() != null) {
String groupName = getValue(criteria.groupCriteria().Value());
Group group = OneDev.getInstance(GroupManager.class).find(groupName);
Group group = OneDev.getInstance(GroupService.class).find(groupName);
if (group != null) {
emailAddresses.addAll(group.getMembers().stream()
.map(it->it.getPrimaryEmailAddress())

View File

@ -3,7 +3,7 @@ package io.onedev.server.buildspec.job.gitcredential;
import io.onedev.k8shelper.CloneInfo;
import io.onedev.k8shelper.DefaultCloneInfo;
import io.onedev.server.OneDev;
import io.onedev.server.web.UrlManager;
import io.onedev.server.web.UrlService;
import io.onedev.server.model.Build;
import io.onedev.server.annotation.Editable;
@ -14,7 +14,7 @@ public class DefaultCredential implements GitCredential {
@Override
public CloneInfo newCloneInfo(Build build, String jobToken) {
return new DefaultCloneInfo(OneDev.getInstance(UrlManager.class).cloneUrlFor(build.getProject(), false), jobToken);
return new DefaultCloneInfo(OneDev.getInstance(UrlService.class).cloneUrlFor(build.getProject(), false), jobToken);
}
}

View File

@ -10,7 +10,7 @@ import javax.validation.constraints.NotEmpty;
import io.onedev.k8shelper.CloneInfo;
import io.onedev.k8shelper.HttpCloneInfo;
import io.onedev.server.OneDev;
import io.onedev.server.web.UrlManager;
import io.onedev.server.web.UrlService;
import io.onedev.server.model.Build;
import io.onedev.server.model.Project;
import io.onedev.server.validation.Validatable;
@ -45,7 +45,7 @@ public class HttpCredential implements GitCredential, Validatable {
@Override
public CloneInfo newCloneInfo(Build build, String jobToken) {
return new HttpCloneInfo(OneDev.getInstance(UrlManager.class).cloneUrlFor(build.getProject(), false),
return new HttpCloneInfo(OneDev.getInstance(UrlService.class).cloneUrlFor(build.getProject(), false),
build.getJobAuthorizationContext().getSecretValue(accessTokenSecret));
}

View File

@ -14,8 +14,8 @@ import javax.validation.constraints.NotEmpty;
import io.onedev.k8shelper.CloneInfo;
import io.onedev.k8shelper.SshCloneInfo;
import io.onedev.server.OneDev;
import io.onedev.server.entitymanager.SettingManager;
import io.onedev.server.web.UrlManager;
import io.onedev.server.service.SettingService;
import io.onedev.server.web.UrlService;
import io.onedev.server.model.Build;
import io.onedev.server.model.Project;
import io.onedev.server.model.support.administration.SshSetting;
@ -52,10 +52,10 @@ public class SshCredential implements GitCredential, Validatable {
@Override
public CloneInfo newCloneInfo(Build build, String jobToken) {
String cloneUrl = OneDev.getInstance(UrlManager.class).cloneUrlFor(build.getProject(), true);
SettingManager settingManager = OneDev.getInstance(SettingManager.class);
SystemSetting systemSetting = settingManager.getSystemSetting();
SshSetting sshSetting = settingManager.getSshSetting();
String cloneUrl = OneDev.getInstance(UrlService.class).cloneUrlFor(build.getProject(), true);
SettingService settingService = OneDev.getInstance(SettingService.class);
SystemSetting systemSetting = settingService.getSystemSetting();
SshSetting sshSetting = settingService.getSshSetting();
StringBuilder knownHosts = new StringBuilder(systemSetting.getSshServerName()).append(" ");
try {
PublicKeyEntry.appendPublicKeyEntry(knownHosts,

View File

@ -5,7 +5,7 @@ import com.google.common.collect.Lists;
import io.onedev.server.job.log.StyleBuilder;
import io.onedev.server.web.asset.emoji.Emojis;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;

View File

@ -2,7 +2,7 @@ package io.onedev.server.buildspec.job.projectdependency;
import java.io.Serializable;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
import io.onedev.server.model.Build;
import io.onedev.server.model.Project;

View File

@ -7,13 +7,13 @@ import javax.validation.constraints.NotEmpty;
import edu.emory.mathcs.backport.java.util.Collections;
import io.onedev.server.OneDev;
import io.onedev.server.entitymanager.BuildManager;
import io.onedev.server.model.Build;
import io.onedev.server.model.Project;
import io.onedev.server.util.EditContext;
import io.onedev.server.annotation.ChoiceProvider;
import io.onedev.server.annotation.Editable;
import io.onedev.server.annotation.OmitName;
import io.onedev.server.model.Build;
import io.onedev.server.model.Project;
import io.onedev.server.security.SecurityUtils;
import io.onedev.server.service.BuildService;
import io.onedev.server.util.EditContext;
@Editable(order=100, name="Last Finished of Specified Job")
public class LastFinishedBuild implements BuildProvider {
@ -25,7 +25,6 @@ public class LastFinishedBuild implements BuildProvider {
private String refName;
@Editable(order=100)
@OmitName
@ChoiceProvider("getJobChoices")
@NotEmpty
public String getJobName() {
@ -51,7 +50,7 @@ public class LastFinishedBuild implements BuildProvider {
Project project = ProjectDependency.getInputProject(EditContext.get(1));
List<String> jobNames = new ArrayList<>();
if (project != null) {
jobNames.addAll(OneDev.getInstance(BuildManager.class).getAccessibleJobNames(project));
jobNames.addAll(OneDev.getInstance(BuildService.class).getAccessibleJobNames(SecurityUtils.getSubject(), project));
Collections.sort(jobNames);
}
return jobNames;
@ -59,7 +58,7 @@ public class LastFinishedBuild implements BuildProvider {
@Override
public Build getBuild(Project project) {
return OneDev.getInstance(BuildManager.class).findLastFinished(project, jobName, refName);
return OneDev.getInstance(BuildService.class).findLastFinished(project, jobName, refName);
}
@Override

View File

@ -8,7 +8,7 @@ import io.onedev.server.annotation.Editable;
import io.onedev.server.annotation.Interpolative;
import io.onedev.server.annotation.Patterns;
import io.onedev.server.buildspec.BuildSpec;
import io.onedev.server.entitymanager.ProjectManager;
import io.onedev.server.service.ProjectService;
import io.onedev.server.model.Project;
import io.onedev.server.security.SecurityUtils;
import io.onedev.server.security.permission.AccessProject;
@ -17,7 +17,7 @@ import io.onedev.server.util.facade.ProjectCache;
import io.onedev.server.web.page.project.ProjectPage;
import io.onedev.server.web.util.WicketUtils;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
@ -57,8 +57,8 @@ public class ProjectDependency implements Serializable {
List<String> choices = new ArrayList<>();
Project currentProject = ((ProjectPage)WicketUtils.getPage()).getProject();
ProjectManager projectManager = OneDev.getInstance(ProjectManager.class);
ProjectCache cache = projectManager.cloneCache();
ProjectService projectService = OneDev.getInstance(ProjectService.class);
ProjectCache cache = projectService.cloneCache();
for (Project project: SecurityUtils.getAuthorizedProjects(new AccessProject())) {
if (!project.equals(currentProject))
choices.add(cache.get(project.getId()).getPath());
@ -83,7 +83,7 @@ public class ProjectDependency implements Serializable {
static Project getInputProject(EditContext editContext) {
String projectPath = (String) editContext.getInputValue("projectPath");
if (projectPath != null) {
Project project = OneDev.getInstance(ProjectManager.class).findByPath(projectPath);
Project project = OneDev.getInstance(ProjectService.class).findByPath(projectPath);
if (project != null && SecurityUtils.canReadCode(project))
return project;
}

View File

@ -8,7 +8,7 @@ import javax.validation.constraints.NotEmpty;
import io.onedev.commons.codeassist.InputSuggestion;
import io.onedev.server.OneDev;
import io.onedev.server.buildspec.BuildSpec;
import io.onedev.server.entitymanager.BuildManager;
import io.onedev.server.service.BuildService;
import io.onedev.server.model.Build;
import io.onedev.server.model.Project;
import io.onedev.server.util.EditContext;
@ -59,7 +59,7 @@ public class SpecifiedBuild implements BuildProvider {
else
buildNumber = Long.parseLong(this.buildNumber);
return OneDev.getInstance(BuildManager.class).find(project, buildNumber);
return OneDev.getInstance(BuildService.class).find(project, buildNumber);
}
@Override

View File

@ -2,14 +2,14 @@ package io.onedev.server.buildspec.job.retrycondition;
import java.util.regex.Pattern;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.From;
import javax.persistence.criteria.Predicate;
import io.onedev.server.OneDev;
import io.onedev.server.job.log.LogManager;
import io.onedev.server.job.log.LogService;
import io.onedev.server.model.Build;
import io.onedev.server.util.ProjectScope;
import io.onedev.server.util.criteria.Criteria;
@ -33,7 +33,7 @@ public class LogCriteria extends Criteria<RetryContext> {
public boolean matches(RetryContext context) {
Pattern pattern = Pattern.compile(value);
return context.getErrorMessage() != null && pattern.matcher(context.getErrorMessage()).find()
|| OneDev.getInstance(LogManager.class).matches(context.getBuild(), pattern);
|| OneDev.getInstance(LogService.class).matches(context.getBuild(), pattern);
}
@Override

View File

@ -1,6 +1,6 @@
package io.onedev.server.buildspec.job.retrycondition;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.From;

View File

@ -2,7 +2,7 @@ package io.onedev.server.buildspec.job.retrycondition;
import java.util.List;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.From;

View File

@ -2,7 +2,7 @@ package io.onedev.server.buildspec.job.retrycondition;
import java.util.List;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.From;

View File

@ -10,7 +10,7 @@ import static io.onedev.server.model.Build.NAME_LOG;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.From;

View File

@ -2,7 +2,7 @@ package io.onedev.server.buildspec.job.retrycondition;
import io.onedev.server.model.Build;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
public class RetryContext {

View File

@ -17,7 +17,7 @@ import io.onedev.server.annotation.Patterns;
import io.onedev.server.annotation.UserMatch;
import io.onedev.server.buildspec.job.Job;
import io.onedev.server.buildspec.job.TriggerMatch;
import io.onedev.server.entitymanager.ProjectManager;
import io.onedev.server.service.ProjectService;
import io.onedev.server.event.project.ProjectEvent;
import io.onedev.server.event.project.RefUpdated;
import io.onedev.server.git.GitUtils;
@ -93,7 +93,7 @@ public class BranchUpdateTrigger extends JobTrigger {
} else if (refUpdated.getNewCommitId().equals(ObjectId.zeroId())) {
return false;
} else {
Repository repository = OneDev.getInstance(ProjectManager.class)
Repository repository = OneDev.getInstance(ProjectService.class)
.getRepository(refUpdated.getProject().getId());
Collection<String> changedFiles = GitUtils.getChangedFiles(
repository,

View File

@ -5,7 +5,7 @@ import io.onedev.server.annotation.ChoiceProvider;
import io.onedev.server.annotation.Editable;
import io.onedev.server.buildspec.job.Job;
import io.onedev.server.buildspec.job.TriggerMatch;
import io.onedev.server.entitymanager.SettingManager;
import io.onedev.server.service.SettingService;
import io.onedev.server.event.project.ProjectEvent;
import io.onedev.server.event.project.issue.IssueChanged;
import io.onedev.server.event.project.issue.IssueOpened;
@ -16,7 +16,7 @@ import io.onedev.server.model.support.issue.changedata.IssueStateChangeData;
import io.onedev.server.search.entity.issue.IssueQuery;
import io.onedev.server.search.entity.issue.IssueQueryParseOption;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
import javax.validation.constraints.NotEmpty;
import java.util.List;
@ -42,7 +42,7 @@ public class IssueInStateTrigger extends JobTrigger {
@SuppressWarnings("unused")
private static List<String> getStateChoices() {
return OneDev.getInstance(SettingManager.class).getIssueSetting()
return OneDev.getInstance(SettingService.class).getIssueSetting()
.getStateSpecs().stream().map(StateSpec::getName).collect(toList());
}

View File

@ -20,7 +20,7 @@ import io.onedev.server.web.util.WicketUtils;
import org.apache.wicket.Component;
import org.eclipse.jgit.revwalk.RevCommit;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
import javax.validation.Valid;
import java.io.Serializable;
import java.util.ArrayList;

View File

@ -5,7 +5,7 @@ import io.onedev.server.OneDev;
import io.onedev.server.annotation.Editable;
import io.onedev.server.annotation.Patterns;
import io.onedev.server.buildspec.job.TriggerMatch;
import io.onedev.server.entitymanager.ProjectManager;
import io.onedev.server.service.ProjectService;
import io.onedev.server.git.GitUtils;
import io.onedev.server.model.Project;
import io.onedev.server.model.PullRequest;
@ -15,7 +15,7 @@ import io.onedev.server.util.patternset.PatternSet;
import io.onedev.server.web.util.SuggestionUtils;
import org.eclipse.jgit.lib.Repository;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
import java.util.Collection;
import java.util.List;
@ -65,7 +65,7 @@ public abstract class PullRequestTrigger extends JobTrigger {
private boolean touchedFile(PullRequest request) {
if (getPaths() != null) {
Repository repository = OneDev.getInstance(ProjectManager.class)
Repository repository = OneDev.getInstance(ProjectService.class)
.getRepository(request.getTargetProject().getId());
Collection<String> changedFiles = GitUtils.getChangedFiles(repository,
request.getBaseCommit(), request.getLatestUpdate().getHeadCommit());

View File

@ -17,7 +17,7 @@ import org.apache.commons.lang.SerializationUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
import javax.validation.ValidationException;
import java.io.Serializable;
import java.util.*;

View File

@ -4,7 +4,7 @@ import io.onedev.server.annotation.Editable;
import io.onedev.server.buildspec.param.ParamCombination;
import io.onedev.server.model.Build;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
import java.io.Serializable;
import java.util.List;

View File

@ -3,7 +3,7 @@ package io.onedev.server.buildspec.param.instance;
import java.io.Serializable;
import java.util.List;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
import io.onedev.server.buildspec.param.ParamCombination;
import io.onedev.server.model.Build;

View File

@ -2,7 +2,7 @@ package io.onedev.server.buildspec.param.spec;
import java.util.List;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
import javax.validation.Valid;
import io.onedev.server.annotation.Multiline;

View File

@ -119,6 +119,10 @@ public class BuildImageWithKanikoStep extends CommandStep {
this.moreOptions = moreOptions;
}
static List<InputSuggestion> suggestVariables(String matchWith) {
return BuildSpec.suggestVariables(matchWith, true, true, false);
}
@Override
public Interpreter getInterpreter() {
return new DefaultInterpreter() {

View File

@ -8,11 +8,11 @@ import io.onedev.server.annotation.ChoiceProvider;
import io.onedev.server.annotation.Editable;
import io.onedev.server.annotation.Interpolative;
import io.onedev.server.buildspec.BuildSpec;
import io.onedev.server.entitymanager.BuildManager;
import io.onedev.server.entitymanager.IterationManager;
import io.onedev.server.service.BuildService;
import io.onedev.server.service.IterationService;
import io.onedev.server.model.Iteration;
import io.onedev.server.model.Project;
import io.onedev.server.persistence.TransactionManager;
import io.onedev.server.persistence.TransactionService;
import javax.validation.constraints.NotEmpty;
import java.io.File;
@ -63,16 +63,16 @@ public class CloseIterationStep extends ServerSideStep {
@Override
public ServerStepResult run(Long buildId, File inputDir, TaskLogger logger) {
return OneDev.getInstance(TransactionManager.class).call(() -> {
var build = OneDev.getInstance(BuildManager.class).load(buildId);
return OneDev.getInstance(TransactionService.class).call(() -> {
var build = OneDev.getInstance(BuildService.class).load(buildId);
Project project = build.getProject();
String iterationName = getIterationName();
IterationManager iterationManager = OneDev.getInstance(IterationManager.class);
Iteration iteration = iterationManager.findInHierarchy(project, iterationName);
IterationService iterationService = OneDev.getInstance(IterationService.class);
Iteration iteration = iterationService.findInHierarchy(project, iterationName);
if (iteration != null) {
if (build.canCloseIteration(getAccessTokenSecret())) {
iteration.setClosed(true);
iterationManager.createOrUpdate(iteration);
iterationService.createOrUpdate(iteration);
} else {
logger.error("This build is not authorized to close iteration '" + iterationName + "'");
return new ServerStepResult(false);

View File

@ -71,6 +71,12 @@ public class CommandStep extends Step {
}
static List<InputSuggestion> suggestVariables(String matchWith) {
/*
* We do not support dynamic variable here as:
* 1. @file:@ notion will not work for workspace files generated in current step
* 2. It is very easy to use file content in shell script via shell utilities
* in regardless the file is generated in current or previous steps
*/
return BuildSpec.suggestVariables(matchWith, false, false, false);
}

View File

@ -1,20 +1,22 @@
package io.onedev.server.buildspec.step;
import static io.onedev.agent.DockerExecutorUtils.buildDockerConfig;
import static io.onedev.k8shelper.RegistryLoginFacade.merge;
import java.util.List;
import java.util.Map;
import io.onedev.commons.codeassist.InputSuggestion;
import io.onedev.k8shelper.CommandFacade;
import io.onedev.k8shelper.RegistryLoginFacade;
import io.onedev.server.annotation.Editable;
import io.onedev.server.annotation.Interpolative;
import io.onedev.server.annotation.Multiline;
import io.onedev.server.buildspec.BuildSpec;
import io.onedev.server.buildspec.step.commandinterpreter.DefaultInterpreter;
import io.onedev.server.buildspec.step.commandinterpreter.Interpreter;
import io.onedev.server.model.support.administration.jobexecutor.JobExecutor;
import io.onedev.server.model.support.administration.jobexecutor.DockerAware;
import java.util.List;
import java.util.Map;
import static io.onedev.agent.DockerExecutorUtils.buildDockerConfig;
import static io.onedev.k8shelper.RegistryLoginFacade.merge;
import io.onedev.server.model.support.administration.jobexecutor.JobExecutor;
public abstract class CraneStep extends CommandStep {
@ -70,6 +72,10 @@ public abstract class CraneStep extends CommandStep {
super.setRegistryLogins(registryLogins);
}
static List<InputSuggestion> suggestVariables(String matchWith) {
return BuildSpec.suggestVariables(matchWith, true, true, false);
}
@Override
public Interpreter getInterpreter() {
return new DefaultInterpreter() {

View File

@ -10,12 +10,12 @@ import io.onedev.server.annotation.ChoiceProvider;
import io.onedev.server.annotation.Editable;
import io.onedev.server.annotation.Interpolative;
import io.onedev.server.buildspec.BuildSpec;
import io.onedev.server.entitymanager.BuildManager;
import io.onedev.server.service.BuildService;
import io.onedev.server.git.GitUtils;
import io.onedev.server.git.service.GitService;
import io.onedev.server.git.service.RefFacade;
import io.onedev.server.model.Project;
import io.onedev.server.persistence.SessionManager;
import io.onedev.server.persistence.SessionService;
import io.onedev.server.web.util.SuggestionUtils;
import org.eclipse.jgit.lib.Repository;
@ -93,8 +93,8 @@ public class CreateBranchStep extends ServerSideStep {
@Override
public ServerStepResult run(Long buildId, File inputDir, TaskLogger logger) {
return OneDev.getInstance(SessionManager.class).call(() -> {
var build = OneDev.getInstance(BuildManager.class).load(buildId);
return OneDev.getInstance(SessionService.class).call(() -> {
var build = OneDev.getInstance(BuildService.class).load(buildId);
Project project = build.getProject();
String branchName = getBranchName();

View File

@ -7,14 +7,14 @@ import io.onedev.k8shelper.ServerStepResult;
import io.onedev.server.OneDev;
import io.onedev.server.annotation.*;
import io.onedev.server.buildspec.BuildSpec;
import io.onedev.server.entitymanager.BuildManager;
import io.onedev.server.entitymanager.ProjectManager;
import io.onedev.server.entitymanager.UserManager;
import io.onedev.server.service.BuildService;
import io.onedev.server.service.ProjectService;
import io.onedev.server.service.UserService;
import io.onedev.server.git.GitUtils;
import io.onedev.server.git.service.GitService;
import io.onedev.server.git.service.RefFacade;
import io.onedev.server.model.Project;
import io.onedev.server.persistence.SessionManager;
import io.onedev.server.persistence.SessionService;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.Repository;
@ -81,9 +81,9 @@ public class CreateTagStep extends ServerSideStep {
@Override
public ServerStepResult run(Long buildId, File inputDir, TaskLogger logger) {
return OneDev.getInstance(SessionManager.class).call(() -> {
var build = OneDev.getInstance(BuildManager.class).load(buildId);
PersonIdent taggerIdent = OneDev.getInstance(UserManager.class).getSystem().asPerson();
return OneDev.getInstance(SessionService.class).call(() -> {
var build = OneDev.getInstance(BuildService.class).load(buildId);
PersonIdent taggerIdent = OneDev.getInstance(UserService.class).getSystem().asPerson();
Project project = build.getProject();
String tagName = getTagName();
@ -95,7 +95,7 @@ public class CreateTagStep extends ServerSideStep {
if (build.canCreateTag(getAccessTokenSecret(), tagName)) {
RefFacade tagRef = project.getTagRef(tagName);
if (tagRef != null)
OneDev.getInstance(ProjectManager.class).deleteTag(project, tagName);
OneDev.getInstance(ProjectService.class).deleteTag(project, tagName);
OneDev.getInstance(GitService.class).createTag(project, tagName, build.getCommitHash(),
taggerIdent, getTagMessage(), false);
} else {

View File

@ -1,15 +1,18 @@
package io.onedev.server.buildspec.step;
import io.onedev.server.annotation.Editable;
import io.onedev.server.annotation.Interpolative;
import io.onedev.server.buildspec.step.commandinterpreter.Interpreter;
import io.onedev.server.buildspec.step.commandinterpreter.ShellInterpreter;
import static io.onedev.server.buildspec.step.StepGroup.UTILITIES;
import javax.validation.constraints.NotEmpty;
import java.util.ArrayList;
import java.util.List;
import static io.onedev.server.buildspec.step.StepGroup.UTILITIES;
import javax.validation.constraints.NotEmpty;
import io.onedev.commons.codeassist.InputSuggestion;
import io.onedev.server.annotation.Editable;
import io.onedev.server.annotation.Interpolative;
import io.onedev.server.buildspec.BuildSpec;
import io.onedev.server.buildspec.step.commandinterpreter.Interpreter;
import io.onedev.server.buildspec.step.commandinterpreter.ShellInterpreter;
@Editable(order=1110, group = UTILITIES, name="Generate File Checksum", description = "" +
"This step can only be executed by a docker aware executor")
@ -45,6 +48,10 @@ public class GenerateChecksumStep extends CommandStep {
this.targetFile = targetFile;
}
static List<InputSuggestion> suggestVariables(String matchWith) {
return BuildSpec.suggestVariables(matchWith, true, true, false);
}
@Override
public boolean isRunInContainer() {
return true;

View File

@ -6,15 +6,15 @@ import io.onedev.commons.utils.LockUtils;
import io.onedev.commons.utils.TaskLogger;
import io.onedev.k8shelper.ServerStepResult;
import io.onedev.server.OneDev;
import io.onedev.server.StorageManager;
import io.onedev.server.StorageService;
import io.onedev.server.annotation.Editable;
import io.onedev.server.annotation.Interpolative;
import io.onedev.server.annotation.Patterns;
import io.onedev.server.annotation.SubPath;
import io.onedev.server.buildspec.BuildSpec;
import io.onedev.server.entitymanager.BuildManager;
import io.onedev.server.entitymanager.ProjectManager;
import io.onedev.server.persistence.SessionManager;
import io.onedev.server.service.BuildService;
import io.onedev.server.service.ProjectService;
import io.onedev.server.persistence.SessionService;
import io.onedev.server.util.patternset.PatternSet;
import javax.validation.constraints.NotEmpty;
@ -71,13 +71,13 @@ public class PublishArtifactStep extends ServerSideStep {
@Override
public ServerStepResult run(Long buildId, File inputDir, TaskLogger jobLogger) {
return OneDev.getInstance(SessionManager.class).call(() -> {
var build = OneDev.getInstance(BuildManager.class).load(buildId);
return OneDev.getInstance(SessionService.class).call(() -> {
var build = OneDev.getInstance(BuildService.class).load(buildId);
return LockUtils.write(build.getArtifactsLockName(), () -> {
var projectId = build.getProject().getId();
var artifactsDir = OneDev.getInstance(StorageManager.class).initArtifactsDir(projectId, build.getNumber());
var artifactsDir = OneDev.getInstance(StorageService.class).initArtifactsDir(projectId, build.getNumber());
FileUtils.copyDirectory(inputDir, artifactsDir);
OneDev.getInstance(ProjectManager.class).directoryModified(projectId, artifactsDir);
OneDev.getInstance(ProjectService.class).directoryModified(projectId, artifactsDir);
return new ServerStepResult(true);
});
});

View File

@ -20,13 +20,13 @@ import io.onedev.server.annotation.Patterns;
import io.onedev.server.annotation.ProjectChoice;
import io.onedev.server.annotation.SubPath;
import io.onedev.server.buildspec.BuildSpec;
import io.onedev.server.entitymanager.BuildManager;
import io.onedev.server.entitymanager.ProjectManager;
import io.onedev.server.entitymanager.SettingManager;
import io.onedev.server.service.BuildService;
import io.onedev.server.service.ProjectService;
import io.onedev.server.service.SettingService;
import io.onedev.server.job.JobContext;
import io.onedev.server.job.JobManager;
import io.onedev.server.job.JobService;
import io.onedev.server.model.Project;
import io.onedev.server.persistence.SessionManager;
import io.onedev.server.persistence.SessionService;
import io.onedev.server.util.patternset.PatternSet;
@Editable(order=1060, name="Site", group = PUBLISH, description="This step publishes specified files to be served as project web site. "
@ -92,13 +92,13 @@ public class PublishSiteStep extends ServerSideStep {
@Override
public ServerStepResult run(Long buildId, File inputDir, TaskLogger logger) {
return OneDev.getInstance(SessionManager.class).call(() -> {
var build = OneDev.getInstance(BuildManager.class).load(buildId);
JobContext jobContext = OneDev.getInstance(JobManager.class).getJobContext(build.getId());
return OneDev.getInstance(SessionService.class).call(() -> {
var build = OneDev.getInstance(BuildService.class).load(buildId);
JobContext jobContext = OneDev.getInstance(JobService.class).getJobContext(build.getId());
if (jobContext.getJobExecutor().isSitePublishEnabled()) {
Project project;
if (projectPath != null) {
project = OneDev.getInstance(ProjectManager.class).findByPath(projectPath);
project = OneDev.getInstance(ProjectService.class).findByPath(projectPath);
if (project == null) {
logger.error("Unable to find project: " + projectPath);
return new ServerStepResult(false);
@ -108,13 +108,13 @@ public class PublishSiteStep extends ServerSideStep {
}
var projectId = project.getId();
LockUtils.write(project.getSiteLockName(), () -> {
File projectSiteDir = OneDev.getInstance(ProjectManager.class).getSiteDir(projectId);
File projectSiteDir = OneDev.getInstance(ProjectService.class).getSiteDir(projectId);
FileUtils.cleanDir(projectSiteDir);
FileUtils.copyDirectory(inputDir, projectSiteDir);
OneDev.getInstance(ProjectManager.class).directoryModified(projectId, projectSiteDir);
OneDev.getInstance(ProjectService.class).directoryModified(projectId, projectSiteDir);
return null;
});
String serverUrl = OneDev.getInstance(SettingManager.class).getSystemSetting().getServerUrl();
String serverUrl = OneDev.getInstance(SettingService.class).getSystemSetting().getServerUrl();
logger.log("Site published as "
+ StringUtils.stripEnd(serverUrl, "/") + "/" + project.getPath() + "/~site");
} else {

View File

@ -14,7 +14,7 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
import javax.validation.constraints.NotEmpty;
import org.eclipse.jgit.lib.AnyObjectId;
@ -45,9 +45,9 @@ import io.onedev.server.annotation.Interpolative;
import io.onedev.server.annotation.ProjectChoice;
import io.onedev.server.buildspec.BuildSpec;
import io.onedev.server.cluster.ClusterTask;
import io.onedev.server.entitymanager.BuildManager;
import io.onedev.server.entitymanager.ProjectManager;
import io.onedev.server.entitymanager.UserManager;
import io.onedev.server.service.BuildService;
import io.onedev.server.service.ProjectService;
import io.onedev.server.service.UserService;
import io.onedev.server.event.ListenerRegistry;
import io.onedev.server.event.project.RefUpdated;
import io.onedev.server.git.CommandUtils;
@ -57,7 +57,7 @@ import io.onedev.server.git.command.LfsFetchCommand;
import io.onedev.server.git.service.RefFacade;
import io.onedev.server.model.Project;
import io.onedev.server.model.User;
import io.onedev.server.persistence.SessionManager;
import io.onedev.server.persistence.SessionService;
import io.onedev.server.security.SecurityUtils;
@Editable(order=1070, name="Pull from Remote", group=StepGroup.REPOSITORY_SYNC, description=""
@ -139,12 +139,12 @@ public class PullRepository extends SyncRepository {
@Override
public ServerStepResult run(Long buildId, File inputDir, TaskLogger logger) {
return OneDev.getInstance(SessionManager.class).call(() -> {
var build = OneDev.getInstance(BuildManager.class).load(buildId);
return OneDev.getInstance(SessionService.class).call(() -> {
var build = OneDev.getInstance(BuildService.class).load(buildId);
Project project = build.getProject();
Project targetProject;
if (getTargetProject() != null) {
targetProject = getProjectManager().findByPath(getTargetProject());
targetProject = getProjectService().findByPath(getTargetProject());
if (targetProject == null)
throw new ExplicitException("Target project not found: " + getTargetProject());
} else {
@ -171,17 +171,17 @@ public class PullRepository extends SyncRepository {
String remoteUrl = getRemoteUrlWithCredential(build);
Long targetProjectId = targetProject.getId();
var task = new PullTask(targetProjectId, userId, remoteUrl, getCertificate(), getRefs(), isForce(), isWithLfs(), getProxy(), build.getSecretMasker());
getProjectManager().runOnActiveServer(targetProjectId, task);
getProjectService().runOnActiveServer(targetProjectId, task);
return new ServerStepResult(true);
});
}
private static ProjectManager getProjectManager() {
return OneDev.getInstance(ProjectManager.class);
private static ProjectService getProjectService() {
return OneDev.getInstance(ProjectService.class);
}
private static UserManager getUserManager() {
return OneDev.getInstance(UserManager.class);
private static UserService getUserService() {
return OneDev.getInstance(UserService.class);
}
private static class PullTask implements ClusterTask<Void> {
@ -242,7 +242,7 @@ public class PullRepository extends SyncRepository {
var certificateFile = writeCertificate(certificate);
SecretMasker.push(secretMasker);
try {
Repository repository = getProjectManager().getRepository(projectId);
Repository repository = getProjectService().getRepository(projectId);
String defaultBranch = GitUtils.getDefaultBranch(repository);
Map<String, ObjectId> oldCommitIds = getRefCommits(repository);
@ -361,7 +361,7 @@ public class PullRepository extends SyncRepository {
git.clearArgs();
configureProxy(git, proxy);
configureCertificate(git, certificateFile);
var sinceCommitIds = getProjectManager().readLfsSinceCommits(projectId);
var sinceCommitIds = getProjectService().readLfsSinceCommits(projectId);
if (sinceCommitIds.isEmpty()) {
new LfsFetchAllCommand(git.workingDir(), remoteUrl) {
@ -379,15 +379,15 @@ public class PullRepository extends SyncRepository {
}
}.run();
}
getProjectManager().writeLfsSinceCommits(projectId, newCommitIds.values());
getProjectService().writeLfsSinceCommits(projectId, newCommitIds.values());
}
OneDev.getInstance(SessionManager.class).runAsync(() -> {
OneDev.getInstance(SessionService.class).runAsync(() -> {
try {
// Access db connection in a separate thread to avoid possible deadlock, as
// the parent thread is blocking another thread holding database connections
var project = getProjectManager().load(projectId);
var user = getUserManager().load(userId);
var project = getProjectService().load(projectId);
var user = getUserService().load(userId);
MapDifference<String, ObjectId> difference = difference(oldCommitIds, newCommitIds);
ListenerRegistry registry = OneDev.getInstance(ListenerRegistry.class);
for (Map.Entry<String, ObjectId> entry : difference.entriesOnlyOnLeft().entrySet()) {

View File

@ -16,12 +16,12 @@ import io.onedev.commons.utils.command.LineConsumer;
import io.onedev.k8shelper.ServerStepResult;
import io.onedev.server.OneDev;
import io.onedev.server.annotation.Editable;
import io.onedev.server.entitymanager.BuildManager;
import io.onedev.server.entitymanager.ProjectManager;
import io.onedev.server.service.BuildService;
import io.onedev.server.service.ProjectService;
import io.onedev.server.git.CommandUtils;
import io.onedev.server.git.GitUtils;
import io.onedev.server.model.Project;
import io.onedev.server.persistence.SessionManager;
import io.onedev.server.persistence.SessionService;
@Editable(order=1080, name="Push to Remote", group=StepGroup.REPOSITORY_SYNC,
description="This step pushes current commit to same ref on remote")
@ -31,15 +31,15 @@ public class PushRepository extends SyncRepository {
@Override
public ServerStepResult run(Long buildId, File inputDir, TaskLogger logger) {
return OneDev.getInstance(SessionManager.class).call(() -> {
var build = OneDev.getInstance(BuildManager.class).load(buildId);
return OneDev.getInstance(SessionService.class).call(() -> {
var build = OneDev.getInstance(BuildService.class).load(buildId);
var certificateFile = writeCertificate(getCertificate());
SecretMasker.push(build.getSecretMasker());
try {
if (OneDev.getInstance(ProjectManager.class).hasLfsObjects(build.getProject().getId())) {
if (OneDev.getInstance(ProjectService.class).hasLfsObjects(build.getProject().getId())) {
Project project = build.getProject();
Commandline git = CommandUtils.newGit();
git.workingDir(OneDev.getInstance(ProjectManager.class).getGitDir(project.getId()));
git.workingDir(OneDev.getInstance(ProjectService.class).getGitDir(project.getId()));
configureProxy(git, getProxy());
configureCertificate(git, certificateFile);
@ -89,7 +89,7 @@ public class PushRepository extends SyncRepository {
}).checkReturnCode();
Repository repository = OneDev.getInstance(ProjectManager.class)
Repository repository = OneDev.getInstance(ProjectService.class)
.getRepository(project.getId());
String mergeBaseId = GitUtils.getMergeBase(repository,
ObjectId.fromString(remoteCommitId.get()), build.getCommitId()).name();
@ -143,7 +143,7 @@ public class PushRepository extends SyncRepository {
Commandline git = CommandUtils.newGit();
configureProxy(git, getProxy());
configureCertificate(git, certificateFile);
git.workingDir(OneDev.getInstance(ProjectManager.class).getGitDir(build.getProject().getId()));
git.workingDir(OneDev.getInstance(ProjectService.class).getGitDir(build.getProject().getId()));
git.addArgs("push");
if (isForce())
git.addArgs("--force");

View File

@ -7,7 +7,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
@ -142,7 +142,7 @@ public class RunContainerStep extends Step {
}
static List<InputSuggestion> suggestVariables(String matchWith) {
return BuildSpec.suggestVariables(matchWith, false, false, false);
return BuildSpec.suggestVariables(matchWith, true, true, false);
}
@Override

View File

@ -1,20 +1,23 @@
package io.onedev.server.buildspec.step;
import io.onedev.commons.utils.StringUtils;
import io.onedev.server.annotation.ChoiceProvider;
import io.onedev.server.annotation.Editable;
import io.onedev.server.annotation.Interpolative;
import io.onedev.server.buildspec.step.commandinterpreter.DefaultInterpreter;
import io.onedev.server.buildspec.step.commandinterpreter.Interpreter;
import io.onedev.server.model.Build;
import io.onedev.server.model.Project;
import static io.onedev.server.buildspec.step.StepGroup.UTILITIES;
import javax.validation.constraints.NotEmpty;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import static io.onedev.server.buildspec.step.StepGroup.UTILITIES;
import javax.validation.constraints.NotEmpty;
import io.onedev.commons.codeassist.InputSuggestion;
import io.onedev.commons.utils.StringUtils;
import io.onedev.server.annotation.ChoiceProvider;
import io.onedev.server.annotation.Editable;
import io.onedev.server.annotation.Interpolative;
import io.onedev.server.buildspec.BuildSpec;
import io.onedev.server.buildspec.step.commandinterpreter.DefaultInterpreter;
import io.onedev.server.buildspec.step.commandinterpreter.Interpreter;
import io.onedev.server.model.Build;
import io.onedev.server.model.Project;
@Editable(order=1100, group = UTILITIES, name="Copy Files with SCP", description = "" +
"This step can only be executed by a docker aware executor. It runs under <a href='https://docs.onedev.io/concepts#job-workspace' target='_blank'>job workspace</a>")
@ -82,6 +85,10 @@ public class SCPCommandStep extends CommandStep {
this.options = options;
}
static List<InputSuggestion> suggestVariables(String matchWith) {
return BuildSpec.suggestVariables(matchWith, true, true, false);
}
@Editable
@Override
public boolean isRunInContainer() {

View File

@ -1,22 +1,25 @@
package io.onedev.server.buildspec.step;
import static io.onedev.server.buildspec.step.StepGroup.UTILITIES;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import javax.validation.constraints.NotEmpty;
import io.onedev.commons.codeassist.InputSuggestion;
import io.onedev.commons.utils.StringUtils;
import io.onedev.server.annotation.ChoiceProvider;
import io.onedev.server.annotation.Code;
import io.onedev.server.annotation.Editable;
import io.onedev.server.annotation.Interpolative;
import io.onedev.server.buildspec.BuildSpec;
import io.onedev.server.buildspec.step.commandinterpreter.DefaultInterpreter;
import io.onedev.server.buildspec.step.commandinterpreter.Interpreter;
import io.onedev.server.model.Build;
import io.onedev.server.model.Project;
import javax.validation.constraints.NotEmpty;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import static io.onedev.server.buildspec.step.StepGroup.UTILITIES;
@Editable(order=1090, group = UTILITIES, name="Execute Commands via SSH", description = "" +
"This step can only be executed by a docker aware executor")
public class SSHCommandStep extends CommandStep {
@ -84,11 +87,15 @@ public class SSHCommandStep extends CommandStep {
this.options = options;
}
static List<InputSuggestion> suggestVariables(String matchWith) {
return BuildSpec.suggestVariables(matchWith, true, true, false);
}
@Editable(order=300, description="Specify commands to be executed on remote machine. " +
"<b class='text-warning'>Note:</b> user environments will not be picked up when execute these " +
"commands, set up them explicitly in commands if necessary")
@Interpolative
@Code(language=Code.SHELL, variableProvider="suggestVariables")
@Code(language=Code.SHELL, variableProvider="suggestStaticVariables")
@NotEmpty
public String getCommands() {
return commands;
@ -98,6 +105,10 @@ public class SSHCommandStep extends CommandStep {
this.commands = commands;
}
static List<InputSuggestion> suggestStaticVariables(String matchWith) {
return BuildSpec.suggestVariables(matchWith, true, false, false);
}
@Editable
@Override
public boolean isRunInContainer() {

View File

@ -4,7 +4,7 @@ import java.io.File;
import java.util.Collection;
import java.util.HashSet;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
import io.onedev.commons.utils.TaskLogger;
import io.onedev.k8shelper.KubernetesHelper;

View File

@ -8,10 +8,10 @@ import io.onedev.server.annotation.Editable;
import io.onedev.server.annotation.Interpolative;
import io.onedev.server.annotation.Markdown;
import io.onedev.server.buildspec.BuildSpec;
import io.onedev.server.entitymanager.BuildManager;
import io.onedev.server.service.BuildService;
import io.onedev.server.event.ListenerRegistry;
import io.onedev.server.event.project.build.BuildUpdated;
import io.onedev.server.persistence.TransactionManager;
import io.onedev.server.persistence.TransactionService;
import javax.validation.constraints.NotEmpty;
import java.io.File;
@ -43,8 +43,8 @@ public class SetBuildDescriptionStep extends ServerSideStep {
@Override
public ServerStepResult run(Long buildId, File inputDir, TaskLogger jobLogger) {
return OneDev.getInstance(TransactionManager.class).call(() -> {
var build = OneDev.getInstance(BuildManager.class).load(buildId);
return OneDev.getInstance(TransactionService.class).call(() -> {
var build = OneDev.getInstance(BuildService.class).load(buildId);
build.setDescription(buildDescription);
OneDev.getInstance(ListenerRegistry.class).post(new BuildUpdated(build));
return new ServerStepResult(true);

View File

@ -7,10 +7,10 @@ import io.onedev.server.OneDev;
import io.onedev.server.annotation.Editable;
import io.onedev.server.annotation.Interpolative;
import io.onedev.server.buildspec.BuildSpec;
import io.onedev.server.entitymanager.BuildManager;
import io.onedev.server.service.BuildService;
import io.onedev.server.event.ListenerRegistry;
import io.onedev.server.event.project.build.BuildUpdated;
import io.onedev.server.persistence.TransactionManager;
import io.onedev.server.persistence.TransactionService;
import javax.validation.constraints.NotEmpty;
import java.io.File;
@ -46,8 +46,8 @@ public class SetBuildVersionStep extends ServerSideStep {
@Override
public ServerStepResult run(Long buildId, File inputDir, TaskLogger logger) {
return OneDev.getInstance(TransactionManager.class).call(() -> {
var build = OneDev.getInstance(BuildManager.class).load(buildId);
return OneDev.getInstance(TransactionService.class).call(() -> {
var build = OneDev.getInstance(BuildService.class).load(buildId);
build.setVersion(buildVersion);
OneDev.getInstance(ListenerRegistry.class).post(new BuildUpdated(build));
Map<String, byte[]> outputFiles = new HashMap<>();

View File

@ -10,7 +10,7 @@ import io.onedev.server.buildspec.BuildSpec;
import io.onedev.server.model.Build;
import io.onedev.server.model.Project;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
import javax.validation.constraints.NotEmpty;
import java.io.File;
import java.io.UnsupportedEncodingException;

View File

@ -45,7 +45,7 @@ public class VolumeMount implements Serializable {
@SuppressWarnings("unused")
private static List<InputSuggestion> suggestVariables(String matchWith) {
return BuildSpec.suggestVariables(matchWith, false, false, false);
return BuildSpec.suggestVariables(matchWith, true, true, false);
}
}

View File

@ -7,7 +7,7 @@ import io.onedev.server.annotation.Editable;
import io.onedev.server.buildspec.BuildSpec;
import io.onedev.server.model.support.administration.jobexecutor.JobExecutor;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
import java.io.Serializable;
import java.util.List;
import java.util.Map;

View File

@ -3,7 +3,7 @@ package io.onedev.server.buildspecmodel.inputspec;
import java.io.Serializable;
import java.util.List;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
import javax.validation.ValidationException;
import org.apache.commons.lang3.builder.EqualsBuilder;

View File

@ -2,7 +2,7 @@ package io.onedev.server.buildspecmodel.inputspec;
import java.util.List;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
import io.onedev.server.util.ComponentContext;
import io.onedev.server.web.util.WicketUtils;

View File

@ -6,7 +6,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
import io.onedev.server.buildspecmodel.inputspec.choiceinput.choiceprovider.ChoiceProvider;
import io.onedev.server.buildspecmodel.inputspec.showcondition.ShowCondition;

View File

@ -8,7 +8,7 @@ import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
import javax.validation.ConstraintValidatorContext;
import javax.validation.constraints.Size;

View File

@ -5,7 +5,7 @@ import java.util.List;
import edu.emory.mathcs.backport.java.util.Collections;
import io.onedev.server.OneDev;
import io.onedev.server.entitymanager.GroupManager;
import io.onedev.server.service.GroupService;
import io.onedev.server.model.Group;
import io.onedev.server.annotation.Editable;
@ -16,7 +16,7 @@ public class AllGroups implements ChoiceProvider {
@Override
public List<Group> getChoices(boolean allPossible) {
List<Group> groups = OneDev.getInstance(GroupManager.class).query();
List<Group> groups = OneDev.getInstance(GroupService.class).query();
Collections.sort(groups, new Comparator<Group>() {
@Override

Some files were not shown because too many files have changed in this diff Show More