You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@oodt.apache.org by ma...@apache.org on 2017/02/18 23:39:51 UTC
[5/6] oodt git commit: update files for new curator
http://git-wip-us.apache.org/repos/asf/oodt/blob/a47b088a/curator2/src/main/java/org/apache/oodt/cas/curation/service/CurationServiceConfig.java
----------------------------------------------------------------------
diff --git a/curator2/src/main/java/org/apache/oodt/cas/curation/service/CurationServiceConfig.java b/curator2/src/main/java/org/apache/oodt/cas/curation/service/CurationServiceConfig.java
new file mode 100644
index 0000000..dc497ed
--- /dev/null
+++ b/curator2/src/main/java/org/apache/oodt/cas/curation/service/CurationServiceConfig.java
@@ -0,0 +1,227 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.oodt.cas.curation.service;
+
+//OODT imports
+import org.apache.oodt.cas.curation.servlet.CuratorConfMetKeys;
+import org.apache.oodt.cas.filemgr.datatransfer.DataTransferFactory;
+import org.apache.oodt.cas.filemgr.system.XmlRpcFileManagerClient;
+import org.apache.oodt.cas.metadata.util.PathUtils;
+
+//JDK imports
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+
+/**
+ *
+ *
+ * Configures the {@link CurationService} by reading the parameters out of the
+ * <code>context.xml</code> file, doing a
+ * {@link PathUtils#replaceEnvVariables(String)} on each property in the
+ * context.xml. This allows you to specify environment variables using the
+ * traditional CAS syntax of:
+ *
+ * <pre>
+ * [VAR_NAME], e.g., [CAS_CURATOR_HOME]/some/other/path
+ * </pre>
+ *
+ * The configuration parameters are read once upon loading the instance of this
+ * object.
+ *
+ * @author pramirez
+ * @author mattmann
+ * @version $Revision$
+ *
+ */
+public class CurationServiceConfig implements CuratorConfMetKeys {
+ private static CurationServiceConfig instance;
+
+ private final Map<String, String> parameters = new HashMap<String, String>();
+
+ private XmlRpcFileManagerClient fmClient = null;
+
+ private static final Logger LOG = Logger
+ .getLogger(CurationServiceConfig.class.getName());
+
+ /**
+ * Gets a singleton static instance of the global
+ * {@link CurationServiceConfig} for the CAS Curator Webapp.
+ *
+ * @param conf
+ * The {@link ServletConfig} read on startup of the webapp. This is
+ * typically specified in a <code>context.xml</code> file, but can
+ * also be specified in <code>web.xml</code>.
+ * @return A singleton instance of the global {@link link
+ * CurationServiceConfig}.
+ * @throws InstantiationException
+ * If there is any error constructing the config.
+ */
+ public static CurationServiceConfig getInstance(ServletConfig conf) {
+ if (instance == null) {
+ instance = new CurationServiceConfig(conf);
+ }
+ return instance;
+ }
+
+ /**
+ *
+ * @return The metadata output file path.
+ */
+ public String getMetAreaPath() {
+ return this.evaluateParameter(MET_AREA_PATH);
+ }
+
+ /**
+ *
+ * @return The extension of metadata files that will be generated and consumed
+ * by CAS curator.
+ */
+ public String getMetExtension() {
+ return this.evaluateParameter(MET_EXTENSION);
+ }
+
+ /**
+ *
+ * @return The path to the staging area where the CAS curator is ingesting
+ * files from.
+ */
+ public String getStagingAreaPath() {
+ return this.evaluateParameter(STAGING_AREA_PATH);
+ }
+
+ /**
+ *
+ * @return A {@link String} representation of the CAS File Manager {@link URL}
+ * .
+ */
+ public String getFileMgrURL() {
+ return this.evaluateParameter(FM_URL);
+ }
+
+ /**
+ *
+ * @return The full {@link XmlRpcFileManagerClient} built from the CAS curator
+ * property <code>filemgr.url</code>.
+ */
+ public XmlRpcFileManagerClient getFileManagerClient() {
+ try {
+ return new XmlRpcFileManagerClient(new URL(this.getFileMgrURL()));
+ } catch (Exception e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ /**
+ *
+ * @return The java class name (fully-qualified) of the CAS SSO security
+ * implementation.
+ */
+ public String getSSOImplClass() {
+ return this.evaluateParameter(SSO_IMPL_CLASS);
+ }
+
+ /**
+ *
+ * @return The display name of the project.
+ */
+ public String getProjectDisplayName() {
+ return this.evaluateParameter(PROJECT_DISPLAY_NAME);
+ }
+
+ /**
+ *
+ * @return The upload path for metadata extractor config files.
+ */
+ public String getMetExtrConfUploadPath() {
+ return this.evaluateParameter(MET_EXTRACTOR_CONF_UPLOAD_PATH);
+ }
+
+ /**
+ *
+ * @return The path to the crawler config file.
+ */
+ public String getCrawlerConfFile() {
+ return this.evaluateParameter(CRAWLER_CONF_FILE);
+ }
+
+ /**
+ *
+ * @return The path to the location where policy directories should be
+ * uploaded to.
+ */
+ public String getPolicyUploadPath() {
+ return this.evaluateParameter(POLICY_UPLOAD_PATH);
+ }
+
+ /**
+ *
+ * @return The default CAS File Manager {@link DataTransferFactory} classname.
+ */
+ public String getDefaultTransferFactory() {
+ return this.evaluateParameter(DEFAULT_TRANSFER_FACTORY);
+ }
+
+ /**
+ * Gets a property from the CAS Curator config without calling
+ * {@link PathUtils#replaceEnvVariables(String)}.
+ *
+ * @param name
+ * The name of the parameter to return.
+ * @return The un-evaluated property value from the config.
+ */
+ public String getParameter(String name) {
+ return this.parameters.get(name);
+ }
+
+ public String getFileMgrProps() {
+ return this.evaluateParameter(FM_PROPS);
+ }
+
+ private String evaluateParameter(String name) {
+ return PathUtils.replaceEnvVariables(this.parameters.get(name));
+ }
+
+ // Note that the constructor is private
+ private CurationServiceConfig(ServletConfig conf) {
+ readContextParams(conf.getServletContext());
+ try {
+ fmClient = new XmlRpcFileManagerClient(new URL(this.getFileMgrURL()));
+ } catch (Exception e) {
+ e.printStackTrace();
+ LOG.log(Level.WARNING, "Unable to build CurationServiceConfig: Message: " + e.getMessage());
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private void readContextParams(ServletContext context) {
+ for (Enumeration<String> names = context.getInitParameterNames(); names
+ .hasMoreElements();) {
+ String name = names.nextElement();
+ parameters.put(name, context.getInitParameter(name));
+ }
+ LOG.log(Level.INFO, "Init Parameters: " + parameters);
+ }
+}
http://git-wip-us.apache.org/repos/asf/oodt/blob/a47b088a/curator2/src/main/java/org/apache/oodt/cas/curation/service/DirectoryResource.java
----------------------------------------------------------------------
diff --git a/curator2/src/main/java/org/apache/oodt/cas/curation/service/DirectoryResource.java b/curator2/src/main/java/org/apache/oodt/cas/curation/service/DirectoryResource.java
new file mode 100644
index 0000000..2700a69
--- /dev/null
+++ b/curator2/src/main/java/org/apache/oodt/cas/curation/service/DirectoryResource.java
@@ -0,0 +1,138 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.oodt.cas.curation.service;
+
+//JDK imports
+import java.io.File;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+//JAX-RS imports
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.UriInfo;
+
+
+
+@Path("directory")
+/**
+ *
+ * A web service endpoint to a service providing views of the staging area, the
+ * archive area, and the met output area.
+ *
+ * @author pramirez
+ * @version $Id$
+ */
+public class DirectoryResource extends CurationService {
+ private static final Logger LOG = Logger.getLogger(DirectoryResource.class
+ .getName());
+
+ @Context
+ UriInfo uriInfo;
+
+ private static final long serialVersionUID = 715126227357637464L;
+
+ @GET
+ @Path("staging")
+ @Produces("text/plain")
+ public String showStagingArea(
+ @DefaultValue("/") @QueryParam("path") String path,
+ @DefaultValue("true") @QueryParam("showFiles") boolean showFiles,
+ @DefaultValue(FORMAT_HTML) @QueryParam("format") String format) {
+ if (FORMAT_HTML.equals(format)) {
+ String response = this.getDirectoryAreaAsHTML(CurationService.config
+ .getStagingAreaPath(), path, showFiles);
+ return response;
+ }
+ return this.getDirectoryAreaAsJSON(CurationService.config
+ .getStagingAreaPath(), path, showFiles);
+ }
+
+ @GET
+ @Path("metadata")
+ @Produces("text/plain")
+ public String showMetArea(@DefaultValue("/") @QueryParam("path") String path,
+ @DefaultValue("true") @QueryParam("showFiles") boolean showFiles) {
+ return this.getDirectoryAreaAsJSON(CurationService.config.getMetAreaPath(),
+ path, showFiles);
+ }
+
+ @GET
+ @Path("catalog")
+ @Produces("text/plain")
+ public String showArchiveArea(@QueryParam("policy") String policy,
+ @QueryParam("productType") String productType,
+ @DefaultValue("20") @QueryParam("num") int numberOfResults,
+ @DefaultValue("0") @QueryParam("start") int start) {
+
+ // Figure out where the product type root path is and display contents
+ return productType;
+ }
+
+
+ public String getDirectoryAreaAsHTML(String base, String path,
+ boolean showFiles) {
+ StringBuffer html = new StringBuffer();
+ String relativePath = null;
+ try {
+ relativePath = this.cleansePath(path);
+ } catch (Exception e) {
+ e.printStackTrace();
+ LOG.log(Level.WARNING, "Error decoding path: [" + path + "]: Message: "
+ + e.getMessage());
+ return html.toString();
+ }
+
+ String startingPath = (base + "/" + relativePath);
+ String f[] = this.getFilesInDirectory(startingPath, showFiles);
+
+ html.append("<ul class=\"fileTree\">\r\n");
+ // Loop through and list directories first. Nicer for UI to get these first
+ for (int i = 0; i < f.length; i++) {
+ if (new File(startingPath + "/" + f[i]).isDirectory()) {
+ html.append(" <li class=\"directory collapsed\">");
+ html.append("<a href=\"#\" rel=\"").append(relativePath).append("/")
+ .append(f[i]).append("\">").append(f[i]).append("</a>");
+ html.append("</li>\r\n");
+ }
+ }
+ // If we are showing files now loop through and show files
+ if (showFiles) {
+ for (int i = 0; i < f.length; i++) {
+ if (new File(startingPath + "/" + f[i]).isFile()) {
+ String filename = new File(startingPath + "/" + f[i]).getName();
+ String ext = filename.substring(filename.lastIndexOf('.') + 1);
+ html.append(" <li class=\"file draggy ext_").append(ext)
+ .append("\">");
+ html.append("<a href=\"#\" rel=\"").append(relativePath).append("/")
+ .append(f[i]).append("\">").append(f[i]).append("</a>");
+ html.append("</li>\r\n");
+ }
+ }
+ }
+ html.append("</ul>");
+
+ return html.toString();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/oodt/blob/a47b088a/curator2/src/main/java/org/apache/oodt/cas/curation/service/IngestionResource.java
----------------------------------------------------------------------
diff --git a/curator2/src/main/java/org/apache/oodt/cas/curation/service/IngestionResource.java b/curator2/src/main/java/org/apache/oodt/cas/curation/service/IngestionResource.java
new file mode 100644
index 0000000..2ea61bb
--- /dev/null
+++ b/curator2/src/main/java/org/apache/oodt/cas/curation/service/IngestionResource.java
@@ -0,0 +1,352 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.oodt.cas.curation.service;
+
+//OODT imports
+import org.apache.oodt.cas.curation.structs.IngestionTask;
+import org.apache.oodt.cas.curation.util.DateUtils;
+import org.apache.oodt.cas.curation.util.ExtractorConfigReader;
+import org.apache.oodt.cas.filemgr.ingest.Ingester;
+import org.apache.oodt.cas.filemgr.ingest.StdIngester;
+import org.apache.oodt.cas.filemgr.structs.exceptions.IngestException;
+import org.apache.oodt.cas.metadata.Metadata;
+
+//JDK imports
+import java.io.File;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.Vector;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+//JAX-RS imports
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.UriInfo;
+
+//JSON imports
+import net.sf.json.JSONObject;
+
+/**
+ *
+ * Leverages CAS {@link Ingester} interface to ingest Products into the CAS File
+ * Manager via CAS Curator and a REST-ful interface.
+ *
+ * @author mattmann
+ * @version $Revision$
+ *
+ */
+@Path("ingest")
+public class IngestionResource extends CurationService {
+
+ private static final long serialVersionUID = -7514150767897700936L;
+
+ private static final Logger LOG = Logger.getLogger(IngestionResource.class
+ .getName());
+
+ private static final String DATA_TRANSFER_SERVICE = "org.apache.oodt.cas.filemgr.datatransfer.LocalDataTransferFactory";
+
+ private static final String RESP_SUCCESS = "success";
+
+ private IngestionTaskList taskList;
+
+ public IngestionResource() {
+ super();
+ this.taskList = new IngestionTaskList();
+ IngestionTask task = new IngestionTask();
+ task.setCreateDate(new Date());
+
+ }
+
+ @Context
+ UriInfo uriInfo;
+
+ @GET
+ @Path("create")
+ @Produces("text/plain")
+ public String createTask(@QueryParam("files") String fileList,
+ @QueryParam("numfiles") Integer numFiles,
+ @QueryParam("metExtCfgId") String metExtractorConfigId,
+ @QueryParam("policy") String policy,
+ @QueryParam("ptype") String productType) {
+
+ IngestionTask newTask = new IngestionTask();
+ newTask.setCreateDate(new Date());
+ try {
+ newTask.setExtConf(ExtractorConfigReader.readFromDirectory(new File(
+ CurationService.config.getMetExtrConfUploadPath()),
+ metExtractorConfigId));
+ } catch (Exception e) {
+ e.printStackTrace();
+ String errorMsg = "Unable to load extractor config from metExtCfgId: ["
+ + metExtractorConfigId + "]";
+ LOG.log(Level.WARNING, errorMsg);
+ return errorMsg;
+ }
+ newTask.setFileList(deducePaths(Arrays.asList(fileList.split(","))));
+ newTask.setPolicy(policy);
+ newTask.setProductType(productType);
+ newTask.setStatus(IngestionTask.NOT_STARTED);
+ return this.taskList.addIngestionTask(newTask);
+ }
+
+ @GET
+ @Path("remove")
+ @Produces("text/plain")
+ public void removeTask(@QueryParam("taskId") String ingestTaskId) {
+ this.taskList.removeIngestionTask(ingestTaskId);
+ }
+
+ @GET
+ @Path("list")
+ @Produces("text/plain")
+ public String getIngestTaskList(
+ @QueryParam("format") @DefaultValue(FORMAT_HTML) String format) {
+ if (format.equals(FORMAT_HTML)) {
+ return this.encodeTaskListAsHTML(this.taskList.getTaskList());
+ } else if (format.equals(FORMAT_JSON)) {
+ return this.encodeTaskListAsJSON(this.taskList.getTaskList());
+ } else {
+ return "Unsupported Format!";
+ }
+ }
+
+ @GET
+ @Path("start")
+ @Produces("text/plain")
+ public String doIngest(@QueryParam("taskId") String ingestTaskId) {
+ IngestionTask task = this.taskList.getIngestionTaskById(ingestTaskId);
+ if (task == null) {
+ String errorMsg = "Task with ID [" + ingestTaskId
+ + "] is not being managed by this Ingestion Resource!";
+ LOG.log(Level.WARNING, errorMsg);
+ return this.encodeIngestResponseAsJSON(false, errorMsg);
+ }
+
+ Ingester ingest = this.configureIngester();
+ MetadataResource metService = new MetadataResource();
+ for (String file : task.getFileList()) {
+ Metadata fileMet = null;
+ try {
+ String vFilePath = this.getVirtualPath(CurationService.config
+ .getStagingAreaPath(), file);
+ LOG.log(Level.FINE,
+ "IngestionResource: getting staging metadata for virtual path: ["
+ + vFilePath + "]");
+ fileMet = metService.getStagingMetadata(vFilePath, task.getExtConf()
+ .getIdentifier(), false);
+ } catch (Exception e) {
+ e.printStackTrace();
+ return this.encodeIngestResponseAsHTML(false, e.getMessage());
+ }
+
+ try {
+ ingest.ingest(safeGetUrl(CurationService.config.getFileMgrURL()),
+ new File(file), fileMet);
+ } catch (IngestException e) {
+ e.printStackTrace();
+ return this.encodeIngestResponseAsHTML(false, e.getMessage());
+ }
+
+ // set task status to success
+ task.setStatus(IngestionTask.FINISHED);
+ }
+
+ return this.encodeIngestResponseAsHTML(true, null);
+ }
+
+ private String encodeTaskListAsHTML(List<IngestionTask> taskList) {
+ StringBuffer out = new StringBuffer();
+
+ for (IngestionTask task : taskList) {
+ out.append("<tr>");
+ out.append("<td>");
+ out.append(task.getId());
+ out.append("</td><td>");
+ out.append(DateUtils.getDateAsISO8601String(task.getCreateDate()));
+ out.append("</td><td>");
+ out.append(task.getFileList().size());
+ out.append("</td><td>");
+ out.append(task.getPolicy());
+ out.append("</td><td>");
+ out.append(task.getProductType());
+ out.append("</td><td>");
+ out.append(task.getExtConf().getIdentifier());
+ out.append("</td><td>");
+ out.append(task.getExtConf().getConfigFiles().size());
+ out.append("</td><td id='");
+ out.append(task.getId());
+ out.append("_Status'>");
+ out.append(task.getStatus());
+ out.append("</td>");
+ if (!task.getStatus().equals(IngestionTask.FINISHED)) {
+ out.append("<td><input type=\"button\" rel=\"_taskid_\" value=\"Start\" onclick=\"startIngestionTask('");
+ out.append(task.getId());
+ out.append("')\"/></td>");
+ } else {
+ out.append("<td><input type=\"button\" rel=\"_taskid_\" value=\"Remove\" onclick=\"removeIngestionTask('");
+ out.append(task.getId());
+ out.append("')\"></td>");
+ }
+
+ out.append("</tr>");
+ }
+ return out.toString();
+ }
+
+ private String encodeTaskListAsJSON(List<IngestionTask> taskList) {
+ List<Map<String, String>> jsonFriendlyTaskList = new Vector<Map<String, String>>();
+ for (IngestionTask task : taskList) {
+ Map<String, String> taskPropMap = new HashMap<String, String>();
+ taskPropMap.put("id", task.getId());
+ taskPropMap.put("createDate", DateUtils.getDateAsISO8601String(task
+ .getCreateDate()));
+ taskPropMap.put("policy", task.getPolicy());
+ taskPropMap.put("productType", task.getProductType());
+ taskPropMap.put("status", task.getStatus());
+ taskPropMap.put("fileList", task.getFileList().toString());
+ taskPropMap.put("extractorClass", task.getExtConf().getClassName());
+ taskPropMap.put("extractorConfFiles", task.getExtConf().getConfigFiles()
+ .toString());
+ jsonFriendlyTaskList.add(taskPropMap);
+ }
+
+ JSONObject resObj = new JSONObject();
+ resObj.put("taskList", jsonFriendlyTaskList);
+ return resObj.toString();
+
+ }
+
+ private String encodeIngestResponseAsHTML(boolean success, String msg) {
+ StringBuffer out = new StringBuffer();
+ if (success) {
+ out.append("Success");
+ } else {
+ out.append(msg);
+ }
+ return out.toString();
+ }
+
+ private String encodeIngestResponseAsJSON(boolean success, String msg) {
+ Map<String, Object> resMap = new HashMap<String, Object>();
+ resMap.put("success", success);
+ resMap.put("msg", msg);
+ JSONObject resObj = new JSONObject();
+ resObj.putAll(resMap);
+ return resObj.toString();
+
+ }
+
+ private Ingester configureIngester() {
+ StdIngester ingest = new StdIngester(DATA_TRANSFER_SERVICE);
+ return ingest;
+ }
+
+ private URL safeGetUrl(String urlStr) {
+ try {
+ return new URL(urlStr);
+ } catch (Exception e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ private List<String> deducePaths(List<String> vPaths) {
+ List<String> absolutePaths = new Vector<String>();
+ String stagingIngestPath = CurationService.config.getStagingAreaPath();
+ if (!stagingIngestPath.endsWith("/")) {
+ stagingIngestPath += "/";
+ }
+
+ for (String vPath : vPaths) {
+ String realPath = stagingIngestPath + vPath;
+ absolutePaths.add(realPath);
+ }
+
+ return absolutePaths;
+ }
+
+ private String getVirtualPath(String stagingAreaPath, String fullFilePath) {
+ int startIdx = stagingAreaPath.length();
+ try {
+ return fullFilePath.substring(startIdx);
+ } catch (Exception e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ class IngestionTaskList {
+
+ private HashMap<String, IngestionTask> taskMap;
+
+ public IngestionTaskList() {
+ this.taskMap = new HashMap<String, IngestionTask>();
+ }
+
+ public synchronized String addIngestionTask(IngestionTask task) {
+ this.provideTaskId(task);
+ taskMap.put(task.getId(), task);
+ return task.getId();
+ }
+
+ public synchronized void removeIngestionTask(String taskId) {
+ taskMap.remove(taskId);
+ }
+
+ public IngestionTask getIngestionTaskById(String taskId) {
+ return taskMap.get(taskId);
+ }
+
+ public List<IngestionTask> getTaskList() {
+ List<IngestionTask> taskList = Arrays.asList(taskMap.values().toArray(
+ new IngestionTask[taskMap.values().size()]));
+ Collections.sort(taskList, new Comparator<IngestionTask>() {
+
+ public int compare(IngestionTask o1, IngestionTask o2) {
+ if (o1.getCreateDate().before(o2.getCreateDate())) {
+ return -1;
+ } else if (o1.getCreateDate().equals(o2.getCreateDate())) {
+ return 0;
+ } else
+ return 1;
+ }
+ });
+ return taskList;
+ }
+
+ private void provideTaskId(IngestionTask task) {
+ UUID id = UUID.randomUUID();
+ task.setId(id.toString());
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/oodt/blob/a47b088a/curator2/src/main/java/org/apache/oodt/cas/curation/service/MetadataResource.java
----------------------------------------------------------------------
diff --git a/curator2/src/main/java/org/apache/oodt/cas/curation/service/MetadataResource.java b/curator2/src/main/java/org/apache/oodt/cas/curation/service/MetadataResource.java
new file mode 100644
index 0000000..77eba3f
--- /dev/null
+++ b/curator2/src/main/java/org/apache/oodt/cas/curation/service/MetadataResource.java
@@ -0,0 +1,970 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.oodt.cas.curation.service;
+
+//JDK imports
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+//JAX-RS imports
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.FormParam;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+
+
+
+//JSON imports
+import net.sf.json.JSONArray;
+import net.sf.json.JSONObject;
+import net.sf.json.JSONSerializer;
+
+
+
+//OODT imports
+import org.apache.oodt.cas.curation.service.CurationService;
+import org.apache.oodt.cas.curation.structs.ExtractorConfig;
+import org.apache.oodt.cas.curation.util.CurationXmlStructFactory;
+import org.apache.oodt.cas.curation.util.ExtractorConfigReader;
+import org.apache.oodt.cas.filemgr.catalog.Catalog;
+import org.apache.oodt.cas.filemgr.repository.XMLRepositoryManager;
+import org.apache.oodt.cas.filemgr.structs.Element;
+import org.apache.oodt.cas.filemgr.structs.Product;
+import org.apache.oodt.cas.filemgr.structs.ProductType;
+import org.apache.oodt.cas.filemgr.structs.Reference;
+import org.apache.oodt.cas.filemgr.structs.exceptions.CatalogException;
+import org.apache.oodt.cas.filemgr.structs.exceptions.RepositoryManagerException;
+import org.apache.oodt.cas.filemgr.structs.exceptions.ValidationLayerException;
+import org.apache.oodt.cas.filemgr.system.XmlRpcFileManagerClient;
+import org.apache.oodt.cas.filemgr.util.GenericFileManagerObjectFactory;
+import org.apache.oodt.cas.filemgr.validation.XMLValidationLayer;
+import org.apache.oodt.cas.metadata.MetExtractor;
+import org.apache.oodt.cas.metadata.Metadata;
+import org.apache.oodt.cas.metadata.SerializableMetadata;
+import org.apache.oodt.cas.metadata.exceptions.MetExtractionException;
+import org.apache.oodt.cas.metadata.util.GenericMetadataObjectFactory;
+
+//SPRING imports
+import org.springframework.util.StringUtils;
+
+@Path("metadata")
+/**
+ *
+ * A web-service endpoint for dealing with CAS {@link Metadata} object.
+ *
+ * @author pramirez
+ * @version $Id$
+ */
+public class MetadataResource extends CurationService {
+
+ @Context
+ UriInfo uriInfo;
+
+ @Context
+ private ServletContext context;
+
+ private static final long serialVersionUID = 1930946924218765724L;
+
+ public static final String STAGING = "staging";
+
+ public static final String CATALOG = "catalog";
+
+ public static final String PRODUCT_TYPE = "productType";
+
+ public static final String UPDATE = "update";
+
+ public static final String DELETE = "delete";
+
+ // single instance of CAS catalog shared among all requests
+ private Catalog catalog = null;
+
+ public MetadataResource(){
+
+ }
+
+ public MetadataResource(@Context ServletContext context) {
+
+ }
+
+ @GET
+ @Path(STAGING)
+ @Produces("text/plain")
+ public String getStagingMetadata(@QueryParam("id") String id,
+ @DefaultValue(FORMAT_HTML) @QueryParam("format") String format,
+ @QueryParam("configId") String configId,
+ @DefaultValue("false") @QueryParam("overwrite") Boolean overwrite,
+ @Context HttpServletRequest req, @Context HttpServletResponse res) {
+
+ // this.sendRedirect("login.jsp", uriInfo, res);
+
+ Metadata metadata = null;
+
+ try {
+ metadata = this.getStagingMetadata(id, configId, overwrite);
+ } catch (Exception e) {
+ return "<div class=\"error\">" + e.getMessage() + "</div>";
+ }
+
+ if (FORMAT_HTML.equals(format)) {
+ return this.getMetadataAsHTML(metadata);
+ }
+ return this.getMetadataAsJSON(metadata).toString();
+ }
+
+ @GET
+ @Path("extractor/config")
+ @Produces("text/plain")
+ public String getMetExtractorConfigList(
+ @DefaultValue("") @QueryParam("current") String current,
+ @DefaultValue(FORMAT_HTML) @QueryParam("format") String format) {
+ String[] configIds = this.getFilesInDirectory(this.config
+ .getMetExtrConfUploadPath(), false);
+
+ if (FORMAT_HTML.equals(format)) {
+ return this.getExtractorConfigIdsAsHTML(configIds, current);
+ }
+ return this.getExtractorConfigIdsAsJSON(configIds);
+ }
+
+ protected String getExtractorConfigIdsAsHTML(String[] configIds,
+ String current) {
+ StringBuffer html = new StringBuffer();
+ for (int i = 0; i < configIds.length; i++) {
+ html.append("<option ");
+ if (configIds[i].equals(current)) {
+ html.append("selected ");
+ }
+ html.append("value=\"");
+ html.append(configIds[i]);
+ html.append("\">");
+ html.append(configIds[i]);
+ html.append("</option>\r\n");
+ }
+ return html.toString();
+ }
+
+ protected String getExtractorConfigIdsAsJSON(String[] configIds) {
+ // TODO: Support JSON WHY, OH WHY!!!
+ return "Not Implemented...";
+ }
+
+ /**
+ *
+ * @param id
+ * Relative path from staging root to product. The met extension will
+ * be added to this id to look up and see if a met file exists with
+ * in the met area.
+ * @param configId
+ * Reference to the extractor config. {@link ExtractorConfigReader}
+ * will load the configuration
+ * @param overwrite
+ * Flag to indicate whether or not to overwrite a met file if present
+ * in the staging area.
+ * @return The {@link Metadata} retrieved from the met area path if present or
+ * extracted using the met extractor config.
+ * @throws FileNotFoundException
+ * @throws InstantiationException
+ * @throws IOException
+ * @throws MetExtractionException
+ */
+ protected Metadata getStagingMetadata(String id, String configId,
+ Boolean overwrite) throws FileNotFoundException, InstantiationException,
+ IOException, MetExtractionException {
+ if (configId == null || configId.trim().length() == 0) {
+ return this.readMetFile(id + CurationService.config.getMetExtension());
+ } else {
+ String relMetPath = id.startsWith("/") ? id : "/" + id;
+ String pathToMetFile = CurationService.config.getMetAreaPath()
+ + relMetPath + CurationService.config.getMetExtension();
+ if (!overwrite && new File(pathToMetFile).exists()) {
+ return this.readMetFile(id + CurationService.config.getMetExtension());
+ } else {
+ // Make sure the parent directory exists
+ new File(pathToMetFile).getParentFile().mkdirs();
+ Metadata metadata = this.runMetExtractor(id, ExtractorConfigReader
+ .readFromDirectory(
+ new File(CurationService.config
+ .getMetExtrConfUploadPath()), configId));
+ this.writeMetFile(id, metadata);
+ return metadata;
+ }
+ }
+ }
+
+ /**
+ *
+ * @param id
+ * Relative path from staging root to the product
+ * @param config
+ * Configuration to run this met extractor
+ * @return
+ * @throws MetExtractionException
+ */
+ protected Metadata runMetExtractor(String id, ExtractorConfig config)
+ throws MetExtractionException {
+ MetExtractor metExtractor = GenericMetadataObjectFactory
+ .getMetExtractorFromClassName(config.getClassName());
+ metExtractor.setConfigFile(config.getConfigFiles().get(0));
+ return metExtractor.extractMetadata(CurationService.config
+ .getStagingAreaPath()
+ + "/" + id);
+ }
+
+ @GET
+ @Path(CATALOG)
+ @Produces("text/plain")
+ public String getCatalogMetadata(@QueryParam("id") String id,
+ @DefaultValue(FORMAT_HTML) @QueryParam("format") String format,
+ @Context HttpServletRequest req, @Context HttpServletResponse res) {
+
+ // this.sendRedirect("login.jsp", uriInfo, res);
+ // Call file manager to get metadata
+ Product prod;
+ Metadata metadata;
+ String productId = id.substring(id.lastIndexOf("/") + 1);
+
+ try {
+ prod = CurationService.config.getFileManagerClient().getProductById(
+ productId);
+ metadata = this.getCatalogMetadata(prod);
+ } catch (Exception e) {
+ return "<div class=\"error\">" + e.getMessage() + "</div>";
+ }
+
+ if (FORMAT_HTML.equals(format)) {
+ return this.getMetadataAsHTML(metadata);
+ }
+ return this.getMetadataAsJSON(metadata).toString();
+ }
+
+ @POST
+ @Path(CATALOG)
+ @Consumes("application/x-www-form-urlencoded")
+ @Produces("text/plain")
+ public String setCatalogMetadata(MultivaluedMap<String, String> formParams,
+ @FormParam("id") String id) {
+
+ Product prod;
+ Metadata metadata = this.getMetadataFromMap(formParams);
+
+ String productId = id.substring(id.lastIndexOf("/") + 1);
+
+ try {
+ prod = CurationService.config.getFileManagerClient().getProductById(
+ productId);
+ this.updateCatalogMetadata(prod, metadata);
+ } catch (Exception e) {
+ e.printStackTrace();
+ return "<div class=\"error\">" + e.getMessage() + "</div>";
+ }
+
+ return this.getMetadataAsHTML(metadata);
+ }
+
+ @GET
+ @Path(PRODUCT_TYPE)
+ @Produces("text/plain")
+ public String getProductTypeMetadata(@QueryParam("id") String id,
+ @DefaultValue(FORMAT_HTML) @QueryParam("format") String format,
+ @Context HttpServletRequest req, @Context HttpServletResponse res) {
+
+ // this.sendRedirect("login.jsp", uriInfo, res);
+
+ Metadata metadata;
+ String[] idParts = id.split("/", 3);
+ String policy = idParts[1];
+ String productType = idParts[2];
+ productType = productType.substring(0, productType.lastIndexOf("/"));
+ try {
+ metadata = getProductTypeMetadataForPolicy(policy, productType);
+ } catch (Exception e) {
+ return "<div class=\"error\">" + e.getMessage() + "</div>";
+ }
+
+ if (FORMAT_HTML.equals(format)) {
+ return this.getMetadataAsHTML(metadata);
+ }
+ return this.getMetadataAsJSON(metadata).toString();
+ }
+
+
+ @POST
+ @Path(PRODUCT_TYPE)
+ @Consumes("application/x-www-form-urlencoded")
+ @Produces("text/plain")
+ public String setProductTypeMetadata(MultivaluedMap<String, String> formParams) {
+ String[] idParts = formParams.getFirst("id").split("/");
+ String policy = idParts[1];
+ String productType = idParts[2];
+ try {
+ this.writeProductTypeMetadata(policy, productType, this
+ .getMetadataFromMap(formParams));
+ } catch (Exception e) {
+ return "<div class=\"error\">" + e.getMessage() + "</div>";
+ }
+ return "";
+ }
+
+ @POST
+ @Path(STAGING)
+ @Consumes("application/x-www-form-urlencoded")
+ @Produces("text/plain")
+ public String setStagingMetadata(MultivaluedMap<String, String> formParams) {
+ try {
+ this.writeMetFile(formParams.getFirst("id"), this
+ .getMetadataFromMap(formParams));
+ } catch (Exception e) {
+ return "<div class=\"error\">" + e.getMessage() + "</div>";
+ }
+ return "";
+ }
+
+ @GET
+ @Path("staging/info")
+ @Produces("text/plain")
+ public String getMetadataInfo(@QueryParam("id") String id) {
+
+ return "Staging met info";
+ }
+
+
+ private JSONObject getMetadataAsJSON(Metadata metadata) {
+ return JSONObject.fromObject(metadata.getHashTable());
+ }
+
+ private Metadata getMetadataFromJSON(String metadataJSON) {
+ JSONObject json = (JSONObject) JSONSerializer.toJSON(metadataJSON);
+ Metadata metadata = new Metadata();
+
+ Set<String> keys = json.keySet();
+ for (String key : keys) {
+ List values = (List) JSONSerializer.toJava((JSONArray) json.get(key));
+ metadata.addMetadata(key, values);
+ }
+
+ return metadata;
+ }
+
+ private Metadata getMetadataFromMap(MultivaluedMap<String, String> formParams) {
+ Metadata metadata = new Metadata();
+
+ for (String key : formParams.keySet()) {
+ if (key.startsWith("metadata.")) {
+ String newKey = key.substring(key.indexOf('.') + 1);
+ for (String value : formParams.get(key)) {
+ metadata.addMetadata(newKey, value);
+ }
+ }
+ }
+
+ return metadata;
+ }
+
+ protected String getMetadataAsHTML(Metadata metadata) {
+ if (metadata == null) {
+ return "<table></table>";
+ }
+
+ StringBuffer html = new StringBuffer();
+
+ html.append("<table>\r\n");
+ for (String key : (Set<String>) metadata.getHashTable().keySet()) {
+ html.append(" <tr>\r\n");
+ html.append(" <th>").append(key).append("</th>\r\n");
+ html.append(" <td class=\"").append(key).append("\">");
+ List<String> values = metadata.getAllMetadata(key);
+ for (Iterator<String> i = values.iterator(); i.hasNext();) {
+ html.append("<span>").append(i.next()).append("</span>");
+ if (i.hasNext()) {
+ html.append(", ");
+ }
+ }
+ for (String value : (List<String>) metadata.getAllMetadata(key)) {
+ }
+ html.append("</td>\r\n");
+ html.append(" </tr>\r\n");
+ }
+ html.append("</table>\r\n");
+
+ return html.toString();
+ }
+
+
+ /**
+ * Reads a {@link Metadata} object from a String representation of a .met
+ * {@link File}.
+ *
+ * @param file
+ * The full path to the .met {@link File}.
+ * @return The read-in CAS {@link Metadata} object.
+ * @throws InstantiationException
+ * @throws InstantiationException
+ * If there is an error instantiating the {@link Metadata} class.
+ * @throws IOException
+ * @throws FileNotFoundException
+ * @throws FileNotFoundException
+ * If the .met {@link File} is not found.
+ * @throws IOException
+ * If there is an IO problem opening the met file.
+ */
+ public Metadata readMetFile(String file) throws InstantiationException,
+ FileNotFoundException, IOException {
+ SerializableMetadata metadata = new SerializableMetadata("UTF-8", false);
+ metadata.loadMetadataFromXmlStream(new FileInputStream(config
+ .getMetAreaPath()
+ + "/" + file));
+
+ return metadata;
+ }
+
+ /**
+ * Retrieves the cataloged {@link Metadata} associated with a {@link Product}.
+ *
+ * @param product
+ * The {@link Product} to obtain cataloged {@link Metadata} for.
+ * @return The cataloged {@link Metadata} for {@link Product}.
+ * @throws CatalogException
+ * If there is an error talking to the CAS File Manager
+ * {@link Catalog}.
+ */
+ public Metadata getCatalogMetadata(Product product) throws CatalogException {
+ return CurationService.config.getFileManagerClient().getMetadata(
+ CurationService.config.getFileManagerClient().getProductById(
+ product.getProductId()));
+ }
+
+ /**
+ * Writes a CAS {@link Metadata} {@link File} using the given identifier.
+ *
+ * @param id
+ * The identifier of the .met file to write.
+ * @param metadata
+ * The {@link Metadata} object to persist and write to a {@link File}
+ * .
+ * @throws FileNotFoundException
+ * If the .met {@link File} cannot be written.
+ * @throws IOException
+ * If there is an IO exception writing the {@link File}.
+ */
+ public void writeMetFile(String id, Metadata metadata)
+ throws FileNotFoundException, IOException {
+ SerializableMetadata serMet = new SerializableMetadata(metadata, "UTF-8",
+ false);
+ serMet.writeMetadataToXmlStream(new FileOutputStream(new File(config
+ .getMetAreaPath(), id + config.getMetExtension())));
+ }
+
+ /**
+ * Method to update the catalog metadata for a given product.
+ * All current metadata fields will be preserved,
+ * except those specified in the HTTP POST request as 'metadata.<field_name>=<field_value>'.
+ *
+ * @param id
+ * identifier of CAS product - either 'id' or 'name' must be specified
+ * @param name
+ * name of CAS product - either 'id' or 'name' must be specified
+ * @param formParams
+ * HTTP (name, value) form parameters. The parameter names MUST start with "metadata."
+ * @param replace
+ * optional flag set to false to add the new metadata values to the existing values, for the given flags
+ */
+ @POST
+ @Path(UPDATE)
+ @Consumes("application/x-www-form-urlencoded")
+ @Produces("text/plain")
+ public String updateMetadata(MultivaluedMap<String, String> formParams,
+ @FormParam("id") String id,
+ @FormParam("name") String name,
+ @DefaultValue("true") @FormParam("replace") boolean replace,
+ @DefaultValue("false") @FormParam("remove") boolean remove) {
+
+ // new metadata from HTTP POST request
+ Metadata newMetadata = this.getMetadataFromMap(formParams);
+
+ // client for interacting with remote File Manager
+ XmlRpcFileManagerClient fmClient = CurationService.config.getFileManagerClient();
+
+ // empty metadata
+ Metadata metadata = new Metadata();
+
+ try {
+
+ // retrieve product from catalog
+ Product product = null;
+ if (StringUtils.hasText(id)) {
+ id = id.substring(id.lastIndexOf("/") + 1);
+ product = fmClient.getProductById(id);
+ } else if (StringUtils.hasText(name)) {
+ product = fmClient.getProductByName(name);
+ } else {
+ throw new Exception("Either the HTTP parameter 'id' or the HTTP parameter 'name' must be specified");
+ }
+
+ // retrieve existing metadata
+ metadata = fmClient.getMetadata(product);
+
+ // remove product references (as they will be added later)
+ metadata.removeMetadata("reference_orig");
+ metadata.removeMetadata("reference_data_store");
+ metadata.removeMetadata("reference_fileSize");
+ metadata.removeMetadata("reference_mimeType");
+
+ // merge new and existing metadata
+ metadata.addMetadata(newMetadata);
+
+ // replace metadata values for keys specified in HTTP request (not others)
+ if (replace) {
+ for (String key : newMetadata.getAllKeys()) {
+ metadata.replaceMetadata(key, newMetadata.getAllMetadata(key));
+ }
+ }
+
+ // remove metadata tags
+ if (remove) {
+ for (String key : newMetadata.getAllKeys()) {
+ metadata.removeMetadata(key);
+ }
+ }
+
+ // insert old and new metadata
+ fmClient.updateMetadata(product, metadata);
+
+ // return product id to downstream processors
+ return "id="+product.getProductId();
+
+ } catch (Exception e) {
+
+ e.printStackTrace();
+ // return error message
+ throw new WebApplicationException(e, Response.Status.INTERNAL_SERVER_ERROR);
+
+ }
+
+ }
+
+ /**
+ * Updates the cataloged {@link Metadata} for a {@link Product} in the CAS
+ * File Manager.
+ *
+ * @param product
+ * The {@link Product} to update {@link Metadata} for.
+ * @param newMetadata
+ * The new {@link Metadata} to persist into the {@link Catalog}.
+ * @throws CatalogException
+ * If any error occurs during the update.
+ * @throws IOException
+ * @throws FileNotFoundException
+ */
+ public void updateCatalogMetadata(Product product, Metadata newMetadata)
+ throws CatalogException, FileNotFoundException, IOException {
+ System.getProperties().load(
+ new FileInputStream(CurationService.config.getFileMgrProps()));
+ Catalog catalog = this.getCatalog();
+
+ Metadata oldMetadata = catalog.getMetadata(product);
+ List<Reference> references = catalog.getProductReferences(product);
+ Product newProduct = new Product(product.getProductName(), product
+ .getProductType(), product.getProductStructure(), product
+ .getTransferStatus(), product.getProductReferences());
+ // Constructor is bugged and doesn't set transfer status
+ newProduct.setTransferStatus(product.getTransferStatus());
+ catalog.removeMetadata(oldMetadata, product);
+ catalog.removeProduct(product);
+ newProduct.setProductId(product.getProductId());
+ catalog.addProduct(newProduct);
+ newProduct.setProductReferences(references);
+ catalog.addProductReferences(newProduct);
+ catalog.addMetadata(newMetadata, newProduct);
+ }
+
+ /**
+ * Method to delete a specific product from the catalog
+ *
+ * @param id
+ * identifier of CAS product - either 'id' or 'name' must be specified
+ * @param name
+ * name of CAS product - either 'id' or 'name' must be specified
+ * @return the product ID of the deleted product if deletion successful
+ */
+ @POST
+ @Path(DELETE)
+ @Consumes("application/x-www-form-urlencoded")
+ @Produces("text/plain")
+ public String deleteCatalogMetadata(
+ @FormParam("id") String id,
+ @FormParam("name") String name) {
+
+ try {
+ // retrieve product from catalog
+ Product product = null;
+ if (StringUtils.hasText(id)) {
+ id = id.substring(id.lastIndexOf("/") + 1);
+ product = CurationService.config.getFileManagerClient().getProductById(id);
+ } else if (StringUtils.hasText(name)) {
+ product = CurationService.config.getFileManagerClient().getProductByName(name);
+ } else {
+ throw new Exception("Either the HTTP parameter 'id' or the HTTP parameter 'name' must be specified");
+ }
+
+ // remove product from catalog
+ this.deleteCatalogProduct(product);
+
+ // return product id to downstream processors
+ return "id="+product.getProductId();
+
+ } catch (Exception e) {
+
+ e.printStackTrace();
+ // return error message
+ throw new WebApplicationException(e, Response.Status.INTERNAL_SERVER_ERROR);
+
+ }
+ }
+
+ /**
+ * Deletes a given product from the catalog
+ *
+ * @param product
+ * The {@link Product} to delete
+ * @throws FileNotFoundException
+ * @throws IOException
+ * @throws CatalogException
+ * If any error occurs during this delete operation.
+ */
+ public void deleteCatalogProduct(Product product)
+ throws FileNotFoundException, IOException, CatalogException {
+ CurationService.config.getFileManagerClient().removeProduct(product);
+ }
+
+ private Metadata getProductTypeMetadataForPolicy(String policy,
+ String productTypeName) throws MalformedURLException,
+ InstantiationException, RepositoryManagerException {
+ String rootPolicyPath = this.cleanse(CurationService.config
+ .getPolicyUploadPath());
+ String policyPath = new File(rootPolicyPath + policy).toURL()
+ .toExternalForm();
+ String[] policies = { policyPath };
+ XMLRepositoryManager repMgr = new XMLRepositoryManager(Arrays
+ .asList(policies));
+ ProductType productType = repMgr.getProductTypeByName(productTypeName);
+
+ return productType.getTypeMetadata();
+ }
+
+ private Metadata writeProductTypeMetadata(String policy,
+ String productTypeName, Metadata metadata) throws Exception {
+ String rootPolicyPath = this.cleanse(CurationService.config
+ .getPolicyUploadPath());
+ String policyPath = new File(rootPolicyPath + policy).toURL()
+ .toExternalForm();
+ String[] policies = { policyPath };
+ XMLRepositoryManager repMgr = new XMLRepositoryManager(Arrays
+ .asList(policies));
+
+ ProductType productType = repMgr.getProductTypeByName(productTypeName);
+ productType.setTypeMetadata(metadata);
+
+ CurationXmlStructFactory.writeProductTypeXmlDocument(repMgr
+ .getProductTypes(), rootPolicyPath + policy + "/product-types.xml");
+
+ // refresh the config on the fm end
+ CurationService.config.getFileManagerClient().refreshConfigAndPolicy();
+
+ return productType.getTypeMetadata();
+ }
+
+ private String cleanse(String origPath) {
+ String retStr = origPath;
+ if (!retStr.endsWith("/")) {
+ retStr += "/";
+ }
+ return retStr;
+ }
+
+ // Method to instantiate the CAS catalog, if not done already.
+ private synchronized Catalog getCatalog() {
+
+ if (catalog==null) {
+ String catalogFactoryClass = this.context.getInitParameter(CATALOG_FACTORY_CLASS);
+ // preserve backward compatibility
+ if (!StringUtils.hasText(catalogFactoryClass))
+ catalogFactoryClass = "org.apache.oodt.cas.filemgr.catalog.LuceneCatalogFactory";
+ catalog = GenericFileManagerObjectFactory.getCatalogServiceFromFactory(catalogFactoryClass);
+ }
+
+ return catalog;
+ }
+
+ @DELETE
+ @Path(PRODUCT_TYPE+"/remove")
+ @Produces("text/plain")
+ public boolean removeProductType(
+ @FormParam("policy") String policy,
+ @FormParam("id") String id) {
+ XMLRepositoryManager xmlRepo = getRepo(policy);
+ try {
+ ProductType type = xmlRepo.getProductTypeById(id);
+ xmlRepo.removeProductType(type);
+ return true;
+ } catch (RepositoryManagerException e) {
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ @GET
+ @Path(PRODUCT_TYPE+"/parentmap")
+ @Produces("text/plain")
+ public String getParentTypeMap(
+ @FormParam("policy") String policy) {
+ XMLValidationLayer vLayer = getValidationLayer(policy);
+ return JSONSerializer.toJSON(vLayer.getSubToSuperMap()).toString();
+ }
+
+ @POST
+ @Path(PRODUCT_TYPE+"/parent/add")
+ @Produces("text/plain")
+ public boolean addParentForProductType(
+ @FormParam("policy") String policy,
+ @FormParam("id") String id,
+ @FormParam("parentId") String parentId) {
+ XMLValidationLayer vLayer = getValidationLayer(policy);
+ XMLRepositoryManager xmlRepo = getRepo(policy);
+ try {
+ ProductType type = xmlRepo.getProductTypeById(id);
+ vLayer.addParentForProductType(type, parentId);
+ return true;
+ } catch (RepositoryManagerException e) {
+ e.printStackTrace();
+ }
+ return false;
+ }
+
+ @DELETE
+ @Path(PRODUCT_TYPE+"/parent/remove")
+ @Produces("text/plain")
+ public boolean removeParentForProductType(
+ @FormParam("policy") String policy,
+ @FormParam("id") String id)
+ throws ValidationLayerException {
+ XMLValidationLayer vLayer = getValidationLayer(policy);
+ XMLRepositoryManager xmlRepo = getRepo(policy);
+ try {
+ ProductType type = xmlRepo.getProductTypeById(id);
+ vLayer.removeParentForProductType(type);
+ return true;
+ } catch (RepositoryManagerException e) {
+ e.printStackTrace();
+ }
+ return false;
+ }
+
+ @POST
+ @Path(PRODUCT_TYPE+"/elements/add")
+ @Produces("text/plain")
+ public boolean addElementsForProductType(
+ @FormParam("policy") String policy,
+ @FormParam("id") String id,
+ @FormParam("elementIds") String elementIds) {
+ XMLValidationLayer vLayer = getValidationLayer(policy);
+ XMLRepositoryManager xmlRepo = getRepo(policy);
+ try {
+ ProductType type = xmlRepo.getProductTypeById(id);
+ for(String elementid: elementIds.split(",")) {
+ Element element = vLayer.getElementById(elementid);
+ if(element == null) {
+ element = new Element(elementid, elementid, "", "", "Automatically added", "");
+ vLayer.addElement(element);
+ }
+ vLayer.addElementToProductType(type, element);
+ }
+ return true;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return false;
+ }
+
+ @GET
+ @Path(PRODUCT_TYPE+"/elements")
+ @Produces("text/plain")
+ public String getElementsForProductType(
+ @FormParam("policy") String policy,
+ @FormParam("id") String id,
+ @FormParam("direct") boolean direct) {
+ XMLValidationLayer vLayer = getValidationLayer(policy);
+ XMLRepositoryManager xmlRepo = getRepo(policy);
+ try {
+ ProductType type = xmlRepo.getProductTypeById(id);
+ ArrayList<String> elementIds = new ArrayList<String>();
+ for(Element el : vLayer.getElements(type, direct)) {
+ elementIds.add(el.getElementId());
+ }
+ return JSONSerializer.toJSON(elementIds).toString();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ @DELETE
+ @Path(PRODUCT_TYPE+"/elements/remove/all")
+ @Produces("text/plain")
+ public boolean removeAllElementsForProductType(
+ @FormParam("policy") String policy,
+ @FormParam("id") String id) {
+ XMLValidationLayer vLayer = getValidationLayer(policy);
+ XMLRepositoryManager xmlRepo = getRepo(policy);
+ try {
+ ProductType type = xmlRepo.getProductTypeById(id);
+ List<Element> elementList = vLayer.getElements(type);
+ for(Element element: elementList) {
+ vLayer.removeElementFromProductType(type, element);
+ }
+ this.removeUnusedElements(elementList, xmlRepo, vLayer);
+ return true;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return false;
+ }
+
+ @DELETE
+ @Path(PRODUCT_TYPE+"/elements/remove")
+ @Produces("text/plain")
+ public boolean removeElementsForProductType(
+ @FormParam("policy") String policy,
+ @FormParam("id") String id,
+ @FormParam("elementIds") String elementIds) {
+ XMLValidationLayer vLayer = getValidationLayer(policy);
+ XMLRepositoryManager xmlRepo = getRepo(policy);
+ try {
+ ProductType type = xmlRepo.getProductTypeById(id);
+ ArrayList<Element> elements = new ArrayList<Element>();
+ for(String elementId: elementIds.split(",")) {
+ Element element = vLayer.getElementById(elementId);
+ if(element != null) {
+ vLayer.removeElementFromProductType(type, element);
+ elements.add(element);
+ }
+ }
+ this.removeUnusedElements(elements, xmlRepo, vLayer);
+ return true;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return false;
+ }
+
+ @GET
+ @Path(PRODUCT_TYPE+"/typeswithelement/{elementId}")
+ @Produces("text/plain")
+ public String getProductTypeIdsHavingElement(
+ @FormParam("policy") String policy,
+ @PathParam("elementId") String elementId) {
+ XMLValidationLayer vLayer = getValidationLayer(policy);
+ XMLRepositoryManager xmlRepo = getRepo(policy);
+ ArrayList<String> typeids = new ArrayList<String>();
+ try {
+ for(ProductType type : xmlRepo.getProductTypes()) {
+ for(Element el : vLayer.getElements(type)) {
+ if(el.getElementId().equals(elementId))
+ typeids.add(type.getProductTypeId());
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return JSONSerializer.toJSON(typeids).toString();
+ }
+
+
+ /*
+ * Private helper functions
+ */
+ private void removeUnusedElements(List<Element> elements,
+ XMLRepositoryManager xmlRepo, XMLValidationLayer vLayer)
+ throws ValidationLayerException, RepositoryManagerException {
+ // Remove Elements that aren't used in any product type
+ List<ProductType> ptypelist = xmlRepo.getProductTypes();
+ HashMap<String, Boolean> usedElementIds = new HashMap<String, Boolean>();
+ for(ProductType ptype: ptypelist) {
+ List<Element> ptypeElements =
+ vLayer.getElements(ptype);
+ for(Element el: ptypeElements) {
+ usedElementIds.put(el.getElementId(), true);
+ }
+ }
+ for(Element el: elements) {
+ if(!usedElementIds.containsKey(el.getElementId()))
+ vLayer.removeElement(el);
+ }
+ }
+
+ private XMLRepositoryManager getRepo(String policy) {
+ XMLRepositoryManager xmlRepo = null;
+ String url = "file://" + CurationService.config.getPolicyUploadPath() + "/" + policy;
+
+ try {
+ xmlRepo = new XMLRepositoryManager(Collections.singletonList(url));
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ return xmlRepo;
+ }
+
+ private XMLValidationLayer getValidationLayer(String policy) {
+ XMLValidationLayer vLayer = null;
+ String url = "file://" + CurationService.config.getPolicyUploadPath() + "/" + policy;
+
+ try {
+ vLayer = new XMLValidationLayer(Collections.singletonList(url));
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return vLayer;
+ }
+}
http://git-wip-us.apache.org/repos/asf/oodt/blob/a47b088a/curator2/src/main/java/org/apache/oodt/cas/curation/service/PolicyResource.java
----------------------------------------------------------------------
diff --git a/curator2/src/main/java/org/apache/oodt/cas/curation/service/PolicyResource.java b/curator2/src/main/java/org/apache/oodt/cas/curation/service/PolicyResource.java
new file mode 100644
index 0000000..ff98753
--- /dev/null
+++ b/curator2/src/main/java/org/apache/oodt/cas/curation/service/PolicyResource.java
@@ -0,0 +1,310 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.oodt.cas.curation.service;
+
+//OODT imports
+import org.apache.commons.lang.StringEscapeUtils;
+import org.apache.oodt.cas.filemgr.repository.XMLRepositoryManager;
+import org.apache.oodt.cas.filemgr.structs.Product;
+import org.apache.oodt.cas.filemgr.structs.ProductPage;
+import org.apache.oodt.cas.filemgr.structs.ProductType;
+import org.apache.oodt.cas.filemgr.structs.Query;
+import org.apache.oodt.cas.filemgr.structs.exceptions.RepositoryManagerException;
+
+//JDK imports
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Vector;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+//JAX-RS imports
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.UriInfo;
+
+//JSON imports
+import net.sf.json.JSONObject;
+
+@Path("policy")
+public class PolicyResource extends CurationService {
+
+ @Context
+ UriInfo uriInfo;
+
+ private static final long serialVersionUID = -3757481221589264709L;
+
+ private static final Logger LOG = Logger.getLogger(PolicyResource.class
+ .getName());
+
+ private static final FilenameFilter DIR_FILTER = new FilenameFilter() {
+
+ public boolean accept(File dir, String name) {
+ return new File(dir, name).isDirectory()
+ && !new File(dir, name).getName().startsWith(".");
+ }
+ };
+
+ public PolicyResource(@Context ServletContext context){
+
+ }
+
+ @GET
+ @Path("browse")
+ @Produces("text/plain")
+ public String browseCatalog(
+ @QueryParam("path") @DefaultValue("/") String path,
+ @DefaultValue(FORMAT_HTML) @QueryParam("format") String format,
+ @DefaultValue("1") @QueryParam("pageNum") Integer pageNum,
+ @Context HttpServletRequest req, @Context HttpServletResponse res)
+ throws IOException {
+
+ // TODO: Send a not authorized response if not logged in. This should be a
+ // utility method as a part of CurationService that every service interface
+ // calls.
+
+ String[] pathToks = tokenizeVirtualPath(path);
+ String policy = null;
+ String productType = null;
+
+ if (pathToks == null) {
+ LOG.log(Level.WARNING, "malformed path token string: "
+ + Arrays.asList(pathToks));
+ return "";
+ }
+
+ policy = pathToks.length > 0 ? pathToks[0]:null;
+ productType = pathToks.length > 1 ? pathToks[1] : null;
+
+ if (policy != null) {
+ if (productType != null) {
+ return getProductsForProductType(policy, productType, format, pageNum);
+ } else {
+ return getProductTypesForPolicy(policy, format);
+ }
+ } else {
+ return getPolicies(format);
+ }
+
+ }
+
+ private String getProductsForProductType(String policy,
+ String productTypeName,
+ String format, int pageNum) {
+
+ ProductType productType;
+ ProductPage page;
+ try {
+ productType = this.config.getFileManagerClient().getProductTypeByName(
+ productTypeName);
+ page = this.config.getFileManagerClient().pagedQuery(new Query(),
+ productType, pageNum);
+ } catch (Exception e) {
+ e.printStackTrace();
+ LOG.log(Level.WARNING, "Unable to obtain products for product type: ["
+ + productTypeName + "]: Message: " + e.getMessage());
+ return "";
+ }
+
+ if (format.equals(FORMAT_HTML)) {
+ return encodeProductsAsHTML(page, policy, productTypeName);
+ } else if (format.equals(FORMAT_JSON)) {
+ return encodeProductsAsJSON(page, policy, productTypeName);
+ } else {
+ return UNKNOWN_OUT_FORMAT;
+ }
+ }
+
+ private String encodeProductsAsHTML(ProductPage page, String policy,
+ String productTypeName) {
+ StringBuffer html = new StringBuffer();
+ html.append("<ul class=\"fileTree\" >\r\n");
+
+ for (Product product : page.getPageProducts()) {
+ html.append(" <li class=\"file\">");
+ html.append("<a href=\"#\" rel=\"/");
+ html.append(policy);
+ html.append("/");
+ html.append(productTypeName);
+ html.append("/");
+ html.append(product.getProductId());
+ html.append("\">");
+ html.append(product.getProductName());
+ html.append("</a>");
+ html.append("</li>\r\n");
+ }
+
+ html.append("</ul>");
+ return html.toString();
+ }
+
+ private String encodeProductsAsJSON(ProductPage page, String policy,
+ String productTypeName) {
+ return "NOT IMPLENTED YET";
+ }
+
+ private String getPolicies(String format) {
+ String policyPath = this.cleanse(CurationService.config
+ .getPolicyUploadPath());
+ String[] policyDirs = new File(policyPath).list(DIR_FILTER);
+
+ if (format.equals(FORMAT_HTML)) {
+ return encodePoliciesAsHTML(policyDirs);
+ } else if (format.equals(FORMAT_JSON)) {
+ return encodePoliciesAsJSON(policyDirs);
+ } else {
+ return UNKNOWN_OUT_FORMAT;
+ }
+
+ }
+
+ private String getProductTypesForPolicy(String policy, String format) {
+ String[] typeNames = null;
+ try {
+ typeNames = this.getProductTypeNamesForPolicy(policy);
+ } catch (Exception e) {
+ e.printStackTrace();
+ LOG.log(Level.WARNING,
+ "Unable to obtain product type names for policy: [" + policy
+ + "]: Message: " + e.getMessage());
+ return "";
+ }
+
+ if (format.equals(FORMAT_HTML)) {
+ return encodeProductTypesAsHTML(policy, typeNames);
+ } else if (format.equals(FORMAT_JSON)) {
+ return encodeProductTypesAsJSON(policy, typeNames);
+ } else {
+ return UNKNOWN_OUT_FORMAT;
+ }
+
+ }
+
+ private String encodePoliciesAsHTML(String[] policyDirs) {
+ StringBuffer out = new StringBuffer();
+ out.append("<ul class=\"fileTree\" >");
+ for (String policy : policyDirs) {
+ out.append("<li class=\"directory collapsed\"><a href=\"#\" rel=\"/");
+ out.append(StringEscapeUtils.escapeHtml(policy));
+ out.append("/\">");
+ out.append(StringEscapeUtils.escapeHtml(policy));
+ out.append("</a></li>");
+ }
+ out.append("</ul>");
+ return out.toString();
+ }
+
+ private String encodePoliciesAsJSON(String[] policyDirs) {
+ Map<String, String> retMap = new HashMap<String, String>();
+ for (String policyDir : policyDirs) {
+ retMap.put("policy", policyDir);
+ }
+ JSONObject resObj = new JSONObject();
+ resObj.put("policies", retMap);
+ resObj.put("succeed", true);
+ return resObj.toString();
+ }
+
+ private String encodeProductTypesAsHTML(String policy, String[] typeNames) {
+ StringBuffer out = new StringBuffer();
+ out.append("<ul class=\"fileTree\" >");
+ for (String type : typeNames) {
+ out
+ .append("<li class=\"directory collapsed productType\"><a href=\"#\" rel=\"/");
+ out.append(StringEscapeUtils.escapeHtml(policy));
+ out.append("/");
+ out.append(StringEscapeUtils.escapeHtml(type));
+ out.append("/\">");
+ out.append(StringEscapeUtils.escapeHtml(type));
+ out.append("</a></li>");
+ }
+
+ out.append("</ul>");
+ return out.toString();
+ }
+
+ private String encodeProductTypesAsJSON(String policy, String[] typeNames) {
+ Map<String, Object> retMap = new HashMap<String, Object>();
+ retMap.put("policy", policy);
+ List<Map<String, String>> typeList = new Vector<Map<String, String>>();
+ for (String typeName : typeNames) {
+ Map<String, String> typeMap = new HashMap<String, String>();
+ typeMap.put("name", typeName);
+ typeList.add(typeMap);
+ }
+ retMap.put("productTypes", typeList);
+ JSONObject resObj = new JSONObject();
+ resObj.putAll(retMap);
+ return resObj.toString();
+ }
+
+ private String[] getProductTypeNamesForPolicy(String policy)
+ throws MalformedURLException, InstantiationException,
+ RepositoryManagerException {
+ String rootPolicyPath = this.cleanse(CurationService.config
+ .getPolicyUploadPath());
+ String policyPath = new File(rootPolicyPath + policy).toURL()
+ .toExternalForm();
+ String[] policies = { policyPath };
+ XMLRepositoryManager repMgr = new XMLRepositoryManager(Arrays
+ .asList(policies));
+ List<ProductType> types = repMgr.getProductTypes();
+ String[] typeNames = new String[types.size()];
+ int i = 0;
+ for (ProductType type : types) {
+ typeNames[i] = type.getName();
+ i++;
+ }
+
+ return typeNames;
+ }
+
+ private String cleanse(String origPath) {
+ String retStr = origPath;
+ if (!retStr.endsWith("/")) {
+ retStr += "/";
+ }
+ return retStr;
+ }
+
+ private String[] tokenizeVirtualPath(String path) {
+ String vPath = path;
+ if (vPath.startsWith("/") && vPath.length() != 1) {
+ vPath = vPath.substring(1);
+ }
+ String[] pathToks = vPath.split("/");
+ LOG.log(Level.INFO, "origPath: ["+path+"]");
+ LOG.log(Level.INFO, "pathToks: "+Arrays.asList(pathToks));
+ return pathToks;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/oodt/blob/a47b088a/curator2/src/main/java/org/apache/oodt/cas/curation/service/SystemResource.java
----------------------------------------------------------------------
diff --git a/curator2/src/main/java/org/apache/oodt/cas/curation/service/SystemResource.java b/curator2/src/main/java/org/apache/oodt/cas/curation/service/SystemResource.java
new file mode 100644
index 0000000..784d383
--- /dev/null
+++ b/curator2/src/main/java/org/apache/oodt/cas/curation/service/SystemResource.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.oodt.cas.curation.service;
+
+//JAX-RS imports
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.UriInfo;
+
+@Path("system")
+public class SystemResource extends CurationService {
+
+ @Context
+ UriInfo uriInfo;
+
+ private static final long serialVersionUID = -2318607955517605998L;
+
+ /**
+ * This is what will go in the upper left box on landing page. To gather
+ * information such as is the file manager up If this needs to be something
+ * that gets updated periodically then it would change into a JSON feed
+ */
+ @GET
+ @Path("stats")
+ @Produces("text/html")
+ public String getStatistics() {
+ return "<div>Server Stats</div>";
+ }
+
+ /**
+ * This returns the configuration information that is set in the context.xml
+ * file.
+ */
+ @GET
+ @Path("config")
+ @Produces("text/html")
+ public String getConfig() {
+ return "";
+ }
+
+ /**
+ * This will return the information that appears in the upper right box on
+ * landing page.
+ */
+ @GET
+ @Path("feed")
+ @Produces("text/html")
+ public String getFeed() {
+ return "<div>Latest Products?</div>";
+ }
+}
http://git-wip-us.apache.org/repos/asf/oodt/blob/a47b088a/curator2/src/main/java/org/apache/oodt/cas/curation/servlet/CuratorConfMetKeys.java
----------------------------------------------------------------------
diff --git a/curator2/src/main/java/org/apache/oodt/cas/curation/servlet/CuratorConfMetKeys.java b/curator2/src/main/java/org/apache/oodt/cas/curation/servlet/CuratorConfMetKeys.java
new file mode 100644
index 0000000..6233775
--- /dev/null
+++ b/curator2/src/main/java/org/apache/oodt/cas/curation/servlet/CuratorConfMetKeys.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.oodt.cas.curation.servlet;
+
+/**
+ *
+ * Met keys used in the <code>context.xml</code> file to configure the CAS
+ * curator webapp.
+ *
+ * @author mattmann
+ * @version $Revision$
+ *
+ */
+public interface CuratorConfMetKeys {
+
+ final String MET_EXTRACTOR_CONF_UPLOAD_PATH = "org.apache.oodt.cas.curator.metExtractorConf.uploadPath";
+
+ final String POLICY_UPLOAD_PATH = "org.apache.oodt.cas.curator.dataDefinition.uploadPath";
+
+ final String FM_URL = "org.apache.oodt.cas.fm.url";
+
+ final String SSO_IMPL_CLASS = "org.apache.oodt.security.sso.implClass";
+
+ final String DEFAULT_TRANSFER_FACTORY = "org.apache.oodt.cas.filemgr.datatransfer.LocalDataTransferFactory";
+
+ final String CRAWLER_CONF_FILE = "classpath:/org.apache/oodt/cas/crawl/crawler-config.xml";
+
+ final String PROJECT_DISPLAY_NAME = "org.apache.oodt.cas.curator.projectName";
+
+ final String STAGING_AREA_PATH = "org.apache.oodt.cas.curator.stagingAreaPath";
+
+ final String MET_AREA_PATH = "org.apache.oodt.cas.curator.metAreaPath";
+
+ final String MET_EXTENSION = "org.apache.oodt.cas.curator.metExtension";
+
+ final String FM_PROPS = "org.apache.oodt.cas.curator.fmProps";
+
+ final String CATALOG_FACTORY_CLASS = "org.apache.oodt.cas.curator.catalogFactoryClass";
+
+}
http://git-wip-us.apache.org/repos/asf/oodt/blob/a47b088a/curator2/src/main/java/org/apache/oodt/cas/curation/servlet/CuratorServlet.java
----------------------------------------------------------------------
diff --git a/curator2/src/main/java/org/apache/oodt/cas/curation/servlet/CuratorServlet.java b/curator2/src/main/java/org/apache/oodt/cas/curation/servlet/CuratorServlet.java
new file mode 100644
index 0000000..aed7f14
--- /dev/null
+++ b/curator2/src/main/java/org/apache/oodt/cas/curation/servlet/CuratorServlet.java
@@ -0,0 +1,28 @@
+/**
+ *
+ */
+package org.apache.oodt.cas.curation.servlet;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+
+import org.apache.oodt.cas.curation.configuration.Configuration;
+
+
+/**
+ * Handles basic servlet features like config
+ *
+ * @author starchmd
+ */
+public class CuratorServlet extends HttpServlet {
+
+ private static final long serialVersionUID = 1498427942585673418L;
+
+ @Override
+ public void init(ServletConfig conf) throws ServletException {
+ super.init(conf);
+ //Load configuration from context
+ Configuration.loadConfiguration(conf.getServletContext());
+ }
+}
http://git-wip-us.apache.org/repos/asf/oodt/blob/a47b088a/curator2/src/main/java/org/apache/oodt/cas/curation/structs/ExtractorConfig.java
----------------------------------------------------------------------
diff --git a/curator2/src/main/java/org/apache/oodt/cas/curation/structs/ExtractorConfig.java b/curator2/src/main/java/org/apache/oodt/cas/curation/structs/ExtractorConfig.java
new file mode 100644
index 0000000..79beb30
--- /dev/null
+++ b/curator2/src/main/java/org/apache/oodt/cas/curation/structs/ExtractorConfig.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.oodt.cas.curation.structs;
+
+import java.io.File;
+import java.util.List;
+/**
+ * A class holding the configuration for metadata extractors
+ *
+ * @author starchmd - cleanup only, original author unspecified
+ */
+public class ExtractorConfig {
+
+ public final static String PROP_CLASS_NAME = "extractor.classname";
+ public final static String PROP_CONFIG_FILES = "extractor.config.files";
+ public final static String PROP_FILLER = "extractor.filler";
+
+ private final List<File> configFiles;
+ private final String className;
+ private final String identifier;
+ private final String filler;
+ /**
+ * Creates a new extractor configuration object
+ * @param identifier - name of this extractor
+ * @param className - class name of extractor
+ * @param configFiles - list of config file for this extractor (Note: only the first is used)
+ * @param filler - fill string for unextracted fields
+ */
+ public ExtractorConfig(String identifier, String className, List<File> configFiles, String filler) {
+ this.configFiles = configFiles;
+ this.className = className;
+ this.identifier = identifier;
+ this.filler = filler;
+ }
+ /**
+ * Gets the list of configuration files (Note: only the first, index 0, is used)
+ * @return config files
+ */
+ public List<File> getConfigFiles() {
+ return this.configFiles;
+ }
+ /**
+ * Accessor - get class name of this extractor
+ * @return class name
+ */
+ public String getClassName() {
+ return this.className;
+ }
+ /**
+ * Accessor - get identifier (i.e. name) of this extractor
+ * @return identifier
+ */
+ public String getIdentifier() {
+ return this.identifier;
+ }
+ /**
+ * Accessor - get the filler string
+ * @return filler
+ */
+ public String getFiller() {
+ return this.filler;
+ }
+}
http://git-wip-us.apache.org/repos/asf/oodt/blob/a47b088a/curator2/src/main/java/org/apache/oodt/cas/curation/structs/IngestionTask.java
----------------------------------------------------------------------
diff --git a/curator2/src/main/java/org/apache/oodt/cas/curation/structs/IngestionTask.java b/curator2/src/main/java/org/apache/oodt/cas/curation/structs/IngestionTask.java
new file mode 100644
index 0000000..d1a4327
--- /dev/null
+++ b/curator2/src/main/java/org/apache/oodt/cas/curation/structs/IngestionTask.java
@@ -0,0 +1,168 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.oodt.cas.curation.structs;
+
+//OODT imports
+import org.apache.oodt.cas.filemgr.ingest.Ingester;
+
+//JDK imports
+import java.util.Date;
+import java.util.List;
+import java.util.Vector;
+
+/**
+ *
+ * A specification for ingestion using the {@link Ingester} interface in the
+ * CAS.
+ *
+ * @author mattmann
+ * @version $Revision$
+ *
+ */
+public class IngestionTask implements IngestionTaskStatus {
+
+ private String id;
+
+ private Date createDate;
+
+ private List<String> fileList;
+
+ private String policy;
+
+ private String productType;
+
+ private String status;
+
+ private ExtractorConfig extConf;
+
+ public IngestionTask() {
+ this.id = null;
+ this.createDate = null;
+ this.fileList = new Vector<String>();
+ this.policy = null;
+ this.productType = null;
+ this.extConf = new ExtractorConfig(null, null, null,null);
+ }
+
+ /**
+ * @return the id
+ */
+ public String getId() {
+ return id;
+ }
+
+ /**
+ * @param id
+ * the id to set
+ */
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ /**
+ * @return the createDate
+ */
+ public Date getCreateDate() {
+ return createDate;
+ }
+
+ /**
+ * @param createDate
+ * the createDate to set
+ */
+ public void setCreateDate(Date createDate) {
+ this.createDate = createDate;
+ }
+
+ /**
+ * @return the fileList
+ */
+ public List<String> getFileList() {
+ return fileList;
+ }
+
+ /**
+ * @param fileList
+ * the fileList to set
+ */
+ public void setFileList(List<String> fileList) {
+ this.fileList = fileList;
+ }
+
+ /**
+ * @return the policy
+ */
+ public String getPolicy() {
+ return policy;
+ }
+
+ /**
+ * @param policy
+ * the policy to set
+ */
+ public void setPolicy(String policy) {
+ this.policy = policy;
+ }
+
+ /**
+ * @return the productType
+ */
+ public String getProductType() {
+ return productType;
+ }
+
+ /**
+ * @param productType
+ * the productType to set
+ */
+ public void setProductType(String productType) {
+ this.productType = productType;
+ }
+
+ /**
+ * @return the status
+ */
+ public String getStatus() {
+ return status;
+ }
+
+ /**
+ * @param status
+ * the status to set
+ */
+ public void setStatus(String status) {
+ this.status = status;
+ }
+
+ /**
+ * @return the extConf
+ */
+ public ExtractorConfig getExtConf() {
+ return extConf;
+ }
+
+ /**
+ * @param extConf
+ * the extConf to set
+ */
+ public void setExtConf(ExtractorConfig extConf) {
+ this.extConf = extConf;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/oodt/blob/a47b088a/curator2/src/main/java/org/apache/oodt/cas/curation/structs/IngestionTaskStatus.java
----------------------------------------------------------------------
diff --git a/curator2/src/main/java/org/apache/oodt/cas/curation/structs/IngestionTaskStatus.java b/curator2/src/main/java/org/apache/oodt/cas/curation/structs/IngestionTaskStatus.java
new file mode 100644
index 0000000..7527060
--- /dev/null
+++ b/curator2/src/main/java/org/apache/oodt/cas/curation/structs/IngestionTaskStatus.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.oodt.cas.curation.structs;
+
+/**
+ *
+ * Met keys for the {@link IngestionTask#getStatus()} field.
+ *
+ * @author mattmann
+ * @version $Revision$
+ *
+ */
+public interface IngestionTaskStatus {
+
+ public static final String FINISHED = "Finished";
+
+ public static final String STARTED = "Started";
+
+ public static final String NOT_STARTED = "Not Started";
+}