Skip to content

Commit

Permalink
Split: without extracted ConfigurationBeanLoader, ModelNames and sta…
Browse files Browse the repository at this point in the history
…rtup_listeners.txt modifications.

    Proof of concept for dynapi february sprint (#253)

    * Dynamic API RPC starting point

    * Use String to store dateTime until a better type defined

    * instantinate objects independently in configuration bean loader

    * Modified ontology files

    * Replace requireXXX with requresXXX in dynamic API ontology

    * Parse boolean type while loading instances with ConfigurationBeanLoader

    * Ontology modifications, refactoring.

    * Added n3 template rdf class

    * Renamed rpc name set method

    * Implemented basic support of sparql queries

    * Current state for discussion

    * Multiple fixes, added n3 action example

    * Added typed parameter example, fixed localization tags

    * Defined rdf class RPC to represent RPC call, defined class to represent REST Resources

    * Initialize pools with StartupManager

    * Added draft of REST Endpoint

    * Added default http method to define a method should be used for rpc execution and also REST custom action

    * fix: a mistake, Action should have firstStep, next should be an option of OperationalStep

    * fix: REST custom action names shouldn't be equal to RPC names
  • Loading branch information
litvinovg committed Apr 19, 2024
1 parent eb75133 commit 93e9536
Show file tree
Hide file tree
Showing 36 changed files with 1,980 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package edu.cornell.mannlib.vitro.webapp.dynapi;

import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.FULL_UNION;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import javax.servlet.ServletContext;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.jena.ontology.OntModel;

import edu.cornell.mannlib.vitro.webapp.dynapi.components.Action;
import edu.cornell.mannlib.vitro.webapp.dynapi.components.DefaultAction;
import edu.cornell.mannlib.vitro.webapp.modelaccess.ContextModelAccess;
import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess;
import edu.cornell.mannlib.vitro.webapp.utils.configuration.ConfigurationBeanLoader;

public class ActionPool {

private static ActionPool INSTANCE = null;
private static final Log log = LogFactory.getLog(ActionPool.class);

private Map<String,Action> actions;
private ServletContext ctx;
private ConfigurationBeanLoader loader;
private ContextModelAccess modelAccess;
private OntModel dynamicAPIModel;

private ActionPool(){
this.actions = new HashMap<String,Action>();
INSTANCE = this;
}

public static ActionPool getInstance() {
if (INSTANCE == null) {
INSTANCE = new ActionPool();
}
return INSTANCE;
}

public Action getByName(String name) {
Action action = actions.get(name);
if (action == null) {
action = new DefaultAction();
}
return action;
}

public void printActionNames() {
for (Map.Entry<String,Action> entry : actions.entrySet()) {
log.debug("Action in pool: '" + entry.getKey() + "'");
}
}

public void reload() {
if (ctx == null ) {
log.error("Context is null. Can't reload action pool.");
return;
}
if (loader == null ) {
log.error("Loader is null. Can't reload action pool.");
return;
}
for (Map.Entry<String,Action> entry : actions.entrySet()) {
entry.getValue().dereference();
}
actions.clear();
loadActions();
}

public void init(ServletContext ctx) {
this.ctx = ctx;
modelAccess = ModelAccess.on(ctx);
dynamicAPIModel = modelAccess.getOntModel(FULL_UNION);
loader = new ConfigurationBeanLoader( dynamicAPIModel, ctx);
log.debug("Context Initialization ...");
loadActions();
}

private void loadActions() {
Set<Action> actions = loader.loadEach(Action.class);
log.debug("Context Initialization. actions loaded: " + actions.size());
for (Action action : actions) {
if (action.isValid()) {
add(action);
} else {
log.error("Action with rpcName " + action.getName() + " is invalid.");
}
}
log.debug("Context Initialization finished. " + actions.size() + " actions loaded.");
}

private void add(Action action) {
actions.put(action.getName(), action);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package edu.cornell.mannlib.vitro.webapp.dynapi;

public class DynamicAPIDocumentation {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package edu.cornell.mannlib.vitro.webapp.dynapi;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class Initializer implements ServletContextListener {
public Initializer() {}

private void initializeResourcePool(ServletContext ctx) {
ResourcePool resourcePool = ResourcePool.getInstance();
resourcePool.init(ctx);
}

private void initializeActionPool(ServletContext ctx) {
ActionPool actionPool = ActionPool.getInstance();
actionPool.init(ctx);
}

@Override
public void contextInitialized(ServletContextEvent sce) {
ServletContext ctx = sce.getServletContext();
initializeActionPool(ctx);
initializeResourcePool(ctx);
}

@Override
public void contextDestroyed(ServletContextEvent sce) {
// TODO Auto-generated method stub
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package edu.cornell.mannlib.vitro.webapp.dynapi;

import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;

public class OperationData {

private Map<String, String[]> params;
private ServletContext context;

public OperationData(HttpServletRequest request) {
params = request.getParameterMap();
context = request.getServletContext();
}

public ServletContext getContext() {
return context;
}

public boolean has(String paramName) {
if (params.containsKey(paramName)) {
return true;
}
return false;
}

public String[] get(String paramName) {
return params.get(paramName);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package edu.cornell.mannlib.vitro.webapp.dynapi;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import edu.cornell.mannlib.vitro.webapp.controller.VitroHttpServlet;

@WebServlet(name = "RESTEndpoint", urlPatterns = { "/api/rest/*" })
public class RESTEndpoint extends VitroHttpServlet {

private static final long serialVersionUID = 1L;
private static final Log log = LogFactory.getLog(RESTEndpoint.class);
private ResourcePool resourcePool = ResourcePool.getInstance();


@Override
public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
if (request.getMethod().equalsIgnoreCase("PATCH")){
doPatch(request, response);
} else {
super.service(request, response);
}
}

@Override
public void doPost( HttpServletRequest request, HttpServletResponse response ) {
process(request, response);
}

@Override
public void doGet( HttpServletRequest request, HttpServletResponse response ) {
process(request, response);
}

@Override
public void doDelete( HttpServletRequest request, HttpServletResponse response ) {
process(request, response);
}

@Override
public void doPut( HttpServletRequest request, HttpServletResponse response ) {
process(request, response);
}

public void doPatch( HttpServletRequest request, HttpServletResponse response ) {
process(request, response);
}

private void process(HttpServletRequest request, HttpServletResponse response) {
String requestURL = request.getRequestURI();
//String resourceName = requestURL.substring(requestURL.lastIndexOf("/") + 1 );
//Resource resource = resourcePool.getByName(resourceName);
log.debug(request.getMethod());
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package edu.cornell.mannlib.vitro.webapp.dynapi;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import edu.cornell.mannlib.vitro.webapp.controller.VitroHttpServlet;
import edu.cornell.mannlib.vitro.webapp.dynapi.components.Action;
import edu.cornell.mannlib.vitro.webapp.dynapi.components.OperationResult;

@WebServlet(name = "RPCEndpoint", urlPatterns = { "/api/rpc/*" })
public class RPCEndpoint extends VitroHttpServlet {

private static final long serialVersionUID = 1L;
private static final Log log = LogFactory.getLog(RPCEndpoint.class);
private ActionPool actionPool = ActionPool.getInstance();

@Override
public void doGet( HttpServletRequest request, HttpServletResponse response ) {
process(request, response);
}

@Override
public void doPost( HttpServletRequest request, HttpServletResponse response ) {
process(request, response);
}

@Override
public void doDelete( HttpServletRequest request, HttpServletResponse response ) {
process(request, response);
}

@Override
public void doPut( HttpServletRequest request, HttpServletResponse response ) {
process(request, response);
}

private void process(HttpServletRequest request, HttpServletResponse response) {
String requestURL = request.getRequestURI();
String actionName = requestURL.substring(requestURL.lastIndexOf("/") + 1 );
log.debug(actionName);
actionPool.printActionNames();
Action action = actionPool.getByName(actionName);
OperationData input = new OperationData(request);
OperationResult result = action.run(input);
result.prepareResponse(response);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package edu.cornell.mannlib.vitro.webapp.dynapi;

import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.FULL_UNION;

import java.util.HashMap;
import java.util.Set;

import javax.servlet.ServletContext;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.jena.ontology.OntModel;

import edu.cornell.mannlib.vitro.webapp.dynapi.components.Resource;
import edu.cornell.mannlib.vitro.webapp.modelaccess.ContextModelAccess;
import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess;
import edu.cornell.mannlib.vitro.webapp.utils.configuration.ConfigurationBeanLoader;

public class ResourcePool {

private static final Log log = LogFactory.getLog(ResourcePool.class);
private static ResourcePool INSTANCE;
private ContextModelAccess modelAccess;
private OntModel dynamicAPIModel;
private ConfigurationBeanLoader loader;
private HashMap<String, Resource> resources;
private ServletContext ctx;

private ResourcePool() {
this.resources = new HashMap<String,Resource>();
INSTANCE = this;
}
public static ResourcePool getInstance() {
if (INSTANCE == null) {
INSTANCE = new ResourcePool();
}
return INSTANCE;
}

public void init(ServletContext ctx) {
this.ctx = ctx;
modelAccess = ModelAccess.on(ctx);
dynamicAPIModel = modelAccess.getOntModel(FULL_UNION);
loader = new ConfigurationBeanLoader( dynamicAPIModel, ctx);
loadResources();
}

private void loadResources() {
Set<Resource> resources = loader.loadEach(Resource.class);
log.debug("Context Initialization. resources created: " + resources.size());
for (Resource resource : resources) {
add(resource);
}
log.debug("Context Initialization finished. " + resources.size() + " resources loaded.");
}

private void add(Resource resource) {
resources.put(resource.getName(), resource);
}
}
Loading

0 comments on commit 93e9536

Please sign in to comment.