API for CDAP System Applications - provides interfaces and abstract classes for building system services that run in the CDAP system namespace
—
System-level HTTP service handlers for creating web APIs and HTTP endpoints with enhanced system privileges, namespace access, and remote task execution capabilities.
Abstract base class for system HTTP service handlers that can only be deployed in the system namespace.
/**
* Abstract class for system http service handlers. System handlers can only be used
* in applications that are deployed in the system namespace.
*/
@Beta
public class AbstractSystemHttpServiceHandler
extends AbstractHttpServiceHandler<SystemHttpServiceContext, SystemHttpServiceConfigurer> {
/**
* Creates a system table that conforms to the given table specification
* when the application is deployed.
* @param tableSpecification the specification for the system table
*/
protected void createTable(StructuredTableSpecification tableSpecification);
}Usage Example:
import io.cdap.cdap.api.service.http.AbstractSystemHttpServiceHandler;
import io.cdap.cdap.api.service.http.SystemHttpServiceConfigurer;
import io.cdap.cdap.api.service.http.HttpServiceRequest;
import io.cdap.cdap.api.service.http.HttpServiceResponder;
import io.cdap.cdap.spi.data.StructuredTableSpecification;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
@Path("/system")
public class SystemApiHandler extends AbstractSystemHttpServiceHandler {
@Override
public void configure(SystemHttpServiceConfigurer configurer) {
// Create system table for API metadata
StructuredTableSpecification tableSpec = StructuredTableSpecification.builder()
.withId("api-requests")
.withFields(/* field definitions */)
.build();
createTable(tableSpec);
}
@GET
@Path("/namespaces")
public void listNamespaces(HttpServiceRequest request, HttpServiceResponder responder) {
try {
// Access system context capabilities
List<NamespaceSummary> namespaces = getContext().listNamespaces();
responder.sendJson(namespaces);
} catch (Exception e) {
responder.sendError(500, "Failed to list namespaces: " + e.getMessage());
}
}
}Interface for system HTTP service handlers with capabilities not available to user service handlers.
/**
* A System HttpServiceHandler that exposes capabilities beyond those that
* are not available to user service handlers.
*/
@Beta
public interface SystemHttpServiceHandler
extends HttpServiceHandler<SystemHttpServiceContext, SystemHttpServiceConfigurer> {
// Inherits all methods from HttpServiceHandler with system-specific context and configurer
}System HTTP service configurer with capabilities beyond user configurers.
/**
* System HttpServiceConfigurer that provides capabilities beyond those
* available to user configurers.
*/
@Beta
public interface SystemHttpServiceConfigurer extends HttpServiceConfigurer, SystemTableConfigurer {
// Inherits all methods from HttpServiceConfigurer and SystemTableConfigurer
}System HTTP service context with enhanced capabilities including macro evaluation, remote task execution, and namespace administration.
/**
* A System HttpServiceContext that exposes capabilities beyond those available
* to service contexts for user services.
*/
@Beta
public interface SystemHttpServiceContext
extends HttpServiceContext, TransactionRunner, SystemNamespaceAdmin {
/**
* Evaluates lookup macros and the 'secure' macro function using provided macro evaluator.
* @param namespace the namespace context for macro evaluation
* @param properties map of properties containing macros to evaluate
* @param evaluator the macro evaluator to use
* @return map with evaluated macros
* @throws InvalidMacroException if macro evaluation fails
*/
default Map<String, String> evaluateMacros(String namespace,
Map<String, String> properties,
MacroEvaluator evaluator)
throws InvalidMacroException;
/**
* Evaluates macros using provided macro evaluator with the provided parsing options.
* @param namespace the namespace context for macro evaluation
* @param properties map of properties containing macros to evaluate
* @param evaluator the macro evaluator to use
* @param options macro parsing options
* @return map with evaluated macros
* @throws InvalidMacroException if macro evaluation fails
*/
Map<String, String> evaluateMacros(String namespace,
Map<String, String> properties,
MacroEvaluator evaluator,
MacroParserOptions options)
throws InvalidMacroException;
/**
* Gets preferences for the given namespace.
* @param namespace the namespace to get preferences for
* @param resolved whether to resolve macros in preference values
* @return map of preference key-value pairs
* @throws IOException if reading preferences fails
* @throws IllegalArgumentException if namespace is invalid
* @throws AccessException if access to namespace is denied
*/
default Map<String, String> getPreferencesForNamespace(String namespace, boolean resolved)
throws IOException, IllegalArgumentException, AccessException;
/**
* Returns ContextAccessEnforcer that can be used to enforce access for current request.
* @return context access enforcer
*/
ContextAccessEnforcer getContextAccessEnforcer();
/**
* Runs the task from RunnableTaskRequest remotely on a task worker.
* @param runnableTaskRequest the task request to execute
* @return task execution result as byte array
* @throws Exception if task execution fails
*/
byte[] runTask(RunnableTaskRequest runnableTaskRequest) throws Exception;
/**
* Returns boolean indicating whether remote task execution is enabled.
* @return true if remote task execution is enabled
*/
boolean isRemoteTaskEnabled();
}Usage Examples:
import io.cdap.cdap.api.service.http.SystemHttpServiceContext;
import io.cdap.cdap.api.service.worker.RunnableTaskRequest;
import io.cdap.cdap.api.macro.MacroEvaluator;
@Path("/system")
public class SystemApiHandler extends AbstractSystemHttpServiceHandler {
@POST
@Path("/evaluate-macros/{namespace}")
public void evaluateMacros(@PathParam("namespace") String namespace,
HttpServiceRequest request,
HttpServiceResponder responder) {
try {
SystemHttpServiceContext context = getContext();
// Parse request body as properties map
Map<String, String> properties = /* parse from request */;
MacroEvaluator evaluator = /* create evaluator */;
// Evaluate macros for the namespace
Map<String, String> evaluated = context.evaluateMacros(namespace, properties, evaluator);
responder.sendJson(evaluated);
} catch (Exception e) {
responder.sendError(500, "Macro evaluation failed: " + e.getMessage());
}
}
@POST
@Path("/run-task")
public void runRemoteTask(HttpServiceRequest request, HttpServiceResponder responder) {
try {
SystemHttpServiceContext context = getContext();
if (!context.isRemoteTaskEnabled()) {
responder.sendError(503, "Remote task execution is disabled");
return;
}
// Create task request
RunnableTaskRequest taskRequest = RunnableTaskRequest.getBuilder("com.example.MyTask")
.withParam("task-parameter")
.withNamespace("default")
.build();
// Execute task remotely
byte[] result = context.runTask(taskRequest);
responder.sendBytes(result, "application/octet-stream");
} catch (Exception e) {
responder.sendError(500, "Task execution failed: " + e.getMessage());
}
}
@GET
@Path("/preferences/{namespace}")
public void getNamespacePreferences(@PathParam("namespace") String namespace,
HttpServiceRequest request,
HttpServiceResponder responder) {
try {
SystemHttpServiceContext context = getContext();
// Get resolved preferences for namespace
Map<String, String> preferences = context.getPreferencesForNamespace(namespace, true);
responder.sendJson(preferences);
} catch (Exception e) {
responder.sendError(500, "Failed to get preferences: " + e.getMessage());
}
}
}@Beta annotation are subject to changerunTask() methodresolved parameter is trueInstall with Tessl CLI
npx tessl i tessl/maven-io-cdap-cdap--cdap-system-app-api