blob: 94c893f62f1b27bb2d9f8fdf3f465fe9027a2711 [file] [log] [blame]
// Copyright (C) 2025 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.server.restapi.flow;
import com.google.common.annotations.VisibleForTesting;
import com.google.gerrit.extensions.common.FlowInfo;
import com.google.gerrit.extensions.common.FlowInput;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.extensions.restapi.MethodNotAllowedException;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.extensions.restapi.Response;
import com.google.gerrit.extensions.restapi.RestCollectionModifyView;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.change.ChangeResource;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.flow.Flow;
import com.google.gerrit.server.flow.FlowCreation;
import com.google.gerrit.server.flow.FlowPermissionDeniedException;
import com.google.gerrit.server.flow.FlowServiceUtil;
import com.google.gerrit.server.flow.InvalidFlowException;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import org.eclipse.jgit.lib.Config;
/**
* REST endpoint to create a flow .
*
* <p>This REST endpoint handles {@code POST /change/<change-id>/flows} requests.
*/
@Singleton
public class CreateFlow
implements RestCollectionModifyView<ChangeResource, FlowResource, FlowInput> {
@VisibleForTesting public static final int DEFAULT_MAX_FLOWS_PER_CHANGE = 20;
private final Provider<Config> cfgProvider;
private final FlowServiceUtil flowServiceUtil;
private final Provider<CurrentUser> self;
@Inject
CreateFlow(
@GerritServerConfig Provider<Config> cfgProvider,
FlowServiceUtil flowServiceUtil,
Provider<CurrentUser> self) {
this.cfgProvider = cfgProvider;
this.flowServiceUtil = flowServiceUtil;
this.self = self;
}
@Override
public Response<FlowInfo> apply(ChangeResource changeResource, FlowInput flowInput)
throws AuthException,
BadRequestException,
MethodNotAllowedException,
ResourceConflictException {
if (!self.get().isIdentifiedUser()) {
throw new AuthException("Authentication required");
}
if (flowInput == null) {
flowInput = new FlowInput();
}
int maxFlowsPerChange =
cfgProvider.get().getInt("flows", "maxPerChange", DEFAULT_MAX_FLOWS_PER_CHANGE);
if (maxFlowsPerChange > 0
&& flowServiceUtil
.getFlowServiceOrThrow()
.listFlows(changeResource.getProject(), changeResource.getId())
.size()
>= maxFlowsPerChange) {
throw new ResourceConflictException(
String.format("Too many flows (max %s flow allowed per change)", maxFlowsPerChange));
}
FlowCreation flowCreation =
FlowJson.createFlowCreation(
changeResource.getProject(),
changeResource.getId(),
self.get().asIdentifiedUser().getAccountId(),
flowInput);
try {
Flow flow = flowServiceUtil.getFlowServiceOrThrow().createFlow(flowCreation);
return Response.created(FlowJson.format(flow));
} catch (FlowPermissionDeniedException e) {
throw new AuthException(e.getMessage(), e);
} catch (InvalidFlowException e) {
throw new BadRequestException(e.getMessage(), e);
}
}
}