Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
io.cdap.cdap.gateway.handlers.PreferencesHttpHandler Maven / Gradle / Ivy
/*
* Copyright © 2015-2019 Cask Data, Inc.
*
* 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 io.cdap.cdap.gateway.handlers;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import com.google.inject.Inject;
import io.cdap.cdap.app.store.Store;
import io.cdap.cdap.common.ApplicationNotFoundException;
import io.cdap.cdap.common.BadRequestException;
import io.cdap.cdap.common.conf.Constants;
import io.cdap.cdap.common.security.AuditDetail;
import io.cdap.cdap.common.security.AuditPolicy;
import io.cdap.cdap.config.PreferencesService;
import io.cdap.cdap.gateway.handlers.util.AbstractAppFabricHttpHandler;
import io.cdap.cdap.internal.app.store.ApplicationMeta;
import io.cdap.cdap.proto.ProgramType;
import io.cdap.cdap.proto.id.ApplicationId;
import io.cdap.cdap.proto.id.InstanceId;
import io.cdap.cdap.proto.id.NamespaceId;
import io.cdap.cdap.proto.id.ProgramId;
import io.cdap.cdap.proto.security.StandardPermission;
import io.cdap.cdap.security.spi.authentication.AuthenticationContext;
import io.cdap.cdap.security.spi.authorization.AccessEnforcer;
import io.cdap.cdap.store.NamespaceStore;
import io.cdap.http.HttpResponder;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpRequest;
import io.netty.handler.codec.http.HttpResponseStatus;
import java.util.Map;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.QueryParam;
/**
* Program Preferences HTTP Handler.
*/
@Path(Constants.Gateway.API_VERSION_3)
public class PreferencesHttpHandler extends AbstractAppFabricHttpHandler {
private static final Gson GSON = new Gson();
private final AccessEnforcer accessEnforcer;
private final AuthenticationContext authenticationContext;
private final PreferencesService preferencesService;
private final Store store;
private final NamespaceStore nsStore;
@Inject
PreferencesHttpHandler(AccessEnforcer accessEnforcer,
AuthenticationContext authenticationContext,
PreferencesService preferencesService,
Store store, NamespaceStore nsStore) {
this.accessEnforcer = accessEnforcer;
this.authenticationContext = authenticationContext;
this.preferencesService = preferencesService;
this.store = store;
this.nsStore = nsStore;
}
//Instance Level Properties
@Path("/preferences")
@GET
public void getInstancePrefs(HttpRequest request, HttpResponder responder) throws Exception {
InstanceId instanceId = new InstanceId("");
accessEnforcer.enforce(instanceId, authenticationContext.getPrincipal(), StandardPermission.GET);
responder.sendJson(HttpResponseStatus.OK, GSON.toJson(preferencesService.getProperties()));
}
@Path("/preferences")
@DELETE
public void deleteInstancePrefs(HttpRequest request, HttpResponder responder) throws Exception {
InstanceId instanceId = new InstanceId("");
accessEnforcer.enforce(instanceId, authenticationContext.getPrincipal(), StandardPermission.UPDATE);
preferencesService.deleteProperties();
responder.sendStatus(HttpResponseStatus.OK);
}
@Path("/preferences")
@PUT
@AuditPolicy(AuditDetail.REQUEST_BODY)
public void setInstancePrefs(FullHttpRequest request, HttpResponder responder) throws Exception {
InstanceId instanceId = new InstanceId("");
accessEnforcer.enforce(instanceId, authenticationContext.getPrincipal(), StandardPermission.UPDATE);
try {
Map propMap = decodeArguments(request);
preferencesService.setProperties(propMap);
responder.sendStatus(HttpResponseStatus.OK);
} catch (JsonSyntaxException jsonEx) {
responder.sendString(HttpResponseStatus.BAD_REQUEST, "Invalid JSON in body");
}
}
//Namespace Level Properties
//Resolved field, if set to true, returns the collapsed property map (Instance < Namespace)
@Path("/namespaces/{namespace-id}/preferences")
@GET
public void getNamespacePrefs(HttpRequest request, HttpResponder responder,
@PathParam("namespace-id") String namespace, @QueryParam("resolved") boolean resolved)
throws Exception {
NamespaceId namespaceId = new NamespaceId(namespace);
accessEnforcer.enforce(namespaceId, authenticationContext.getPrincipal(), StandardPermission.GET);
if (nsStore.get(namespaceId) == null) {
responder.sendString(HttpResponseStatus.NOT_FOUND, String.format("Namespace %s not present", namespace));
} else {
if (resolved) {
responder.sendJson(HttpResponseStatus.OK,
GSON.toJson(preferencesService.getResolvedProperties(namespaceId)));
} else {
responder.sendJson(HttpResponseStatus.OK,
GSON.toJson(preferencesService.getProperties(namespaceId)));
}
}
}
@Path("/namespaces/{namespace-id}/preferences")
@PUT
@AuditPolicy(AuditDetail.REQUEST_BODY)
public void setNamespacePrefs(FullHttpRequest request, HttpResponder responder,
@PathParam("namespace-id") String namespace) throws Exception {
NamespaceId namespaceId = new NamespaceId(namespace);
accessEnforcer.enforce(namespaceId, authenticationContext.getPrincipal(), StandardPermission.UPDATE);
if (nsStore.get(namespaceId) == null) {
responder.sendString(HttpResponseStatus.NOT_FOUND, String.format("Namespace %s not present", namespace));
return;
}
try {
Map propMap = decodeArguments(request);
preferencesService.setProperties(namespaceId, propMap);
responder.sendStatus(HttpResponseStatus.OK);
} catch (JsonSyntaxException jsonEx) {
responder.sendString(HttpResponseStatus.BAD_REQUEST, "Invalid JSON in body");
}
}
@Path("/namespaces/{namespace-id}/preferences")
@DELETE
public void deleteNamespacePrefs(HttpRequest request, HttpResponder responder,
@PathParam("namespace-id") String namespace) throws Exception {
NamespaceId namespaceId = new NamespaceId(namespace);
accessEnforcer.enforce(namespaceId, authenticationContext.getPrincipal(), StandardPermission.UPDATE);
if (nsStore.get(namespaceId) == null) {
responder.sendString(HttpResponseStatus.NOT_FOUND, String.format("Namespace %s not present", namespace));
} else {
preferencesService.deleteProperties(namespaceId);
responder.sendStatus(HttpResponseStatus.OK);
}
}
//Application Level Properties
//Resolved field, if set to true, returns the collapsed property map (Instance < Namespace < Application)
@Path("/namespaces/{namespace-id}/apps/{application-id}/preferences")
@GET
public void getAppPrefs(HttpRequest request, HttpResponder responder,
@PathParam("namespace-id") String namespace, @PathParam("application-id") String appId,
@QueryParam("resolved") boolean resolved) throws Exception {
ApplicationId applicationId = new ApplicationId(namespace, appId,
getLatestAppVersion(new NamespaceId(namespace), appId));
accessEnforcer.enforce(applicationId, authenticationContext.getPrincipal(), StandardPermission.GET);
if (store.getApplication(applicationId) == null) {
responder.sendString(HttpResponseStatus.NOT_FOUND, String.format("Application %s in Namespace %s not present",
appId, namespace));
} else {
if (resolved) {
responder.sendJson(HttpResponseStatus.OK, GSON.toJson(preferencesService.getResolvedProperties(applicationId)));
} else {
responder.sendJson(HttpResponseStatus.OK, GSON.toJson(preferencesService.getProperties(applicationId)));
}
}
}
@Path("/namespaces/{namespace-id}/apps/{application-id}/preferences")
@PUT
@AuditPolicy(AuditDetail.REQUEST_BODY)
public void putAppPrefs(FullHttpRequest request, HttpResponder responder,
@PathParam("namespace-id") String namespace, @PathParam("application-id") String appId)
throws Exception {
ApplicationId applicationId = new ApplicationId(namespace, appId,
getLatestAppVersion(new NamespaceId(namespace), appId));
accessEnforcer.enforce(applicationId, authenticationContext.getPrincipal(), StandardPermission.UPDATE);
if (store.getApplication(applicationId) == null) {
responder.sendString(HttpResponseStatus.NOT_FOUND, String.format("Application %s in Namespace %s not present",
appId, namespace));
return;
}
try {
Map propMap = decodeArguments(request);
preferencesService.setProperties(applicationId, propMap);
responder.sendStatus(HttpResponseStatus.OK);
} catch (JsonSyntaxException jsonEx) {
responder.sendString(HttpResponseStatus.BAD_REQUEST, "Invalid JSON in body");
}
}
@Path("/namespaces/{namespace-id}/apps/{application-id}/preferences")
@DELETE
public void deleteAppPrefs(HttpRequest request, HttpResponder responder,
@PathParam("namespace-id") String namespace, @PathParam("application-id") String appId)
throws Exception {
ApplicationId applicationId = new ApplicationId(namespace, appId,
getLatestAppVersion(new NamespaceId(namespace), appId));
accessEnforcer.enforce(applicationId, authenticationContext.getPrincipal(), StandardPermission.UPDATE);
if (store.getApplication(applicationId) == null) {
responder.sendString(HttpResponseStatus.NOT_FOUND, String.format("Application %s in Namespace %s not present",
appId, namespace));
} else {
preferencesService.deleteProperties(applicationId);
responder.sendStatus(HttpResponseStatus.OK);
}
}
//Program Level Properties
//Resolved field, if set to true, returns the collapsed property map (Instance < Namespace < Application < Program)
@Path("/namespaces/{namespace-id}/apps/{application-id}/{program-type}/{program-id}/preferences")
@GET
public void getProgramPrefs(HttpRequest request, HttpResponder responder,
@PathParam("namespace-id") String namespace, @PathParam("application-id") String appId,
@PathParam("program-type") String programType, @PathParam("program-id") String programId,
@QueryParam("resolved") boolean resolved) throws Exception {
ApplicationId applicationId = new ApplicationId(namespace, appId,
getLatestAppVersion(new NamespaceId(namespace), appId));
ProgramId program = new ProgramId(applicationId, getProgramType(programType), programId);
accessEnforcer.enforce(program, authenticationContext.getPrincipal(), StandardPermission.GET);
Store.ensureProgramExists(program, store.getApplication(program.getParent()));
if (resolved) {
responder.sendJson(HttpResponseStatus.OK, GSON.toJson(preferencesService.getResolvedProperties(program)));
} else {
responder.sendJson(HttpResponseStatus.OK, GSON.toJson(preferencesService.getProperties(program)));
}
}
@Path("/namespaces/{namespace-id}/apps/{application-id}/{program-type}/{program-id}/preferences")
@PUT
@AuditPolicy(AuditDetail.REQUEST_BODY)
public void putProgramPrefs(FullHttpRequest request, HttpResponder responder,
@PathParam("namespace-id") String namespace,
@PathParam("application-id") String appId,
@PathParam("program-type") String programType,
@PathParam("program-id") String programId) throws Exception {
ApplicationId applicationId = new ApplicationId(namespace, appId,
getLatestAppVersion(new NamespaceId(namespace), appId));
ProgramId program = new ProgramId(applicationId, getProgramType(programType), programId);
accessEnforcer.enforce(program, authenticationContext.getPrincipal(), StandardPermission.UPDATE);
Store.ensureProgramExists(program, store.getApplication(program.getParent()));
try {
Map propMap = decodeArguments(request);
preferencesService.setProperties(program, propMap);
responder.sendStatus(HttpResponseStatus.OK);
} catch (JsonSyntaxException jsonEx) {
responder.sendString(HttpResponseStatus.BAD_REQUEST, "Invalid JSON in body");
}
}
@Path("/namespaces/{namespace-id}/apps/{application-id}/{program-type}/{program-id}/preferences")
@DELETE
public void deleteProgramPrefs(HttpRequest request, HttpResponder responder,
@PathParam("namespace-id") String namespace, @PathParam("application-id") String appId,
@PathParam("program-type") String programType,
@PathParam("program-id") String programId) throws Exception {
ApplicationId applicationId = new ApplicationId(namespace, appId,
getLatestAppVersion(new NamespaceId(namespace), appId));
ProgramId program = new ProgramId(applicationId, getProgramType(programType), programId);
accessEnforcer.enforce(program, authenticationContext.getPrincipal(), StandardPermission.UPDATE);
Store.ensureProgramExists(program, store.getApplication(program.getParent()));
preferencesService.deleteProperties(program);
responder.sendStatus(HttpResponseStatus.OK);
}
/**
* Parses the give program type into {@link ProgramType} object.
*
* @param programType the program type to parse.
* @throws BadRequestException if the given program type is not a valid {@link ProgramType}.
*/
private ProgramType getProgramType(String programType) throws BadRequestException {
try {
return ProgramType.valueOfCategoryName(programType);
} catch (Exception e) {
throw new BadRequestException(String.format("Invalid program type '%s'", programType), e);
}
}
/**
*
* @param namespaceId namespace ID
* @param appId application ID
* @return latest app version
*/
private String getLatestAppVersion(NamespaceId namespaceId, String appId) throws ApplicationNotFoundException {
ApplicationMeta latestApplicationMeta = store.getLatest(namespaceId.appReference(appId));
if (latestApplicationMeta == null) {
throw new ApplicationNotFoundException(new ApplicationId(namespaceId.getNamespace(), appId));
}
return latestApplicationMeta.getSpec().getAppVersion();
}
}